8586: Replace SyntaxRewriter usage with ted in eager::eager_macro_recur r=Veykril a=Veykril



Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-04-19 18:03:56 +00:00 committed by GitHub
commit b6a7276c54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 23 deletions

View File

@ -29,7 +29,7 @@ use base_db::CrateId;
use mbe::ExpandResult; use mbe::ExpandResult;
use parser::FragmentKind; use parser::FragmentKind;
use std::sync::Arc; use std::sync::Arc;
use syntax::{algo::SyntaxRewriter, SyntaxNode}; use syntax::{ted, SyntaxNode};
#[derive(Debug)] #[derive(Debug)]
pub struct ErrorEmitted { pub struct ErrorEmitted {
@ -192,10 +192,10 @@ fn eager_macro_recur(
macro_resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>, macro_resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>,
mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError), mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
) -> Result<SyntaxNode, ErrorEmitted> { ) -> Result<SyntaxNode, ErrorEmitted> {
let original = curr.value.clone(); let original = curr.value.clone().clone_for_update();
let children = curr.value.descendants().filter_map(ast::MacroCall::cast); let children = original.descendants().filter_map(ast::MacroCall::cast);
let mut rewriter = SyntaxRewriter::default(); let mut replacements = Vec::new();
// Collect replacement // Collect replacement
for child in children { for child in children {
@ -214,6 +214,7 @@ fn eager_macro_recur(
.into(); .into();
db.parse_or_expand(id.as_file()) db.parse_or_expand(id.as_file())
.expect("successful macro expansion should be parseable") .expect("successful macro expansion should be parseable")
.clone_for_update()
} }
MacroDefKind::Declarative(_) MacroDefKind::Declarative(_)
| MacroDefKind::BuiltIn(..) | MacroDefKind::BuiltIn(..)
@ -227,15 +228,14 @@ fn eager_macro_recur(
} }
}; };
// check if the whole original sytnax is replaced // check if the whole original syntax is replaced
// Note that SyntaxRewriter cannot replace the root node itself
if child.syntax() == &original { if child.syntax() == &original {
return Ok(insert); return Ok(insert);
} }
rewriter.replace(child.syntax(), &insert); replacements.push((child, insert));
} }
let res = rewriter.rewrite(&original); replacements.into_iter().rev().for_each(|(old, new)| ted::replace(old.syntax(), new));
Ok(res) Ok(original)
} }

View File

@ -3,9 +3,7 @@ use std::iter;
use hir::Semantics; use hir::Semantics;
use ide_db::RootDatabase; use ide_db::RootDatabase;
use syntax::{ use syntax::{
algo::{find_node_at_offset, SyntaxRewriter}, algo::find_node_at_offset, ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*,
ast, AstNode, NodeOrToken, SyntaxKind,
SyntaxKind::*,
SyntaxNode, WalkEvent, T, SyntaxNode, WalkEvent, T,
}; };
@ -46,26 +44,23 @@ fn expand_macro_recur(
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
macro_call: &ast::MacroCall, macro_call: &ast::MacroCall,
) -> Option<SyntaxNode> { ) -> Option<SyntaxNode> {
let mut expanded = sema.expand(macro_call)?; let expanded = sema.expand(macro_call)?.clone_for_update();
let children = expanded.descendants().filter_map(ast::MacroCall::cast); let children = expanded.descendants().filter_map(ast::MacroCall::cast);
let mut rewriter = SyntaxRewriter::default(); let mut replacements = Vec::new();
for child in children.into_iter() { for child in children {
if let Some(new_node) = expand_macro_recur(sema, &child) { if let Some(new_node) = expand_macro_recur(sema, &child) {
// Replace the whole node if it is root // check if the whole original syntax is replaced
// `replace_descendants` will not replace the parent node
// but `SyntaxNode::descendants include itself
if expanded == *child.syntax() { if expanded == *child.syntax() {
expanded = new_node; return Some(new_node);
} else {
rewriter.replace(child.syntax(), &new_node)
} }
replacements.push((child, new_node));
} }
} }
let res = rewriter.rewrite(&expanded); replacements.into_iter().rev().for_each(|(old, new)| ted::replace(old.syntax(), new));
Some(res) Some(expanded)
} }
// FIXME: It would also be cool to share logic here and in the mbe tests, // FIXME: It would also be cool to share logic here and in the mbe tests,