1919use PHPStan \Reflection \InitializerExprTypeResolver ;
2020use PHPStan \Reflection \ParameterReflection ;
2121use PHPStan \Reflection \PassedByReference ;
22+ use PHPStan \Reflection \ReflectionProvider \ReflectionProviderProvider ;
2223use PHPStan \ShouldNotHappenException ;
2324use ReflectionFunction ;
2425use function array_map ;
@@ -36,6 +37,7 @@ public function __construct(
3637 private InitializerExprTypeResolver $ initializerExprTypeResolver ,
3738 private ReflectionSourceStubber $ reflectionSourceStubber ,
3839 private Reflector $ reflector ,
40+ private ReflectionProviderProvider $ reflectionProviderProvider ,
3941 #[AutowiredParameter(ref: '@currentPhpVersionPhpParser ' )]
4042 private Parser $ parser ,
4143 )
@@ -47,7 +49,8 @@ public function __construct(
4749 */
4850 public function fromClosureObject (Closure $ closure ): ClosureType
4951 {
50- $ stubData = $ this ->reflectionSourceStubber ->generateFunctionStubFromReflection (new ReflectionFunction ($ closure ));
52+ $ closureReflectionFunction = new ReflectionFunction ($ closure );
53+ $ stubData = $ this ->reflectionSourceStubber ->generateFunctionStubFromReflection ($ closureReflectionFunction );
5154 if ($ stubData === null ) {
5255 throw new ShouldNotHappenException ('Closure reflection not found. ' );
5356 }
@@ -117,7 +120,16 @@ public function getDefaultValue(): ?Type
117120
118121 }, $ betterReflectionFunction ->getParameters ());
119122
120- return new ClosureType ($ parameters , TypehintHelper::decideTypeFromReflection (ReflectionType::fromTypeOrNull ($ betterReflectionFunction ->getReturnType ())), $ betterReflectionFunction ->isVariadic ());
123+ $ selfClass = null ;
124+ if ($ closureReflectionFunction ->getClosureCalledClass () !== null ) {
125+ $ potentialSelfClassName = $ closureReflectionFunction ->getClosureCalledClass ()->getName ();
126+ $ reflectionProvider = $ this ->reflectionProviderProvider ->getReflectionProvider ();
127+ if ($ reflectionProvider ->hasClass ($ potentialSelfClassName )) {
128+ $ selfClass = $ reflectionProvider ->getClass ($ potentialSelfClassName );
129+ }
130+ }
131+
132+ return new ClosureType ($ parameters , TypehintHelper::decideTypeFromReflection (ReflectionType::fromTypeOrNull ($ betterReflectionFunction ->getReturnType ()), null , $ selfClass ), $ betterReflectionFunction ->isVariadic ());
121133 }
122134
123135}
0 commit comments