aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-11-06 21:39:02 +0000
committerGitHub <[email protected]>2020-11-06 21:39:02 +0000
commit7f12a1f225c7d3397f27964ce039b55d680772d3 (patch)
tree26043b20588eae4510e28249f11a094aacaf190d /crates/syntax/src
parentcdddcaee851be1cff1eeb23599f5a58f1b30a927 (diff)
parent6158304f8b64ef7cdf58b14bc675baf33a27a853 (diff)
Merge #6485
6485: Remove RAW literals r=matklad a=matklad bors r+ 🤖 closes https://github.com/rust-analyzer/rust-analyzer/issues/6308 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/syntax/src')
-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.rs10
-rw-r--r--crates/syntax/src/ast/token_ext.rs90
-rw-r--r--crates/syntax/src/parsing/lexer.rs4
-rw-r--r--crates/syntax/src/parsing/reparsing.rs2
-rw-r--r--crates/syntax/src/validation.rs41
7 files changed, 75 insertions, 91 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..ce35ac01a 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -7,7 +7,7 @@ use itertools::Itertools;
7use parser::SyntaxKind; 7use parser::SyntaxKind;
8 8
9use crate::{ 9use crate::{
10 ast::{self, support, token_ext::HasStringValue, AstNode, AstToken, NameOwner, SyntaxNode}, 10 ast::{self, support, AstNode, AstToken, NameOwner, SyntaxNode},
11 SmolStr, SyntaxElement, SyntaxToken, T, 11 SmolStr, SyntaxElement, SyntaxToken, T,
12}; 12};
13 13
@@ -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..bf0035986 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -114,39 +114,24 @@ impl QuoteOffsets {
114 } 114 }
115} 115}
116 116
117pub trait HasQuotes: AstToken { 117impl ast::String {
118 fn quote_offsets(&self) -> Option<QuoteOffsets> { 118 pub fn is_raw(&self) -> bool {
119 let text = self.text().as_str(); 119 self.text().starts_with('r')
120 let offsets = QuoteOffsets::new(text)?;
121 let o = self.syntax().text_range().start();
122 let offsets = QuoteOffsets {
123 quotes: (offsets.quotes.0 + o, offsets.quotes.1 + o),
124 contents: offsets.contents + o,
125 };
126 Some(offsets)
127 }
128 fn open_quote_text_range(&self) -> Option<TextRange> {
129 self.quote_offsets().map(|it| it.quotes.0)
130 } 120 }
131 121 pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> {
132 fn close_quote_text_range(&self) -> Option<TextRange> { 122 let contents_range = self.text_range_between_quotes()?;
133 self.quote_offsets().map(|it| it.quotes.1) 123 assert!(TextRange::up_to(contents_range.len()).contains_range(range));
134 } 124 Some(range + contents_range.start())
135
136 fn text_range_between_quotes(&self) -> Option<TextRange> {
137 self.quote_offsets().map(|it| it.contents)
138 } 125 }
139}
140
141impl HasQuotes for ast::String {}
142impl HasQuotes for ast::RawString {}
143 126
144pub trait HasStringValue: HasQuotes { 127 pub fn value(&self) -> Option<Cow<'_, str>> {
145 fn value(&self) -> Option<Cow<'_, str>>; 128 if self.is_raw() {
146} 129 let text = self.text().as_str();
130 let text =
131 &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
132 return Some(Cow::Borrowed(text));
133 }
147 134
148impl HasStringValue for ast::String {
149 fn value(&self) -> Option<Cow<'_, str>> {
150 let text = self.text().as_str(); 135 let text = self.text().as_str();
151 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; 136 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
152 137
@@ -164,22 +149,31 @@ impl HasStringValue for ast::String {
164 let res = if buf == text { Cow::Borrowed(text) } else { Cow::Owned(buf) }; 149 let res = if buf == text { Cow::Borrowed(text) } else { Cow::Owned(buf) };
165 Some(res) 150 Some(res)
166 } 151 }
167}
168 152
169// FIXME: merge `ast::RawString` and `ast::String`. 153 pub fn quote_offsets(&self) -> Option<QuoteOffsets> {
170impl HasStringValue for ast::RawString {
171 fn value(&self) -> Option<Cow<'_, str>> {
172 let text = self.text().as_str(); 154 let text = self.text().as_str();
173 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; 155 let offsets = QuoteOffsets::new(text)?;
174 Some(Cow::Borrowed(text)) 156 let o = self.syntax().text_range().start();
157 let offsets = QuoteOffsets {
158 quotes: (offsets.quotes.0 + o, offsets.quotes.1 + o),
159 contents: offsets.contents + o,
160 };
161 Some(offsets)
162 }
163 pub fn text_range_between_quotes(&self) -> Option<TextRange> {
164 self.quote_offsets().map(|it| it.contents)
165 }
166 pub fn open_quote_text_range(&self) -> Option<TextRange> {
167 self.quote_offsets().map(|it| it.quotes.0)
168 }
169 pub fn close_quote_text_range(&self) -> Option<TextRange> {
170 self.quote_offsets().map(|it| it.quotes.1)
175 } 171 }
176} 172}
177 173
178impl ast::RawString { 174impl ast::ByteString {
179 pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> { 175 pub fn is_raw(&self) -> bool {
180 let contents_range = self.text_range_between_quotes()?; 176 self.text().starts_with("br")
181 assert!(TextRange::up_to(contents_range.len()).contains_range(range));
182 Some(range + contents_range.start())
183 } 177 }
184} 178}
185 179
@@ -522,22 +516,6 @@ impl HasFormatSpecifier for ast::String {
522 } 516 }
523} 517}
524 518
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 { 519impl ast::IntNumber {
542 #[rustfmt::skip] 520 #[rustfmt::skip]
543 pub(crate) const SUFFIXES: &'static [&'static str] = &[ 521 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
5use crate::{ 5use 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};
10use rowan::Direction; 10use 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 _ => (),