Unnamed repository; edit this file 'description' to name the repository.
Fix syntax_editor duplicated changed tokens
| -rw-r--r-- | crates/syntax/src/syntax_editor.rs | 18 | ||||
| -rw-r--r-- | crates/syntax/src/syntax_editor/edit_algo.rs | 24 |
2 files changed, 40 insertions, 2 deletions
diff --git a/crates/syntax/src/syntax_editor.rs b/crates/syntax/src/syntax_editor.rs index a0ead400cd..5683d891be 100644 --- a/crates/syntax/src/syntax_editor.rs +++ b/crates/syntax/src/syntax_editor.rs @@ -655,6 +655,24 @@ mod tests { } #[test] + fn test_more_times_replace_node_to_mutable_token() { + let arg_list = + make::arg_list([make::expr_literal("1").into(), make::expr_literal("2").into()]); + + let mut editor = SyntaxEditor::new(arg_list.syntax().clone()); + let target_expr = make::token(parser::SyntaxKind::UNDERSCORE); + + for arg in arg_list.args() { + editor.replace(arg.syntax(), &target_expr); + } + + let edit = editor.finish(); + + let expect = expect![["(_, _)"]]; + expect.assert_eq(&edit.new_root.to_string()); + } + + #[test] fn test_more_times_replace_node_to_mutable() { let arg_list = make::arg_list([make::expr_literal("1").into(), make::expr_literal("2").into()]); diff --git a/crates/syntax/src/syntax_editor/edit_algo.rs b/crates/syntax/src/syntax_editor/edit_algo.rs index d54837b9f2..e697d97061 100644 --- a/crates/syntax/src/syntax_editor/edit_algo.rs +++ b/crates/syntax/src/syntax_editor/edit_algo.rs @@ -152,9 +152,29 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit { let mut changed_elements = vec![]; let mut changed_elements_set = rustc_hash::FxHashSet::default(); let mut deduplicate_node = |node_or_token: &mut SyntaxElement| { - let SyntaxElement::Node(node) = node_or_token else { return }; + let node; + let node = match node_or_token { + SyntaxElement::Token(token) => match token.parent() { + None => return, + Some(parent) => { + node = parent; + &node + } + }, + SyntaxElement::Node(node) => node, + }; if changed_elements_set.contains(node) { - *node = node.clone_subtree().clone_for_update(); + let new_node = node.clone_subtree().clone_for_update(); + match node_or_token { + SyntaxElement::Node(node) => *node = new_node, + SyntaxElement::Token(token) => { + *token = new_node + .children_with_tokens() + .filter_map(SyntaxElement::into_token) + .find(|it| it.kind() == token.kind() && it.text() == token.text()) + .unwrap(); + } + } } else { changed_elements_set.insert(node.clone()); } |