Cleanup editing API

This commit is contained in:
Aleksey Kladov 2020-02-29 13:49:43 +01:00
parent b53ff214aa
commit 5f8b37563e
5 changed files with 36 additions and 12 deletions

View file

@ -157,7 +157,7 @@ impl<'a> QualifyPaths<'a> {
pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N { pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N {
let syntax = node.syntax(); let syntax = node.syntax();
let result = ra_syntax::algo::replace_descendants(syntax, &|element| match element { let result = ra_syntax::algo::replace_descendants(syntax, |element| match element {
ra_syntax::SyntaxElement::Node(n) => { ra_syntax::SyntaxElement::Node(n) => {
let replacement = transformer.get_substitution(&n)?; let replacement = transformer.get_substitution(&n)?;
Some(replacement.into()) Some(replacement.into())

View file

@ -52,7 +52,7 @@ fn expand_macro_recur(
} }
} }
Some(replace_descendants(&expanded, &|n| replaces.get(n).cloned())) Some(replace_descendants(&expanded, |n| replaces.get(n).cloned()))
} }
// 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,

View file

@ -570,7 +570,7 @@ mod tests {
let token_tree = insert_children( let token_tree = insert_children(
&rbrace.parent().unwrap(), &rbrace.parent().unwrap(),
InsertPosition::Last, InsertPosition::Last,
&mut std::iter::once(space), std::iter::once(space),
); );
// Token Tree now is : // Token Tree now is :

View file

@ -142,6 +142,15 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
/// This is a type-unsafe low-level editing API, if you need to use it, /// This is a type-unsafe low-level editing API, if you need to use it,
/// prefer to create a type-safe abstraction on top of it instead. /// prefer to create a type-safe abstraction on top of it instead.
pub fn insert_children( pub fn insert_children(
parent: &SyntaxNode,
position: InsertPosition<SyntaxElement>,
to_insert: impl IntoIterator<Item = SyntaxElement>,
) -> SyntaxNode {
let mut to_insert = to_insert.into_iter();
_insert_children(parent, position, &mut to_insert)
}
fn _insert_children(
parent: &SyntaxNode, parent: &SyntaxNode,
position: InsertPosition<SyntaxElement>, position: InsertPosition<SyntaxElement>,
to_insert: &mut dyn Iterator<Item = SyntaxElement>, to_insert: &mut dyn Iterator<Item = SyntaxElement>,
@ -176,6 +185,15 @@ pub fn insert_children(
/// This is a type-unsafe low-level editing API, if you need to use it, /// This is a type-unsafe low-level editing API, if you need to use it,
/// prefer to create a type-safe abstraction on top of it instead. /// prefer to create a type-safe abstraction on top of it instead.
pub fn replace_children( pub fn replace_children(
parent: &SyntaxNode,
to_delete: RangeInclusive<SyntaxElement>,
to_insert: impl IntoIterator<Item = SyntaxElement>,
) -> SyntaxNode {
let mut to_insert = to_insert.into_iter();
_replace_children(parent, to_delete, &mut to_insert)
}
fn _replace_children(
parent: &SyntaxNode, parent: &SyntaxNode,
to_delete: RangeInclusive<SyntaxElement>, to_delete: RangeInclusive<SyntaxElement>,
to_insert: &mut dyn Iterator<Item = SyntaxElement>, to_insert: &mut dyn Iterator<Item = SyntaxElement>,
@ -202,14 +220,21 @@ pub fn replace_children(
/// to create a type-safe abstraction on top of it instead. /// to create a type-safe abstraction on top of it instead.
pub fn replace_descendants( pub fn replace_descendants(
parent: &SyntaxNode, parent: &SyntaxNode,
map: &impl Fn(&SyntaxElement) -> Option<SyntaxElement>, map: impl Fn(&SyntaxElement) -> Option<SyntaxElement>,
) -> SyntaxNode {
_replace_descendants(parent, &map)
}
fn _replace_descendants(
parent: &SyntaxNode,
map: &dyn Fn(&SyntaxElement) -> Option<SyntaxElement>,
) -> SyntaxNode { ) -> SyntaxNode {
// FIXME: this could be made much faster. // FIXME: this could be made much faster.
let new_children = parent.children_with_tokens().map(|it| go(map, it)).collect::<Vec<_>>(); let new_children = parent.children_with_tokens().map(|it| go(map, it)).collect::<Vec<_>>();
return with_children(parent, new_children); return with_children(parent, new_children);
fn go( fn go(
map: &impl Fn(&SyntaxElement) -> Option<SyntaxElement>, map: &dyn Fn(&SyntaxElement) -> Option<SyntaxElement>,
element: SyntaxElement, element: SyntaxElement,
) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> { ) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> {
if let Some(replacement) = map(&element) { if let Some(replacement) = map(&element) {
@ -221,7 +246,7 @@ pub fn replace_descendants(
match element { match element {
NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()), NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()),
NodeOrToken::Node(it) => { NodeOrToken::Node(it) => {
NodeOrToken::Node(replace_descendants(&it, map).green().clone()) NodeOrToken::Node(_replace_descendants(&it, map).green().clone())
} }
} }
} }

View file

@ -276,7 +276,7 @@ pub fn replace_descendants<N: AstNode, D: AstNode>(
.into_iter() .into_iter()
.map(|(from, to)| (from.syntax().clone().into(), to.syntax().clone().into())) .map(|(from, to)| (from.syntax().clone().into(), to.syntax().clone().into()))
.collect::<FxHashMap<SyntaxElement, _>>(); .collect::<FxHashMap<SyntaxElement, _>>();
let new_syntax = algo::replace_descendants(parent.syntax(), &|n| map.get(n).cloned()); let new_syntax = algo::replace_descendants(parent.syntax(), |n| map.get(n).cloned());
N::cast(new_syntax).unwrap() N::cast(new_syntax).unwrap()
} }
@ -331,7 +331,7 @@ impl IndentLevel {
) )
}) })
.collect(); .collect();
algo::replace_descendants(&node, &|n| replacements.get(n).cloned()) algo::replace_descendants(&node, |n| replacements.get(n).cloned())
} }
pub fn decrease_indent<N: AstNode>(self, node: N) -> N { pub fn decrease_indent<N: AstNode>(self, node: N) -> N {
@ -359,7 +359,7 @@ impl IndentLevel {
) )
}) })
.collect(); .collect();
algo::replace_descendants(&node, &|n| replacements.get(n).cloned()) algo::replace_descendants(&node, |n| replacements.get(n).cloned())
} }
} }
@ -389,7 +389,7 @@ fn insert_children<N: AstNode>(
position: InsertPosition<SyntaxElement>, position: InsertPosition<SyntaxElement>,
to_insert: impl IntoIterator<Item = SyntaxElement>, to_insert: impl IntoIterator<Item = SyntaxElement>,
) -> N { ) -> N {
let new_syntax = algo::insert_children(parent.syntax(), position, &mut to_insert.into_iter()); let new_syntax = algo::insert_children(parent.syntax(), position, to_insert);
N::cast(new_syntax).unwrap() N::cast(new_syntax).unwrap()
} }
@ -404,8 +404,7 @@ fn replace_children<N: AstNode>(
to_replace: RangeInclusive<SyntaxElement>, to_replace: RangeInclusive<SyntaxElement>,
to_insert: impl IntoIterator<Item = SyntaxElement>, to_insert: impl IntoIterator<Item = SyntaxElement>,
) -> N { ) -> N {
let new_syntax = let new_syntax = algo::replace_children(parent.syntax(), to_replace, to_insert);
algo::replace_children(parent.syntax(), to_replace, &mut to_insert.into_iter());
N::cast(new_syntax).unwrap() N::cast(new_syntax).unwrap()
} }