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 ,
@@ -359,6 +364,13 @@ public function check(
359364 if ($ this ->checkArgumentTypes ) {
360365 $ parameterType = TypeUtils::resolveLateResolvableTypes ($ parameter ->getType ());
361366
367+ if (! $ funcCall instanceof Node \Expr \New_) {
368+ $ overriddenType = $ this ->getParameterTypeFromDynamicExtension ($ funcCall , $ calleeReflection , $ parameter , $ scope );
369+ if ($ overriddenType !== null ) {
370+ $ parameterType = $ overriddenType ;
371+ }
372+ }
373+
362374 if (
363375 !$ parameter ->passedByReference ()->createsNewVariable ()
364376 || (!$ isBuiltin && !$ argumentValueType instanceof ErrorType)
@@ -744,4 +756,50 @@ private function callReturnsByReference(Expr $expr, Scope $scope): bool
744756 return false ;
745757 }
746758
759+ private function getParameterTypeFromDynamicExtension (
760+ Node \Expr \FuncCall |Node \Expr \MethodCall |Node \Expr \StaticCall $ funcCall ,
761+ MethodReflection |FunctionReflection |null $ calleeReflection ,
762+ ParameterReflection $ parameter ,
763+ Scope $ scope ,
764+ ): ?Type
765+ {
766+ if ($ calleeReflection === null ) {
767+ return null ;
768+ }
769+
770+ if ($ funcCall instanceof Node \Expr \FuncCall && $ calleeReflection instanceof FunctionReflection) {
771+ foreach ($ this ->dynamicParameterTypeExtensionProvider ->getDynamicFunctionParameterTypeExtensions () as $ extension ) {
772+ if (!$ extension ->isFunctionSupported ($ calleeReflection , $ parameter )) {
773+ continue ;
774+ }
775+ $ type = $ extension ->getTypeFromFunctionCall ($ calleeReflection , $ funcCall , $ parameter , $ scope );
776+ if ($ type !== null ) {
777+ return $ type ;
778+ }
779+ }
780+ } elseif ($ funcCall instanceof Node \Expr \StaticCall && $ calleeReflection instanceof MethodReflection) {
781+ foreach ($ this ->dynamicParameterTypeExtensionProvider ->getDynamicStaticMethodParameterTypeExtensions () as $ extension ) {
782+ if (!$ extension ->isStaticMethodSupported ($ calleeReflection , $ parameter )) {
783+ continue ;
784+ }
785+ $ type = $ extension ->getTypeFromStaticMethodCall ($ calleeReflection , $ funcCall , $ parameter , $ scope );
786+ if ($ type !== null ) {
787+ return $ type ;
788+ }
789+ }
790+ } elseif ($ funcCall instanceof Node \Expr \MethodCall && $ calleeReflection instanceof MethodReflection) {
791+ foreach ($ this ->dynamicParameterTypeExtensionProvider ->getDynamicMethodParameterTypeExtensions () as $ extension ) {
792+ if (!$ extension ->isMethodSupported ($ calleeReflection , $ parameter )) {
793+ continue ;
794+ }
795+ $ type = $ extension ->getTypeFromMethodCall ($ calleeReflection , $ funcCall , $ parameter , $ scope );
796+ if ($ type !== null ) {
797+ return $ type ;
798+ }
799+ }
800+ }
801+
802+ return null ;
803+ }
804+
747805}
0 commit comments