diff options
author | Aleksey Kladov <[email protected]> | 2019-05-07 17:38:26 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-05-07 17:41:59 +0100 |
commit | 313314e14b629ebf50389dbd2d440bda922f6ae7 (patch) | |
tree | ca6a4aee6ad4077a869a932a18c6c8d134406f8c /crates/ra_syntax/src/validation.rs | |
parent | ef782adc293deb287128f005dbab2038ba3ccdc1 (diff) |
share literal validation logic with compiler
Diffstat (limited to 'crates/ra_syntax/src/validation.rs')
-rw-r--r-- | crates/ra_syntax/src/validation.rs | 64 |
1 files changed, 54 insertions, 10 deletions
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index c2f545173..11a1fb4a7 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -1,17 +1,17 @@ | |||
1 | mod byte; | 1 | mod unescape; |
2 | mod byte_string; | 2 | |
3 | mod char; | ||
4 | mod string; | ||
5 | mod block; | 3 | mod block; |
6 | mod field_expr; | 4 | mod field_expr; |
7 | 5 | ||
8 | use crate::{ | 6 | use crate::{ |
9 | SourceFile, SyntaxError, AstNode, SyntaxNode, | 7 | SourceFile, SyntaxError, AstNode, SyntaxNode, TextUnit, |
10 | SyntaxKind::{L_CURLY, R_CURLY, BYTE, BYTE_STRING, STRING, CHAR}, | 8 | SyntaxKind::{L_CURLY, R_CURLY, BYTE, BYTE_STRING, STRING, CHAR}, |
11 | ast, | 9 | ast, |
12 | algo::visit::{visitor_ctx, VisitorCtx}, | 10 | algo::visit::{visitor_ctx, VisitorCtx}, |
13 | }; | 11 | }; |
14 | 12 | ||
13 | pub(crate) use unescape::EscapeError; | ||
14 | |||
15 | pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> { | 15 | pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> { |
16 | let mut errors = Vec::new(); | 16 | let mut errors = Vec::new(); |
17 | for node in file.syntax().descendants() { | 17 | for node in file.syntax().descendants() { |
@@ -26,11 +26,55 @@ pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> { | |||
26 | 26 | ||
27 | // FIXME: kill duplication | 27 | // FIXME: kill duplication |
28 | fn validate_literal(literal: &ast::Literal, acc: &mut Vec<SyntaxError>) { | 28 | fn validate_literal(literal: &ast::Literal, acc: &mut Vec<SyntaxError>) { |
29 | match literal.token().kind() { | 29 | let token = literal.token(); |
30 | BYTE => byte::validate_byte_node(literal.token(), acc), | 30 | let text = token.text().as_str(); |
31 | BYTE_STRING => byte_string::validate_byte_string_node(literal.token(), acc), | 31 | match token.kind() { |
32 | STRING => string::validate_string_node(literal.token(), acc), | 32 | BYTE => { |
33 | CHAR => char::validate_char_node(literal.token(), acc), | 33 | if let Some(end) = text.rfind('\'') { |
34 | if let Some(without_quotes) = text.get(2..end) { | ||
35 | if let Err((off, err)) = unescape::unescape_byte(without_quotes) { | ||
36 | let off = token.range().start() + TextUnit::from_usize(off + 2); | ||
37 | acc.push(SyntaxError::new(err.into(), off)) | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | CHAR => { | ||
43 | if let Some(end) = text.rfind('\'') { | ||
44 | if let Some(without_quotes) = text.get(1..end) { | ||
45 | if let Err((off, err)) = unescape::unescape_char(without_quotes) { | ||
46 | let off = token.range().start() + TextUnit::from_usize(off + 1); | ||
47 | acc.push(SyntaxError::new(err.into(), off)) | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | BYTE_STRING => { | ||
53 | if let Some(end) = text.rfind('\"') { | ||
54 | if let Some(without_quotes) = text.get(2..end) { | ||
55 | unescape::unescape_byte_str(without_quotes, &mut |range, char| { | ||
56 | if let Err(err) = char { | ||
57 | let off = range.start; | ||
58 | let off = token.range().start() + TextUnit::from_usize(off + 2); | ||
59 | acc.push(SyntaxError::new(err.into(), off)) | ||
60 | } | ||
61 | }) | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | STRING => { | ||
66 | if let Some(end) = text.rfind('\"') { | ||
67 | if let Some(without_quotes) = text.get(1..end) { | ||
68 | unescape::unescape_str(without_quotes, &mut |range, char| { | ||
69 | if let Err(err) = char { | ||
70 | let off = range.start; | ||
71 | let off = token.range().start() + TextUnit::from_usize(off + 1); | ||
72 | acc.push(SyntaxError::new(err.into(), off)) | ||
73 | } | ||
74 | }) | ||
75 | } | ||
76 | } | ||
77 | } | ||
34 | _ => (), | 78 | _ => (), |
35 | } | 79 | } |
36 | } | 80 | } |