aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-05-18 12:42:41 +0100
committerAleksey Kladov <[email protected]>2021-05-22 13:27:32 +0100
commit47d7434dde215460fc95916f2703c6925f58dcce (patch)
tree2eb017e9a32da4fb6f729b6b9c617c2516dafc40 /crates/syntax
parent3cfe2d0a5d663d29c3d196f9d16e91964780792a (diff)
internal: replace AstTransformer with mutable syntax trees
Diffstat (limited to 'crates/syntax')
-rw-r--r--crates/syntax/src/ast/edit.rs56
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs10
-rw-r--r--crates/syntax/src/ast/make.rs4
-rw-r--r--crates/syntax/src/ted.rs3
4 files changed, 19 insertions, 54 deletions
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 61952377f..19107ee38 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -6,14 +6,12 @@ use std::{
6 ops::{self, RangeInclusive}, 6 ops::{self, RangeInclusive},
7}; 7};
8 8
9use arrayvec::ArrayVec;
10
11use crate::{ 9use crate::{
12 algo, 10 algo,
13 ast::{self, make, AstNode}, 11 ast::{self, make, AstNode},
14 ted, AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxKind, 12 ted, AstToken, NodeOrToken, SyntaxElement, SyntaxKind,
15 SyntaxKind::{ATTR, COMMENT, WHITESPACE}, 13 SyntaxKind::{ATTR, COMMENT, WHITESPACE},
16 SyntaxNode, SyntaxToken, T, 14 SyntaxNode, SyntaxToken,
17}; 15};
18 16
19impl ast::BinExpr { 17impl ast::BinExpr {
@@ -25,46 +23,6 @@ impl ast::BinExpr {
25 } 23 }
26} 24}
27 25
28impl ast::Path {
29 #[must_use]
30 pub fn with_segment(&self, segment: ast::PathSegment) -> ast::Path {
31 if let Some(old) = self.segment() {
32 return self.replace_children(
33 single_node(old.syntax().clone()),
34 iter::once(segment.syntax().clone().into()),
35 );
36 }
37 self.clone()
38 }
39}
40
41impl ast::PathSegment {
42 #[must_use]
43 pub fn with_generic_args(&self, type_args: ast::GenericArgList) -> ast::PathSegment {
44 self._with_generic_args(type_args, false)
45 }
46
47 #[must_use]
48 pub fn with_turbo_fish(&self, type_args: ast::GenericArgList) -> ast::PathSegment {
49 self._with_generic_args(type_args, true)
50 }
51
52 fn _with_generic_args(&self, type_args: ast::GenericArgList, turbo: bool) -> ast::PathSegment {
53 if let Some(old) = self.generic_arg_list() {
54 return self.replace_children(
55 single_node(old.syntax().clone()),
56 iter::once(type_args.syntax().clone().into()),
57 );
58 }
59 let mut to_insert: ArrayVec<SyntaxElement, 2> = ArrayVec::new();
60 if turbo {
61 to_insert.push(make::token(T![::]).into());
62 }
63 to_insert.push(type_args.syntax().clone().into());
64 self.insert_children(InsertPosition::Last, to_insert)
65 }
66}
67
68impl ast::UseTree { 26impl ast::UseTree {
69 /// Splits off the given prefix, making it the path component of the use tree, appending the rest of the path to all UseTreeList items. 27 /// Splits off the given prefix, making it the path component of the use tree, appending the rest of the path to all UseTreeList items.
70 #[must_use] 28 #[must_use]
@@ -234,16 +192,6 @@ fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
234 192
235pub trait AstNodeEdit: AstNode + Clone + Sized { 193pub trait AstNodeEdit: AstNode + Clone + Sized {
236 #[must_use] 194 #[must_use]
237 fn insert_children(
238 &self,
239 position: InsertPosition<SyntaxElement>,
240 to_insert: impl IntoIterator<Item = SyntaxElement>,
241 ) -> Self {
242 let new_syntax = algo::insert_children(self.syntax(), position, to_insert);
243 Self::cast(new_syntax).unwrap()
244 }
245
246 #[must_use]
247 fn replace_children( 195 fn replace_children(
248 &self, 196 &self,
249 to_replace: RangeInclusive<SyntaxElement>, 197 to_replace: RangeInclusive<SyntaxElement>,
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index 2676ed8c9..ca8103668 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -239,6 +239,16 @@ impl ast::TypeBoundList {
239 } 239 }
240} 240}
241 241
242impl ast::PathSegment {
243 pub fn get_or_create_generic_arg_list(&self) -> ast::GenericArgList {
244 if self.generic_arg_list().is_none() {
245 let arg_list = make::generic_arg_list().clone_for_update();
246 ted::append_child(self.syntax(), arg_list.syntax())
247 }
248 self.generic_arg_list().unwrap()
249 }
250}
251
242impl ast::UseTree { 252impl ast::UseTree {
243 pub fn remove(&self) { 253 pub fn remove(&self) {
244 for &dir in [Direction::Next, Direction::Prev].iter() { 254 for &dir in [Direction::Next, Direction::Prev].iter() {
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index d13926ded..0cf170626 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -106,6 +106,10 @@ pub fn impl_trait(trait_: ast::Path, ty: ast::Path) -> ast::Impl {
106 ast_from_text(&format!("impl {} for {} {{}}", trait_, ty)) 106 ast_from_text(&format!("impl {} for {} {{}}", trait_, ty))
107} 107}
108 108
109pub(crate) fn generic_arg_list() -> ast::GenericArgList {
110 ast_from_text("const S: T<> = ();")
111}
112
109pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment { 113pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
110 ast_from_text(&format!("use {};", name_ref)) 114 ast_from_text(&format!("use {};", name_ref))
111} 115}
diff --git a/crates/syntax/src/ted.rs b/crates/syntax/src/ted.rs
index a50c0dbca..ae970f44f 100644
--- a/crates/syntax/src/ted.rs
+++ b/crates/syntax/src/ted.rs
@@ -184,6 +184,9 @@ fn ws_between(left: &SyntaxElement, right: &SyntaxElement) -> Option<SyntaxToken
184 if left.kind() == T![&] && right.kind() == SyntaxKind::LIFETIME { 184 if left.kind() == T![&] && right.kind() == SyntaxKind::LIFETIME {
185 return None; 185 return None;
186 } 186 }
187 if right.kind() == SyntaxKind::GENERIC_ARG_LIST {
188 return None;
189 }
187 190
188 if right.kind() == SyntaxKind::USE { 191 if right.kind() == SyntaxKind::USE {
189 let mut indent = IndentLevel::from_element(left); 192 let mut indent = IndentLevel::from_element(left);