From 33e747d786e588ab61133fe2c0fb6341826e2cea Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 7 Jun 2021 16:05:36 +0200 Subject: Make "expand macro" command work with attribute macros --- crates/ide/src/expand_macro.rs | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index e0d01fa96..3f38e2145 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -3,8 +3,7 @@ use std::iter; use hir::Semantics; use ide_db::RootDatabase; use syntax::{ - algo::find_node_at_offset, ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*, - SyntaxNode, WalkEvent, T, + ast, match_ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*, SyntaxNode, WalkEvent, T, }; use crate::FilePosition; @@ -28,16 +27,37 @@ pub struct ExpandedMacro { pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option { let sema = Semantics::new(db); let file = sema.parse(position.file_id); - let mac = find_node_at_offset::(file.syntax(), position.offset)?; - let name = mac.path()?.segment()?.name_ref()?; - let expanded = expand_macro_recur(&sema, &mac)?; + let tok = file.syntax().token_at_offset(position.offset).left_biased()?; + let mut expanded = None; + let mut name = None; + for node in tok.ancestors() { + match_ast! { + match node { + ast::MacroCall(mac) => { + name = Some(mac.path()?.segment()?.name_ref()?.to_string()); + expanded = expand_macro_recur(&sema, &mac); + break; + }, + ast::Item(item) => { + // FIXME: add the macro name + // FIXME: make this recursive too + name = Some("?".to_string()); + expanded = sema.expand_attr_macro(&item); + if expanded.is_some() { + break; + } + }, + _ => {} + } + } + } // FIXME: // macro expansion may lose all white space information // But we hope someday we can use ra_fmt for that - let expansion = insert_whitespaces(expanded); - Some(ExpandedMacro { name: name.to_string(), expansion }) + let expansion = insert_whitespaces(expanded?); + Some(ExpandedMacro { name: name?, expansion }) } fn expand_macro_recur( -- cgit v1.2.3 From 33be5762e579a9e03288ba27821951ca7db3a68e Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 7 Jun 2021 19:32:28 +0200 Subject: Attempt to track attr macros during highlighting --- crates/ide/src/syntax_highlighting.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'crates/ide') diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 79c2f4a1e..b03f1c71f 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -192,6 +192,7 @@ fn traverse( let mut bindings_shadow_count: FxHashMap = FxHashMap::default(); let mut current_macro_call: Option = None; + let mut current_attr_macro_call = None; let mut current_macro: Option = None; let mut macro_highlighter = MacroHighlighter::default(); let mut inside_attribute = false; @@ -227,6 +228,19 @@ fn traverse( } _ => (), } + match event.clone().map(|it| it.into_node().and_then(ast::Item::cast)) { + WalkEvent::Enter(Some(item)) => { + if sema.is_attr_macro_call(&item) { + current_attr_macro_call = Some(item); + } + } + WalkEvent::Leave(Some(item)) => { + if current_attr_macro_call == Some(item) { + current_attr_macro_call = None; + } + } + _ => (), + } match event.clone().map(|it| it.into_node().and_then(ast::Macro::cast)) { WalkEvent::Enter(Some(mac)) => { @@ -286,6 +300,22 @@ fn traverse( } None => token.into(), } + } else if current_attr_macro_call.is_some() { + let token = match element.clone().into_token() { + Some(it) => it, + _ => continue, + }; + let token = sema.descend_into_macros(token.clone()); + match token.parent() { + Some(parent) => { + // We only care Name and Name_ref + match (token.kind(), parent.kind()) { + (IDENT, NAME) | (IDENT, NAME_REF) => parent.into(), + _ => token.into(), + } + } + None => token.into(), + } } else { element.clone() }; -- cgit v1.2.3