aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src/ast
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-11-06 21:21:56 +0000
committerAleksey Kladov <[email protected]>2020-11-06 21:23:14 +0000
commit5ba4f949c23dcf53f34995c90b7c01e6c641b1f0 (patch)
treefe5064dde4e948a776c87d38fba972903acad3ec /crates/syntax/src/ast
parent6725dcf847300b9cddcbb061b159317113860f31 (diff)
Kill RAW_ literals
Syntactically, they are indistinguishable from non-raw versions, so it doesn't make sense to separate then *at the syntax* level.
Diffstat (limited to 'crates/syntax/src/ast')
-rw-r--r--crates/syntax/src/ast/expr_ext.rs11
-rw-r--r--crates/syntax/src/ast/generated/tokens.rs8
-rw-r--r--crates/syntax/src/ast/node_ext.rs8
-rw-r--r--crates/syntax/src/ast/token_ext.rs52
4 files changed, 35 insertions, 44 deletions
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs
index 3d33cd1cf..eb44bb2ab 100644
--- a/crates/syntax/src/ast/expr_ext.rs
+++ b/crates/syntax/src/ast/expr_ext.rs
@@ -320,6 +320,13 @@ impl ast::Literal {
320 ast::IntNumber::cast(self.token()) 320 ast::IntNumber::cast(self.token())
321 } 321 }
322 322
323 pub fn as_string(&self) -> Option<ast::String> {
324 ast::String::cast(self.token())
325 }
326 pub fn as_byte_string(&self) -> Option<ast::ByteString> {
327 ast::ByteString::cast(self.token())
328 }
329
323 fn find_suffix(text: &str, possible_suffixes: &[&str]) -> Option<SmolStr> { 330 fn find_suffix(text: &str, possible_suffixes: &[&str]) -> Option<SmolStr> {
324 possible_suffixes 331 possible_suffixes
325 .iter() 332 .iter()
@@ -351,10 +358,10 @@ impl ast::Literal {
351 suffix: Self::find_suffix(&text, &ast::FloatNumber::SUFFIXES), 358 suffix: Self::find_suffix(&text, &ast::FloatNumber::SUFFIXES),
352 } 359 }
353 } 360 }
354 STRING | RAW_STRING => LiteralKind::String, 361 STRING => LiteralKind::String,
355 T![true] => LiteralKind::Bool(true), 362 T![true] => LiteralKind::Bool(true),
356 T![false] => LiteralKind::Bool(false), 363 T![false] => LiteralKind::Bool(false),
357 BYTE_STRING | RAW_BYTE_STRING => LiteralKind::ByteString, 364 BYTE_STRING => LiteralKind::ByteString,
358 CHAR => LiteralKind::Char, 365 CHAR => LiteralKind::Char,
359 BYTE => LiteralKind::Byte, 366 BYTE => LiteralKind::Byte,
360 _ => unreachable!(), 367 _ => unreachable!(),
diff --git a/crates/syntax/src/ast/generated/tokens.rs b/crates/syntax/src/ast/generated/tokens.rs
index 1b8449221..728b72cd7 100644
--- a/crates/syntax/src/ast/generated/tokens.rs
+++ b/crates/syntax/src/ast/generated/tokens.rs
@@ -70,16 +70,16 @@ impl AstToken for String {
70} 70}
71 71
72#[derive(Debug, Clone, PartialEq, Eq, Hash)] 72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct RawString { 73pub struct ByteString {
74 pub(crate) syntax: SyntaxToken, 74 pub(crate) syntax: SyntaxToken,
75} 75}
76impl std::fmt::Display for RawString { 76impl std::fmt::Display for ByteString {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 std::fmt::Display::fmt(&self.syntax, f) 78 std::fmt::Display::fmt(&self.syntax, f)
79 } 79 }
80} 80}
81impl AstToken for RawString { 81impl AstToken for ByteString {
82 fn can_cast(kind: SyntaxKind) -> bool { kind == RAW_STRING } 82 fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE_STRING }
83 fn cast(syntax: SyntaxToken) -> Option<Self> { 83 fn cast(syntax: SyntaxToken) -> Option<Self> {
84 if Self::can_cast(syntax.kind()) { 84 if Self::can_cast(syntax.kind()) {
85 Some(Self { syntax }) 85 Some(Self { syntax })
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index c5cd1c504..5579f72b9 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -55,13 +55,7 @@ impl ast::Attr {
55 let key = self.simple_name()?; 55 let key = self.simple_name()?;
56 let value_token = lit.syntax().first_token()?; 56 let value_token = lit.syntax().first_token()?;
57 57
58 let value: SmolStr = if let Some(s) = ast::String::cast(value_token.clone()) { 58 let value: SmolStr = ast::String::cast(value_token.clone())?.value()?.into();
59 s.value()?.into()
60 } else if let Some(s) = ast::RawString::cast(value_token) {
61 s.value()?.into()
62 } else {
63 return None;
64 };
65 59
66 Some((key, value)) 60 Some((key, value))
67 } 61 }
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index 8d3fad5a6..6cd20b6a6 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -139,14 +139,31 @@ pub trait HasQuotes: AstToken {
139} 139}
140 140
141impl HasQuotes for ast::String {} 141impl HasQuotes for ast::String {}
142impl HasQuotes for ast::RawString {}
143 142
144pub trait HasStringValue: HasQuotes { 143pub trait HasStringValue: HasQuotes {
145 fn value(&self) -> Option<Cow<'_, str>>; 144 fn value(&self) -> Option<Cow<'_, str>>;
146} 145}
147 146
147impl ast::String {
148 pub fn is_raw(&self) -> bool {
149 self.text().starts_with('r')
150 }
151 pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> {
152 let contents_range = self.text_range_between_quotes()?;
153 assert!(TextRange::up_to(contents_range.len()).contains_range(range));
154 Some(range + contents_range.start())
155 }
156}
157
148impl HasStringValue for ast::String { 158impl HasStringValue for ast::String {
149 fn value(&self) -> Option<Cow<'_, str>> { 159 fn value(&self) -> Option<Cow<'_, str>> {
160 if self.is_raw() {
161 let text = self.text().as_str();
162 let text =
163 &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
164 return Some(Cow::Borrowed(text));
165 }
166
150 let text = self.text().as_str(); 167 let text = self.text().as_str();
151 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; 168 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
152 169
@@ -166,20 +183,9 @@ impl HasStringValue for ast::String {
166 } 183 }
167} 184}
168 185
169// FIXME: merge `ast::RawString` and `ast::String`. 186impl ast::ByteString {
170impl HasStringValue for ast::RawString { 187 pub fn is_raw(&self) -> bool {
171 fn value(&self) -> Option<Cow<'_, str>> { 188 self.text().starts_with("br")
172 let text = self.text().as_str();
173 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
174 Some(Cow::Borrowed(text))
175 }
176}
177
178impl ast::RawString {
179 pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> {
180 let contents_range = self.text_range_between_quotes()?;
181 assert!(TextRange::up_to(contents_range.len()).contains_range(range));
182 Some(range + contents_range.start())
183 } 189 }
184} 190}
185 191
@@ -522,22 +528,6 @@ impl HasFormatSpecifier for ast::String {
522 } 528 }
523} 529}
524 530
525impl HasFormatSpecifier for ast::RawString {
526 fn char_ranges(
527 &self,
528 ) -> Option<Vec<(TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>> {
529 let text = self.text().as_str();
530 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
531 let offset = self.text_range_between_quotes()?.start() - self.syntax().text_range().start();
532
533 let mut res = Vec::with_capacity(text.len());
534 for (idx, c) in text.char_indices() {
535 res.push((TextRange::at(idx.try_into().unwrap(), TextSize::of(c)) + offset, Ok(c)));
536 }
537 Some(res)
538 }
539}
540
541impl ast::IntNumber { 531impl ast::IntNumber {
542 #[rustfmt::skip] 532 #[rustfmt::skip]
543 pub(crate) const SUFFIXES: &'static [&'static str] = &[ 533 pub(crate) const SUFFIXES: &'static [&'static str] = &[