1010use PHPStan \Reflection \ExtendedParametersAcceptor ;
1111use PHPStan \Reflection \Php \ExtendedDummyParameter ;
1212use PHPStan \Reflection \ResolvedMethodReflection ;
13+ use PHPStan \Type \ThisType ;
1314use PHPStan \Type \Type ;
15+ use PHPStan \Type \TypeCombinator ;
1416use function array_map ;
1517
1618final class CallbackUnresolvedMethodPrototypeReflection implements UnresolvedMethodPrototypeReflection
@@ -82,32 +84,42 @@ public function withCalledOnType(Type $type): UnresolvedMethodPrototypeReflectio
8284
8385 private function transformMethodWithStaticType (ClassReflection $ declaringClass , ExtendedMethodReflection $ method ): ExtendedMethodReflection
8486 {
85- $ variantFn = fn (ExtendedParametersAcceptor $ acceptor ): ExtendedParametersAcceptor => new ExtendedFunctionVariant (
86- $ acceptor ->getTemplateTypeMap (),
87- $ acceptor ->getResolvedTemplateTypeMap (),
88- array_map (
89- fn (ExtendedParameterReflection $ parameter ): ExtendedParameterReflection => new ExtendedDummyParameter (
90- $ parameter ->getName (),
91- $ this ->transformStaticType ($ parameter ->getType ()),
92- $ parameter ->isOptional (),
93- $ parameter ->passedByReference (),
94- $ parameter ->isVariadic (),
95- $ parameter ->getDefaultValue (),
96- $ parameter ->getNativeType (),
97- $ this ->transformStaticType ($ parameter ->getPhpDocType ()),
98- $ parameter ->getOutType () !== null ? $ this ->transformStaticType ($ parameter ->getOutType ()) : null ,
99- $ parameter ->isImmediatelyInvokedCallable (),
100- $ parameter ->getClosureThisType () !== null ? $ this ->transformStaticType ($ parameter ->getClosureThisType ()) : null ,
101- $ parameter ->getAttributes (),
87+ $ selfOutType = $ method ->getSelfOutType () !== null ? $ this ->transformStaticType ($ method ->getSelfOutType ()) : null ;
88+ $ variantFn = function (ExtendedParametersAcceptor $ acceptor ) use (&$ selfOutType ): ExtendedParametersAcceptor {
89+ $ originalReturnType = $ acceptor ->getReturnType ();
90+ if ($ originalReturnType instanceof ThisType && $ selfOutType !== null ) {
91+ $ returnType = TypeCombinator::intersect ($ selfOutType , $ this ->transformStaticType ($ originalReturnType ));
92+ $ selfOutType = $ returnType ;
93+ } else {
94+ $ returnType = $ this ->transformStaticType ($ originalReturnType );
95+ }
96+ return new ExtendedFunctionVariant (
97+ $ acceptor ->getTemplateTypeMap (),
98+ $ acceptor ->getResolvedTemplateTypeMap (),
99+ array_map (
100+ fn (ExtendedParameterReflection $ parameter ): ExtendedParameterReflection => new ExtendedDummyParameter (
101+ $ parameter ->getName (),
102+ $ this ->transformStaticType ($ parameter ->getType ()),
103+ $ parameter ->isOptional (),
104+ $ parameter ->passedByReference (),
105+ $ parameter ->isVariadic (),
106+ $ parameter ->getDefaultValue (),
107+ $ parameter ->getNativeType (),
108+ $ this ->transformStaticType ($ parameter ->getPhpDocType ()),
109+ $ parameter ->getOutType () !== null ? $ this ->transformStaticType ($ parameter ->getOutType ()) : null ,
110+ $ parameter ->isImmediatelyInvokedCallable (),
111+ $ parameter ->getClosureThisType () !== null ? $ this ->transformStaticType ($ parameter ->getClosureThisType ()) : null ,
112+ $ parameter ->getAttributes (),
113+ ),
114+ $ acceptor ->getParameters (),
102115 ),
103- $ acceptor ->getParameters (),
104- ),
105- $ acceptor ->isVariadic (),
106- $ this ->transformStaticType ($ acceptor ->getReturnType ()),
107- $ this ->transformStaticType ($ acceptor ->getPhpDocReturnType ()),
108- $ this ->transformStaticType ($ acceptor ->getNativeReturnType ()),
109- $ acceptor ->getCallSiteVarianceMap (),
110- );
116+ $ acceptor ->isVariadic (),
117+ $ returnType ,
118+ $ this ->transformStaticType ($ acceptor ->getPhpDocReturnType ()),
119+ $ this ->transformStaticType ($ acceptor ->getNativeReturnType ()),
120+ $ acceptor ->getCallSiteVarianceMap (),
121+ );
122+ };
111123 $ variants = array_map ($ variantFn , $ method ->getVariants ());
112124 $ namedArgumentVariants = $ method ->getNamedArgumentsVariants ();
113125 $ namedArgumentVariants = $ namedArgumentVariants !== null
@@ -119,7 +131,7 @@ private function transformMethodWithStaticType(ClassReflection $declaringClass,
119131 $ method ,
120132 $ variants ,
121133 $ namedArgumentVariants ,
122- $ method -> getSelfOutType () !== null ? $ this -> transformStaticType ( $ method -> getSelfOutType ()) : null ,
134+ $ selfOutType ,
123135 );
124136 }
125137
0 commit comments