From 245a9b165acb179c40b8c9d4a085e5ccdd4b75d3 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 26 Nov 2019 15:05:53 +0800 Subject: [PATCH 1/2] Add hygiene information to SourceAnalyzer --- crates/ra_hir/src/source_binder.rs | 13 ++++++----- crates/ra_hir_def/src/path.rs | 2 +- crates/ra_ide_api/src/call_info.rs | 9 +++----- crates/ra_ide_api/src/expand_macro.rs | 23 ++++++++++++++++++++ crates/ra_ide_api/src/references/classify.rs | 2 +- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index cbfeca3abb7..287cea88087 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -14,7 +14,8 @@ DefWithBodyId, }; use hir_expand::{ - name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source, + hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, + Source, }; use ra_syntax::{ ast::{self, AstNode}, @@ -236,10 +237,10 @@ pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option, ) -> Option { - // This must be a normal source file rather than macro file. - let path = macro_call.path().and_then(Path::from_ast)?; + let hygiene = Hygiene::new(db, macro_call.file_id); + let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) } @@ -441,12 +442,14 @@ pub fn expand( db: &impl HirDatabase, macro_call: Source<&ast::MacroCall>, ) -> Option { - let def = self.resolve_macro_call(db, macro_call.value)?.id; + let def = self.resolve_macro_call(db, macro_call)?.id; let ast_id = AstId::new( macro_call.file_id, db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), ); let macro_call_loc = MacroCallLoc { def, ast_id }; + let kind = to_macro_file_kind(macro_call.value); + dbg!(kind); Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc), macro_file_kind: to_macro_file_kind(macro_call.value), diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 0e606fd0e81..6810a26dbbd 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -97,7 +97,7 @@ pub fn from_ast(path: ast::Path) -> Option { /// Converts an `ast::Path` to `Path`. Works with use trees. /// It correctly handles `$crate` based path from macro call. - pub(crate) fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option { + pub fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option { let mut kind = PathKind::Plain; let mut segments = Vec::new(); loop { diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 9beceb29cf9..7ebdfc585a1 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -18,12 +18,9 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { //FIXME: don't poke into Ty @@ -44,7 +41,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { - let macro_def = analyzer.resolve_macro_call(db, &expr)?; + let macro_def = analyzer.resolve_macro_call(db, name_ref.with_value(&expr))?; (CallInfo::with_macro(db, macro_def)?, false) } }; diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 0b540b8cdea..abc602244ca 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs @@ -269,4 +269,27 @@ fn main() { assert_eq!(res.name, "foo"); assert_snapshot!(res.expansion, @r###"bar!()"###); } + + #[test] + fn macro_expand_with_dollar_crate() { + let res = check_expand_macro( + r#" + //- /lib.rs + #[macro_export] + macro_rules! bar { + () => {0}; + } + macro_rules! foo { + () => {$crate::bar!()}; + } + + fn main() { + let res = fo<|>o!(); + } + "#, + ); + + assert_eq!(res.name, "foo"); + assert_snapshot!(res.expansion, @r###"0"###); + } } diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs index cab06dea941..227737ad24d 100644 --- a/crates/ra_ide_api/src/references/classify.rs +++ b/crates/ra_ide_api/src/references/classify.rs @@ -152,7 +152,7 @@ pub(crate) fn classify_name_ref( if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { tested_by!(goto_definition_works_for_macros); - if let Some(macro_def) = analyzer.resolve_macro_call(db, ¯o_call) { + if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(¯o_call)) { let kind = NameKind::Macro(macro_def); return Some(NameDefinition { kind, container, visibility }); } From 0623164c1d1ec461570c7d3d330d7c90fb00cf6e Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 26 Nov 2019 21:13:36 +0800 Subject: [PATCH 2/2] Remove dbg! --- crates/ra_hir/src/source_binder.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 287cea88087..144e144bbb5 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -448,8 +448,6 @@ pub fn expand( db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), ); let macro_call_loc = MacroCallLoc { def, ast_id }; - let kind = to_macro_file_kind(macro_call.value); - dbg!(kind); Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc), macro_file_kind: to_macro_file_kind(macro_call.value),