88use PHPStan \Analyser \Scope ;
99use PHPStan \DependencyInjection \AutowiredParameter ;
1010use PHPStan \DependencyInjection \AutowiredService ;
11+ use PHPStan \DependencyInjection \Type \DynamicParameterTypeExtensionProvider ;
1112use PHPStan \Reflection \ExtendedParameterReflection ;
13+ use PHPStan \Reflection \FunctionReflection ;
14+ use PHPStan \Reflection \MethodReflection ;
1215use PHPStan \Reflection \ParameterReflection ;
1316use PHPStan \Reflection \ParametersAcceptor ;
1417use 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}
0 commit comments