Skip to content

Commit

Permalink
Fix interact method inference
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet authored and ondrejmirtes committed Jun 7, 2024
1 parent af6ae0f commit bca27f1
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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;
Expand All @@ -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);
}

}
12 changes: 8 additions & 4 deletions tests/Type/Symfony/data/ExampleBaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<int, string>|string|null', $input->getArgument('diff'));
assertType('array<int, string>|null', $input->getArgument('arr'));
assertType('string', $input->getArgument('aaa'));
assertType('string', $input->getArgument('bbb'));
assertType('string|null', $input->getArgument('required'));
assertType('array<int, string>|string', $input->getArgument('diff'));
assertType('array<int, string>', $input->getArgument('arr'));
assertType('string|null', $input->getArgument('both'));
assertType('Symfony\Component\Console\Helper\QuestionHelper', $this->getHelper('question'));
}
Expand All @@ -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<int, string>|string', $input->getArgument('diff'));
assertType('array<int, string>', $input->getArgument('arr'));
assertType('string|null', $input->getArgument('both'));
Expand Down

0 comments on commit bca27f1

Please sign in to comment.