@@ -11,9 +11,13 @@ use ra_ap_base_db::CrateGraph;
1111use ra_ap_base_db:: CrateId ;
1212use ra_ap_base_db:: SourceDatabase ;
1313use ra_ap_cfg:: CfgAtom ;
14- use ra_ap_hir:: { DefMap , ModuleDefId , db:: HirDatabase } ;
14+ use ra_ap_hir:: { DefMap , ModuleDefId , PathKind , db:: HirDatabase } ;
1515use ra_ap_hir:: { VariantId , Visibility , db:: DefDatabase } ;
16- use ra_ap_hir_def:: { AssocItemId , LocalModuleId , data:: adt:: VariantData , nameres:: ModuleData } ;
16+ use ra_ap_hir_def:: Lookup ;
17+ use ra_ap_hir_def:: {
18+ AssocItemId , LocalModuleId , data:: adt:: VariantData , item_scope:: ImportOrGlob ,
19+ item_tree:: ImportKind , nameres:: ModuleData , path:: ImportAlias ,
20+ } ;
1721use ra_ap_hir_def:: { HasModule , visibility:: VisibilityExplicitness } ;
1822use ra_ap_hir_def:: { ModuleId , resolver:: HasResolver } ;
1923use ra_ap_hir_ty:: TraitRefExt ;
@@ -24,6 +28,7 @@ use ra_ap_hir_ty::{Binders, FnPointer};
2428use ra_ap_hir_ty:: { Interner , ProjectionTy } ;
2529use ra_ap_ide_db:: RootDatabase ;
2630use ra_ap_vfs:: { Vfs , VfsPath } ;
31+
2732use std:: hash:: Hasher ;
2833use std:: { cmp:: Ordering , collections:: HashMap , path:: PathBuf } ;
2934use std:: { hash:: Hash , vec} ;
@@ -178,20 +183,106 @@ fn emit_module_children(
178183 . collect ( )
179184}
180185
186+ fn emit_reexport (
187+ db : & dyn HirDatabase ,
188+ trap : & mut TrapFile ,
189+ uses : & mut HashMap < String , trap:: Label < generated:: Item > > ,
190+ import : ImportOrGlob ,
191+ name : & str ,
192+ ) {
193+ let ( use_, idx) = match import {
194+ ImportOrGlob :: Glob ( import) => ( import. use_ , import. idx ) ,
195+ ImportOrGlob :: Import ( import) => ( import. use_ , import. idx ) ,
196+ } ;
197+ let def_db = db. upcast ( ) ;
198+ let loc = use_. lookup ( def_db) ;
199+ let use_ = & loc. id . item_tree ( def_db) [ loc. id . value ] ;
200+
201+ use_. use_tree . expand ( |id, path, kind, alias| {
202+ if id == idx {
203+ let mut path_components = Vec :: new ( ) ;
204+ match path. kind {
205+ PathKind :: Plain => ( ) ,
206+ PathKind :: Super ( 0 ) => path_components. push ( "self" . to_owned ( ) ) ,
207+ PathKind :: Super ( n) => {
208+ path_components. extend ( std:: iter:: repeat_n ( "parent" . to_owned ( ) , n. into ( ) ) ) ;
209+ }
210+ PathKind :: Crate => path_components. push ( "crate" . to_owned ( ) ) ,
211+ PathKind :: Abs => path_components. push ( "" . to_owned ( ) ) ,
212+ PathKind :: DollarCrate ( _) => path_components. push ( "$crate" . to_owned ( ) ) ,
213+ }
214+ path_components. extend ( path. segments ( ) . iter ( ) . map ( |x| x. as_str ( ) . to_owned ( ) ) ) ;
215+ match kind {
216+ ImportKind :: Plain => ( ) ,
217+ ImportKind :: Glob => path_components. push ( name. to_owned ( ) ) ,
218+ ImportKind :: TypeOnly => path_components. push ( "self" . to_owned ( ) ) ,
219+ } ;
220+ let key = path_components. join ( "::" ) ;
221+ // prevent duplicate imports
222+ if uses. contains_key ( & key) {
223+ return ;
224+ }
225+
226+ let alias = alias. map ( |alias| match alias {
227+ ImportAlias :: Underscore => "_" . to_owned ( ) ,
228+ ImportAlias :: Alias ( name) => name. as_str ( ) . to_owned ( ) ,
229+ } ) ;
230+ let rename = alias. map ( |name| {
231+ let name = Some ( trap. emit ( generated:: Name {
232+ id : trap:: TrapId :: Star ,
233+ text : Some ( name) ,
234+ } ) ) ;
235+ trap. emit ( generated:: Rename {
236+ id : trap:: TrapId :: Star ,
237+ name,
238+ } )
239+ } ) ;
240+ let path = make_qualified_path ( trap, path_components) ;
241+ let use_tree = trap. emit ( generated:: UseTree {
242+ id : trap:: TrapId :: Star ,
243+ is_glob : false ,
244+ path,
245+ rename,
246+ use_tree_list : None ,
247+ } ) ;
248+ let visibility = emit_visibility ( db, trap, Visibility :: Public ) ;
249+ uses. insert (
250+ key,
251+ trap. emit ( generated:: Use {
252+ id : trap:: TrapId :: Star ,
253+ attrs : vec ! [ ] ,
254+ use_tree : Some ( use_tree) ,
255+ visibility,
256+ } )
257+ . into ( ) ,
258+ ) ;
259+ }
260+ } ) ;
261+ }
262+
181263fn emit_module_items (
182264 crate_graph : & CrateGraph ,
183265 db : & dyn HirDatabase ,
184266 module : & ModuleData ,
185267 trap : & mut TrapFile ,
186268) -> Vec < trap:: Label < generated:: Item > > {
187269 let mut items = Vec :: new ( ) ;
270+ let mut uses = HashMap :: new ( ) ;
188271 let item_scope = & module. scope ;
189272 for ( name, item) in item_scope. entries ( ) {
190273 let def = item. filter_visibility ( |x| matches ! ( x, ra_ap_hir:: Visibility :: Public ) ) ;
274+ if let Some ( ra_ap_hir_def:: per_ns:: Item {
275+ def : _,
276+ vis : _,
277+ import : Some ( import) ,
278+ } ) = def. values
279+ {
280+ emit_reexport ( db, trap, & mut uses, import, name. as_str ( ) ) ;
281+ }
191282 if let Some ( ra_ap_hir_def:: per_ns:: Item {
192283 def : value,
193284 vis,
194- import : _ ,
285+ import : None ,
195286 } ) = def. values
196287 {
197288 match value {
@@ -231,10 +322,21 @@ fn emit_module_items(
231322 _ => ( ) ,
232323 }
233324 }
325+ if let Some ( ra_ap_hir_def:: per_ns:: Item {
326+ def : _,
327+ vis : _,
328+ import : Some ( import) ,
329+ } ) = def. types
330+ {
331+ // TODO: handle ExternCrate as well?
332+ if let Some ( import) = import. import_or_glob ( ) {
333+ emit_reexport ( db, trap, & mut uses, import, name. as_str ( ) ) ;
334+ }
335+ }
234336 if let Some ( ra_ap_hir_def:: per_ns:: Item {
235337 def : type_id,
236338 vis,
237- import : _ ,
339+ import : None ,
238340 } ) = def. types
239341 {
240342 match type_id {
@@ -255,6 +357,7 @@ fn emit_module_items(
255357 }
256358 }
257359 }
360+ items. extend ( uses. values ( ) ) ;
258361 items
259362}
260363
0 commit comments