diff options
author | Aleksey Kladov <[email protected]> | 2020-11-06 21:21:56 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-11-06 21:23:14 +0000 |
commit | 5ba4f949c23dcf53f34995c90b7c01e6c641b1f0 (patch) | |
tree | fe5064dde4e948a776c87d38fba972903acad3ec /crates/syntax/src | |
parent | 6725dcf847300b9cddcbb061b159317113860f31 (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')
-rw-r--r-- | crates/syntax/src/ast/expr_ext.rs | 11 | ||||
-rw-r--r-- | crates/syntax/src/ast/generated/tokens.rs | 8 | ||||
-rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 8 | ||||
-rw-r--r-- | crates/syntax/src/ast/token_ext.rs | 52 | ||||
-rw-r--r-- | crates/syntax/src/parsing/lexer.rs | 4 | ||||
-rw-r--r-- | crates/syntax/src/parsing/reparsing.rs | 2 | ||||
-rw-r--r-- | crates/syntax/src/validation.rs | 41 |
7 files changed, 61 insertions, 65 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)] |
73 | pub struct RawString { | 73 | pub struct ByteString { |
74 | pub(crate) syntax: SyntaxToken, | 74 | pub(crate) syntax: SyntaxToken, |
75 | } | 75 | } |
76 | impl std::fmt::Display for RawString { | 76 | impl 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 | } |
81 | impl AstToken for RawString { | 81 | impl 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 | ||
141 | impl HasQuotes for ast::String {} | 141 | impl HasQuotes for ast::String {} |
142 | impl HasQuotes for ast::RawString {} | ||
143 | 142 | ||
144 | pub trait HasStringValue: HasQuotes { | 143 | pub trait HasStringValue: HasQuotes { |
145 | fn value(&self) -> Option<Cow<'_, str>>; | 144 | fn value(&self) -> Option<Cow<'_, str>>; |
146 | } | 145 | } |
147 | 146 | ||
147 | impl 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 | |||
148 | impl HasStringValue for ast::String { | 158 | impl 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`. | 186 | impl ast::ByteString { |
170 | impl 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 | |||
178 | impl 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 | ||
525 | impl 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 | |||
541 | impl ast::IntNumber { | 531 | impl ast::IntNumber { |
542 | #[rustfmt::skip] | 532 | #[rustfmt::skip] |
543 | pub(crate) const SUFFIXES: &'static [&'static str] = &[ | 533 | pub(crate) const SUFFIXES: &'static [&'static str] = &[ |
diff --git a/crates/syntax/src/parsing/lexer.rs b/crates/syntax/src/parsing/lexer.rs index 5674ecb84..8afd7e53b 100644 --- a/crates/syntax/src/parsing/lexer.rs +++ b/crates/syntax/src/parsing/lexer.rs | |||
@@ -235,7 +235,7 @@ fn rustc_token_kind_to_syntax_kind( | |||
235 | RawStrError::TooManyDelimiters { .. } => "Too many `#` symbols: raw strings may be delimited by up to 65535 `#` symbols", | 235 | RawStrError::TooManyDelimiters { .. } => "Too many `#` symbols: raw strings may be delimited by up to 65535 `#` symbols", |
236 | }; | 236 | }; |
237 | }; | 237 | }; |
238 | RAW_STRING | 238 | STRING |
239 | } | 239 | } |
240 | rustc_lexer::LiteralKind::RawByteStr { err: raw_str_err, .. } => { | 240 | rustc_lexer::LiteralKind::RawByteStr { err: raw_str_err, .. } => { |
241 | if let Some(raw_str_err) = raw_str_err { | 241 | if let Some(raw_str_err) = raw_str_err { |
@@ -250,7 +250,7 @@ fn rustc_token_kind_to_syntax_kind( | |||
250 | }; | 250 | }; |
251 | }; | 251 | }; |
252 | 252 | ||
253 | RAW_BYTE_STRING | 253 | BYTE_STRING |
254 | } | 254 | } |
255 | }; | 255 | }; |
256 | 256 | ||
diff --git a/crates/syntax/src/parsing/reparsing.rs b/crates/syntax/src/parsing/reparsing.rs index 4149f856a..190f5f67a 100644 --- a/crates/syntax/src/parsing/reparsing.rs +++ b/crates/syntax/src/parsing/reparsing.rs | |||
@@ -44,7 +44,7 @@ fn reparse_token<'node>( | |||
44 | let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone(); | 44 | let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone(); |
45 | let prev_token_kind = prev_token.kind(); | 45 | let prev_token_kind = prev_token.kind(); |
46 | match prev_token_kind { | 46 | match prev_token_kind { |
47 | WHITESPACE | COMMENT | IDENT | STRING | RAW_STRING => { | 47 | WHITESPACE | COMMENT | IDENT | STRING => { |
48 | if prev_token_kind == WHITESPACE || prev_token_kind == COMMENT { | 48 | if prev_token_kind == WHITESPACE || prev_token_kind == COMMENT { |
49 | // removing a new line may extends previous token | 49 | // removing a new line may extends previous token |
50 | let deleted_range = edit.delete - prev_token.text_range().start(); | 50 | let deleted_range = edit.delete - prev_token.text_range().start(); |
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 0f9a5e8ae..62a37c50a 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs | |||
@@ -4,7 +4,7 @@ mod block; | |||
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | algo, ast, match_ast, AstNode, SyntaxError, | 6 | algo, ast, match_ast, AstNode, SyntaxError, |
7 | SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST, FN, INT_NUMBER, STRING, TYPE_ALIAS}, | 7 | SyntaxKind::{BYTE, CHAR, CONST, FN, INT_NUMBER, TYPE_ALIAS}, |
8 | SyntaxNode, SyntaxToken, TextSize, T, | 8 | SyntaxNode, SyntaxToken, TextSize, T, |
9 | }; | 9 | }; |
10 | use rowan::Direction; | 10 | use rowan::Direction; |
@@ -121,18 +121,19 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) { | |||
121 | acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off)); | 121 | acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off)); |
122 | }; | 122 | }; |
123 | 123 | ||
124 | match token.kind() { | 124 | if let Some(s) = literal.as_string() { |
125 | BYTE => { | 125 | if !s.is_raw() { |
126 | if let Some(Err(e)) = unquote(text, 2, '\'').map(unescape_byte) { | 126 | if let Some(without_quotes) = unquote(text, 1, '"') { |
127 | push_err(2, e); | 127 | unescape_literal(without_quotes, Mode::Str, &mut |range, char| { |
128 | } | 128 | if let Err(err) = char { |
129 | } | 129 | push_err(1, (range.start, err)); |
130 | CHAR => { | 130 | } |
131 | if let Some(Err(e)) = unquote(text, 1, '\'').map(unescape_char) { | 131 | }) |
132 | push_err(1, e); | ||
133 | } | 132 | } |
134 | } | 133 | } |
135 | BYTE_STRING => { | 134 | } |
135 | if let Some(s) = literal.as_byte_string() { | ||
136 | if !s.is_raw() { | ||
136 | if let Some(without_quotes) = unquote(text, 2, '"') { | 137 | if let Some(without_quotes) = unquote(text, 2, '"') { |
137 | unescape_byte_literal(without_quotes, Mode::ByteStr, &mut |range, char| { | 138 | unescape_byte_literal(without_quotes, Mode::ByteStr, &mut |range, char| { |
138 | if let Err(err) = char { | 139 | if let Err(err) = char { |
@@ -141,13 +142,17 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) { | |||
141 | }) | 142 | }) |
142 | } | 143 | } |
143 | } | 144 | } |
144 | STRING => { | 145 | } |
145 | if let Some(without_quotes) = unquote(text, 1, '"') { | 146 | |
146 | unescape_literal(without_quotes, Mode::Str, &mut |range, char| { | 147 | match token.kind() { |
147 | if let Err(err) = char { | 148 | BYTE => { |
148 | push_err(1, (range.start, err)); | 149 | if let Some(Err(e)) = unquote(text, 2, '\'').map(unescape_byte) { |
149 | } | 150 | push_err(2, e); |
150 | }) | 151 | } |
152 | } | ||
153 | CHAR => { | ||
154 | if let Some(Err(e)) = unquote(text, 1, '\'').map(unescape_char) { | ||
155 | push_err(1, e); | ||
151 | } | 156 | } |
152 | } | 157 | } |
153 | _ => (), | 158 | _ => (), |