diff options
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r-- | crates/ra_syntax/src/algo.rs | 12 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/make.rs | 11 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/tokens.rs | 369 | ||||
-rw-r--r-- | crates/ra_syntax/src/fuzz.rs | 15 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/lexer.rs | 32 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/reparsing.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/text_token_source.rs | 8 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/text_tree_sink.rs | 14 | ||||
-rw-r--r-- | crates/ra_syntax/src/ptr.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/syntax_error.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/src/syntax_node.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/tests.rs | 8 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation.rs | 6 |
14 files changed, 432 insertions, 63 deletions
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs index 06df8495c..2a8dac757 100644 --- a/crates/ra_syntax/src/algo.rs +++ b/crates/ra_syntax/src/algo.rs | |||
@@ -11,7 +11,7 @@ use rustc_hash::FxHashMap; | |||
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr, | 13 | AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr, |
14 | SyntaxToken, TextRange, TextUnit, | 14 | SyntaxToken, TextRange, TextSize, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | /// Returns ancestors of the node at the offset, sorted by length. This should | 17 | /// Returns ancestors of the node at the offset, sorted by length. This should |
@@ -21,7 +21,7 @@ use crate::{ | |||
21 | /// t.parent().ancestors())`. | 21 | /// t.parent().ancestors())`. |
22 | pub fn ancestors_at_offset( | 22 | pub fn ancestors_at_offset( |
23 | node: &SyntaxNode, | 23 | node: &SyntaxNode, |
24 | offset: TextUnit, | 24 | offset: TextSize, |
25 | ) -> impl Iterator<Item = SyntaxNode> { | 25 | ) -> impl Iterator<Item = SyntaxNode> { |
26 | node.token_at_offset(offset) | 26 | node.token_at_offset(offset) |
27 | .map(|token| token.parent().ancestors()) | 27 | .map(|token| token.parent().ancestors()) |
@@ -37,7 +37,7 @@ pub fn ancestors_at_offset( | |||
37 | /// ``` | 37 | /// ``` |
38 | /// | 38 | /// |
39 | /// then the shorter node will be silently preferred. | 39 | /// then the shorter node will be silently preferred. |
40 | pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextUnit) -> Option<N> { | 40 | pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextSize) -> Option<N> { |
41 | ancestors_at_offset(syntax, offset).find_map(N::cast) | 41 | ancestors_at_offset(syntax, offset).find_map(N::cast) |
42 | } | 42 | } |
43 | 43 | ||
@@ -180,7 +180,7 @@ fn _insert_children( | |||
180 | position: InsertPosition<SyntaxElement>, | 180 | position: InsertPosition<SyntaxElement>, |
181 | to_insert: &mut dyn Iterator<Item = SyntaxElement>, | 181 | to_insert: &mut dyn Iterator<Item = SyntaxElement>, |
182 | ) -> SyntaxNode { | 182 | ) -> SyntaxNode { |
183 | let mut delta = TextUnit::default(); | 183 | let mut delta = TextSize::default(); |
184 | let to_insert = to_insert.map(|element| { | 184 | let to_insert = to_insert.map(|element| { |
185 | delta += element.text_range().len(); | 185 | delta += element.text_range().len(); |
186 | to_green_element(element) | 186 | to_green_element(element) |
@@ -347,7 +347,7 @@ fn with_children( | |||
347 | parent: &SyntaxNode, | 347 | parent: &SyntaxNode, |
348 | new_children: Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>, | 348 | new_children: Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>, |
349 | ) -> SyntaxNode { | 349 | ) -> SyntaxNode { |
350 | let len = new_children.iter().map(|it| it.text_len()).sum::<TextUnit>(); | 350 | let len = new_children.iter().map(|it| it.text_len()).sum::<TextSize>(); |
351 | let new_node = rowan::GreenNode::new(rowan::SyntaxKind(parent.kind() as u16), new_children); | 351 | let new_node = rowan::GreenNode::new(rowan::SyntaxKind(parent.kind() as u16), new_children); |
352 | let new_root_node = parent.replace_with(new_node); | 352 | let new_root_node = parent.replace_with(new_node); |
353 | let new_root_node = SyntaxNode::new_root(new_root_node); | 353 | let new_root_node = SyntaxNode::new_root(new_root_node); |
@@ -355,7 +355,7 @@ fn with_children( | |||
355 | // FIXME: use a more elegant way to re-fetch the node (#1185), make | 355 | // FIXME: use a more elegant way to re-fetch the node (#1185), make |
356 | // `range` private afterwards | 356 | // `range` private afterwards |
357 | let mut ptr = SyntaxNodePtr::new(parent); | 357 | let mut ptr = SyntaxNodePtr::new(parent); |
358 | ptr.range = TextRange::offset_len(ptr.range.start(), len); | 358 | ptr.range = TextRange::at(ptr.range.start(), len); |
359 | ptr.to_node(&new_root_node) | 359 | ptr.to_node(&new_root_node) |
360 | } | 360 | } |
361 | 361 | ||
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs index 0f4a50be4..ee0f5cc40 100644 --- a/crates/ra_syntax/src/ast/make.rs +++ b/crates/ra_syntax/src/ast/make.rs | |||
@@ -293,11 +293,20 @@ pub fn fn_def( | |||
293 | ast_from_text(&format!("fn {}{}{} {}", fn_name, type_params, params, body)) | 293 | ast_from_text(&format!("fn {}{}{} {}", fn_name, type_params, params, body)) |
294 | } | 294 | } |
295 | 295 | ||
296 | pub fn add_newlines(amount_of_newlines: usize, t: impl AstNode) -> ast::SourceFile { | 296 | pub fn add_leading_newlines(amount_of_newlines: usize, t: impl AstNode) -> ast::SourceFile { |
297 | let newlines = "\n".repeat(amount_of_newlines); | 297 | let newlines = "\n".repeat(amount_of_newlines); |
298 | ast_from_text(&format!("{}{}", newlines, t.syntax())) | 298 | ast_from_text(&format!("{}{}", newlines, t.syntax())) |
299 | } | 299 | } |
300 | 300 | ||
301 | pub fn add_trailing_newlines(amount_of_newlines: usize, t: impl AstNode) -> ast::SourceFile { | ||
302 | let newlines = "\n".repeat(amount_of_newlines); | ||
303 | ast_from_text(&format!("{}{}", t.syntax(), newlines)) | ||
304 | } | ||
305 | |||
306 | pub fn add_pub_crate_modifier(fn_def: ast::FnDef) -> ast::FnDef { | ||
307 | ast_from_text(&format!("pub(crate) {}", fn_def)) | ||
308 | } | ||
309 | |||
301 | fn ast_from_text<N: AstNode>(text: &str) -> N { | 310 | fn ast_from_text<N: AstNode>(text: &str) -> N { |
302 | let parse = SourceFile::parse(text); | 311 | let parse = SourceFile::parse(text); |
303 | let node = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); | 312 | let node = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); |
diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs index e8320b57e..8e04b0bbd 100644 --- a/crates/ra_syntax/src/ast/tokens.rs +++ b/crates/ra_syntax/src/ast/tokens.rs | |||
@@ -1,8 +1,10 @@ | |||
1 | //! There are many AstNodes, but only a few tokens, so we hand-write them here. | 1 | //! There are many AstNodes, but only a few tokens, so we hand-write them here. |
2 | 2 | ||
3 | use std::convert::{TryFrom, TryInto}; | ||
4 | |||
3 | use crate::{ | 5 | use crate::{ |
4 | ast::{AstToken, Comment, RawString, String, Whitespace}, | 6 | ast::{AstToken, Comment, RawString, String, Whitespace}, |
5 | TextRange, TextUnit, | 7 | TextRange, TextSize, |
6 | }; | 8 | }; |
7 | 9 | ||
8 | impl Comment { | 10 | impl Comment { |
@@ -94,14 +96,14 @@ impl QuoteOffsets { | |||
94 | return None; | 96 | return None; |
95 | } | 97 | } |
96 | 98 | ||
97 | let start = TextUnit::from(0); | 99 | let start = TextSize::from(0); |
98 | let left_quote = TextUnit::from_usize(left_quote) + TextUnit::of_char('"'); | 100 | let left_quote = TextSize::try_from(left_quote).unwrap() + TextSize::of('"'); |
99 | let right_quote = TextUnit::from_usize(right_quote); | 101 | let right_quote = TextSize::try_from(right_quote).unwrap(); |
100 | let end = TextUnit::of_str(literal); | 102 | let end = TextSize::of(literal); |
101 | 103 | ||
102 | let res = QuoteOffsets { | 104 | let res = QuoteOffsets { |
103 | quotes: [TextRange::from_to(start, left_quote), TextRange::from_to(right_quote, end)], | 105 | quotes: [TextRange::new(start, left_quote), TextRange::new(right_quote, end)], |
104 | contents: TextRange::from_to(left_quote, right_quote), | 106 | contents: TextRange::new(left_quote, right_quote), |
105 | }; | 107 | }; |
106 | Some(res) | 108 | Some(res) |
107 | } | 109 | } |
@@ -168,7 +170,358 @@ impl HasStringValue for RawString { | |||
168 | impl RawString { | 170 | impl RawString { |
169 | pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> { | 171 | pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> { |
170 | let contents_range = self.text_range_between_quotes()?; | 172 | let contents_range = self.text_range_between_quotes()?; |
171 | assert!(range.is_subrange(&TextRange::offset_len(0.into(), contents_range.len()))); | 173 | assert!(TextRange::up_to(contents_range.len()).contains_range(range)); |
172 | Some(range + contents_range.start()) | 174 | Some(range + contents_range.start()) |
173 | } | 175 | } |
174 | } | 176 | } |
177 | |||
178 | #[derive(Debug)] | ||
179 | pub enum FormatSpecifier { | ||
180 | Open, | ||
181 | Close, | ||
182 | Integer, | ||
183 | Identifier, | ||
184 | Colon, | ||
185 | Fill, | ||
186 | Align, | ||
187 | Sign, | ||
188 | NumberSign, | ||
189 | Zero, | ||
190 | DollarSign, | ||
191 | Dot, | ||
192 | Asterisk, | ||
193 | QuestionMark, | ||
194 | } | ||
195 | |||
196 | pub trait HasFormatSpecifier: AstToken { | ||
197 | fn char_ranges( | ||
198 | &self, | ||
199 | ) -> Option<Vec<(TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>>; | ||
200 | |||
201 | fn lex_format_specifier<F>(&self, mut callback: F) | ||
202 | where | ||
203 | F: FnMut(TextRange, FormatSpecifier), | ||
204 | { | ||
205 | let char_ranges = if let Some(char_ranges) = self.char_ranges() { | ||
206 | char_ranges | ||
207 | } else { | ||
208 | return; | ||
209 | }; | ||
210 | let mut chars = char_ranges.iter().peekable(); | ||
211 | |||
212 | while let Some((range, first_char)) = chars.next() { | ||
213 | match first_char { | ||
214 | Ok('{') => { | ||
215 | // Format specifier, see syntax at https://doc.rust-lang.org/std/fmt/index.html#syntax | ||
216 | if let Some((_, Ok('{'))) = chars.peek() { | ||
217 | // Escaped format specifier, `{{` | ||
218 | chars.next(); | ||
219 | continue; | ||
220 | } | ||
221 | |||
222 | callback(*range, FormatSpecifier::Open); | ||
223 | |||
224 | // check for integer/identifier | ||
225 | match chars | ||
226 | .peek() | ||
227 | .and_then(|next| next.1.as_ref().ok()) | ||
228 | .copied() | ||
229 | .unwrap_or_default() | ||
230 | { | ||
231 | '0'..='9' => { | ||
232 | // integer | ||
233 | read_integer(&mut chars, &mut callback); | ||
234 | } | ||
235 | c if c == '_' || c.is_alphabetic() => { | ||
236 | // identifier | ||
237 | read_identifier(&mut chars, &mut callback); | ||
238 | } | ||
239 | _ => {} | ||
240 | } | ||
241 | |||
242 | if let Some((_, Ok(':'))) = chars.peek() { | ||
243 | skip_char_and_emit(&mut chars, FormatSpecifier::Colon, &mut callback); | ||
244 | |||
245 | // check for fill/align | ||
246 | let mut cloned = chars.clone().take(2); | ||
247 | let first = cloned | ||
248 | .next() | ||
249 | .and_then(|next| next.1.as_ref().ok()) | ||
250 | .copied() | ||
251 | .unwrap_or_default(); | ||
252 | let second = cloned | ||
253 | .next() | ||
254 | .and_then(|next| next.1.as_ref().ok()) | ||
255 | .copied() | ||
256 | .unwrap_or_default(); | ||
257 | match second { | ||
258 | '<' | '^' | '>' => { | ||
259 | // alignment specifier, first char specifies fillment | ||
260 | skip_char_and_emit( | ||
261 | &mut chars, | ||
262 | FormatSpecifier::Fill, | ||
263 | &mut callback, | ||
264 | ); | ||
265 | skip_char_and_emit( | ||
266 | &mut chars, | ||
267 | FormatSpecifier::Align, | ||
268 | &mut callback, | ||
269 | ); | ||
270 | } | ||
271 | _ => match first { | ||
272 | '<' | '^' | '>' => { | ||
273 | skip_char_and_emit( | ||
274 | &mut chars, | ||
275 | FormatSpecifier::Align, | ||
276 | &mut callback, | ||
277 | ); | ||
278 | } | ||
279 | _ => {} | ||
280 | }, | ||
281 | } | ||
282 | |||
283 | // check for sign | ||
284 | match chars | ||
285 | .peek() | ||
286 | .and_then(|next| next.1.as_ref().ok()) | ||
287 | .copied() | ||
288 | .unwrap_or_default() | ||
289 | { | ||
290 | '+' | '-' => { | ||
291 | skip_char_and_emit( | ||
292 | &mut chars, | ||
293 | FormatSpecifier::Sign, | ||
294 | &mut callback, | ||
295 | ); | ||
296 | } | ||
297 | _ => {} | ||
298 | } | ||
299 | |||
300 | // check for `#` | ||
301 | if let Some((_, Ok('#'))) = chars.peek() { | ||
302 | skip_char_and_emit( | ||
303 | &mut chars, | ||
304 | FormatSpecifier::NumberSign, | ||
305 | &mut callback, | ||
306 | ); | ||
307 | } | ||
308 | |||
309 | // check for `0` | ||
310 | let mut cloned = chars.clone().take(2); | ||
311 | let first = cloned.next().and_then(|next| next.1.as_ref().ok()).copied(); | ||
312 | let second = cloned.next().and_then(|next| next.1.as_ref().ok()).copied(); | ||
313 | |||
314 | if first == Some('0') && second != Some('$') { | ||
315 | skip_char_and_emit(&mut chars, FormatSpecifier::Zero, &mut callback); | ||
316 | } | ||
317 | |||
318 | // width | ||
319 | match chars | ||
320 | .peek() | ||
321 | .and_then(|next| next.1.as_ref().ok()) | ||
322 | .copied() | ||
323 | .unwrap_or_default() | ||
324 | { | ||
325 | '0'..='9' => { | ||
326 | read_integer(&mut chars, &mut callback); | ||
327 | if let Some((_, Ok('$'))) = chars.peek() { | ||
328 | skip_char_and_emit( | ||
329 | &mut chars, | ||
330 | FormatSpecifier::DollarSign, | ||
331 | &mut callback, | ||
332 | ); | ||
333 | } | ||
334 | } | ||
335 | c if c == '_' || c.is_alphabetic() => { | ||
336 | read_identifier(&mut chars, &mut callback); | ||
337 | if chars.peek().and_then(|next| next.1.as_ref().ok()).copied() | ||
338 | != Some('$') | ||
339 | { | ||
340 | continue; | ||
341 | } | ||
342 | skip_char_and_emit( | ||
343 | &mut chars, | ||
344 | FormatSpecifier::DollarSign, | ||
345 | &mut callback, | ||
346 | ); | ||
347 | } | ||
348 | _ => {} | ||
349 | } | ||
350 | |||
351 | // precision | ||
352 | if let Some((_, Ok('.'))) = chars.peek() { | ||
353 | skip_char_and_emit(&mut chars, FormatSpecifier::Dot, &mut callback); | ||
354 | |||
355 | match chars | ||
356 | .peek() | ||
357 | .and_then(|next| next.1.as_ref().ok()) | ||
358 | .copied() | ||
359 | .unwrap_or_default() | ||
360 | { | ||
361 | '*' => { | ||
362 | skip_char_and_emit( | ||
363 | &mut chars, | ||
364 | FormatSpecifier::Asterisk, | ||
365 | &mut callback, | ||
366 | ); | ||
367 | } | ||
368 | '0'..='9' => { | ||
369 | read_integer(&mut chars, &mut callback); | ||
370 | if let Some((_, Ok('$'))) = chars.peek() { | ||
371 | skip_char_and_emit( | ||
372 | &mut chars, | ||
373 | FormatSpecifier::DollarSign, | ||
374 | &mut callback, | ||
375 | ); | ||
376 | } | ||
377 | } | ||
378 | c if c == '_' || c.is_alphabetic() => { | ||
379 | read_identifier(&mut chars, &mut callback); | ||
380 | if chars.peek().and_then(|next| next.1.as_ref().ok()).copied() | ||
381 | != Some('$') | ||
382 | { | ||
383 | continue; | ||
384 | } | ||
385 | skip_char_and_emit( | ||
386 | &mut chars, | ||
387 | FormatSpecifier::DollarSign, | ||
388 | &mut callback, | ||
389 | ); | ||
390 | } | ||
391 | _ => { | ||
392 | continue; | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | |||
397 | // type | ||
398 | match chars | ||
399 | .peek() | ||
400 | .and_then(|next| next.1.as_ref().ok()) | ||
401 | .copied() | ||
402 | .unwrap_or_default() | ||
403 | { | ||
404 | '?' => { | ||
405 | skip_char_and_emit( | ||
406 | &mut chars, | ||
407 | FormatSpecifier::QuestionMark, | ||
408 | &mut callback, | ||
409 | ); | ||
410 | } | ||
411 | c if c == '_' || c.is_alphabetic() => { | ||
412 | read_identifier(&mut chars, &mut callback); | ||
413 | } | ||
414 | _ => {} | ||
415 | } | ||
416 | } | ||
417 | |||
418 | let mut cloned = chars.clone().take(2); | ||
419 | let first = cloned.next().and_then(|next| next.1.as_ref().ok()).copied(); | ||
420 | let second = cloned.next().and_then(|next| next.1.as_ref().ok()).copied(); | ||
421 | if first != Some('}') { | ||
422 | continue; | ||
423 | } | ||
424 | if second == Some('}') { | ||
425 | // Escaped format end specifier, `}}` | ||
426 | continue; | ||
427 | } | ||
428 | skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback); | ||
429 | } | ||
430 | _ => { | ||
431 | while let Some((_, Ok(next_char))) = chars.peek() { | ||
432 | match next_char { | ||
433 | '{' => break, | ||
434 | _ => {} | ||
435 | } | ||
436 | chars.next(); | ||
437 | } | ||
438 | } | ||
439 | }; | ||
440 | } | ||
441 | |||
442 | fn skip_char_and_emit<'a, I, F>( | ||
443 | chars: &mut std::iter::Peekable<I>, | ||
444 | emit: FormatSpecifier, | ||
445 | callback: &mut F, | ||
446 | ) where | ||
447 | I: Iterator<Item = &'a (TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>, | ||
448 | F: FnMut(TextRange, FormatSpecifier), | ||
449 | { | ||
450 | let (range, _) = chars.next().unwrap(); | ||
451 | callback(*range, emit); | ||
452 | } | ||
453 | |||
454 | fn read_integer<'a, I, F>(chars: &mut std::iter::Peekable<I>, callback: &mut F) | ||
455 | where | ||
456 | I: Iterator<Item = &'a (TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>, | ||
457 | F: FnMut(TextRange, FormatSpecifier), | ||
458 | { | ||
459 | let (mut range, c) = chars.next().unwrap(); | ||
460 | assert!(c.as_ref().unwrap().is_ascii_digit()); | ||
461 | while let Some((r, Ok(next_char))) = chars.peek() { | ||
462 | if next_char.is_ascii_digit() { | ||
463 | chars.next(); | ||
464 | range = range.cover(*r); | ||
465 | } else { | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | callback(range, FormatSpecifier::Integer); | ||
470 | } | ||
471 | |||
472 | fn read_identifier<'a, I, F>(chars: &mut std::iter::Peekable<I>, callback: &mut F) | ||
473 | where | ||
474 | I: Iterator<Item = &'a (TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>, | ||
475 | F: FnMut(TextRange, FormatSpecifier), | ||
476 | { | ||
477 | let (mut range, c) = chars.next().unwrap(); | ||
478 | assert!(c.as_ref().unwrap().is_alphabetic() || *c.as_ref().unwrap() == '_'); | ||
479 | while let Some((r, Ok(next_char))) = chars.peek() { | ||
480 | if *next_char == '_' || next_char.is_ascii_digit() || next_char.is_alphabetic() { | ||
481 | chars.next(); | ||
482 | range = range.cover(*r); | ||
483 | } else { | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | callback(range, FormatSpecifier::Identifier); | ||
488 | } | ||
489 | } | ||
490 | } | ||
491 | |||
492 | impl HasFormatSpecifier for String { | ||
493 | fn char_ranges( | ||
494 | &self, | ||
495 | ) -> Option<Vec<(TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>> { | ||
496 | let text = self.text().as_str(); | ||
497 | let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; | ||
498 | let offset = self.text_range_between_quotes()?.start() - self.syntax().text_range().start(); | ||
499 | |||
500 | let mut res = Vec::with_capacity(text.len()); | ||
501 | rustc_lexer::unescape::unescape_str(text, &mut |range, unescaped_char| { | ||
502 | res.push(( | ||
503 | TextRange::new(range.start.try_into().unwrap(), range.end.try_into().unwrap()) | ||
504 | + offset, | ||
505 | unescaped_char, | ||
506 | )) | ||
507 | }); | ||
508 | |||
509 | Some(res) | ||
510 | } | ||
511 | } | ||
512 | |||
513 | impl HasFormatSpecifier for RawString { | ||
514 | fn char_ranges( | ||
515 | &self, | ||
516 | ) -> Option<Vec<(TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>> { | ||
517 | let text = self.text().as_str(); | ||
518 | let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; | ||
519 | let offset = self.text_range_between_quotes()?.start() - self.syntax().text_range().start(); | ||
520 | |||
521 | let mut res = Vec::with_capacity(text.len()); | ||
522 | for (idx, c) in text.char_indices() { | ||
523 | res.push((TextRange::at(idx.try_into().unwrap(), TextSize::of(c)) + offset, Ok(c))); | ||
524 | } | ||
525 | Some(res) | ||
526 | } | ||
527 | } | ||
diff --git a/crates/ra_syntax/src/fuzz.rs b/crates/ra_syntax/src/fuzz.rs index 7012df7f0..10fbe3176 100644 --- a/crates/ra_syntax/src/fuzz.rs +++ b/crates/ra_syntax/src/fuzz.rs | |||
@@ -1,8 +1,13 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use crate::{validation, AstNode, SourceFile, TextRange, TextUnit}; | 3 | use std::{ |
4 | convert::TryInto, | ||
5 | str::{self, FromStr}, | ||
6 | }; | ||
7 | |||
4 | use ra_text_edit::AtomTextEdit; | 8 | use ra_text_edit::AtomTextEdit; |
5 | use std::str::{self, FromStr}; | 9 | |
10 | use crate::{validation, AstNode, SourceFile, TextRange}; | ||
6 | 11 | ||
7 | fn check_file_invariants(file: &SourceFile) { | 12 | fn check_file_invariants(file: &SourceFile) { |
8 | let root = file.syntax(); | 13 | let root = file.syntax(); |
@@ -34,10 +39,8 @@ impl CheckReparse { | |||
34 | let text = lines.collect::<Vec<_>>().join("\n"); | 39 | let text = lines.collect::<Vec<_>>().join("\n"); |
35 | let text = format!("{}{}{}", PREFIX, text, SUFFIX); | 40 | let text = format!("{}{}{}", PREFIX, text, SUFFIX); |
36 | text.get(delete_start..delete_start.checked_add(delete_len)?)?; // make sure delete is a valid range | 41 | text.get(delete_start..delete_start.checked_add(delete_len)?)?; // make sure delete is a valid range |
37 | let delete = TextRange::offset_len( | 42 | let delete = |
38 | TextUnit::from_usize(delete_start), | 43 | TextRange::at(delete_start.try_into().unwrap(), delete_len.try_into().unwrap()); |
39 | TextUnit::from_usize(delete_len), | ||
40 | ); | ||
41 | let edited_text = | 44 | let edited_text = |
42 | format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]); | 45 | format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]); |
43 | let edit = AtomTextEdit { delete, insert }; | 46 | let edit = AtomTextEdit { delete, insert }; |
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index a796e78b1..ceeb2bde9 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -55,7 +55,7 @@ pub use crate::{ | |||
55 | }, | 55 | }, |
56 | }; | 56 | }; |
57 | pub use ra_parser::{SyntaxKind, T}; | 57 | pub use ra_parser::{SyntaxKind, T}; |
58 | pub use rowan::{SmolStr, SyntaxText, TextRange, TextUnit, TokenAtOffset, WalkEvent}; | 58 | pub use rowan::{SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEvent}; |
59 | 59 | ||
60 | /// `Parse` is the result of the parsing: a syntax tree and a collection of | 60 | /// `Parse` is the result of the parsing: a syntax tree and a collection of |
61 | /// errors. | 61 | /// errors. |
@@ -266,7 +266,7 @@ fn api_walkthrough() { | |||
266 | assert_eq!(expr_syntax.kind(), SyntaxKind::BIN_EXPR); | 266 | assert_eq!(expr_syntax.kind(), SyntaxKind::BIN_EXPR); |
267 | 267 | ||
268 | // And text range: | 268 | // And text range: |
269 | assert_eq!(expr_syntax.text_range(), TextRange::from_to(32.into(), 37.into())); | 269 | assert_eq!(expr_syntax.text_range(), TextRange::new(32.into(), 37.into())); |
270 | 270 | ||
271 | // You can get node's text as a `SyntaxText` object, which will traverse the | 271 | // You can get node's text as a `SyntaxText` object, which will traverse the |
272 | // tree collecting token's text: | 272 | // tree collecting token's text: |
diff --git a/crates/ra_syntax/src/parsing/lexer.rs b/crates/ra_syntax/src/parsing/lexer.rs index 67c1f1b48..f450ef4a2 100644 --- a/crates/ra_syntax/src/parsing/lexer.rs +++ b/crates/ra_syntax/src/parsing/lexer.rs | |||
@@ -1,10 +1,12 @@ | |||
1 | //! Lexer analyzes raw input string and produces lexemes (tokens). | 1 | //! Lexer analyzes raw input string and produces lexemes (tokens). |
2 | //! It is just a bridge to `rustc_lexer`. | 2 | //! It is just a bridge to `rustc_lexer`. |
3 | 3 | ||
4 | use std::convert::TryInto; | ||
5 | |||
4 | use crate::{ | 6 | use crate::{ |
5 | SyntaxError, | 7 | SyntaxError, |
6 | SyntaxKind::{self, *}, | 8 | SyntaxKind::{self, *}, |
7 | TextRange, TextUnit, T, | 9 | TextRange, TextSize, T, |
8 | }; | 10 | }; |
9 | 11 | ||
10 | /// A token of Rust source. | 12 | /// A token of Rust source. |
@@ -13,7 +15,7 @@ pub struct Token { | |||
13 | /// The kind of token. | 15 | /// The kind of token. |
14 | pub kind: SyntaxKind, | 16 | pub kind: SyntaxKind, |
15 | /// The length of the token. | 17 | /// The length of the token. |
16 | pub len: TextUnit, | 18 | pub len: TextSize, |
17 | } | 19 | } |
18 | 20 | ||
19 | /// Break a string up into its component tokens. | 21 | /// Break a string up into its component tokens. |
@@ -28,18 +30,19 @@ pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) { | |||
28 | let mut tokens = Vec::new(); | 30 | let mut tokens = Vec::new(); |
29 | let mut errors = Vec::new(); | 31 | let mut errors = Vec::new(); |
30 | 32 | ||
31 | let mut offset: usize = rustc_lexer::strip_shebang(text) | 33 | let mut offset = match rustc_lexer::strip_shebang(text) { |
32 | .map(|shebang_len| { | 34 | Some(shebang_len) => { |
33 | tokens.push(Token { kind: SHEBANG, len: TextUnit::from_usize(shebang_len) }); | 35 | tokens.push(Token { kind: SHEBANG, len: shebang_len.try_into().unwrap() }); |
34 | shebang_len | 36 | shebang_len |
35 | }) | 37 | } |
36 | .unwrap_or(0); | 38 | None => 0, |
39 | }; | ||
37 | 40 | ||
38 | let text_without_shebang = &text[offset..]; | 41 | let text_without_shebang = &text[offset..]; |
39 | 42 | ||
40 | for rustc_token in rustc_lexer::tokenize(text_without_shebang) { | 43 | for rustc_token in rustc_lexer::tokenize(text_without_shebang) { |
41 | let token_len = TextUnit::from_usize(rustc_token.len); | 44 | let token_len: TextSize = rustc_token.len.try_into().unwrap(); |
42 | let token_range = TextRange::offset_len(TextUnit::from_usize(offset), token_len); | 45 | let token_range = TextRange::at(offset.try_into().unwrap(), token_len); |
43 | 46 | ||
44 | let (syntax_kind, err_message) = | 47 | let (syntax_kind, err_message) = |
45 | rustc_token_kind_to_syntax_kind(&rustc_token.kind, &text[token_range]); | 48 | rustc_token_kind_to_syntax_kind(&rustc_token.kind, &text[token_range]); |
@@ -65,7 +68,7 @@ pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) { | |||
65 | /// Beware that unescape errors are not checked at tokenization time. | 68 | /// Beware that unescape errors are not checked at tokenization time. |
66 | pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxError>)> { | 69 | pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxError>)> { |
67 | lex_first_token(text) | 70 | lex_first_token(text) |
68 | .filter(|(token, _)| token.len == TextUnit::of_str(text)) | 71 | .filter(|(token, _)| token.len == TextSize::of(text)) |
69 | .map(|(token, error)| (token.kind, error)) | 72 | .map(|(token, error)| (token.kind, error)) |
70 | } | 73 | } |
71 | 74 | ||
@@ -75,7 +78,7 @@ pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxEr | |||
75 | /// Beware that unescape errors are not checked at tokenization time. | 78 | /// Beware that unescape errors are not checked at tokenization time. |
76 | pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> { | 79 | pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> { |
77 | lex_first_token(text) | 80 | lex_first_token(text) |
78 | .filter(|(token, error)| !error.is_some() && token.len == TextUnit::of_str(text)) | 81 | .filter(|(token, error)| !error.is_some() && token.len == TextSize::of(text)) |
79 | .map(|(token, _error)| token.kind) | 82 | .map(|(token, _error)| token.kind) |
80 | } | 83 | } |
81 | 84 | ||
@@ -96,10 +99,9 @@ fn lex_first_token(text: &str) -> Option<(Token, Option<SyntaxError>)> { | |||
96 | let rustc_token = rustc_lexer::first_token(text); | 99 | let rustc_token = rustc_lexer::first_token(text); |
97 | let (syntax_kind, err_message) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text); | 100 | let (syntax_kind, err_message) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text); |
98 | 101 | ||
99 | let token = Token { kind: syntax_kind, len: TextUnit::from_usize(rustc_token.len) }; | 102 | let token = Token { kind: syntax_kind, len: rustc_token.len.try_into().unwrap() }; |
100 | let optional_error = err_message.map(|err_message| { | 103 | let optional_error = err_message |
101 | SyntaxError::new(err_message, TextRange::from_to(0.into(), TextUnit::of_str(text))) | 104 | .map(|err_message| SyntaxError::new(err_message, TextRange::up_to(TextSize::of(text)))); |
102 | }); | ||
103 | 105 | ||
104 | Some((token, optional_error)) | 106 | Some((token, optional_error)) |
105 | } | 107 | } |
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 2d65b91f1..ffff0a7b2 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | syntax_node::{GreenNode, GreenToken, NodeOrToken, SyntaxElement, SyntaxNode}, | 19 | syntax_node::{GreenNode, GreenToken, NodeOrToken, SyntaxElement, SyntaxNode}, |
20 | SyntaxError, | 20 | SyntaxError, |
21 | SyntaxKind::*, | 21 | SyntaxKind::*, |
22 | TextRange, TextUnit, T, | 22 | TextRange, TextSize, T, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | pub(crate) fn incremental_reparse( | 25 | pub(crate) fn incremental_reparse( |
@@ -176,7 +176,7 @@ fn merge_errors( | |||
176 | if old_err_range.end() <= range_before_reparse.start() { | 176 | if old_err_range.end() <= range_before_reparse.start() { |
177 | res.push(old_err); | 177 | res.push(old_err); |
178 | } else if old_err_range.start() >= range_before_reparse.end() { | 178 | } else if old_err_range.start() >= range_before_reparse.end() { |
179 | let inserted_len = TextUnit::of_str(&edit.insert); | 179 | let inserted_len = TextSize::of(&edit.insert); |
180 | res.push(old_err.with_range((old_err_range + inserted_len) - edit.delete.len())); | 180 | res.push(old_err.with_range((old_err_range + inserted_len) - edit.delete.len())); |
181 | // Note: extra parens are intentional to prevent uint underflow, HWAB (here was a bug) | 181 | // Note: extra parens are intentional to prevent uint underflow, HWAB (here was a bug) |
182 | } | 182 | } |
diff --git a/crates/ra_syntax/src/parsing/text_token_source.rs b/crates/ra_syntax/src/parsing/text_token_source.rs index e2433913c..7ddc2c2c3 100644 --- a/crates/ra_syntax/src/parsing/text_token_source.rs +++ b/crates/ra_syntax/src/parsing/text_token_source.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use ra_parser::Token as PToken; | 3 | use ra_parser::Token as PToken; |
4 | use ra_parser::TokenSource; | 4 | use ra_parser::TokenSource; |
5 | 5 | ||
6 | use crate::{parsing::lexer::Token, SyntaxKind::EOF, TextRange, TextUnit}; | 6 | use crate::{parsing::lexer::Token, SyntaxKind::EOF, TextRange, TextSize}; |
7 | 7 | ||
8 | pub(crate) struct TextTokenSource<'t> { | 8 | pub(crate) struct TextTokenSource<'t> { |
9 | text: &'t str, | 9 | text: &'t str, |
@@ -15,7 +15,7 @@ pub(crate) struct TextTokenSource<'t> { | |||
15 | /// 0 7 10 | 15 | /// 0 7 10 |
16 | /// ``` | 16 | /// ``` |
17 | /// (token, start_offset): `[(struct, 0), (Foo, 7), (;, 10)]` | 17 | /// (token, start_offset): `[(struct, 0), (Foo, 7), (;, 10)]` |
18 | start_offsets: Vec<TextUnit>, | 18 | start_offsets: Vec<TextSize>, |
19 | /// non-whitespace/comment tokens | 19 | /// non-whitespace/comment tokens |
20 | /// ```non-rust | 20 | /// ```non-rust |
21 | /// struct Foo {} | 21 | /// struct Foo {} |
@@ -51,12 +51,12 @@ impl<'t> TokenSource for TextTokenSource<'t> { | |||
51 | if pos >= self.tokens.len() { | 51 | if pos >= self.tokens.len() { |
52 | return false; | 52 | return false; |
53 | } | 53 | } |
54 | let range = TextRange::offset_len(self.start_offsets[pos], self.tokens[pos].len); | 54 | let range = TextRange::at(self.start_offsets[pos], self.tokens[pos].len); |
55 | self.text[range] == *kw | 55 | self.text[range] == *kw |
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | fn mk_token(pos: usize, start_offsets: &[TextUnit], tokens: &[Token]) -> PToken { | 59 | fn mk_token(pos: usize, start_offsets: &[TextSize], tokens: &[Token]) -> PToken { |
60 | let kind = tokens.get(pos).map(|t| t.kind).unwrap_or(EOF); | 60 | let kind = tokens.get(pos).map(|t| t.kind).unwrap_or(EOF); |
61 | let is_jointed_to_next = if pos + 1 < start_offsets.len() { | 61 | let is_jointed_to_next = if pos + 1 < start_offsets.len() { |
62 | start_offsets[pos] + tokens[pos].len == start_offsets[pos + 1] | 62 | start_offsets[pos] + tokens[pos].len == start_offsets[pos + 1] |
diff --git a/crates/ra_syntax/src/parsing/text_tree_sink.rs b/crates/ra_syntax/src/parsing/text_tree_sink.rs index 87bb21cd9..22aed1db1 100644 --- a/crates/ra_syntax/src/parsing/text_tree_sink.rs +++ b/crates/ra_syntax/src/parsing/text_tree_sink.rs | |||
@@ -9,7 +9,7 @@ use crate::{ | |||
9 | syntax_node::GreenNode, | 9 | syntax_node::GreenNode, |
10 | SmolStr, SyntaxError, | 10 | SmolStr, SyntaxError, |
11 | SyntaxKind::{self, *}, | 11 | SyntaxKind::{self, *}, |
12 | SyntaxTreeBuilder, TextRange, TextUnit, | 12 | SyntaxTreeBuilder, TextRange, TextSize, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | /// Bridges the parser with our specific syntax tree representation. | 15 | /// Bridges the parser with our specific syntax tree representation. |
@@ -18,7 +18,7 @@ use crate::{ | |||
18 | pub(crate) struct TextTreeSink<'a> { | 18 | pub(crate) struct TextTreeSink<'a> { |
19 | text: &'a str, | 19 | text: &'a str, |
20 | tokens: &'a [Token], | 20 | tokens: &'a [Token], |
21 | text_pos: TextUnit, | 21 | text_pos: TextSize, |
22 | token_pos: usize, | 22 | token_pos: usize, |
23 | state: State, | 23 | state: State, |
24 | inner: SyntaxTreeBuilder, | 24 | inner: SyntaxTreeBuilder, |
@@ -42,7 +42,7 @@ impl<'a> TreeSink for TextTreeSink<'a> { | |||
42 | let len = self.tokens[self.token_pos..self.token_pos + n_tokens] | 42 | let len = self.tokens[self.token_pos..self.token_pos + n_tokens] |
43 | .iter() | 43 | .iter() |
44 | .map(|it| it.len) | 44 | .map(|it| it.len) |
45 | .sum::<TextUnit>(); | 45 | .sum::<TextSize>(); |
46 | self.do_token(kind, len, n_tokens); | 46 | self.do_token(kind, len, n_tokens); |
47 | } | 47 | } |
48 | 48 | ||
@@ -62,12 +62,12 @@ impl<'a> TreeSink for TextTreeSink<'a> { | |||
62 | self.tokens[self.token_pos..].iter().take_while(|it| it.kind.is_trivia()).count(); | 62 | self.tokens[self.token_pos..].iter().take_while(|it| it.kind.is_trivia()).count(); |
63 | let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias]; | 63 | let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias]; |
64 | let mut trivia_end = | 64 | let mut trivia_end = |
65 | self.text_pos + leading_trivias.iter().map(|it| it.len).sum::<TextUnit>(); | 65 | self.text_pos + leading_trivias.iter().map(|it| it.len).sum::<TextSize>(); |
66 | 66 | ||
67 | let n_attached_trivias = { | 67 | let n_attached_trivias = { |
68 | let leading_trivias = leading_trivias.iter().rev().map(|it| { | 68 | let leading_trivias = leading_trivias.iter().rev().map(|it| { |
69 | let next_end = trivia_end - it.len; | 69 | let next_end = trivia_end - it.len; |
70 | let range = TextRange::from_to(next_end, trivia_end); | 70 | let range = TextRange::new(next_end, trivia_end); |
71 | trivia_end = next_end; | 71 | trivia_end = next_end; |
72 | (it.kind, &self.text[range]) | 72 | (it.kind, &self.text[range]) |
73 | }); | 73 | }); |
@@ -132,8 +132,8 @@ impl<'a> TextTreeSink<'a> { | |||
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | fn do_token(&mut self, kind: SyntaxKind, len: TextUnit, n_tokens: usize) { | 135 | fn do_token(&mut self, kind: SyntaxKind, len: TextSize, n_tokens: usize) { |
136 | let range = TextRange::offset_len(self.text_pos, len); | 136 | let range = TextRange::at(self.text_pos, len); |
137 | let text: SmolStr = self.text[range].into(); | 137 | let text: SmolStr = self.text[range].into(); |
138 | self.text_pos += len; | 138 | self.text_pos += len; |
139 | self.token_pos += n_tokens; | 139 | self.token_pos += n_tokens; |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs index ecbfffcf4..62f03e93d 100644 --- a/crates/ra_syntax/src/ptr.rs +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -24,7 +24,7 @@ impl SyntaxNodePtr { | |||
24 | pub fn to_node(&self, root: &SyntaxNode) -> SyntaxNode { | 24 | pub fn to_node(&self, root: &SyntaxNode) -> SyntaxNode { |
25 | assert!(root.parent().is_none()); | 25 | assert!(root.parent().is_none()); |
26 | successors(Some(root.clone()), |node| { | 26 | successors(Some(root.clone()), |node| { |
27 | node.children().find(|it| self.range.is_subrange(&it.text_range())) | 27 | node.children().find(|it| it.text_range().contains_range(self.range)) |
28 | }) | 28 | }) |
29 | .find(|it| it.text_range() == self.range && it.kind() == self.kind) | 29 | .find(|it| it.text_range() == self.range && it.kind() == self.kind) |
30 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) | 30 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) |
diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs index 54acf7847..7c4511fec 100644 --- a/crates/ra_syntax/src/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_error.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::fmt; | 3 | use std::fmt; |
4 | 4 | ||
5 | use crate::{TextRange, TextUnit}; | 5 | use crate::{TextRange, TextSize}; |
6 | 6 | ||
7 | /// Represents the result of unsuccessful tokenization, parsing | 7 | /// Represents the result of unsuccessful tokenization, parsing |
8 | /// or tree validation. | 8 | /// or tree validation. |
@@ -23,8 +23,8 @@ impl SyntaxError { | |||
23 | pub fn new(message: impl Into<String>, range: TextRange) -> Self { | 23 | pub fn new(message: impl Into<String>, range: TextRange) -> Self { |
24 | Self(message.into(), range) | 24 | Self(message.into(), range) |
25 | } | 25 | } |
26 | pub fn new_at_offset(message: impl Into<String>, offset: TextUnit) -> Self { | 26 | pub fn new_at_offset(message: impl Into<String>, offset: TextSize) -> Self { |
27 | Self(message.into(), TextRange::offset_len(offset, 0.into())) | 27 | Self(message.into(), TextRange::empty(offset)) |
28 | } | 28 | } |
29 | 29 | ||
30 | pub fn range(&self) -> TextRange { | 30 | pub fn range(&self) -> TextRange { |
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index 4e3a1460d..f9d379abf 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | use rowan::{GreenNodeBuilder, Language}; | 9 | use rowan::{GreenNodeBuilder, Language}; |
10 | 10 | ||
11 | use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextUnit}; | 11 | use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize}; |
12 | 12 | ||
13 | pub(crate) use rowan::{GreenNode, GreenToken}; | 13 | pub(crate) use rowan::{GreenNode, GreenToken}; |
14 | 14 | ||
@@ -69,7 +69,7 @@ impl SyntaxTreeBuilder { | |||
69 | self.inner.finish_node() | 69 | self.inner.finish_node() |
70 | } | 70 | } |
71 | 71 | ||
72 | pub fn error(&mut self, error: ra_parser::ParseError, text_pos: TextUnit) { | 72 | pub fn error(&mut self, error: ra_parser::ParseError, text_pos: TextSize) { |
73 | self.errors.push(SyntaxError::new_at_offset(error.0, text_pos)) | 73 | self.errors.push(SyntaxError::new_at_offset(error.0, text_pos)) |
74 | } | 74 | } |
75 | } | 75 | } |
diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs index 355843b94..aee57db62 100644 --- a/crates/ra_syntax/src/tests.rs +++ b/crates/ra_syntax/src/tests.rs | |||
@@ -5,7 +5,7 @@ use std::{ | |||
5 | 5 | ||
6 | use test_utils::{collect_rust_files, dir_tests, project_dir, read_text}; | 6 | use test_utils::{collect_rust_files, dir_tests, project_dir, read_text}; |
7 | 7 | ||
8 | use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextUnit, Token}; | 8 | use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextSize, Token}; |
9 | 9 | ||
10 | #[test] | 10 | #[test] |
11 | fn lexer_tests() { | 11 | fn lexer_tests() { |
@@ -121,12 +121,12 @@ fn assert_errors_are_absent(errors: &[SyntaxError], path: &Path) { | |||
121 | 121 | ||
122 | fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String { | 122 | fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String { |
123 | let mut acc = String::new(); | 123 | let mut acc = String::new(); |
124 | let mut offset = TextUnit::from_usize(0); | 124 | let mut offset: TextSize = 0.into(); |
125 | for token in tokens { | 125 | for token in tokens { |
126 | let token_len = token.len; | 126 | let token_len = token.len; |
127 | let token_text = &text[TextRange::offset_len(offset, token.len)]; | 127 | let token_text = &text[TextRange::at(offset, token.len)]; |
128 | offset += token.len; | 128 | offset += token.len; |
129 | writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap(); | 129 | writeln!(acc, "{:?} {:?} {:?}", token.kind, token_len, token_text).unwrap(); |
130 | } | 130 | } |
131 | for err in errors { | 131 | for err in errors { |
132 | writeln!(acc, "> error{:?} token({:?}) msg({})", err.range(), &text[err.range()], err) | 132 | writeln!(acc, "> error{:?} token({:?}) msg({})", err.range(), &text[err.range()], err) |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index f85b3e61b..5e93895ec 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -2,12 +2,14 @@ | |||
2 | 2 | ||
3 | mod block; | 3 | mod block; |
4 | 4 | ||
5 | use std::convert::TryFrom; | ||
6 | |||
5 | use rustc_lexer::unescape; | 7 | use rustc_lexer::unescape; |
6 | 8 | ||
7 | use crate::{ | 9 | use crate::{ |
8 | ast, match_ast, AstNode, SyntaxError, | 10 | ast, match_ast, AstNode, SyntaxError, |
9 | SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST_DEF, FN_DEF, INT_NUMBER, STRING, TYPE_ALIAS_DEF}, | 11 | SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST_DEF, FN_DEF, INT_NUMBER, STRING, TYPE_ALIAS_DEF}, |
10 | SyntaxNode, SyntaxToken, TextUnit, T, | 12 | SyntaxNode, SyntaxToken, TextSize, T, |
11 | }; | 13 | }; |
12 | 14 | ||
13 | fn rustc_unescape_error_to_string(err: unescape::EscapeError) -> &'static str { | 15 | fn rustc_unescape_error_to_string(err: unescape::EscapeError) -> &'static str { |
@@ -112,7 +114,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) { | |||
112 | 114 | ||
113 | // FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205) | 115 | // FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205) |
114 | let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| { | 116 | let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| { |
115 | let off = token.text_range().start() + TextUnit::from_usize(off + prefix_len); | 117 | let off = token.text_range().start() + TextSize::try_from(off + prefix_len).unwrap(); |
116 | acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off)); | 118 | acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off)); |
117 | }; | 119 | }; |
118 | 120 | ||