aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/syntax')
-rw-r--r--crates/syntax/Cargo.toml2
-rw-r--r--crates/syntax/src/ast/edit.rs21
-rw-r--r--crates/syntax/src/ast/make.rs4
-rw-r--r--crates/syntax/src/ast/node_ext.rs19
-rw-r--r--crates/syntax/src/lib.rs2
-rw-r--r--crates/syntax/src/token_text.rs77
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"
16rowan = "0.13.0-pre.3" 16rowan = "0.13.0-pre.3"
17rustc_lexer = { version = "710.0.0", package = "rustc-ap-rustc_lexer" } 17rustc_lexer = { version = "710.0.0", package = "rustc-ap-rustc_lexer" }
18rustc-hash = "1.1.0" 18rustc-hash = "1.1.0"
19arrayvec = "0.5.1" 19arrayvec = "0.6"
20once_cell = "1.3.1" 20once_cell = "1.3.1"
21indexmap = "1.4.0" 21indexmap = "1.4.0"
22smol_str = { version = "0.1.15", features = ["serde"] } 22smol_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.
4use std::{ 4use 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 {
32impl ast::Fn { 32impl 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
96impl ast::Impl { 95impl 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
270pub fn ident_pat(name: ast::Name) -> ast::IdentPat { 270pub 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}
277pub fn ident_mut_pat(name: ast::Name) -> ast::IdentPat { 277pub 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
9use crate::{ 9use 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
14impl ast::Lifetime { 14impl 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
20impl ast::Name { 20impl 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
26impl ast::NameRef { 26impl 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
36fn text_of_first_token(node: &SyntaxNode) -> &str { 36fn 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
42pub enum Macro { 43pub enum Macro {
@@ -378,7 +379,7 @@ impl fmt::Display for NameOrNameRef {
378} 379}
379 380
380impl NameOrNameRef { 381impl 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;
29mod parsing; 29mod parsing;
30mod validation; 30mod validation;
31mod ptr; 31mod ptr;
32mod token_text;
32#[cfg(test)] 33#[cfg(test)]
33mod tests; 34mod 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};
59pub use parser::{SyntaxKind, T}; 61pub use parser::{SyntaxKind, T};
60pub use rowan::{ 62pub 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
3use std::{cmp::Ordering, fmt, ops};
4
5pub struct TokenText(pub(crate) rowan::GreenToken);
6
7impl TokenText {
8 pub fn as_str(&self) -> &str {
9 self.0.text()
10 }
11}
12
13impl ops::Deref for TokenText {
14 type Target = str;
15
16 fn deref(&self) -> &str {
17 self.as_str()
18 }
19}
20impl AsRef<str> for TokenText {
21 fn as_ref(&self) -> &str {
22 self.as_str()
23 }
24}
25
26impl From<TokenText> for String {
27 fn from(token_text: TokenText) -> Self {
28 token_text.as_str().into()
29 }
30}
31
32impl PartialEq<&'_ str> for TokenText {
33 fn eq(&self, other: &&str) -> bool {
34 self.as_str() == *other
35 }
36}
37impl PartialEq<TokenText> for &'_ str {
38 fn eq(&self, other: &TokenText) -> bool {
39 other == self
40 }
41}
42impl PartialEq<String> for TokenText {
43 fn eq(&self, other: &String) -> bool {
44 self.as_str() == other.as_str()
45 }
46}
47impl PartialEq<TokenText> for String {
48 fn eq(&self, other: &TokenText) -> bool {
49 other == self
50 }
51}
52impl PartialEq for TokenText {
53 fn eq(&self, other: &TokenText) -> bool {
54 self.as_str() == other.as_str()
55 }
56}
57impl Eq for TokenText {}
58impl Ord for TokenText {
59 fn cmp(&self, other: &Self) -> Ordering {
60 self.as_str().cmp(other.as_str())
61 }
62}
63impl PartialOrd for TokenText {
64 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
65 Some(self.cmp(other))
66 }
67}
68impl fmt::Display for TokenText {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 fmt::Display::fmt(self.as_str(), f)
71 }
72}
73impl fmt::Debug for TokenText {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 fmt::Debug::fmt(self.as_str(), f)
76 }
77}