Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d31922c

Browse files
lookymanondrejmirtes
authored andcommitted
Command::getHelper return type
1 parent 9e985a9 commit d31922c

File tree

5 files changed

+97
-0
lines changed

5 files changed

+97
-0
lines changed

‎extension.neon‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ parameters:
1212
- stubs/Symfony/Bundle/FrameworkBundle/KernelBrowser.stub
1313
- stubs/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.stub
1414
- stubs/Symfony/Bundle/FrameworkBundle/Test/TestContainer.stub
15+
- stubs/Symfony/Component/Console/Command.stub
16+
- stubs/Symfony/Component/Console/Helper/HelperInterface.stub
1517
- stubs/Symfony/Component/Form/ChoiceList/Loader/ChoiceLoaderInterface.stub
1618
- stubs/Symfony/Component/DependencyInjection/ContainerBuilder.stub
1719
- stubs/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.stub
@@ -255,3 +257,8 @@ services:
255257
-
256258
factory: PHPStan\Type\Symfony\Form\FormInterfaceDynamicReturnTypeExtension
257259
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
260+
261+
# Command::getHelper() return type
262+
-
263+
factory: PHPStan\Type\Symfony\CommandGetHelperDynamicReturnTypeExtension
264+
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Symfony;
4+
5+
use PhpParser\Node\Expr\MethodCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Reflection\MethodReflection;
8+
use PHPStan\Symfony\ConsoleApplicationResolver;
9+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
10+
use PHPStan\Type\ObjectType;
11+
use PHPStan\Type\Type;
12+
use PHPStan\Type\TypeCombinator;
13+
use PHPStan\Type\TypeUtils;
14+
use Throwable;
15+
use function count;
16+
use function get_class;
17+
18+
final class CommandGetHelperDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
19+
{
20+
21+
/** @var \PHPStan\Symfony\ConsoleApplicationResolver */
22+
private $consoleApplicationResolver;
23+
24+
public function __construct(ConsoleApplicationResolver $consoleApplicationResolver)
25+
{
26+
$this->consoleApplicationResolver = $consoleApplicationResolver;
27+
}
28+
29+
public function getClass(): string
30+
{
31+
return 'Symfony\Component\Console\Command\Command';
32+
}
33+
34+
public function isMethodSupported(MethodReflection $methodReflection): bool
35+
{
36+
return $methodReflection->getName() === 'getHelper';
37+
}
38+
39+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
40+
{
41+
$defaultReturnType = new ObjectType('Symfony\Component\Console\Helper\HelperInterface');
42+
43+
if (!isset($methodCall->getArgs()[0])) {
44+
return $defaultReturnType;
45+
}
46+
47+
$classReflection = $scope->getClassReflection();
48+
if ($classReflection === null) {
49+
return $defaultReturnType;
50+
}
51+
52+
$argStrings = TypeUtils::getConstantStrings($scope->getType($methodCall->getArgs()[0]->value));
53+
if (count($argStrings) !== 1) {
54+
return $defaultReturnType;
55+
}
56+
$argName = $argStrings[0]->getValue();
57+
58+
$returnTypes = [];
59+
foreach ($this->consoleApplicationResolver->findCommands($classReflection) as $command) {
60+
try {
61+
$command->mergeApplicationDefinition();
62+
$returnTypes[] = new ObjectType(get_class($command->getHelper($argName)));
63+
} catch (Throwable $e) {
64+
// no-op
65+
}
66+
}
67+
68+
return count($returnTypes) > 0 ? TypeCombinator::union(...$returnTypes) : $defaultReturnType;
69+
}
70+
71+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\Console\Command;
4+
5+
class Command
6+
{
7+
/**
8+
* @return \Symfony\Component\Console\Helper\HelperInterface
9+
*/
10+
public function getHelper(string $name);
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\Console\Helper;
4+
5+
interface HelperInterface
6+
{
7+
}

‎tests/Type/Symfony/data/ExampleBaseCommand.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
2525
assertType('array<int, string>|string', $input->getArgument('diff'));
2626
assertType('array<int, string>', $input->getArgument('arr'));
2727
assertType('string|null', $input->getArgument('both'));
28+
assertType('Symfony\Component\Console\Helper\QuestionHelper', $this->getHelper('question'));
2829
}
2930

3031
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /