@@ -113,6 +113,7 @@ impl Backend {
113113 & file_use_map,
114114 & file_namespace,
115115 & local_classes,
116+ span. start ,
116117 )
117118 . and_then ( |name| self . find_or_load_class ( & name) )
118119 . map ( |arc| ClassInfo :: clone ( & arc) ) ;
@@ -334,23 +335,35 @@ fn resolve_subject_to_class_name(
334335 file_use_map : & HashMap < String , String > ,
335336 file_namespace : & Option < String > ,
336337 local_classes : & [ Arc < ClassInfo > ] ,
338+ access_offset : u32 ,
337339) -> Option < String > {
338340 let trimmed = subject_text. trim ( ) ;
339341
340342 match trimmed {
341343 "self" | "static" => {
342344 // Find the enclosing class in this file
343- find_enclosing_class_fqn ( local_classes, file_namespace)
345+ find_enclosing_class_fqn ( local_classes, file_namespace, access_offset )
344346 }
345347 "parent" => {
346348 // Find the enclosing class that actually has a parent.
347- // Prefer a class with `parent_class` set — that's the one
348- // where `parent::` is meaningful. Fall back to the first
349- // non-anonymous class if none has a parent (shouldn't happen
350- // in valid code, but be defensive).
349+ // Prefer a class whose offset range contains the access site
350+ // and that has `parent_class` set — that's the one where
351+ // `parent::` is meaningful. Fall back to any non-anonymous
352+ // class with a parent, then to the first non-anonymous class
353+ // (shouldn't happen in valid code, but be defensive).
351354 let cls = local_classes
352355 . iter ( )
353- . find ( |c| !c. name . starts_with ( "__anonymous@" ) && c. parent_class . is_some ( ) )
356+ . find ( |c| {
357+ !c. name . starts_with ( "__anonymous@" )
358+ && c. parent_class . is_some ( )
359+ && access_offset >= c. start_offset
360+ && access_offset <= c. end_offset
361+ } )
362+ . or_else ( || {
363+ local_classes
364+ . iter ( )
365+ . find ( |c| !c. name . starts_with ( "__anonymous@" ) && c. parent_class . is_some ( ) )
366+ } )
354367 . or_else ( || {
355368 local_classes
356369 . iter ( )
@@ -362,7 +375,7 @@ fn resolve_subject_to_class_name(
362375 . map ( |p| resolve_to_fqn ( p, file_use_map, file_namespace) )
363376 } )
364377 }
365- "$this" => find_enclosing_class_fqn ( local_classes, file_namespace) ,
378+ "$this" => find_enclosing_class_fqn ( local_classes, file_namespace, access_offset ) ,
366379 _ if is_static && !trimmed. starts_with ( '$' ) => {
367380 // Static access on a class name: `ClassName::method()`
368381 Some ( resolve_to_fqn ( trimmed, file_use_map, file_namespace) )
@@ -425,11 +438,23 @@ fn resolve_variable_subject(
425438fn find_enclosing_class_fqn (
426439 local_classes : & [ Arc < ClassInfo > ] ,
427440 file_namespace : & Option < String > ,
441+ offset : u32 ,
428442) -> Option < String > {
429- // Skip anonymous classes
443+ // Find the non-anonymous class whose byte range contains the offset.
444+ // Fall back to the first non-anonymous class for top-level code
445+ // outside any class body.
430446 let cls = local_classes
431447 . iter ( )
432- . find ( |c| !c. name . starts_with ( "__anonymous@" ) ) ?;
448+ . find ( |c| {
449+ !c. name . starts_with ( "__anonymous@" )
450+ && offset >= c. start_offset
451+ && offset <= c. end_offset
452+ } )
453+ . or_else ( || {
454+ local_classes
455+ . iter ( )
456+ . find ( |c| !c. name . starts_with ( "__anonymous@" ) )
457+ } ) ?;
433458 if let Some ( ns) = file_namespace {
434459 Some ( format ! ( "{}\\ {}" , ns, cls. name) )
435460 } else {
0 commit comments