From aac8356fa556ab56a4f6bf6a7f920b1cc74c750d Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 20 May 2024 14:48:02 +0200 Subject: [PATCH 1/2] Update getArgument return type in interact method --- ...InterfaceGetArgumentDynamicReturnTypeExtension.php | 6 ++++++ tests/Type/Symfony/data/ExampleBaseCommand.php | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php b/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php index 0af7c88d..1051e9f0 100644 --- a/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php +++ b/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php @@ -10,6 +10,7 @@ use PHPStan\Type\ArrayType; use PHPStan\Type\DynamicMethodReturnTypeExtension; use PHPStan\Type\IntegerType; +use PHPStan\Type\NullType; use PHPStan\Type\StringType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; @@ -76,6 +77,11 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method } } + $method = $scope->getFunction(); + if ($method instanceof MethodReflection && $method->getName() === 'interact') { + $argTypes[] = new NullType(); + } + return count($argTypes) > 0 ? TypeCombinator::union(...$argTypes) : null; } diff --git a/tests/Type/Symfony/data/ExampleBaseCommand.php b/tests/Type/Symfony/data/ExampleBaseCommand.php index 0ab3a322..6c1f9422 100644 --- a/tests/Type/Symfony/data/ExampleBaseCommand.php +++ b/tests/Type/Symfony/data/ExampleBaseCommand.php @@ -17,6 +17,17 @@ protected function configure(): void $this->addArgument('base'); } + protected function interact(InputInterface $input, OutputInterface $output): int + { + assertType('string|null', $input->getArgument('base')); + assertType('string|null', $input->getArgument('aaa')); + assertType('string|null', $input->getArgument('bbb')); + assertType('array|string|null', $input->getArgument('diff')); + assertType('array|null', $input->getArgument('arr')); + assertType('string|null', $input->getArgument('both')); + assertType('Symfony\Component\Console\Helper\QuestionHelper', $this->getHelper('question')); + } + protected function execute(InputInterface $input, OutputInterface $output): int { assertType('string|null', $input->getArgument('base')); From 1dfe11998bcee3529ffc18332a00c385f4e14bb0 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 30 May 2024 16:33:06 +0200 Subject: [PATCH 2/2] Add classname check --- ...InputInterfaceGetArgumentDynamicReturnTypeExtension.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php b/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php index 1051e9f0..a8d3eb37 100644 --- a/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php +++ b/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php @@ -16,6 +16,7 @@ use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypeUtils; use function count; +use function in_array; final class InputInterfaceGetArgumentDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { @@ -78,7 +79,11 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method } $method = $scope->getFunction(); - if ($method instanceof MethodReflection && $method->getName() === 'interact') { + if ( + $method instanceof MethodReflection + && $method->getName() === 'interact' + && in_array('Symfony\Component\Console\Command\Command', $method->getDeclaringClass()->getParentClassesNames(), true) + ) { $argTypes[] = new NullType(); }