From bca27f1701fc1a297749e6c2a1e3da4462c1a6af Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 6 Jun 2024 15:55:20 +0200 Subject: [PATCH] Fix interact method inference --- ...nterfaceGetArgumentDynamicReturnTypeExtension.php | 12 ++++++++++-- tests/Type/Symfony/data/ExampleBaseCommand.php | 12 ++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php b/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php index a8d3eb3..860317f 100644 --- a/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php +++ b/src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php @@ -57,6 +57,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method $argName = $argStrings[0]->getValue(); $argTypes = []; + $canBeNullInInteract = false; foreach ($this->consoleApplicationResolver->findCommands($classReflection) as $command) { try { $command->mergeApplicationDefinition(); @@ -70,6 +71,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method $argType = new StringType(); if (!$argument->isRequired()) { $argType = TypeCombinator::union($argType, $scope->getTypeFromValue($argument->getDefault())); + } else { + $canBeNullInInteract = true; } } $argTypes[] = $argType; @@ -78,16 +81,21 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method } } + if (count($argTypes) === 0) { + return null; + } + $method = $scope->getFunction(); if ( - $method instanceof MethodReflection + $canBeNullInInteract + && $method instanceof MethodReflection && $method->getName() === 'interact' && in_array('Symfony\Component\Console\Command\Command', $method->getDeclaringClass()->getParentClassesNames(), true) ) { $argTypes[] = new NullType(); } - return count($argTypes) > 0 ? TypeCombinator::union(...$argTypes) : null; + return TypeCombinator::union(...$argTypes); } } diff --git a/tests/Type/Symfony/data/ExampleBaseCommand.php b/tests/Type/Symfony/data/ExampleBaseCommand.php index 6c1f942..d235708 100644 --- a/tests/Type/Symfony/data/ExampleBaseCommand.php +++ b/tests/Type/Symfony/data/ExampleBaseCommand.php @@ -3,6 +3,7 @@ namespace PHPStan\Type\Symfony; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use function PHPStan\Testing\assertType; @@ -14,16 +15,18 @@ protected function configure(): void { parent::configure(); + $this->addArgument('required', InputArgument::REQUIRED); $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', $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')); } @@ -33,6 +36,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int assertType('string|null', $input->getArgument('base')); assertType('string', $input->getArgument('aaa')); assertType('string', $input->getArgument('bbb')); + assertType('string', $input->getArgument('required')); assertType('array|string', $input->getArgument('diff')); assertType('array', $input->getArgument('arr')); assertType('string|null', $input->getArgument('both'));