@@ -82,16 +82,16 @@ public static function resolve(TypeNode $node, \ReflectionClass|\ReflectionFunct
8282 }
8383
8484 if ($ node instanceof IdentifierTypeNode) {
85- return self ::resolveIdentifier ($ node , $ declaringClass , $ ref );
85+ return self ::resolveIdentifier ($ node , $ declaringClass , $ ref, $ context , $ thisObj );
8686 }
8787
8888 if ($ node instanceof ConstTypeNode) {
8989 return self ::resolveConstType ($ node , $ declaringClass , $ ref );
9090 }
9191
9292 if ($ node instanceof GenericTypeNode) {
93- $ genericType = self ::resolve ($ node ->type , $ ref , $ thisObj );
94- $ innerTypes = array_map (fn ($ t ) => self ::resolve ($ t , $ ref , $ thisObj ), $ node ->genericTypes );
93+ $ genericType = self ::resolve ($ node ->type , $ context , $ thisObj );
94+ $ innerTypes = array_map (fn ($ t ) => self ::resolve ($ t , $ context , $ thisObj ), $ node ->genericTypes );
9595
9696 return new GenericTypeNode (
9797 $ genericType instanceof IdentifierTypeNode ? $ genericType : $ node ->type ,
@@ -101,55 +101,55 @@ public static function resolve(TypeNode $node, \ReflectionClass|\ReflectionFunct
101101 }
102102
103103 if ($ node instanceof OffsetAccessTypeNode) {
104- return self ::resolveOffsetAccess ($ node , $ ref , $ thisObj );
104+ return self ::resolveOffsetAccess ($ node , $ context , $ thisObj );
105105 }
106106
107107 if ($ node instanceof ArrayShapeNode) {
108- return self ::resolveArrayShape ($ node , $ ref , $ thisObj );
108+ return self ::resolveArrayShape ($ node , $ context , $ thisObj );
109109 }
110110
111111 if ($ node instanceof ObjectShapeNode) {
112- return self ::resolveObjectShape ($ node , $ ref , $ thisObj );
112+ return self ::resolveObjectShape ($ node , $ context , $ thisObj );
113113 }
114114
115115 if ($ node instanceof CallableTypeNode) {
116- return self ::resolveCallable ($ node , $ ref , $ thisObj );
116+ return self ::resolveCallable ($ node , $ context , $ thisObj );
117117 }
118118
119119 if ($ node instanceof ConditionalTypeNode) {
120120 return new ConditionalTypeNode (
121- self ::resolve ($ node ->subjectType , $ ref , $ thisObj ),
122- self ::resolve ($ node ->targetType , $ ref , $ thisObj ),
123- self ::resolve ($ node ->if , $ ref , $ thisObj ),
124- self ::resolve ($ node ->else , $ ref , $ thisObj ),
121+ self ::resolve ($ node ->subjectType , $ context , $ thisObj ),
122+ self ::resolve ($ node ->targetType , $ context , $ thisObj ),
123+ self ::resolve ($ node ->if , $ context , $ thisObj ),
124+ self ::resolve ($ node ->else , $ context , $ thisObj ),
125125 $ node ->negated
126126 );
127127 }
128128
129129 if ($ node instanceof ConditionalTypeForParameterNode) {
130130 return new ConditionalTypeForParameterNode (
131131 $ node ->parameterName ,
132- self ::resolve ($ node ->targetType , $ ref , $ thisObj ),
133- self ::resolve ($ node ->if , $ ref , $ thisObj ),
134- self ::resolve ($ node ->else , $ ref , $ thisObj ),
132+ self ::resolve ($ node ->targetType , $ context , $ thisObj ),
133+ self ::resolve ($ node ->if , $ context , $ thisObj ),
134+ self ::resolve ($ node ->else , $ context , $ thisObj ),
135135 $ node ->negated
136136 );
137137 }
138138
139139 if ($ node instanceof NullableTypeNode) {
140- return new NullableTypeNode (self ::resolve ($ node ->type , $ ref , $ thisObj ));
140+ return new NullableTypeNode (self ::resolve ($ node ->type , $ context , $ thisObj ));
141141 }
142142
143143 if ($ node instanceof ArrayTypeNode) {
144- return new ArrayTypeNode (self ::resolve ($ node ->type , $ ref , $ thisObj ));
144+ return new ArrayTypeNode (self ::resolve ($ node ->type , $ context , $ thisObj ));
145145 }
146146
147147 if ($ node instanceof UnionTypeNode) {
148- return new UnionTypeNode (array_map (fn ($ t ) => self ::resolve ($ t , $ ref , $ thisObj ), $ node ->types ));
148+ return new UnionTypeNode (array_map (fn ($ t ) => self ::resolve ($ t , $ context , $ thisObj ), $ node ->types ));
149149 }
150150
151151 if ($ node instanceof IntersectionTypeNode) {
152- return new IntersectionTypeNode (array_map (fn ($ t ) => self ::resolve ($ t , $ ref , $ thisObj ), $ node ->types ));
152+ return new IntersectionTypeNode (array_map (fn ($ t ) => self ::resolve ($ t , $ context , $ thisObj ), $ node ->types ));
153153 }
154154
155155 return $ node ;
@@ -282,11 +282,35 @@ private static function getReflectionContext(\ReflectionClass|\ReflectionFunctio
282282 /**
283283 * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod $ref
284284 */
285- private static function resolveIdentifier (IdentifierTypeNode $ node , ?string $ declaringClass , \ReflectionClass |\ReflectionFunction |\ReflectionMethod $ ref ): IdentifierTypeNode
286- {
285+ private static function resolveIdentifier (
286+ IdentifierTypeNode $ node ,
287+ ?string $ declaringClass ,
288+ \ReflectionClass |\ReflectionFunction |\ReflectionMethod $ ref ,
289+ \ReflectionClass |\ReflectionFunction |\ReflectionMethod |string $ context ,
290+ ?object $ thisObj = null
291+ ): IdentifierTypeNode {
287292 $ lower = strtolower ($ node ->name );
288293
289- if ($ lower === '$this ' || $ lower === 'static ' ) {
294+ if ($ lower === '$this ' ) {
295+ if ($ thisObj !== null ) {
296+ return new IdentifierTypeNode (\get_class ($ thisObj ));
297+ }
298+
299+ return $ node ;
300+ }
301+
302+ if ($ lower === 'static ' ) {
303+ if ($ thisObj !== null ) {
304+ return new IdentifierTypeNode (\get_class ($ thisObj ));
305+ }
306+
307+ if (\is_string ($ context ) && str_contains ($ context , ':: ' )) {
308+ $ callingClass = explode (':: ' , $ context , 2 )[0 ];
309+ if (class_exists ($ callingClass ) || interface_exists ($ callingClass ) || trait_exists ($ callingClass ) || enum_exists ($ callingClass )) {
310+ return new IdentifierTypeNode ($ callingClass );
311+ }
312+ }
313+
290314 return $ node ;
291315 }
292316
@@ -331,12 +355,13 @@ private static function resolveConstType(ConstTypeNode $node, ?string $declaring
331355 }
332356
333357 /**
334- * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod $ref
358+ * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod|string $context
335359 */
336- private static function resolveOffsetAccess (OffsetAccessTypeNode $ node , \ReflectionClass |\ReflectionFunction |\ReflectionMethod $ ref , ?object $ thisObj ): TypeNode
360+ private static function resolveOffsetAccess (OffsetAccessTypeNode $ node , \ReflectionClass |\ReflectionFunction |\ReflectionMethod | string $ context , ?object $ thisObj ): TypeNode
337361 {
338- $ baseType = self ::resolve ($ node ->type , $ ref , $ thisObj );
339- $ offsetType = self ::resolve ($ node ->offset , $ ref , $ thisObj );
362+ $ ref = self ::getReflectionContext ($ context );
363+ $ baseType = self ::resolve ($ node ->type , $ context , $ thisObj );
364+ $ offsetType = self ::resolve ($ node ->offset , $ context , $ thisObj );
340365
341366 $ offsetKey = self ::extractOffsetKey ($ offsetType );
342367
@@ -362,11 +387,12 @@ private static function resolveOffsetAccess(OffsetAccessTypeNode $node, \Reflect
362387 }
363388
364389 /**
365- * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod $ref
390+ * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod|string $context
366391 */
367- private static function resolveArrayShape (ArrayShapeNode $ node , \ReflectionClass |\ReflectionFunction |\ReflectionMethod $ ref , ?object $ thisObj ): ArrayShapeNode
392+ private static function resolveArrayShape (ArrayShapeNode $ node , \ReflectionClass |\ReflectionFunction |\ReflectionMethod | string $ context , ?object $ thisObj ): ArrayShapeNode
368393 {
369- $ items = array_map (function ($ item ) use ($ ref , $ thisObj ) {
394+ $ ref = self ::getReflectionContext ($ context );
395+ $ items = array_map (function ($ item ) use ($ ref , $ context , $ thisObj ) {
370396 /** @var ConstExprIntegerNode|ConstExprStringNode|ConstFetchNode|IdentifierTypeNode|null $keyName */
371397 $ keyName = $ item ->keyName ;
372398
@@ -404,7 +430,7 @@ private static function resolveArrayShape(ArrayShapeNode $node, \ReflectionClass
404430 return new ArrayShapeItemNode (
405431 $ keyName ,
406432 $ item ->optional ,
407- self ::resolve ($ item ->valueType , $ ref , $ thisObj )
433+ self ::resolve ($ item ->valueType , $ context , $ thisObj )
408434 );
409435 }, $ node ->items );
410436
@@ -414,46 +440,46 @@ private static function resolveArrayShape(ArrayShapeNode $node, \ReflectionClass
414440
415441 $ unsealedType = null ;
416442 if ($ node ->unsealedType !== null ) {
417- $ unsealedKey = $ node ->unsealedType ->keyType !== null ? self ::resolve ($ node ->unsealedType ->keyType , $ ref , $ thisObj ) : null ;
418- $ unsealedValue = self ::resolve ($ node ->unsealedType ->valueType , $ ref , $ thisObj );
443+ $ unsealedKey = $ node ->unsealedType ->keyType !== null ? self ::resolve ($ node ->unsealedType ->keyType , $ context , $ thisObj ) : null ;
444+ $ unsealedValue = self ::resolve ($ node ->unsealedType ->valueType , $ context , $ thisObj );
419445 $ unsealedType = new ArrayShapeUnsealedTypeNode ($ unsealedValue , $ unsealedKey );
420446 }
421447
422448 return ArrayShapeNode::createUnsealed ($ items , $ unsealedType , $ node ->kind );
423449 }
424450
425451 /**
426- * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod $ref
452+ * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod|string $context
427453 */
428- private static function resolveObjectShape (ObjectShapeNode $ node , \ReflectionClass |\ReflectionFunction |\ReflectionMethod $ ref , ?object $ thisObj ): ObjectShapeNode
454+ private static function resolveObjectShape (ObjectShapeNode $ node , \ReflectionClass |\ReflectionFunction |\ReflectionMethod | string $ context , ?object $ thisObj ): ObjectShapeNode
429455 {
430- $ items = array_map (function ($ item ) use ($ ref , $ thisObj ) {
456+ $ items = array_map (function ($ item ) use ($ context , $ thisObj ) {
431457 return new ObjectShapeItemNode (
432458 $ item ->keyName ,
433459 $ item ->optional ,
434- self ::resolve ($ item ->valueType , $ ref , $ thisObj )
460+ self ::resolve ($ item ->valueType , $ context , $ thisObj )
435461 );
436462 }, $ node ->items );
437463
438464 return new ObjectShapeNode ($ items );
439465 }
440466
441467 /**
442- * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod $ref
468+ * @param \ReflectionClass<object>|\ReflectionFunction|\ReflectionMethod|string $context
443469 */
444- private static function resolveCallable (CallableTypeNode $ node , \ReflectionClass |\ReflectionFunction |\ReflectionMethod $ ref , ?object $ thisObj ): CallableTypeNode
470+ private static function resolveCallable (CallableTypeNode $ node , \ReflectionClass |\ReflectionFunction |\ReflectionMethod | string $ context , ?object $ thisObj ): CallableTypeNode
445471 {
446- $ resolvedParameters = array_map (function (CallableTypeParameterNode $ param ) use ($ ref , $ thisObj ) {
472+ $ resolvedParameters = array_map (function (CallableTypeParameterNode $ param ) use ($ context , $ thisObj ) {
447473 return new CallableTypeParameterNode (
448- self ::resolve ($ param ->type , $ ref , $ thisObj ),
474+ self ::resolve ($ param ->type , $ context , $ thisObj ),
449475 $ param ->isReference ,
450476 $ param ->isVariadic ,
451477 $ param ->parameterName ,
452478 $ param ->isOptional
453479 );
454480 }, $ node ->parameters );
455481
456- $ resolvedReturnType = self ::resolve ($ node ->returnType , $ ref , $ thisObj );
482+ $ resolvedReturnType = self ::resolve ($ node ->returnType , $ context , $ thisObj );
457483
458484 return new CallableTypeNode ($ node ->identifier , $ resolvedParameters , $ resolvedReturnType , $ node ->templateTypes );
459485 }
@@ -978,4 +1004,4 @@ private static function parseFileMetadata(string $fileName, string $source): voi
9781004 // Silently fall back to empty metadata if parsing fails
9791005 }
9801006 }
981- }
1007+ }
0 commit comments