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 \ReflectionProvider ;
@@ -49,6 +52,7 @@ public function __construct(
4952 private UnresolvableTypeHelper $ unresolvableTypeHelper ,
5053 private PropertyReflectionFinder $ propertyReflectionFinder ,
5154 private ReflectionProvider $ reflectionProvider ,
55+ private DynamicParameterTypeExtensionProvider $ dynamicParameterTypeExtensionProvider ,
5256 #[AutowiredParameter(ref: '%checkFunctionArgumentTypes% ' )]
5357 private bool $ checkArgumentTypes ,
5458 #[AutowiredParameter]
@@ -69,6 +73,7 @@ public function check(
6973 ParametersAcceptor $ parametersAcceptor ,
7074 Scope $ scope ,
7175 bool $ isBuiltin ,
76+ MethodReflection |FunctionReflection |null $ calleeReflection ,
7277 Node \Expr \FuncCall |Node \Expr \MethodCall |Node \Expr \StaticCall |Node \Expr \New_ $ funcCall ,
7378 string $ nodeType ,
7479 TrinaryLogic $ acceptsNamedArguments ,
@@ -353,6 +358,13 @@ public function check(
353358 if ($ this ->checkArgumentTypes ) {
354359 $ parameterType = TypeUtils::resolveLateResolvableTypes ($ parameter ->getType ());
355360
361+ if (! $ funcCall instanceof Node \Expr \New_) {
362+ $ overriddenType = $ this ->getParameterTypeFromDynamicExtension ($ funcCall , $ calleeReflection , $ parameter , $ scope );
363+ if ($ overriddenType !== null ) {
364+ $ parameterType = $ overriddenType ;
365+ }
366+ }
367+
356368 if (
357369 !$ parameter ->passedByReference ()->createsNewVariable ()
358370 || (!$ isBuiltin && !$ argumentValueType instanceof ErrorType)
@@ -738,4 +750,50 @@ private function callReturnsByReference(Expr $expr, Scope $scope): bool
738750 return false ;
739751 }
740752
753+ private function getParameterTypeFromDynamicExtension (
754+ Node \Expr \FuncCall |Node \Expr \MethodCall |Node \Expr \StaticCall $ funcCall ,
755+ MethodReflection |FunctionReflection |null $ calleeReflection ,
756+ ParameterReflection $ parameter ,
757+ Scope $ scope ,
758+ ): ?Type
759+ {
760+ if ($ calleeReflection === null ) {
761+ return null ;
762+ }
763+
764+ if ($ funcCall instanceof Node \Expr \FuncCall && $ calleeReflection instanceof FunctionReflection) {
765+ foreach ($ this ->dynamicParameterTypeExtensionProvider ->getDynamicFunctionParameterTypeExtensions () as $ extension ) {
766+ if (!$ extension ->isFunctionSupported ($ calleeReflection , $ parameter )) {
767+ continue ;
768+ }
769+ $ type = $ extension ->getTypeFromFunctionCall ($ calleeReflection , $ funcCall , $ parameter , $ scope );
770+ if ($ type !== null ) {
771+ return $ type ;
772+ }
773+ }
774+ } elseif ($ funcCall instanceof Node \Expr \StaticCall && $ calleeReflection instanceof MethodReflection) {
775+ foreach ($ this ->dynamicParameterTypeExtensionProvider ->getDynamicStaticMethodParameterTypeExtensions () as $ extension ) {
776+ if (!$ extension ->isStaticMethodSupported ($ calleeReflection , $ parameter )) {
777+ continue ;
778+ }
779+ $ type = $ extension ->getTypeFromStaticMethodCall ($ calleeReflection , $ funcCall , $ parameter , $ scope );
780+ if ($ type !== null ) {
781+ return $ type ;
782+ }
783+ }
784+ } elseif ($ funcCall instanceof Node \Expr \MethodCall && $ calleeReflection instanceof MethodReflection) {
785+ foreach ($ this ->dynamicParameterTypeExtensionProvider ->getDynamicMethodParameterTypeExtensions () as $ extension ) {
786+ if (!$ extension ->isMethodSupported ($ calleeReflection , $ parameter )) {
787+ continue ;
788+ }
789+ $ type = $ extension ->getTypeFromMethodCall ($ calleeReflection , $ funcCall , $ parameter , $ scope );
790+ if ($ type !== null ) {
791+ return $ type ;
792+ }
793+ }
794+ }
795+
796+ return null ;
797+ }
798+
741799}
0 commit comments