Skip to content

Commit 4e20d2e

Browse files
committed
Forward compatibility fix for extensions of generic methods
1 parent 51488c9 commit 4e20d2e

File tree

3 files changed

+8
-33
lines changed

3 files changed

+8
-33
lines changed

Diff for: src/Type/Symfony/InputBagTypeSpecifyingExtension.php

+3-21
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99
use PHPStan\Analyser\TypeSpecifierAwareExtension;
1010
use PHPStan\Analyser\TypeSpecifierContext;
1111
use PHPStan\Reflection\MethodReflection;
12-
use PHPStan\Reflection\ParametersAcceptorSelector;
13-
use PHPStan\Reflection\ReflectionProvider;
1412
use PHPStan\Type\MethodTypeSpecifyingExtension;
15-
use PHPStan\Type\TypeCombinator;
13+
use PHPStan\Type\NullType;
1614
use Symfony\Component\HttpFoundation\InputBag;
1715

1816
final class InputBagTypeSpecifyingExtension implements MethodTypeSpecifyingExtension, TypeSpecifierAwareExtension
@@ -22,17 +20,9 @@ final class InputBagTypeSpecifyingExtension implements MethodTypeSpecifyingExten
2220
private const HAS_METHOD_NAME = 'has';
2321
private const GET_METHOD_NAME = 'get';
2422

25-
/** @var ReflectionProvider */
26-
private $reflectionProvider;
27-
2823
/** @var TypeSpecifier */
2924
private $typeSpecifier;
3025

31-
public function __construct(ReflectionProvider $reflectionProvider)
32-
{
33-
$this->reflectionProvider = $reflectionProvider;
34-
}
35-
3626
public function getClass(): string
3727
{
3828
return self::INPUT_BAG_CLASS;
@@ -45,18 +35,10 @@ public function isMethodSupported(MethodReflection $methodReflection, MethodCall
4535

4636
public function specifyTypes(MethodReflection $methodReflection, MethodCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes
4737
{
48-
$classReflection = $this->reflectionProvider->getClass(self::INPUT_BAG_CLASS);
49-
$methodVariants = $classReflection->getNativeMethod(self::GET_METHOD_NAME)->getVariants();
50-
$returnType = ParametersAcceptorSelector::selectSingle($methodVariants)->getReturnType();
51-
52-
if (!TypeCombinator::containsNull($returnType)) {
53-
return new SpecifiedTypes();
54-
}
55-
5638
return $this->typeSpecifier->create(
5739
new MethodCall($node->var, self::GET_METHOD_NAME, $node->getArgs()),
58-
TypeCombinator::removeNull($returnType),
59-
$context
40+
new NullType(),
41+
$context->negate()
6042
);
6143
}
6244

Diff for: src/Type/Symfony/RequestTypeSpecifyingExtension.php

+2-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use PHPStan\Analyser\TypeSpecifier;
99
use PHPStan\Analyser\TypeSpecifierAwareExtension;
1010
use PHPStan\Analyser\TypeSpecifierContext;
11-
use PHPStan\Broker\Broker;
1211
use PHPStan\Reflection\MethodReflection;
1312
use PHPStan\Reflection\ParametersAcceptorSelector;
1413
use PHPStan\Type\MethodTypeSpecifyingExtension;
@@ -21,17 +20,9 @@ final class RequestTypeSpecifyingExtension implements MethodTypeSpecifyingExtens
2120
private const HAS_METHOD_NAME = 'hasSession';
2221
private const GET_METHOD_NAME = 'getSession';
2322

24-
/** @var Broker */
25-
private $broker;
26-
2723
/** @var TypeSpecifier */
2824
private $typeSpecifier;
2925

30-
public function __construct(Broker $broker)
31-
{
32-
$this->broker = $broker;
33-
}
34-
3526
public function getClass(): string
3627
{
3728
return self::REQUEST_CLASS;
@@ -44,9 +35,8 @@ public function isMethodSupported(MethodReflection $methodReflection, MethodCall
4435

4536
public function specifyTypes(MethodReflection $methodReflection, MethodCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes
4637
{
47-
$classReflection = $this->broker->getClass(self::REQUEST_CLASS);
48-
$methodVariants = $classReflection->getNativeMethod(self::GET_METHOD_NAME)->getVariants();
49-
$returnType = ParametersAcceptorSelector::selectSingle($methodVariants)->getReturnType();
38+
$methodVariants = $methodReflection->getDeclaringClass()->getNativeMethod(self::GET_METHOD_NAME)->getVariants();
39+
$returnType = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $methodVariants)->getReturnType();
5040

5141
if (!TypeCombinator::containsNull($returnType)) {
5242
return new SpecifiedTypes();

Diff for: tests/Type/Symfony/data/input_bag.php

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
if ($bag->has('foo')) {
1010
assertType('bool|float|int|string', $bag->get('foo'));
1111
assertType('bool|float|int|string|null', $bag->get('bar'));
12+
} else {
13+
assertType('null', $bag->get('foo'));
14+
assertType('bool|float|int|string|null', $bag->get('bar'));
1215
}
1316

1417
assertType('bool|float|int|string|null', $bag->get('foo', null));

0 commit comments

Comments
 (0)