diff options
Diffstat (limited to 'crates/syntax')
-rw-r--r-- | crates/syntax/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/syntax/src/ast/edit.rs | 21 | ||||
-rw-r--r-- | crates/syntax/src/ast/make.rs | 4 | ||||
-rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 19 | ||||
-rw-r--r-- | crates/syntax/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/syntax/src/token_text.rs | 77 |
6 files changed, 102 insertions, 23 deletions
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 0c3fec3c7..9f01acc26 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml | |||
@@ -16,7 +16,7 @@ itertools = "0.10.0" | |||
16 | rowan = "0.13.0-pre.3" | 16 | rowan = "0.13.0-pre.3" |
17 | rustc_lexer = { version = "710.0.0", package = "rustc-ap-rustc_lexer" } | 17 | rustc_lexer = { version = "710.0.0", package = "rustc-ap-rustc_lexer" } |
18 | rustc-hash = "1.1.0" | 18 | rustc-hash = "1.1.0" |
19 | arrayvec = "0.5.1" | 19 | arrayvec = "0.6" |
20 | once_cell = "1.3.1" | 20 | once_cell = "1.3.1" |
21 | indexmap = "1.4.0" | 21 | indexmap = "1.4.0" |
22 | smol_str = { version = "0.1.15", features = ["serde"] } | 22 | smol_str = { version = "0.1.15", features = ["serde"] } |
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 18820786a..8c60927e4 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | //! immutable, all function here return a fresh copy of the tree, instead of | 2 | //! immutable, all function here return a fresh copy of the tree, instead of |
3 | //! doing an in-place modification. | 3 | //! doing an in-place modification. |
4 | use std::{ | 4 | use std::{ |
5 | fmt, iter, | 5 | array, fmt, iter, |
6 | ops::{self, RangeInclusive}, | 6 | ops::{self, RangeInclusive}, |
7 | }; | 7 | }; |
8 | 8 | ||
@@ -32,7 +32,7 @@ impl ast::BinExpr { | |||
32 | impl ast::Fn { | 32 | impl ast::Fn { |
33 | #[must_use] | 33 | #[must_use] |
34 | pub fn with_body(&self, body: ast::BlockExpr) -> ast::Fn { | 34 | pub fn with_body(&self, body: ast::BlockExpr) -> ast::Fn { |
35 | let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new(); | 35 | let mut to_insert: ArrayVec<SyntaxElement, 2> = ArrayVec::new(); |
36 | let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() { | 36 | let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() { |
37 | old_body.syntax().clone().into() | 37 | old_body.syntax().clone().into() |
38 | } else if let Some(semi) = self.semicolon_token() { | 38 | } else if let Some(semi) = self.semicolon_token() { |
@@ -55,9 +55,8 @@ impl ast::Fn { | |||
55 | 55 | ||
56 | let anchor = self.name().expect("The function must have a name").syntax().clone(); | 56 | let anchor = self.name().expect("The function must have a name").syntax().clone(); |
57 | 57 | ||
58 | let mut to_insert: ArrayVec<[SyntaxElement; 1]> = ArrayVec::new(); | 58 | let to_insert = [generic_args.syntax().clone().into()]; |
59 | to_insert.push(generic_args.syntax().clone().into()); | 59 | self.insert_children(InsertPosition::After(anchor.into()), array::IntoIter::new(to_insert)) |
60 | self.insert_children(InsertPosition::After(anchor.into()), to_insert) | ||
61 | } | 60 | } |
62 | } | 61 | } |
63 | 62 | ||
@@ -96,7 +95,7 @@ where | |||
96 | impl ast::Impl { | 95 | impl ast::Impl { |
97 | #[must_use] | 96 | #[must_use] |
98 | pub fn with_assoc_item_list(&self, items: ast::AssocItemList) -> ast::Impl { | 97 | pub fn with_assoc_item_list(&self, items: ast::AssocItemList) -> ast::Impl { |
99 | let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new(); | 98 | let mut to_insert: ArrayVec<SyntaxElement, 2> = ArrayVec::new(); |
100 | if let Some(old_items) = self.assoc_item_list() { | 99 | if let Some(old_items) = self.assoc_item_list() { |
101 | let to_replace: SyntaxElement = old_items.syntax().clone().into(); | 100 | let to_replace: SyntaxElement = old_items.syntax().clone().into(); |
102 | to_insert.push(items.syntax().clone().into()); | 101 | to_insert.push(items.syntax().clone().into()); |
@@ -141,7 +140,7 @@ impl ast::AssocItemList { | |||
141 | }, | 140 | }, |
142 | }; | 141 | }; |
143 | let ws = tokens::WsBuilder::new(&format!("{}{}", whitespace, indent)); | 142 | let ws = tokens::WsBuilder::new(&format!("{}{}", whitespace, indent)); |
144 | let to_insert: ArrayVec<[SyntaxElement; 2]> = | 143 | let to_insert: ArrayVec<SyntaxElement, 2> = |
145 | [ws.ws().into(), item.syntax().clone().into()].into(); | 144 | [ws.ws().into(), item.syntax().clone().into()].into(); |
146 | self.insert_children(position, to_insert) | 145 | self.insert_children(position, to_insert) |
147 | } | 146 | } |
@@ -192,7 +191,7 @@ impl ast::RecordExprFieldList { | |||
192 | tokens::single_space() | 191 | tokens::single_space() |
193 | }; | 192 | }; |
194 | 193 | ||
195 | let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new(); | 194 | let mut to_insert: ArrayVec<SyntaxElement, 4> = ArrayVec::new(); |
196 | to_insert.push(space.into()); | 195 | to_insert.push(space.into()); |
197 | to_insert.push(field.syntax().clone().into()); | 196 | to_insert.push(field.syntax().clone().into()); |
198 | to_insert.push(make::token(T![,]).into()); | 197 | to_insert.push(make::token(T![,]).into()); |
@@ -305,7 +304,7 @@ impl ast::PathSegment { | |||
305 | iter::once(type_args.syntax().clone().into()), | 304 | iter::once(type_args.syntax().clone().into()), |
306 | ); | 305 | ); |
307 | } | 306 | } |
308 | let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new(); | 307 | let mut to_insert: ArrayVec<SyntaxElement, 2> = ArrayVec::new(); |
309 | if turbo { | 308 | if turbo { |
310 | to_insert.push(make::token(T![::]).into()); | 309 | to_insert.push(make::token(T![::]).into()); |
311 | } | 310 | } |
@@ -444,7 +443,7 @@ impl ast::MatchArmList { | |||
444 | let arm_ws = tokens::WsBuilder::new(" "); | 443 | let arm_ws = tokens::WsBuilder::new(" "); |
445 | let match_indent = &leading_indent(self.syntax()).unwrap_or_default(); | 444 | let match_indent = &leading_indent(self.syntax()).unwrap_or_default(); |
446 | let match_ws = tokens::WsBuilder::new(&format!("\n{}", match_indent)); | 445 | let match_ws = tokens::WsBuilder::new(&format!("\n{}", match_indent)); |
447 | let to_insert: ArrayVec<[SyntaxElement; 3]> = | 446 | let to_insert: ArrayVec<SyntaxElement, 3> = |
448 | [arm_ws.ws().into(), item.syntax().clone().into(), match_ws.ws().into()].into(); | 447 | [arm_ws.ws().into(), item.syntax().clone().into(), match_ws.ws().into()].into(); |
449 | self.insert_children(position, to_insert) | 448 | self.insert_children(position, to_insert) |
450 | } | 449 | } |
@@ -465,7 +464,7 @@ impl ast::GenericParamList { | |||
465 | pub fn append_param(&self, item: ast::GenericParam) -> ast::GenericParamList { | 464 | pub fn append_param(&self, item: ast::GenericParam) -> ast::GenericParamList { |
466 | let space = tokens::single_space(); | 465 | let space = tokens::single_space(); |
467 | 466 | ||
468 | let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new(); | 467 | let mut to_insert: ArrayVec<SyntaxElement, 4> = ArrayVec::new(); |
469 | if self.generic_params().next().is_some() { | 468 | if self.generic_params().next().is_some() { |
470 | to_insert.push(space.into()); | 469 | to_insert.push(space.into()); |
471 | } | 470 | } |
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index c08f2c14f..c6a7b99b7 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -268,14 +268,14 @@ pub fn arg_list(args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList { | |||
268 | } | 268 | } |
269 | 269 | ||
270 | pub fn ident_pat(name: ast::Name) -> ast::IdentPat { | 270 | pub fn ident_pat(name: ast::Name) -> ast::IdentPat { |
271 | return from_text(name.text()); | 271 | return from_text(&name.text()); |
272 | 272 | ||
273 | fn from_text(text: &str) -> ast::IdentPat { | 273 | fn from_text(text: &str) -> ast::IdentPat { |
274 | ast_from_text(&format!("fn f({}: ())", text)) | 274 | ast_from_text(&format!("fn f({}: ())", text)) |
275 | } | 275 | } |
276 | } | 276 | } |
277 | pub fn ident_mut_pat(name: ast::Name) -> ast::IdentPat { | 277 | pub fn ident_mut_pat(name: ast::Name) -> ast::IdentPat { |
278 | return from_text(name.text()); | 278 | return from_text(&name.text()); |
279 | 279 | ||
280 | fn from_text(text: &str) -> ast::IdentPat { | 280 | fn from_text(text: &str) -> ast::IdentPat { |
281 | ast_from_text(&format!("fn f(mut {}: ())", text)) | 281 | ast_from_text(&format!("fn f(mut {}: ())", text)) |
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index bdf907a21..2772d7364 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -8,23 +8,23 @@ use parser::SyntaxKind; | |||
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | ast::{self, support, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode}, | 10 | ast::{self, support, AstNode, AstToken, AttrsOwner, NameOwner, SyntaxNode}, |
11 | SmolStr, SyntaxElement, SyntaxToken, T, | 11 | SmolStr, SyntaxElement, SyntaxToken, TokenText, T, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | impl ast::Lifetime { | 14 | impl ast::Lifetime { |
15 | pub fn text(&self) -> &str { | 15 | pub fn text(&self) -> TokenText { |
16 | text_of_first_token(self.syntax()) | 16 | text_of_first_token(self.syntax()) |
17 | } | 17 | } |
18 | } | 18 | } |
19 | 19 | ||
20 | impl ast::Name { | 20 | impl ast::Name { |
21 | pub fn text(&self) -> &str { | 21 | pub fn text(&self) -> TokenText { |
22 | text_of_first_token(self.syntax()) | 22 | text_of_first_token(self.syntax()) |
23 | } | 23 | } |
24 | } | 24 | } |
25 | 25 | ||
26 | impl ast::NameRef { | 26 | impl ast::NameRef { |
27 | pub fn text(&self) -> &str { | 27 | pub fn text(&self) -> TokenText { |
28 | text_of_first_token(self.syntax()) | 28 | text_of_first_token(self.syntax()) |
29 | } | 29 | } |
30 | 30 | ||
@@ -33,10 +33,11 @@ impl ast::NameRef { | |||
33 | } | 33 | } |
34 | } | 34 | } |
35 | 35 | ||
36 | fn text_of_first_token(node: &SyntaxNode) -> &str { | 36 | fn text_of_first_token(node: &SyntaxNode) -> TokenText { |
37 | let t = | 37 | let first_token = |
38 | node.green().children().next().and_then(|it| it.into_token()).unwrap().text().to_string(); | 38 | node.green().children().next().and_then(|it| it.into_token()).unwrap().to_owned(); |
39 | Box::leak(Box::new(t)) | 39 | |
40 | TokenText(first_token) | ||
40 | } | 41 | } |
41 | 42 | ||
42 | pub enum Macro { | 43 | pub enum Macro { |
@@ -378,7 +379,7 @@ impl fmt::Display for NameOrNameRef { | |||
378 | } | 379 | } |
379 | 380 | ||
380 | impl NameOrNameRef { | 381 | impl NameOrNameRef { |
381 | pub fn text(&self) -> &str { | 382 | pub fn text(&self) -> TokenText { |
382 | match self { | 383 | match self { |
383 | NameOrNameRef::Name(name) => name.text(), | 384 | NameOrNameRef::Name(name) => name.text(), |
384 | NameOrNameRef::NameRef(name_ref) => name_ref.text(), | 385 | NameOrNameRef::NameRef(name_ref) => name_ref.text(), |
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 2a5c61171..90de6bef6 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs | |||
@@ -29,6 +29,7 @@ mod syntax_error; | |||
29 | mod parsing; | 29 | mod parsing; |
30 | mod validation; | 30 | mod validation; |
31 | mod ptr; | 31 | mod ptr; |
32 | mod token_text; | ||
32 | #[cfg(test)] | 33 | #[cfg(test)] |
33 | mod tests; | 34 | mod tests; |
34 | 35 | ||
@@ -55,6 +56,7 @@ pub use crate::{ | |||
55 | SyntaxElement, SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren, SyntaxToken, | 56 | SyntaxElement, SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren, SyntaxToken, |
56 | SyntaxTreeBuilder, | 57 | SyntaxTreeBuilder, |
57 | }, | 58 | }, |
59 | token_text::TokenText, | ||
58 | }; | 60 | }; |
59 | pub use parser::{SyntaxKind, T}; | 61 | pub use parser::{SyntaxKind, T}; |
60 | pub use rowan::{ | 62 | pub use rowan::{ |
diff --git a/crates/syntax/src/token_text.rs b/crates/syntax/src/token_text.rs new file mode 100644 index 000000000..d2ed0a12a --- /dev/null +++ b/crates/syntax/src/token_text.rs | |||
@@ -0,0 +1,77 @@ | |||
1 | //! Yet another version of owned string, backed by a syntax tree token. | ||
2 | |||
3 | use std::{cmp::Ordering, fmt, ops}; | ||
4 | |||
5 | pub struct TokenText(pub(crate) rowan::GreenToken); | ||
6 | |||
7 | impl TokenText { | ||
8 | pub fn as_str(&self) -> &str { | ||
9 | self.0.text() | ||
10 | } | ||
11 | } | ||
12 | |||
13 | impl ops::Deref for TokenText { | ||
14 | type Target = str; | ||
15 | |||
16 | fn deref(&self) -> &str { | ||
17 | self.as_str() | ||
18 | } | ||
19 | } | ||
20 | impl AsRef<str> for TokenText { | ||
21 | fn as_ref(&self) -> &str { | ||
22 | self.as_str() | ||
23 | } | ||
24 | } | ||
25 | |||
26 | impl From<TokenText> for String { | ||
27 | fn from(token_text: TokenText) -> Self { | ||
28 | token_text.as_str().into() | ||
29 | } | ||
30 | } | ||
31 | |||
32 | impl PartialEq<&'_ str> for TokenText { | ||
33 | fn eq(&self, other: &&str) -> bool { | ||
34 | self.as_str() == *other | ||
35 | } | ||
36 | } | ||
37 | impl PartialEq<TokenText> for &'_ str { | ||
38 | fn eq(&self, other: &TokenText) -> bool { | ||
39 | other == self | ||
40 | } | ||
41 | } | ||
42 | impl PartialEq<String> for TokenText { | ||
43 | fn eq(&self, other: &String) -> bool { | ||
44 | self.as_str() == other.as_str() | ||
45 | } | ||
46 | } | ||
47 | impl PartialEq<TokenText> for String { | ||
48 | fn eq(&self, other: &TokenText) -> bool { | ||
49 | other == self | ||
50 | } | ||
51 | } | ||
52 | impl PartialEq for TokenText { | ||
53 | fn eq(&self, other: &TokenText) -> bool { | ||
54 | self.as_str() == other.as_str() | ||
55 | } | ||
56 | } | ||
57 | impl Eq for TokenText {} | ||
58 | impl Ord for TokenText { | ||
59 | fn cmp(&self, other: &Self) -> Ordering { | ||
60 | self.as_str().cmp(other.as_str()) | ||
61 | } | ||
62 | } | ||
63 | impl PartialOrd for TokenText { | ||
64 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
65 | Some(self.cmp(other)) | ||
66 | } | ||
67 | } | ||
68 | impl fmt::Display for TokenText { | ||
69 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
70 | fmt::Display::fmt(self.as_str(), f) | ||
71 | } | ||
72 | } | ||
73 | impl fmt::Debug for TokenText { | ||
74 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
75 | fmt::Debug::fmt(self.as_str(), f) | ||
76 | } | ||
77 | } | ||