Skip to content

Commit 01eaf9a

Browse files
committed
refactor: move EditorRemovable trait to syntax_editor
Signed-off-by: Tarek <[email protected]>
1 parent 4e97525 commit 01eaf9a

File tree

5 files changed

+81
-79
lines changed

5 files changed

+81
-79
lines changed

crates/ide-assists/src/handlers/merge_imports.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use ide_db::imports::{
66
use itertools::Itertools;
77
use syntax::{
88
algo::neighbor,
9-
ast::{self, edit_in_place::EditorRemovable, syntax_factory::SyntaxFactory},
10-
match_ast, AstNode, SyntaxElement, SyntaxNode,
9+
ast::{self, syntax_factory::SyntaxFactory},
10+
match_ast,
11+
syntax_editor::edits::Removable,
12+
AstNode, SyntaxElement, SyntaxNode,
1113
};
1214

1315
use crate::{
@@ -68,7 +70,6 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
6870
(selection_range, edits?)
6971
};
7072

71-
// FIXME: Is this the best to get a `SyntaxNode` object? We need one for `SourceChangeBuilder::make_editor`.
7273
let parent_node = match ctx.covering_element() {
7374
SyntaxElement::Node(n) => n,
7475
SyntaxElement::Token(t) => t.parent()?,

crates/syntax/src/ast/edit_in_place.rs

+3-69
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ use parser::{SyntaxKind, T};
66

77
use crate::{
88
algo::{self, neighbor},
9-
ast::{
10-
self, edit::IndentLevel, make, syntax_factory::SyntaxFactory, HasGenericArgs,
11-
HasGenericParams,
12-
},
13-
syntax_editor::SyntaxEditor,
9+
ast::{self, edit::IndentLevel, make, HasGenericArgs, HasGenericParams},
1410
ted::{self, Position},
1511
AstNode, AstToken, Direction, SyntaxElement,
1612
SyntaxKind::{ATTR, COMMENT, WHITESPACE},
@@ -389,10 +385,6 @@ pub trait Removable: AstNode {
389385
fn remove(&self);
390386
}
391387

392-
pub trait EditorRemovable: AstNode {
393-
fn remove(&self, editor: &mut SyntaxEditor);
394-
}
395-
396388
impl Removable for ast::TypeBoundList {
397389
fn remove(&self) {
398390
match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) {
@@ -447,35 +439,16 @@ impl Removable for ast::UseTree {
447439
}
448440
}
449441

450-
impl EditorRemovable for ast::UseTree {
451-
fn remove(&self, editor: &mut SyntaxEditor) {
452-
for dir in [Direction::Next, Direction::Prev] {
453-
if let Some(next_use_tree) = neighbor(self, dir) {
454-
let separators = self
455-
.syntax()
456-
.siblings_with_tokens(dir)
457-
.skip(1)
458-
.take_while(|it| it.as_node() != Some(next_use_tree.syntax()));
459-
for sep in separators {
460-
editor.delete(sep);
461-
}
462-
break;
463-
}
464-
}
465-
editor.delete(self.syntax());
466-
}
467-
}
468-
469442
impl ast::UseTree {
470443
/// Deletes the usetree node represented by the input. Recursively removes parents, including use nodes that become empty.
471444
pub fn remove_recursive(self) {
472445
let parent = self.syntax().parent();
473446

474-
Removable::remove(&self);
447+
self.remove();
475448

476449
if let Some(u) = parent.clone().and_then(ast::Use::cast) {
477450
if u.use_tree().is_none() {
478-
Removable::remove(&u);
451+
u.remove()
479452
}
480453
} else if let Some(u) = parent.and_then(ast::UseTreeList::cast) {
481454
if u.use_trees().next().is_none() {
@@ -643,45 +616,6 @@ impl Removable for ast::Use {
643616
}
644617
}
645618

646-
impl EditorRemovable for ast::Use {
647-
fn remove(&self, editor: &mut SyntaxEditor) {
648-
let make = SyntaxFactory::new();
649-
650-
let next_ws = self
651-
.syntax()
652-
.next_sibling_or_token()
653-
.and_then(|it| it.into_token())
654-
.and_then(ast::Whitespace::cast);
655-
if let Some(next_ws) = next_ws {
656-
let ws_text = next_ws.syntax().text();
657-
if let Some(rest) = ws_text.strip_prefix('\n') {
658-
if rest.is_empty() {
659-
editor.delete(next_ws.syntax());
660-
} else {
661-
editor.replace(next_ws.syntax(), make.whitespace(rest));
662-
}
663-
}
664-
}
665-
let prev_ws = self
666-
.syntax()
667-
.prev_sibling_or_token()
668-
.and_then(|it| it.into_token())
669-
.and_then(ast::Whitespace::cast);
670-
if let Some(prev_ws) = prev_ws {
671-
let ws_text = prev_ws.syntax().text();
672-
let prev_newline = ws_text.rfind('\n').map(|x| x + 1).unwrap_or(0);
673-
let rest = &ws_text[0..prev_newline];
674-
if rest.is_empty() {
675-
editor.delete(prev_ws.syntax());
676-
} else {
677-
editor.replace(prev_ws.syntax(), make.whitespace(rest));
678-
}
679-
}
680-
681-
editor.delete(self.syntax());
682-
}
683-
}
684-
685619
impl ast::Impl {
686620
pub fn get_or_create_assoc_item_list(&self) -> ast::AssocItemList {
687621
if self.assoc_item_list().is_none() {

crates/syntax/src/ast/syntax_factory/constructors.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ impl SyntaxFactory {
1818
make::ty(text).clone_for_update()
1919
}
2020

21+
pub fn whitespace(&self, text: &str) -> SyntaxToken {
22+
make::tokens::whitespace(text)
23+
}
24+
2125
pub fn type_param(
2226
&self,
2327
name: ast::Name,
@@ -40,10 +44,6 @@ impl SyntaxFactory {
4044
ast
4145
}
4246

43-
pub fn whitespace(&self, text: &str) -> SyntaxToken {
44-
make::tokens::whitespace(text)
45-
}
46-
4747
pub fn ident_pat(&self, ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat {
4848
let ast = make::ident_pat(ref_, mut_, name.clone()).clone_for_update();
4949

crates/syntax/src/syntax_editor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_hash::FxHashMap;
1616
use crate::{SyntaxElement, SyntaxNode, SyntaxToken};
1717

1818
mod edit_algo;
19-
mod edits;
19+
pub mod edits;
2020
mod mapping;
2121

2222
pub use mapping::{SyntaxMapping, SyntaxMappingBuilder};

crates/syntax/src/syntax_editor/edits.rs

+69-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
//! Structural editing for ast using `SyntaxEditor`
22
33
use crate::{
4-
ast::make, ast::AstNode, ast::Fn, ast::GenericParam, ast::HasGenericParams, ast::HasName,
5-
syntax_editor::Position, syntax_editor::SyntaxEditor, SyntaxKind,
4+
algo::neighbor,
5+
ast::{
6+
self, make, syntax_factory::SyntaxFactory, AstNode, Fn, GenericParam, HasGenericParams,
7+
HasName,
8+
},
9+
syntax_editor::{Position, SyntaxEditor},
10+
AstToken, Direction, SyntaxKind,
611
};
712

813
impl SyntaxEditor {
@@ -70,3 +75,65 @@ impl SyntaxEditor {
7075
}
7176
}
7277
}
78+
79+
pub trait Removable: AstNode {
80+
fn remove(&self, editor: &mut SyntaxEditor);
81+
}
82+
83+
impl Removable for ast::Use {
84+
fn remove(&self, editor: &mut SyntaxEditor) {
85+
let make = SyntaxFactory::new();
86+
87+
let next_ws = self
88+
.syntax()
89+
.next_sibling_or_token()
90+
.and_then(|it| it.into_token())
91+
.and_then(ast::Whitespace::cast);
92+
if let Some(next_ws) = next_ws {
93+
let ws_text = next_ws.syntax().text();
94+
if let Some(rest) = ws_text.strip_prefix('\n') {
95+
if rest.is_empty() {
96+
editor.delete(next_ws.syntax());
97+
} else {
98+
editor.replace(next_ws.syntax(), make.whitespace(rest));
99+
}
100+
}
101+
}
102+
let prev_ws = self
103+
.syntax()
104+
.prev_sibling_or_token()
105+
.and_then(|it| it.into_token())
106+
.and_then(ast::Whitespace::cast);
107+
if let Some(prev_ws) = prev_ws {
108+
let ws_text = prev_ws.syntax().text();
109+
let prev_newline = ws_text.rfind('\n').map(|x| x + 1).unwrap_or(0);
110+
let rest = &ws_text[0..prev_newline];
111+
if rest.is_empty() {
112+
editor.delete(prev_ws.syntax());
113+
} else {
114+
editor.replace(prev_ws.syntax(), make.whitespace(rest));
115+
}
116+
}
117+
118+
editor.delete(self.syntax());
119+
}
120+
}
121+
122+
impl Removable for ast::UseTree {
123+
fn remove(&self, editor: &mut SyntaxEditor) {
124+
for dir in [Direction::Next, Direction::Prev] {
125+
if let Some(next_use_tree) = neighbor(self, dir) {
126+
let separators = self
127+
.syntax()
128+
.siblings_with_tokens(dir)
129+
.skip(1)
130+
.take_while(|it| it.as_node() != Some(next_use_tree.syntax()));
131+
for sep in separators {
132+
editor.delete(sep);
133+
}
134+
break;
135+
}
136+
}
137+
editor.delete(self.syntax());
138+
}
139+
}

0 commit comments

Comments
 (0)