66use PhpParser \Node \Expr ;
77use PHPStan \Analyser \MutatingScope ;
88use PHPStan \Analyser \Scope ;
9+ use PHPStan \DependencyInjection \Type \ParameterClosureTypeExtensionProvider ;
910use PHPStan \Php \PhpVersion ;
11+ use PHPStan \Reflection \FunctionReflection ;
12+ use PHPStan \Reflection \MethodReflection ;
1013use PHPStan \Reflection \ParameterReflection ;
1114use PHPStan \Reflection \ParameterReflectionWithPhpDocs ;
1215use 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
0 commit comments