From f5bea9051b81f3a490c08afdb336c63c9180aae0 Mon Sep 17 00:00:00 2001 From: uHOOCCOOHu Date: Fri, 30 Aug 2019 01:56:00 +0800 Subject: [PATCH] Support resolution of `#[macro_use] extern crate` --- crates/ra_hir/src/nameres/collector.rs | 17 +++++++++++++++++ crates/ra_hir/src/nameres/raw.rs | 13 +++++++++++-- crates/ra_syntax/src/ast/generated.rs | 1 + crates/ra_syntax/src/grammar.ron | 1 + 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 7da2dcdff1..26158b5c3d 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -295,6 +295,23 @@ where } } + // `#[macro_use] extern crate` glob import macros + if import.is_extern_crate && import.is_macro_use { + if let Some(ModuleDef::Module(m)) = + def.a().and_then(|item| item.take_types()) + { + let item_map = self.db.crate_def_map(m.krate); + let scope = &item_map[m.module_id].scope; + let macros = scope + .macros + .iter() + .map(|(name, res)| (name.clone(), Either::B(*res))) + .collect::>(); + + self.update(module_id, Some(import_id), ¯os); + } + } + let resolution = match def { Either::A(item) => { Either::A(Resolution { def: item, import: Some(import_id) }) diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 2f973359fe..129b047eb5 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -154,6 +154,7 @@ pub struct ImportData { pub(super) is_glob: bool, pub(super) is_prelude: bool, pub(super) is_extern_crate: bool, + pub(super) is_macro_use: bool, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -293,8 +294,14 @@ impl RawItemsCollector { let is_prelude = use_item.has_atom_attr("prelude_import"); Path::expand_use_item(&use_item, |path, use_tree, is_glob, alias| { - let import_data = - ImportData { path, alias, is_glob, is_prelude, is_extern_crate: false }; + let import_data = ImportData { + path, + alias, + is_glob, + is_prelude, + is_extern_crate: false, + is_macro_use: false, + }; self.push_import(current_module, import_data, Either::A(AstPtr::new(use_tree))); }) } @@ -307,12 +314,14 @@ impl RawItemsCollector { if let Some(name_ref) = extern_crate.name_ref() { let path = Path::from_name_ref(&name_ref); let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); + let is_macro_use = extern_crate.has_atom_attr("macro_use"); let import_data = ImportData { path, alias, is_glob: false, is_prelude: false, is_extern_crate: true, + is_macro_use, }; self.push_import(current_module, import_data, Either::B(AstPtr::new(&extern_crate))); } diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 90480b6ca5..d161470e7d 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -934,6 +934,7 @@ impl AstNode for ExternCrateItem { &self.syntax } } +impl ast::AttrsOwner for ExternCrateItem {} impl ExternCrateItem { pub fn name_ref(&self) -> Option { AstChildren::new(&self.syntax).next() diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 1836862fe0..a07293a461 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -669,6 +669,7 @@ Grammar( collections: [("use_trees", "UseTree")] ), "ExternCrateItem": ( + traits: ["AttrsOwner"], options: ["NameRef", "Alias"], ), "ArgList": (