From 1c8f86b96ccb5346610ff74c61c3fb2802e8ade8 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Wed, 19 Jun 2024 21:29:16 +0200 Subject: [PATCH] Also support command argument and initialize method --- ...eGetArgumentDynamicReturnTypeExtension.php | 2 +- ...eHasArgumentDynamicReturnTypeExtension.php | 12 ++++++++++ .../Type/Symfony/data/ExampleBaseCommand.php | 23 ++++++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php b/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php index 860317f6..5eb4cfe9 100644 --- a/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php +++ b/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php @@ -89,7 +89,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method if ( $canBeNullInInteract && $method instanceof MethodReflection - && $method->getName() === 'interact' + && ($method->getName() === 'interact' || $method->getName() === 'initialize') && in_array('Symfony\Component\Console\Command\Command', $method->getDeclaringClass()->getParentClassesNames(), true) ) { $argTypes[] = new NullType(); diff --git a/src/Type/Symfony/InputInterfaceHasArgumentDynamicReturnTypeExtension.php b/src/Type/Symfony/InputInterfaceHasArgumentDynamicReturnTypeExtension.php index 4ce49c4a..2ca6b4a1 100644 --- a/src/Type/Symfony/InputInterfaceHasArgumentDynamicReturnTypeExtension.php +++ b/src/Type/Symfony/InputInterfaceHasArgumentDynamicReturnTypeExtension.php @@ -13,6 +13,7 @@ use PHPStan\Type\TypeUtils; use function array_unique; use function count; +use function in_array; final class InputInterfaceHasArgumentDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { @@ -52,6 +53,17 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method } $argName = $argStrings[0]->getValue(); + if ($argName === 'command') { + $method = $scope->getFunction(); + if ( + $method instanceof MethodReflection + && ($method->getName() === 'interact' || $method->getName() === 'initialize') + && in_array('Symfony\Component\Console\Command\Command', $method->getDeclaringClass()->getParentClassesNames(), true) + ) { + return null; + } + } + $returnTypes = []; foreach ($this->consoleApplicationResolver->findCommands($classReflection) as $command) { try { diff --git a/tests/Type/Symfony/data/ExampleBaseCommand.php b/tests/Type/Symfony/data/ExampleBaseCommand.php index d2357089..0376429f 100644 --- a/tests/Type/Symfony/data/ExampleBaseCommand.php +++ b/tests/Type/Symfony/data/ExampleBaseCommand.php @@ -19,8 +19,26 @@ protected function configure(): void $this->addArgument('base'); } - protected function interact(InputInterface $input, OutputInterface $output): int + protected function initialize(InputInterface $input, OutputInterface $output): void { + assertType('bool', $input->hasArgument('command')); + assertType('string|null', $input->getArgument('command')); + + assertType('string|null', $input->getArgument('base')); + assertType('string', $input->getArgument('aaa')); + assertType('string', $input->getArgument('bbb')); + assertType('string|null', $input->getArgument('required')); + assertType('array|string', $input->getArgument('diff')); + assertType('array', $input->getArgument('arr')); + assertType('string|null', $input->getArgument('both')); + assertType('Symfony\Component\Console\Helper\QuestionHelper', $this->getHelper('question')); + } + + protected function interact(InputInterface $input, OutputInterface $output): void + { + assertType('bool', $input->hasArgument('command')); + assertType('string|null', $input->getArgument('command')); + assertType('string|null', $input->getArgument('base')); assertType('string', $input->getArgument('aaa')); assertType('string', $input->getArgument('bbb')); @@ -33,6 +51,9 @@ protected function interact(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int { + assertType('true', $input->hasArgument('command')); + assertType('string', $input->getArgument('command')); + assertType('string|null', $input->getArgument('base')); assertType('string', $input->getArgument('aaa')); assertType('string', $input->getArgument('bbb'));