From c31c3246a8c87a3639623c30b692a57e728bb046 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 15 Dec 2020 18:43:19 +0100 Subject: Basic support for decl macros 2.0 --- crates/hir_expand/src/builtin_macro.rs | 19 +++++++++++-------- crates/hir_expand/src/db.rs | 5 ++++- crates/hir_expand/src/lib.rs | 7 +++++-- 3 files changed, 20 insertions(+), 11 deletions(-) (limited to 'crates/hir_expand/src') diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index bd9223825..df82cf8e6 100644 --- a/crates/hir_expand/src/builtin_macro.rs +++ b/crates/hir_expand/src/builtin_macro.rs @@ -63,7 +63,7 @@ macro_rules! register_builtin { pub fn find_builtin_macro( ident: &name::Name, krate: CrateId, - ast_id: AstId, + ast_id: AstId, ) -> Option { let kind = find_by_name(ident)?; @@ -515,16 +515,19 @@ mod tests { fn expand_builtin_macro(ra_fixture: &str) -> String { let (db, file_id) = TestDB::with_single_file(&ra_fixture); let parsed = db.parse(file_id); - let macro_rules: Vec<_> = + let mut macro_rules: Vec<_> = parsed.syntax_node().descendants().filter_map(ast::MacroRules::cast).collect(); - let macro_calls: Vec<_> = + let mut macro_calls: Vec<_> = parsed.syntax_node().descendants().filter_map(ast::MacroCall::cast).collect(); let ast_id_map = db.ast_id_map(file_id.into()); assert_eq!(macro_rules.len(), 1, "test must contain exactly 1 `macro_rules!`"); assert_eq!(macro_calls.len(), 1, "test must contain exactly 1 macro call"); - let expander = find_by_name(¯o_rules[0].name().unwrap().as_name()).unwrap(); + let macro_rules = ast::Macro::from(macro_rules.pop().unwrap()); + let macro_call = macro_calls.pop().unwrap(); + + let expander = find_by_name(¯o_rules.name().unwrap().as_name()).unwrap(); let krate = CrateId(0); let file_id = match expander { @@ -532,7 +535,7 @@ mod tests { // the first one should be a macro_rules let def = MacroDefId { krate: Some(CrateId(0)), - ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules[0]))), + ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules))), kind: MacroDefKind::BuiltIn(expander), local_inner: false, }; @@ -542,7 +545,7 @@ mod tests { krate, kind: MacroCallKind::FnLike(AstId::new( file_id.into(), - ast_id_map.ast_id(¯o_calls[0]), + ast_id_map.ast_id(¯o_call), )), }; @@ -553,12 +556,12 @@ mod tests { // the first one should be a macro_rules let def = MacroDefId { krate: Some(krate), - ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules[0]))), + ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules))), kind: MacroDefKind::BuiltInEager(expander), local_inner: false, }; - let args = macro_calls[0].token_tree().unwrap(); + let args = macro_call.token_tree().unwrap(); let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; let arg_id = db.intern_eager_expansion({ diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 11b5b98c8..4477d867f 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs @@ -129,7 +129,10 @@ fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc { fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option> { match id.kind { MacroDefKind::Declarative => { - let macro_call = id.ast_id?.to_node(db); + let macro_call = match id.ast_id?.to_node(db) { + syntax::ast::Macro::MacroRules(mac) => mac, + syntax::ast::Macro::MacroDef(_) => return None, + }; let arg = macro_call.token_tree()?; let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { log::warn!("fail on macro_def to token tree: {:#?}", arg); diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index ae3086a95..55f026c7b 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -145,7 +145,10 @@ impl HirFileId { let arg_tt = loc.kind.arg(db)?; let def = loc.def.ast_id.and_then(|id| { - let def_tt = id.to_node(db).token_tree()?; + let def_tt = match id.to_node(db) { + ast::Macro::MacroRules(mac) => mac.token_tree()?, + ast::Macro::MacroDef(_) => return None, + }; Some(InFile::new(id.file_id, def_tt)) }); @@ -228,7 +231,7 @@ pub struct MacroDefId { // (which will probably require touching this code), we can instead use // that (and also remove the hacks for resolving built-in derives). pub krate: Option, - pub ast_id: Option>, + pub ast_id: Option>, pub kind: MacroDefKind, pub local_inner: bool, -- cgit v1.2.3