@@ -4,7 +4,10 @@ use ra_ap_hir_expand::InFile;
44
55use crate :: ident:: { CanonicalPath , CanonicalType , Ident , TypeKind } ;
66
7- use ra_ap_hir:: { GenericParam , HasSource , Module , Semantics , VariantDef } ;
7+ use ra_ap_hir:: {
8+ db:: DefDatabase , Adt , DefWithBody , GenericParam , HasContainer , HasSource , HirDisplay ,
9+ Module , Semantics , VariantDef ,
10+ } ;
811
912use ra_ap_ide:: { RootDatabase , TextSize } ;
1013use ra_ap_ide_db:: base_db:: SourceDatabase ;
@@ -72,7 +75,7 @@ pub(super) fn canonical_path(
7275 return Some ( CanonicalPath :: new ( name_to_string ( b. name ( ) ) . as_str ( ) ) ) ;
7376 }
7477
75- // let container = get_container_name(sems, db, def);
78+ let container = get_container_name ( db, def) ;
7679 let def_name = def. name ( db) . map ( name_to_string) ;
7780 let module = def. module ( db) ?;
7881
@@ -88,13 +91,78 @@ pub(super) fn canonical_path(
8891 let cp = crate_name
8992 . into_iter ( )
9093 . chain ( module_path)
91- // .chain(container)
94+ . chain ( container)
9295 . chain ( def_name)
9396 . join ( "::" ) ;
9497
9598 Some ( CanonicalPath :: new ( cp. as_str ( ) ) )
9699}
97100
101+ /// Helper function to construct the canonical path
102+ fn get_container_name ( db : & RootDatabase , def : & Definition ) -> Vec < String > {
103+ let mut container_names = vec ! [ ] ;
104+ match def {
105+ Definition :: Field ( f) => {
106+ let parent = f. parent_def ( db) ;
107+ container_names. append ( & mut match parent {
108+ VariantDef :: Variant ( v) => get_container_name ( db, & v. into ( ) ) ,
109+ VariantDef :: Struct ( s) => get_container_name ( db, & Adt :: from ( s) . into ( ) ) ,
110+ VariantDef :: Union ( u) => get_container_name ( db, & Adt :: from ( u) . into ( ) ) ,
111+ } ) ;
112+ container_names. push ( name_to_string ( parent. name ( db) ) )
113+ }
114+ Definition :: Local ( l) => {
115+ let parent = l. parent ( db) ;
116+ let parent_name = parent. name ( db) ;
117+ let parent_def = match parent {
118+ DefWithBody :: Function ( f) => f. into ( ) ,
119+ DefWithBody :: Static ( s) => s. into ( ) ,
120+ DefWithBody :: Const ( c) => c. into ( ) ,
121+ DefWithBody :: Variant ( v) => v. into ( ) ,
122+ DefWithBody :: InTypeConst ( _) => unimplemented ! ( "TODO" ) ,
123+ } ;
124+ container_names. append ( & mut get_container_name ( db, & parent_def) ) ;
125+ container_names. push ( parent_name. map ( name_to_string) . unwrap_or_default ( ) )
126+ }
127+ Definition :: Function ( f) => match f. container ( db) {
128+ ra_ap_hir:: ItemContainer :: Trait ( t) => {
129+ container_names. append ( & mut get_container_name ( db, & t. into ( ) ) ) ;
130+ container_names. push ( name_to_string ( t. name ( db) ) )
131+ }
132+ ra_ap_hir:: ItemContainer :: Impl ( i) => {
133+ let id = ra_ap_hir_def:: ImplId :: from ( i) ;
134+ let impl_data = db. impl_data ( id) ;
135+
136+ let name = if let Some ( trait_ref) = impl_data. target_trait . as_ref ( ) {
137+ format ! (
138+ "<{} as {}>" ,
139+ i. self_ty( db) . display( db) ,
140+ trait_ref. path. display( db)
141+ )
142+ } else {
143+ let adt = i. self_ty ( db) . as_adt ( ) ;
144+ adt. map ( |it| name_to_string ( it. name ( db) ) ) . unwrap_or_default ( )
145+ } ;
146+
147+ container_names. append ( & mut get_container_name ( db, & i. into ( ) ) ) ;
148+ container_names. push ( name) ;
149+ }
150+ _ => { }
151+ } ,
152+ Definition :: Variant ( e) => {
153+ container_names. push ( name_to_string ( e. parent_enum ( db) . name ( db) ) )
154+ }
155+ Definition :: Macro ( m) => {
156+ container_names. append ( & mut get_container_name ( db, & m. module ( db) . into ( ) ) ) ;
157+ container_names. push ( m. name ( db) . display ( db) . to_string ( ) ) ;
158+ }
159+ _ => { }
160+ }
161+ container_names. retain ( |s| !s. is_empty ( ) ) ;
162+
163+ container_names
164+ }
165+
98166/// Type resolution
99167pub ( super ) fn get_canonical_type (
100168 db : & RootDatabase ,
0 commit comments