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 f9ae282

Browse files
committed
fix: apply dynamic parameter type extensions in FunctionCallParametersCheck
1 parent 4cb7082 commit f9ae282

29 files changed

+103
-15
lines changed

‎e2e/parameter-type-extension/phpstan-baseline.neon‎

Lines changed: 0 additions & 7 deletions
This file was deleted.

‎e2e/parameter-type-extension/phpstan.neon.dist‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
includes:
2-
- phpstan-baseline.neon
31
parameters:
42
level: 9
53
paths:

‎src/Rules/AttributesCheck.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public function check(
139139
),
140140
$scope,
141141
$attributeConstructor->getDeclaringClass()->isBuiltin(),
142+
null,
142143
new New_($attribute->name, $attribute->args, $nodeAttributes),
143144
'attribute',
144145
$attributeConstructor->acceptsNamedArguments(),

‎src/Rules/Classes/InstantiationRule.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ private function checkClassName(string $class, bool $isName, Node $node, Scope $
238238
),
239239
$scope,
240240
$constructorReflection->getDeclaringClass()->isBuiltin(),
241+
null,
241242
$node,
242243
'new',
243244
$constructorReflection->acceptsNamedArguments(),

‎src/Rules/FunctionCallParametersCheck.php‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
use PHPStan\Analyser\Scope;
99
use PHPStan\DependencyInjection\AutowiredParameter;
1010
use PHPStan\DependencyInjection\AutowiredService;
11+
use PHPStan\DependencyInjection\Type\DynamicParameterTypeExtensionProvider;
1112
use PHPStan\Reflection\ExtendedParameterReflection;
13+
use PHPStan\Reflection\FunctionReflection;
14+
use PHPStan\Reflection\MethodReflection;
1215
use PHPStan\Reflection\ParameterReflection;
1316
use PHPStan\Reflection\ParametersAcceptor;
1417
use PHPStan\Reflection\ResolvedFunctionVariant;
@@ -46,6 +49,7 @@ public function __construct(
4649
private NullsafeCheck $nullsafeCheck,
4750
private UnresolvableTypeHelper $unresolvableTypeHelper,
4851
private PropertyReflectionFinder $propertyReflectionFinder,
52+
private DynamicParameterTypeExtensionProvider $dynamicParameterTypeExtensionProvider,
4953
#[AutowiredParameter(ref: '%checkFunctionArgumentTypes%')]
5054
private bool $checkArgumentTypes,
5155
#[AutowiredParameter]
@@ -66,6 +70,7 @@ public function check(
6670
ParametersAcceptor $parametersAcceptor,
6771
Scope $scope,
6872
bool $isBuiltin,
73+
MethodReflection|FunctionReflection|null $calleeReflection,
6974
Node\Expr\FuncCall|Node\Expr\MethodCall|Node\Expr\StaticCall|Node\Expr\New_ $funcCall,
7075
string $nodeType,
7176
TrinaryLogic $acceptsNamedArguments,
@@ -349,6 +354,13 @@ public function check(
349354
if ($this->checkArgumentTypes) {
350355
$parameterType = TypeUtils::resolveLateResolvableTypes($parameter->getType());
351356

357+
if (! $funcCall instanceof Node\Expr\New_) {
358+
$overriddenType = $this->getParameterTypeFromDynamicExtension($funcCall, $calleeReflection, $parameter, $scope);
359+
if ($overriddenType !== null) {
360+
$parameterType = $overriddenType;
361+
}
362+
}
363+
352364
if (
353365
!$parameter->passedByReference()->createsNewVariable()
354366
|| (!$isBuiltin && !$argumentValueType instanceof ErrorType)
@@ -681,4 +693,50 @@ private function describeParameter(ParameterReflection $parameter, int|string|nu
681693
return implode('', $parts);
682694
}
683695

696+
private function getParameterTypeFromDynamicExtension(
697+
Node\Expr\FuncCall|Node\Expr\MethodCall|Node\Expr\StaticCall $funcCall,
698+
MethodReflection|FunctionReflection|null $calleeReflection,
699+
ParameterReflection $parameter,
700+
Scope $scope,
701+
): ?Type
702+
{
703+
if ($calleeReflection === null) {
704+
return null;
705+
}
706+
707+
if ($funcCall instanceof Node\Expr\FuncCall && $calleeReflection instanceof FunctionReflection) {
708+
foreach ($this->dynamicParameterTypeExtensionProvider->getDynamicFunctionParameterTypeExtensions() as $extension) {
709+
if (!$extension->isFunctionSupported($calleeReflection, $parameter)) {
710+
continue;
711+
}
712+
$type = $extension->getTypeFromFunctionCall($calleeReflection, $funcCall, $parameter, $scope);
713+
if ($type !== null) {
714+
return $type;
715+
}
716+
}
717+
} elseif ($funcCall instanceof Node\Expr\StaticCall && $calleeReflection instanceof MethodReflection) {
718+
foreach ($this->dynamicParameterTypeExtensionProvider->getDynamicStaticMethodParameterTypeExtensions() as $extension) {
719+
if (!$extension->isStaticMethodSupported($calleeReflection, $parameter)) {
720+
continue;
721+
}
722+
$type = $extension->getTypeFromStaticMethodCall($calleeReflection, $funcCall, $parameter, $scope);
723+
if ($type !== null) {
724+
return $type;
725+
}
726+
}
727+
} elseif ($funcCall instanceof Node\Expr\MethodCall && $calleeReflection instanceof MethodReflection) {
728+
foreach ($this->dynamicParameterTypeExtensionProvider->getDynamicMethodParameterTypeExtensions() as $extension) {
729+
if (!$extension->isMethodSupported($calleeReflection, $parameter)) {
730+
continue;
731+
}
732+
$type = $extension->getTypeFromMethodCall($calleeReflection, $funcCall, $parameter, $scope);
733+
if ($type !== null) {
734+
return $type;
735+
}
736+
}
737+
}
738+
739+
return null;
740+
}
741+
684742
}

‎src/Rules/Functions/CallCallablesRule.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public function processNode(
121121
$parametersAcceptor,
122122
$scope,
123123
false,
124+
null,
124125
$node,
125126
'callable',
126127
$acceptsNamedArguments,

‎src/Rules/Functions/CallToFunctionParametersRule.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public function processNode(Node $node, Scope $scope): array
5050
),
5151
$scope,
5252
$function->isBuiltin(),
53+
$function,
5354
$node,
5455
'function',
5556
$function->acceptsNamedArguments(),

‎src/Rules/Functions/CallUserFuncRule.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public function processNode(Node $node, Scope $scope): array
6666
$parametersAcceptor,
6767
$scope,
6868
false,
69+
null,
6970
$funcCall,
7071
'function',
7172
$acceptsNamedArguments,

‎src/Rules/Methods/CallMethodsRule.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ private function processSingleMethodCall(Scope $scope, MethodCall $node, string
8181
),
8282
$scope,
8383
$declaringClass->isBuiltin(),
84+
$methodReflection,
8485
$node,
8586
'method',
8687
$methodReflection->acceptsNamedArguments(),

‎src/Rules/Methods/CallStaticMethodsRule.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ private function processSingleMethodCall(Scope $scope, StaticCall $node, string
9090
),
9191
$scope,
9292
$method->getDeclaringClass()->isBuiltin(),
93+
$method,
9394
$node,
9495
'staticMethod',
9596
$method->acceptsNamedArguments(),

0 commit comments

Comments
(0)

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