Skip to content

Commit bca27f1

Browse files
VincentLangletondrejmirtes
authored andcommitted
Fix interact method inference
1 parent af6ae0f commit bca27f1

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

src/Type/Symfony/InputInterfaceGetArgumentDynamicReturnTypeExtension.php

+10-2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
5757
$argName = $argStrings[0]->getValue();
5858

5959
$argTypes = [];
60+
$canBeNullInInteract = false;
6061
foreach ($this->consoleApplicationResolver->findCommands($classReflection) as $command) {
6162
try {
6263
$command->mergeApplicationDefinition();
@@ -70,6 +71,8 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
7071
$argType = new StringType();
7172
if (!$argument->isRequired()) {
7273
$argType = TypeCombinator::union($argType, $scope->getTypeFromValue($argument->getDefault()));
74+
} else {
75+
$canBeNullInInteract = true;
7376
}
7477
}
7578
$argTypes[] = $argType;
@@ -78,16 +81,21 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
7881
}
7982
}
8083

84+
if (count($argTypes) === 0) {
85+
return null;
86+
}
87+
8188
$method = $scope->getFunction();
8289
if (
83-
$method instanceof MethodReflection
90+
$canBeNullInInteract
91+
&& $method instanceof MethodReflection
8492
&& $method->getName() === 'interact'
8593
&& in_array('Symfony\Component\Console\Command\Command', $method->getDeclaringClass()->getParentClassesNames(), true)
8694
) {
8795
$argTypes[] = new NullType();
8896
}
8997

90-
return count($argTypes) > 0 ? TypeCombinator::union(...$argTypes) : null;
98+
return TypeCombinator::union(...$argTypes);
9199
}
92100

93101
}

tests/Type/Symfony/data/ExampleBaseCommand.php

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Symfony;
44

55
use Symfony\Component\Console\Command\Command;
6+
use Symfony\Component\Console\Input\InputArgument;
67
use Symfony\Component\Console\Input\InputInterface;
78
use Symfony\Component\Console\Output\OutputInterface;
89
use function PHPStan\Testing\assertType;
@@ -14,16 +15,18 @@ protected function configure(): void
1415
{
1516
parent::configure();
1617

18+
$this->addArgument('required', InputArgument::REQUIRED);
1719
$this->addArgument('base');
1820
}
1921

2022
protected function interact(InputInterface $input, OutputInterface $output): int
2123
{
2224
assertType('string|null', $input->getArgument('base'));
23-
assertType('string|null', $input->getArgument('aaa'));
24-
assertType('string|null', $input->getArgument('bbb'));
25-
assertType('array<int, string>|string|null', $input->getArgument('diff'));
26-
assertType('array<int, string>|null', $input->getArgument('arr'));
25+
assertType('string', $input->getArgument('aaa'));
26+
assertType('string', $input->getArgument('bbb'));
27+
assertType('string|null', $input->getArgument('required'));
28+
assertType('array<int, string>|string', $input->getArgument('diff'));
29+
assertType('array<int, string>', $input->getArgument('arr'));
2730
assertType('string|null', $input->getArgument('both'));
2831
assertType('Symfony\Component\Console\Helper\QuestionHelper', $this->getHelper('question'));
2932
}
@@ -33,6 +36,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
3336
assertType('string|null', $input->getArgument('base'));
3437
assertType('string', $input->getArgument('aaa'));
3538
assertType('string', $input->getArgument('bbb'));
39+
assertType('string', $input->getArgument('required'));
3640
assertType('array<int, string>|string', $input->getArgument('diff'));
3741
assertType('array<int, string>', $input->getArgument('arr'));
3842
assertType('string|null', $input->getArgument('both'));

0 commit comments

Comments
 (0)