From 2ecb126f5caeb248e333f8559eb1b7dfd34cc744 Mon Sep 17 00:00:00 2001 From: uHOOCCOOHu Date: Fri, 27 Sep 2019 01:59:38 +0800 Subject: Support `$crate` in item and expr place. --- crates/ra_hir/src/nameres/raw.rs | 41 +++++++----- crates/ra_hir/src/nameres/tests/macros.rs | 105 ++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 15 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 29aaddbf1..c607b8a11 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -9,7 +9,7 @@ use test_utils::tested_by; use crate::{ db::{AstDatabase, DefDatabase}, - AsName, AstIdMap, Either, FileAstId, HirFileId, ModuleSource, Name, Path, + AsName, AstIdMap, Either, FileAstId, HirFileId, ModuleSource, Name, Path, Source, }; /// `RawItems` is a set of top-level items in a file (except for impls). @@ -71,6 +71,8 @@ impl RawItems { raw_items: RawItems::default(), source_ast_id_map: db.ast_id_map(file_id), source_map: ImportSourceMap::default(), + file_id, + db, }; if let Some(node) = db.parse_or_expand(file_id) { if let Some(source_file) = ast::SourceFile::cast(node.clone()) { @@ -192,13 +194,15 @@ pub(super) struct MacroData { pub(super) export: bool, } -struct RawItemsCollector { +struct RawItemsCollector { raw_items: RawItems, source_ast_id_map: Arc, source_map: ImportSourceMap, + file_id: HirFileId, + db: DB, } -impl RawItemsCollector { +impl RawItemsCollector<&'_ DB> { fn process_module(&mut self, current_module: Option, body: impl ast::ModuleItemOwner) { for item_or_macro in body.items_with_macros() { match item_or_macro { @@ -300,17 +304,21 @@ impl RawItemsCollector { fn add_use_item(&mut self, current_module: Option, use_item: ast::UseItem) { 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, - is_macro_use: false, - }; - self.push_import(current_module, import_data, Either::A(AstPtr::new(use_tree))); - }) + Path::expand_use_item( + Source { ast: use_item, file_id: self.file_id }, + self.db, + |path, use_tree, is_glob, alias| { + 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))); + }, + ) } fn add_extern_crate_item( @@ -335,7 +343,10 @@ impl RawItemsCollector { } fn add_macro(&mut self, current_module: Option, m: ast::MacroCall) { - let path = match m.path().and_then(Path::from_ast) { + let path = match m + .path() + .and_then(|path| Path::from_src(Source { ast: path, file_id: self.file_id }, self.db)) + { Some(it) => it, _ => return, }; diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs index bd60f4258..e4b408394 100644 --- a/crates/ra_hir/src/nameres/tests/macros.rs +++ b/crates/ra_hir/src/nameres/tests/macros.rs @@ -515,3 +515,108 @@ fn path_qualified_macros() { ⋮not_found: _ "###); } + +#[test] +fn macro_dollar_crate_is_correct_in_item() { + covers!(macro_dollar_crate_self); + covers!(macro_dollar_crate_other); + let map = def_map_with_crate_graph( + " + //- /main.rs + #[macro_use] + extern crate foo; + + #[macro_use] + mod m { + macro_rules! current { + () => { + use $crate::Foo as FooSelf; + } + } + } + + struct Foo; + + current!(); + not_current1!(); + foo::not_current2!(); + + //- /lib.rs + mod m { + #[macro_export] + macro_rules! not_current1 { + () => { + use $crate::Bar; + } + } + } + + #[macro_export] + macro_rules! not_current2 { + () => { + use $crate::Baz; + } + } + + struct Bar; + struct Baz; + ", + crate_graph! { + "main": ("/main.rs", ["foo"]), + "foo": ("/lib.rs", []), + }, + ); + assert_snapshot!(map, @r###" + ⋮crate + ⋮Bar: t v + ⋮Baz: t v + ⋮Foo: t v + ⋮FooSelf: t v + ⋮foo: t + ⋮m: t + ⋮ + ⋮crate::m + "###); +} + +#[test] +fn macro_dollar_crate_is_correct_in_indirect_deps() { + covers!(macro_dollar_crate_other); + // From std + let map = def_map_with_crate_graph( + r#" + //- /main.rs + foo!(); + + //- /std.rs + #[prelude_import] + use self::prelude::*; + + pub use core::foo; + + mod prelude {} + + #[macro_use] + mod std_macros; + + //- /core.rs + #[macro_export] + macro_rules! foo { + () => { + use $crate::bar; + } + } + + pub struct bar; + "#, + crate_graph! { + "main": ("/main.rs", ["std"]), + "std": ("/std.rs", ["core"]), + "core": ("/core.rs", []), + }, + ); + assert_snapshot!(map, @r###" + ⋮crate + ⋮bar: t v + "###); +} -- cgit v1.2.3