Skip to content

Commit 9beb618

Browse files
committed
WIP: apply parameter closure type extension in FunctionCallParametersCheck
1 parent 475a18c commit 9beb618

27 files changed

+124
-12
lines changed

src/Rules/AttributesCheck.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ public function check(
127127
$nodeAttributes['isAttribute'] = true;
128128

129129
$parameterErrors = $this->functionCallParametersCheck->check(
130+
$attributeConstructor,
130131
ParametersAcceptorSelector::selectFromArgs(
131132
$scope,
132133
$attribute->args,

src/Rules/Classes/InstantiationRule.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ private function checkClassName(string $class, bool $isName, Node $node, Scope $
192192
$classDisplayName = SprintfHelper::escapeFormatString($classReflection->getDisplayName());
193193

194194
return array_merge($messages, $this->check->check(
195+
$constructorReflection,
195196
ParametersAcceptorSelector::selectFromArgs(
196197
$scope,
197198
$node->getArgs(),

src/Rules/FunctionCallParametersCheck.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
use PhpParser\Node\Expr;
77
use PHPStan\Analyser\MutatingScope;
88
use PHPStan\Analyser\Scope;
9+
use PHPStan\DependencyInjection\Type\ParameterClosureTypeExtensionProvider;
910
use PHPStan\Php\PhpVersion;
11+
use PHPStan\Reflection\FunctionReflection;
12+
use PHPStan\Reflection\MethodReflection;
1013
use PHPStan\Reflection\ParameterReflection;
1114
use PHPStan\Reflection\ParameterReflectionWithPhpDocs;
1215
use PHPStan\Reflection\ParametersAcceptor;
@@ -42,6 +45,7 @@ public function __construct(
4245
private PhpVersion $phpVersion,
4346
private UnresolvableTypeHelper $unresolvableTypeHelper,
4447
private PropertyReflectionFinder $propertyReflectionFinder,
48+
private ParameterClosureTypeExtensionProvider $parameterClosureTypeExtensionProvider,
4549
private bool $checkArgumentTypes,
4650
private bool $checkArgumentsPassedByReference,
4751
private bool $checkExtraArguments,
@@ -52,12 +56,14 @@ public function __construct(
5256
}
5357

5458
/**
59+
* @param MethodReflection|FunctionReflection|null $callReflection
5560
* @param Node\Expr\FuncCall|Node\Expr\MethodCall|Node\Expr\StaticCall|Node\Expr\New_ $funcCall
5661
* @param array{0: string, 1: string, 2: string, 3: string, 4: string, 5: string, 6: string, 7: string, 8: string, 9: string, 10: string, 11: string, 12: string, 13?: string, 14?: string} $messages
5762
* @param 'attribute'|'callable'|'method'|'staticMethod'|'function'|'new' $nodeType
5863
* @return list<IdentifierRuleError>
5964
*/
6065
public function check(
66+
$callReflection,
6167
ParametersAcceptor $parametersAcceptor,
6268
Scope $scope,
6369
bool $isBuiltin,
@@ -313,6 +319,17 @@ public function check(
313319
if ($this->checkArgumentTypes) {
314320
$parameterType = TypeUtils::resolveLateResolvableTypes($parameter->getType());
315321

322+
// TODO: handle other types of extensions
323+
if ($funcCall instanceof Expr\FuncCall && $callReflection instanceof FunctionReflection) {
324+
foreach ($this->parameterClosureTypeExtensionProvider->getFunctionParameterClosureTypeExtensions() as $functionParameterClosureTypeExtension) {
325+
if (!$functionParameterClosureTypeExtension->isFunctionSupported($callReflection, $parameter)) {
326+
continue;
327+
}
328+
$parameterType = $functionParameterClosureTypeExtension->getTypeFromFunctionCall($callReflection, $funcCall, $parameter, $scope) ?? $parameterType;
329+
330+
}
331+
}
332+
316333
if (
317334
!$parameter->passedByReference()->createsNewVariable()
318335
|| (!$isBuiltin && $this->checkUnresolvableParameterTypes) // bleeding edge only

src/Rules/Functions/CallCallablesRule.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public function processNode(
113113
return array_merge(
114114
$messages,
115115
$this->check->check(
116+
null,
116117
$parametersAcceptor,
117118
$scope,
118119
false,

src/Rules/Functions/CallToFunctionParametersRule.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function processNode(Node $node, Scope $scope): array
4040
$functionName = SprintfHelper::escapeFormatString($function->getName());
4141

4242
return $this->check->check(
43+
$function,
4344
ParametersAcceptorSelector::selectFromArgs(
4445
$scope,
4546
$node->getArgs(),

src/Rules/Functions/CallUserFuncRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function processNode(Node $node, Scope $scope): array
6060

6161
$callableDescription = 'callable passed to call_user_func()';
6262

63-
return $this->check->check($parametersAcceptor, $scope, false, $funcCall, [
63+
return $this->check->check(null, $parametersAcceptor, $scope, false, $funcCall, [
6464
ucfirst($callableDescription) . ' invoked with %d parameter, %d required.',
6565
ucfirst($callableDescription) . ' invoked with %d parameters, %d required.',
6666
ucfirst($callableDescription) . ' invoked with %d parameter, at least %d required.',

src/Rules/Methods/CallMethodsRule.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function processNode(Node $node, Scope $scope): array
4646
$messagesMethodName = SprintfHelper::escapeFormatString($declaringClass->getDisplayName() . '::' . $methodReflection->getName() . '()');
4747

4848
return array_merge($errors, $this->parametersCheck->check(
49+
$methodReflection,
4950
ParametersAcceptorSelector::selectFromArgs(
5051
$scope,
5152
$node->getArgs(),

src/Rules/Methods/CallStaticMethodsRule.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public function processNode(Node $node, Scope $scope): array
5454
));
5555

5656
$errors = array_merge($errors, $this->parametersCheck->check(
57+
$method,
5758
ParametersAcceptorSelector::selectFromArgs(
5859
$scope,
5960
$node->getArgs(),

tests/PHPStan/Analyser/Bug9307CallMethodsRuleTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Analyser;
44

5+
use PHPStan\DependencyInjection\Type\ParameterClosureTypeExtensionProvider;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\Rules\FunctionCallParametersCheck;
78
use PHPStan\Rules\Methods\CallMethodsRule;
@@ -26,7 +27,7 @@ protected function getRule(): Rule
2627
$ruleLevelHelper = new RuleLevelHelper($reflectionProvider, true, false, true, true, false, true, false);
2728
return new CallMethodsRule(
2829
new MethodCallCheck($reflectionProvider, $ruleLevelHelper, true, true),
29-
new FunctionCallParametersCheck($ruleLevelHelper, new NullsafeCheck(), new PhpVersion(PHP_VERSION_ID), new UnresolvableTypeHelper(), new PropertyReflectionFinder(), true, true, true, true, true),
30+
new FunctionCallParametersCheck($ruleLevelHelper, new NullsafeCheck(), new PhpVersion(PHP_VERSION_ID), new UnresolvableTypeHelper(), new PropertyReflectionFinder(), self::getContainer()->getByType(ParameterClosureTypeExtensionProvider::class), true, true, true, true, true),
3031
);
3132
}
3233

tests/PHPStan/Rules/Classes/ClassAttributesRuleTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Rules\Classes;
44

5+
use PHPStan\DependencyInjection\Type\ParameterClosureTypeExtensionProvider;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\Rules\AttributesCheck;
78
use PHPStan\Rules\ClassCaseSensitivityCheck;
@@ -34,6 +35,7 @@ protected function getRule(): Rule
3435
new PhpVersion(80000),
3536
new UnresolvableTypeHelper(),
3637
new PropertyReflectionFinder(),
38+
self::getContainer()->getByType(ParameterClosureTypeExtensionProvider::class),
3739
true,
3840
true,
3941
true,

0 commit comments

Comments
 (0)