|
9 | 9 | use PHPStan\Reflection\ParametersAcceptorSelector;
|
10 | 10 | use PHPStan\Type\Constant\ConstantBooleanType;
|
11 | 11 | use PHPStan\Type\DynamicMethodReturnTypeExtension;
|
| 12 | +use PHPStan\Type\NullType; |
12 | 13 | use PHPStan\Type\Type;
|
13 | 14 | use PHPStan\Type\TypeCombinator;
|
14 |
| -use Psr\Container\ContainerInterface; |
| 15 | +use Symfony\Component\DependencyInjection\ContainerInterface; |
15 | 16 |
|
16 | 17 | class ContainerDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
|
17 | 18 | {
|
@@ -41,24 +42,54 @@ public function getTypeFromMethodCall(
|
41 | 42 | Scope $scope
|
42 | 43 | ): Type {
|
43 | 44 | $returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
|
44 |
| - $args = $methodCall->getArgs(); |
45 |
| - if (count($args) !== 1) { |
46 |
| - return $returnType; |
47 |
| - } |
48 |
| - |
49 | 45 | $methodName = $methodReflection->getName();
|
50 |
| - $types = []; |
51 |
| - $argType = $scope->getType($args[0]->value); |
52 | 46 |
|
53 |
| - foreach ($argType->getConstantStrings() as $constantStringType) { |
54 |
| - $serviceId = $constantStringType->getValue(); |
55 |
| - $service = $this->serviceMap->getService($serviceId); |
56 |
| - if ($methodName === 'get') { |
57 |
| - $types[] = $service !== null ? $service->getType() : $returnType; |
58 |
| - } elseif ($methodName === 'has') { |
| 47 | + if ($methodName === 'has') { |
| 48 | + $args = $methodCall->getArgs(); |
| 49 | + if (count($args) !== 1) { |
| 50 | + return $returnType; |
| 51 | + } |
| 52 | + |
| 53 | + $types = []; |
| 54 | + $argType = $scope->getType($args[0]->value); |
| 55 | + |
| 56 | + foreach ($argType->getConstantStrings() as $constantStringType) { |
| 57 | + $serviceId = $constantStringType->getValue(); |
| 58 | + $service = $this->serviceMap->getService($serviceId); |
59 | 59 | $types[] = new ConstantBooleanType($service !== null);
|
60 | 60 | }
|
| 61 | + |
| 62 | + return TypeCombinator::union(...$types); |
| 63 | + } elseif ($methodName === 'get') { |
| 64 | + $args = $methodCall->getArgs(); |
| 65 | + if (count($args) === 0) { |
| 66 | + return $returnType; |
| 67 | + } |
| 68 | + |
| 69 | + $types = []; |
| 70 | + |
| 71 | + if (isset($args[1])) { |
| 72 | + $invalidBehaviour = $scope->getType($args[1]->value); |
| 73 | + |
| 74 | + foreach ($invalidBehaviour->getConstantScalarValues() as $value) { |
| 75 | + if ($value === ContainerInterface::NULL_ON_INVALID_REFERENCE) { |
| 76 | + $types[] = new NullType(); |
| 77 | + break; |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | + $argType = $scope->getType($args[0]->value); |
| 83 | + |
| 84 | + foreach ($argType->getConstantStrings() as $constantStringType) { |
| 85 | + $serviceId = $constantStringType->getValue(); |
| 86 | + $service = $this->serviceMap->getService($serviceId); |
| 87 | + $types[] = $service !== null ? $service->getType() : $returnType; |
| 88 | + } |
| 89 | + |
| 90 | + return TypeCombinator::union(...$types); |
61 | 91 | }
|
62 |
| - return TypeCombinator::union(...$types); |
| 92 | + |
| 93 | + return $returnType; |
63 | 94 | }
|
64 | 95 | }
|
0 commit comments