From 94c63d280246971983cad4fa6ce2d333e3ba9f02 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 19 Nov 2019 22:56:28 +0800 Subject: Change to use Expansion::file_id and reordering --- crates/ra_hir/src/source_binder.rs | 7 +--- crates/ra_ide_api/src/expand_macro.rs | 79 +++++++++++++++++------------------ 2 files changed, 40 insertions(+), 46 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 6d75296a5..5d3196c2a 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -140,12 +140,7 @@ impl Expansion { exp_info.map_token_down(token) } - pub fn source(&self, db: &impl HirDatabase) -> Source> { - let loc = db.lookup_intern_macro(self.macro_call_id); - Source::new(self.file_id(), loc.ast_id) - } - - fn file_id(&self) -> HirFileId { + pub fn file_id(&self) -> HirFileId { self.macro_call_id.as_file(MacroFileKind::Items) } } diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 49c096ed5..bd557d455 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs @@ -11,33 +11,20 @@ use ra_syntax::{ AstNode, NodeOrToken, SyntaxKind, SyntaxNode, WalkEvent, }; -fn insert_whitespaces(syn: SyntaxNode) -> String { - let mut res = String::new(); - - let mut token_iter = syn - .preorder_with_tokens() - .filter_map(|event| { - if let WalkEvent::Enter(NodeOrToken::Token(token)) = event { - Some(token) - } else { - None - } - }) - .peekable(); +pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<(String, String)> { + let parse = db.parse(position.file_id); + let file = parse.tree(); + let name_ref = find_node_at_offset::(file.syntax(), position.offset)?; + let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; - while let Some(token) = token_iter.next() { - res += &token.text().to_string(); - if token.kind().is_keyword() - || token.kind().is_literal() - || token.kind() == SyntaxKind::IDENT - { - if !token_iter.peek().map(|it| it.kind().is_punct()).unwrap_or(false) { - res += " "; - } - } - } + let source = hir::Source::new(position.file_id.into(), mac.syntax()); + let expanded = expand_macro_recur(db, source, &mac)?; - res + // FIXME: + // macro expansion may lose all white space information + // But we hope someday we can use ra_fmt for that + let res = insert_whitespaces(expanded); + Some((name_ref.text().to_string(), res)) } fn expand_macro_recur( @@ -47,14 +34,14 @@ fn expand_macro_recur( ) -> Option { let analyzer = hir::SourceAnalyzer::new(db, source, None); let expansion = analyzer.expand(db, ¯o_call)?; - let new_source = expansion.source(db); - let expanded: SyntaxNode = db.parse_or_expand(new_source.file_id)?; + let macro_file_id = expansion.file_id(); + let expanded: SyntaxNode = db.parse_or_expand(macro_file_id)?; let children = expanded.descendants().filter_map(ast::MacroCall::cast); let mut replaces = FxHashMap::default(); for child in children.into_iter() { - let source = new_source.with_ast(source.ast); + let source = hir::Source::new(macro_file_id, source.ast); let new_node = expand_macro_recur(db, source, &child)?; replaces.insert(child.syntax().clone().into(), new_node.into()); @@ -63,21 +50,33 @@ fn expand_macro_recur( Some(replace_descendants(&expanded, &replaces)) } -pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<(String, String)> { - let parse = db.parse(position.file_id); - let file = parse.tree(); - let name_ref = find_node_at_offset::(file.syntax(), position.offset)?; - let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; +fn insert_whitespaces(syn: SyntaxNode) -> String { + let mut res = String::new(); - let source = hir::Source::new(position.file_id.into(), mac.syntax()); + let mut token_iter = syn + .preorder_with_tokens() + .filter_map(|event| { + if let WalkEvent::Enter(NodeOrToken::Token(token)) = event { + Some(token) + } else { + None + } + }) + .peekable(); - let expanded = expand_macro_recur(db, source, &mac)?; + while let Some(token) = token_iter.next() { + res += &token.text().to_string(); + if token.kind().is_keyword() + || token.kind().is_literal() + || token.kind() == SyntaxKind::IDENT + { + if !token_iter.peek().map(|it| it.kind().is_punct()).unwrap_or(false) { + res += " "; + } + } + } - // FIXME: - // macro expansion may lose all white space information - // But we hope someday we can use ra_fmt for that - let res = insert_whitespaces(expanded); - Some((name_ref.text().to_string(), res)) + res } #[cfg(test)] -- cgit v1.2.3