|
12 | 12 | use PHPStan\DependencyInjection\AutowiredService; |
13 | 13 | use PHPStan\Reflection\ConstantReflection; |
14 | 14 | use PHPStan\Reflection\ExtendedParameterReflection; |
| 15 | +use PHPStan\Reflection\FunctionReflection; |
| 16 | +use PHPStan\Reflection\MethodReflection; |
15 | 17 | use PHPStan\Reflection\ParameterReflection; |
16 | 18 | use PHPStan\Reflection\ParametersAcceptor; |
17 | 19 | use PHPStan\Reflection\ReflectionProvider; |
|
23 | 25 | use PHPStan\TrinaryLogic; |
24 | 26 | use PHPStan\Type\ConditionalType; |
25 | 27 | use PHPStan\Type\Constant\ConstantIntegerType; |
| 28 | +use PHPStan\Type\DynamicParameterTypeResolver; |
26 | 29 | use PHPStan\Type\ErrorType; |
27 | 30 | use PHPStan\Type\Generic\TemplateType; |
28 | 31 | use PHPStan\Type\IntegerRangeType; |
@@ -55,6 +58,7 @@ public function __construct( |
55 | 58 | private UnresolvableTypeHelper $unresolvableTypeHelper, |
56 | 59 | private PropertyReflectionFinder $propertyReflectionFinder, |
57 | 60 | private ReflectionProvider $reflectionProvider, |
| 61 | + private DynamicParameterTypeResolver $dynamicParameterTypeResolver, |
58 | 62 | #[AutowiredParameter(ref: '%checkFunctionArgumentTypes%')] |
59 | 63 | private bool $checkArgumentTypes, |
60 | 64 | #[AutowiredParameter] |
@@ -98,6 +102,7 @@ public function check( |
98 | 102 | string $exclusiveConstantsMessage, |
99 | 103 | string $bitmaskNotAllowedMessage, |
100 | 104 | ?array $renamedNamedArgumentParameterData, |
| 105 | + MethodReflection|FunctionReflection|null $calleeReflection = null, |
101 | 106 | ): array |
102 | 107 | { |
103 | 108 | if ($funcCall instanceof Node\Expr\MethodCall || $funcCall instanceof Node\Expr\StaticCall || $funcCall instanceof Node\Expr\FuncCall) { |
@@ -391,6 +396,15 @@ public function check( |
391 | 396 | if ($this->checkArgumentTypes) { |
392 | 397 | $parameterType = TypeUtils::resolveLateResolvableTypes($parameter->getType()); |
393 | 398 |
|
| 399 | + // judge the argument against the type the extensions announced for |
| 400 | + // the parameter, which is what NodeScopeResolver walked it with |
| 401 | + if (!$funcCall instanceof Node\Expr\New_) { |
| 402 | + $overriddenType = $this->dynamicParameterTypeResolver->resolve($funcCall, $calleeReflection, $parameter, $scope); |
| 403 | + if ($overriddenType !== null) { |
| 404 | + $parameterType = $overriddenType; |
| 405 | + } |
| 406 | + } |
| 407 | + |
394 | 408 | if ( |
395 | 409 | !$parameter->passedByReference()->createsNewVariable() |
396 | 410 | || (!$isBuiltin && !$argumentValueType instanceof ErrorType) |
|
0 commit comments