@@ -17,6 +17,15 @@ use crate::{
17
17
18
18
type FxIndexMap < K , V > = IndexMap < K , V , BuildHasherDefault < FxHasher > > ;
19
19
20
+ /// Item import details stored in the `ImportMap`.
21
+ #[ derive( Debug , Clone , Eq , PartialEq ) ]
22
+ pub struct ImportInfo {
23
+ /// A path that can be used to import the item, relative to the crate's root.
24
+ pub path : ModPath ,
25
+ /// The module containing this item.
26
+ pub container : ModuleId ,
27
+ }
28
+
20
29
/// A map from publicly exported items to the path needed to import/name them from a downstream
21
30
/// crate.
22
31
///
@@ -26,7 +35,7 @@ type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
26
35
/// Note that all paths are relative to the containing crate's root, so the crate name still needs
27
36
/// to be prepended to the `ModPath` before the path is valid.
28
37
pub struct ImportMap {
29
- map : FxIndexMap < ItemInNs , ModPath > ,
38
+ map : FxIndexMap < ItemInNs , ImportInfo > ,
30
39
31
40
/// List of keys stored in `map`, sorted lexicographically by their `ModPath`. Indexed by the
32
41
/// values returned by running `fst`.
@@ -78,12 +87,12 @@ impl ImportMap {
78
87
let path = mk_path ( ) ;
79
88
match import_map. entry ( item) {
80
89
Entry :: Vacant ( entry) => {
81
- entry. insert ( path) ;
90
+ entry. insert ( ImportInfo { path, container : module } ) ;
82
91
}
83
92
Entry :: Occupied ( mut entry) => {
84
93
// If the new path is shorter, prefer that one.
85
- if path. len ( ) < entry. get ( ) . len ( ) {
86
- * entry. get_mut ( ) = path;
94
+ if path. len ( ) < entry. get ( ) . path . len ( ) {
95
+ * entry. get_mut ( ) = ImportInfo { path, container : module } ;
87
96
} else {
88
97
continue ;
89
98
}
@@ -119,7 +128,7 @@ impl ImportMap {
119
128
let start = last_batch_start;
120
129
last_batch_start = idx + 1 ;
121
130
122
- let key = fst_path ( & importables[ start] . 1 ) ;
131
+ let key = fst_path ( & importables[ start] . 1 . path ) ;
123
132
124
133
builder. insert ( key, start as u64 ) . unwrap ( ) ;
125
134
}
@@ -132,6 +141,10 @@ impl ImportMap {
132
141
133
142
/// Returns the `ModPath` needed to import/mention `item`, relative to this crate's root.
134
143
pub fn path_of ( & self , item : ItemInNs ) -> Option < & ModPath > {
144
+ Some ( & self . map . get ( & item) ?. path )
145
+ }
146
+
147
+ pub fn import_info_for ( & self , item : ItemInNs ) -> Option < & ImportInfo > {
135
148
self . map . get ( & item)
136
149
}
137
150
}
@@ -150,13 +163,13 @@ impl fmt::Debug for ImportMap {
150
163
let mut importable_paths: Vec < _ > = self
151
164
. map
152
165
. iter ( )
153
- . map ( |( item, modpath ) | {
166
+ . map ( |( item, info ) | {
154
167
let ns = match item {
155
168
ItemInNs :: Types ( _) => "t" ,
156
169
ItemInNs :: Values ( _) => "v" ,
157
170
ItemInNs :: Macros ( _) => "m" ,
158
171
} ;
159
- format ! ( "- {} ({})" , modpath , ns)
172
+ format ! ( "- {} ({})" , info . path , ns)
160
173
} )
161
174
. collect ( ) ;
162
175
@@ -171,9 +184,9 @@ fn fst_path(path: &ModPath) -> String {
171
184
s
172
185
}
173
186
174
- fn cmp ( ( _, lhs) : & ( & ItemInNs , & ModPath ) , ( _, rhs) : & ( & ItemInNs , & ModPath ) ) -> Ordering {
175
- let lhs_str = fst_path ( lhs) ;
176
- let rhs_str = fst_path ( rhs) ;
187
+ fn cmp ( ( _, lhs) : & ( & ItemInNs , & ImportInfo ) , ( _, rhs) : & ( & ItemInNs , & ImportInfo ) ) -> Ordering {
188
+ let lhs_str = fst_path ( & lhs. path ) ;
189
+ let rhs_str = fst_path ( & rhs. path ) ;
177
190
lhs_str. cmp ( & rhs_str)
178
191
}
179
192
@@ -243,7 +256,7 @@ pub fn search_dependencies<'a>(
243
256
let importables = & import_map. importables [ indexed_value. value as usize ..] ;
244
257
245
258
// Path shared by the importable items in this group.
246
- let path = & import_map. map [ & importables[ 0 ] ] ;
259
+ let path = & import_map. map [ & importables[ 0 ] ] . path ;
247
260
248
261
if query. anchor_end {
249
262
// Last segment must match query.
@@ -256,14 +269,14 @@ pub fn search_dependencies<'a>(
256
269
// Add the items from this `ModPath` group. Those are all subsequent items in
257
270
// `importables` whose paths match `path`.
258
271
let iter = importables. iter ( ) . copied ( ) . take_while ( |item| {
259
- let item_path = & import_map. map [ item] ;
272
+ let item_path = & import_map. map [ item] . path ;
260
273
fst_path ( item_path) == fst_path ( path)
261
274
} ) ;
262
275
263
276
if query. case_sensitive {
264
277
// FIXME: This does not do a subsequence match.
265
278
res. extend ( iter. filter ( |item| {
266
- let item_path = & import_map. map [ item] ;
279
+ let item_path = & import_map. map [ item] . path ;
267
280
item_path. to_string ( ) . contains ( & query. query )
268
281
} ) ) ;
269
282
} else {
0 commit comments