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 5ecd82f

Browse files
committed
Dynamic return type extension for KernelInterface
1 parent 1c99543 commit 5ecd82f

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

‎phpstan.neon‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ parameters:
1212
- */tests/*/console_application_loader.php
1313
- */tests/*/envelope_all.php
1414
- */tests/*/header_bag_get.php
15+
- */tests/*/kernel_interface.php
1516
- */tests/*/request_get_content.php
1617
- */tests/*/serializer.php
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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\Reflection\ParametersAcceptorSelector;
9+
use PHPStan\Type\ArrayType;
10+
use PHPStan\Type\Constant\ConstantBooleanType;
11+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
12+
use PHPStan\Type\IntegerType;
13+
use PHPStan\Type\StringType;
14+
use PHPStan\Type\Type;
15+
16+
final class KernelInterfaceDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
17+
{
18+
19+
public function getClass(): string
20+
{
21+
return 'Symfony\Component\HttpKernel\KernelInterface';
22+
}
23+
24+
public function isMethodSupported(MethodReflection $methodReflection): bool
25+
{
26+
return $methodReflection->getName() === 'locateResource';
27+
}
28+
29+
public function getTypeFromMethodCall(
30+
MethodReflection $methodReflection,
31+
MethodCall $methodCall,
32+
Scope $scope
33+
): Type
34+
{
35+
$firstArgType = isset($methodCall->args[2]) ? $scope->getType($methodCall->args[2]->value) : new ConstantBooleanType(true);
36+
$isTrueType = (new ConstantBooleanType(true))->isSuperTypeOf($firstArgType);
37+
$isFalseType = (new ConstantBooleanType(false))->isSuperTypeOf($firstArgType);
38+
$compareTypes = $isTrueType->compareTo($isFalseType);
39+
40+
if ($compareTypes === $isTrueType) {
41+
return new StringType();
42+
}
43+
if ($compareTypes === $isFalseType) {
44+
return new ArrayType(new IntegerType(), new StringType());
45+
}
46+
47+
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
48+
}
49+
50+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Symfony;
4+
5+
use Iterator;
6+
7+
final class KernelInterfaceDynamicReturnTypeExtensionTest extends ExtensionTestCase
8+
{
9+
10+
/**
11+
* @dataProvider getProvider
12+
*/
13+
public function testGet(string $expression, string $type): void
14+
{
15+
$this->processFile(
16+
__DIR__ . '/kernel_interface.php',
17+
$expression,
18+
$type,
19+
new KernelInterfaceDynamicReturnTypeExtension()
20+
);
21+
}
22+
23+
public function getProvider(): Iterator
24+
{
25+
yield ['$foo', 'string'];
26+
yield ['$bar', 'string'];
27+
yield ['$baz', 'array<int, string>'];
28+
}
29+
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php declare(strict_types = 1);
2+
3+
$kernel = new class ('dev', true) extends \Symfony\Component\HttpKernel\Kernel {
4+
5+
public function registerBundles(): void
6+
{
7+
}
8+
9+
public function registerContainerConfiguration(\Symfony\Component\Config\Loader\LoaderInterface $loader): void
10+
{
11+
}
12+
13+
};
14+
15+
$foo = $kernel->locateResource('');
16+
$bar = $kernel->locateResource('', null, true);
17+
$baz = $kernel->locateResource('', null, false);
18+
19+
die;

0 commit comments

Comments
(0)

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