@@ -37,6 +37,54 @@ pub struct Workspace {
37
37
files : std:: collections:: HashMap < Url , file:: File > ,
38
38
}
39
39
40
+ // Return the possible package qualifiers to_pkg could use for a type imported from from_pkg
41
+ fn possible_qualifiers < ' a > ( from_pkg : & ' a str , to_pkg : & ' a str ) -> Vec < & ' a str > {
42
+ log:: trace!( "possible_qualifiers({from_pkg}, {to_pkg})" ) ;
43
+ if to_pkg == "" {
44
+ return vec ! [ from_pkg] ;
45
+ }
46
+
47
+ let mut res = vec ! [ ] ;
48
+ if let Some ( pkg) = from_pkg. strip_prefix ( to_pkg) {
49
+ let pkg = pkg. strip_prefix ( "." ) . unwrap_or ( pkg) ;
50
+ res. push ( pkg) ;
51
+ }
52
+
53
+ if let Some ( ( to_pkg, _) ) = to_pkg. rsplit_once ( "." ) {
54
+ res. append ( & mut possible_qualifiers ( from_pkg, to_pkg) ) ;
55
+ } else {
56
+ res. push ( from_pkg) ;
57
+ }
58
+ return res;
59
+ }
60
+
61
+ #[ test]
62
+ fn test_possible_qualifiers ( ) {
63
+ let _ = env_logger:: builder ( ) . is_test ( true ) . try_init ( ) ;
64
+ assert_eq ! ( possible_qualifiers( "" , "" ) , vec![ "" ] ) ;
65
+ assert_eq ! ( possible_qualifiers( "foo" , "" ) , vec![ "foo" ] ) ;
66
+ assert_eq ! ( possible_qualifiers( "foo.bar" , "" ) , vec![ "foo.bar" ] ) ;
67
+ assert_eq ! ( possible_qualifiers( "foo" , "bar" ) , vec![ "foo" ] ) ;
68
+ assert_eq ! ( possible_qualifiers( "foo.bar" , "bar" ) , vec![ "foo.bar" ] ) ;
69
+ assert_eq ! ( possible_qualifiers( "foo" , "foo" ) , vec![ "" , "foo" ] ) ;
70
+ assert_eq ! (
71
+ possible_qualifiers( "foo.bar" , "foo" ) ,
72
+ vec![ "bar" , "foo.bar" ]
73
+ ) ;
74
+ assert_eq ! (
75
+ possible_qualifiers( "foo.bar.baz" , "foo.bar" ) ,
76
+ vec![ "baz" , "bar.baz" , "foo.bar.baz" , ]
77
+ ) ;
78
+ assert_eq ! (
79
+ possible_qualifiers( "foo.bar.baz" , "foo.bar.baz" ) ,
80
+ vec![ "" , "baz" , "bar.baz" , "foo.bar.baz" , ]
81
+ ) ;
82
+ assert_eq ! (
83
+ possible_qualifiers( "folder.stuff" , "folder.what" ) ,
84
+ vec![ "stuff" , "folder.stuff" ]
85
+ ) ;
86
+ }
87
+
40
88
impl Workspace {
41
89
pub fn new ( proto_paths : Vec < std:: path:: PathBuf > ) -> Workspace {
42
90
Workspace {
@@ -362,21 +410,25 @@ impl Workspace {
362
410
for ( uri, file) in imports {
363
411
let package = file. package ( ) ;
364
412
if let Some ( sym) = if package == local_package {
365
- log:: trace!( "Searching for {} in {uri}" , typ. name) ;
413
+ log:: trace!( "Searching for {} in {uri} (same package) " , typ. name) ;
366
414
// same package, match the name without the package prefix
367
415
file. symbols ( & mut qc) . find ( |sym| sym. name == typ. name )
368
416
} else if let Some ( package) = package {
417
+ log:: trace!( "Searching for {} in {uri} (different package)" , typ. name) ;
369
418
// different package, fully qualify the name
370
- log:: trace!( "Stripping {package} from {}" , typ. name) ;
371
- let qualified = typ
372
- . name
373
- . strip_prefix ( package)
374
- . unwrap_or ( typ. name )
375
- . strip_prefix ( "." )
376
- . unwrap_or ( typ. name )
377
- . to_string ( ) ;
378
- log:: trace!( "Searching for {} in {uri} (different package)" , qualified) ;
379
- file. symbols ( & mut qc) . find ( |sym| sym. name == qualified)
419
+ let local_package = local_package. unwrap_or ( "" ) ;
420
+ file. symbols ( & mut qc) . find ( |sym| {
421
+ let quals = possible_qualifiers ( package, local_package) ;
422
+ log:: trace!( "Qualifiers: {quals:?}" ) ;
423
+ quals
424
+ . iter ( )
425
+ . inspect ( |q| log:: trace!( "Qual == {q}" ) )
426
+ . filter_map ( |qual| typ. name . strip_prefix ( qual) )
427
+ . inspect ( |q| log:: trace!( "stripped == {q}" ) )
428
+ . filter_map ( |name| name. strip_prefix ( "." ) )
429
+ . inspect ( |q| log:: trace!( "name == {q} == {}" , sym. name) )
430
+ . any ( |name| name == sym. name )
431
+ } )
380
432
} else {
381
433
// target file has no package
382
434
log:: trace!( "Searching for {} in {uri}" , typ. name) ;
0 commit comments