diff options
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 73 |
1 files changed, 53 insertions, 20 deletions
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 0936229ac..b7416ede6 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -31,21 +31,43 @@ pub struct RawItems { | |||
31 | 31 | ||
32 | #[derive(Debug, Default, PartialEq, Eq)] | 32 | #[derive(Debug, Default, PartialEq, Eq)] |
33 | pub struct ImportSourceMap { | 33 | pub struct ImportSourceMap { |
34 | map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>, | 34 | map: ArenaMap<ImportId, ImportSourcePtr>, |
35 | } | ||
36 | |||
37 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
38 | enum ImportSourcePtr { | ||
39 | UseTree(AstPtr<ast::UseTree>), | ||
40 | ExternCrate(AstPtr<ast::ExternCrateItem>), | ||
41 | } | ||
42 | |||
43 | impl ImportSourcePtr { | ||
44 | fn to_node(self, file: &SourceFile) -> ImportSource { | ||
45 | match self { | ||
46 | ImportSourcePtr::UseTree(ptr) => ImportSource::UseTree(ptr.to_node(file).to_owned()), | ||
47 | ImportSourcePtr::ExternCrate(ptr) => { | ||
48 | ImportSource::ExternCrate(ptr.to_node(file).to_owned()) | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
54 | pub enum ImportSource { | ||
55 | UseTree(TreeArc<ast::UseTree>), | ||
56 | ExternCrate(TreeArc<ast::ExternCrateItem>), | ||
35 | } | 57 | } |
36 | 58 | ||
37 | impl ImportSourceMap { | 59 | impl ImportSourceMap { |
38 | fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { | 60 | fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { |
39 | self.map.insert(import, AstPtr::new(segment)) | 61 | self.map.insert(import, ptr) |
40 | } | 62 | } |
41 | 63 | ||
42 | pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> { | 64 | pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> ImportSource { |
43 | let file = match source { | 65 | let file = match source { |
44 | ModuleSource::SourceFile(file) => &*file, | 66 | ModuleSource::SourceFile(file) => &*file, |
45 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), | 67 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), |
46 | }; | 68 | }; |
47 | 69 | ||
48 | self.map[import].to_node(file).to_owned() | 70 | self.map[import].to_node(file) |
49 | } | 71 | } |
50 | } | 72 | } |
51 | 73 | ||
@@ -256,18 +278,14 @@ impl RawItemsCollector { | |||
256 | fn add_use_item(&mut self, current_module: Option<Module>, use_item: &ast::UseItem) { | 278 | fn add_use_item(&mut self, current_module: Option<Module>, use_item: &ast::UseItem) { |
257 | let is_prelude = use_item.has_atom_attr("prelude_import"); | 279 | let is_prelude = use_item.has_atom_attr("prelude_import"); |
258 | 280 | ||
259 | Path::expand_use_item(use_item, |path, segment, alias| { | 281 | Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| { |
260 | let import = self.raw_items.imports.alloc(ImportData { | 282 | let import_data = |
261 | path, | 283 | ImportData { path, alias, is_glob, is_prelude, is_extern_crate: false }; |
262 | alias, | 284 | self.push_import( |
263 | is_glob: segment.is_none(), | 285 | current_module, |
264 | is_prelude, | 286 | import_data, |
265 | is_extern_crate: false, | 287 | ImportSourcePtr::UseTree(AstPtr::new(use_tree)), |
266 | }); | 288 | ); |
267 | if let Some(segment) = segment { | ||
268 | self.source_map.insert(import, segment) | ||
269 | } | ||
270 | self.push_item(current_module, RawItem::Import(import)) | ||
271 | }) | 289 | }) |
272 | } | 290 | } |
273 | 291 | ||
@@ -279,14 +297,18 @@ impl RawItemsCollector { | |||
279 | if let Some(name_ref) = extern_crate.name_ref() { | 297 | if let Some(name_ref) = extern_crate.name_ref() { |
280 | let path = Path::from_name_ref(name_ref); | 298 | let path = Path::from_name_ref(name_ref); |
281 | let alias = extern_crate.alias().and_then(|a| a.name()).map(AsName::as_name); | 299 | let alias = extern_crate.alias().and_then(|a| a.name()).map(AsName::as_name); |
282 | let import = self.raw_items.imports.alloc(ImportData { | 300 | let import_data = ImportData { |
283 | path, | 301 | path, |
284 | alias, | 302 | alias, |
285 | is_glob: false, | 303 | is_glob: false, |
286 | is_prelude: false, | 304 | is_prelude: false, |
287 | is_extern_crate: true, | 305 | is_extern_crate: true, |
288 | }); | 306 | }; |
289 | self.push_item(current_module, RawItem::Import(import)) | 307 | self.push_import( |
308 | current_module, | ||
309 | import_data, | ||
310 | ImportSourcePtr::ExternCrate(AstPtr::new(extern_crate)), | ||
311 | ); | ||
290 | } | 312 | } |
291 | } | 313 | } |
292 | 314 | ||
@@ -303,6 +325,17 @@ impl RawItemsCollector { | |||
303 | self.push_item(current_module, RawItem::Macro(m)); | 325 | self.push_item(current_module, RawItem::Macro(m)); |
304 | } | 326 | } |
305 | 327 | ||
328 | fn push_import( | ||
329 | &mut self, | ||
330 | current_module: Option<Module>, | ||
331 | data: ImportData, | ||
332 | source: ImportSourcePtr, | ||
333 | ) { | ||
334 | let import = self.raw_items.imports.alloc(data); | ||
335 | self.source_map.insert(import, source); | ||
336 | self.push_item(current_module, RawItem::Import(import)) | ||
337 | } | ||
338 | |||
306 | fn push_item(&mut self, current_module: Option<Module>, item: RawItem) { | 339 | fn push_item(&mut self, current_module: Option<Module>, item: RawItem) { |
307 | match current_module { | 340 | match current_module { |
308 | Some(module) => match &mut self.raw_items.modules[module] { | 341 | Some(module) => match &mut self.raw_items.modules[module] { |