aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_parser/src/grammar.rs14
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs10
-rw-r--r--crates/ra_parser/src/grammar/items.rs2
-rw-r--r--crates/ra_parser/src/grammar/paths.rs2
-rw-r--r--crates/ra_parser/src/grammar/type_args.rs4
-rw-r--r--crates/ra_syntax/src/validation.rs25
-rw-r--r--crates/ra_syntax/src/validation/field_expr.rs13
-rw-r--r--crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.txt7
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.txt6
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.txt6
10 files changed, 52 insertions, 37 deletions
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index 2ee121ccd..beedac457 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -273,8 +273,8 @@ fn name(p: &mut Parser) {
273 name_r(p, TokenSet::empty()) 273 name_r(p, TokenSet::empty())
274} 274}
275 275
276fn name_ref(p: &mut Parser, allow_numeric_names: bool) { 276fn name_ref(p: &mut Parser) {
277 if p.at(IDENT) || (allow_numeric_names && p.at(INT_NUMBER)) { 277 if p.at(IDENT) {
278 let m = p.start(); 278 let m = p.start();
279 p.bump(); 279 p.bump();
280 m.complete(p, NAME_REF); 280 m.complete(p, NAME_REF);
@@ -287,6 +287,16 @@ fn name_ref(p: &mut Parser, allow_numeric_names: bool) {
287 } 287 }
288} 288}
289 289
290fn name_ref_or_index(p: &mut Parser) {
291 if p.at(IDENT) || p.at(INT_NUMBER) {
292 let m = p.start();
293 p.bump();
294 m.complete(p, NAME_REF);
295 } else {
296 p.err_and_bump("expected identifier");
297 }
298}
299
290fn error_block(p: &mut Parser, message: &str) { 300fn error_block(p: &mut Parser, message: &str) {
291 assert!(p.at(T!['{'])); 301 assert!(p.at(T!['{']));
292 let m = p.start(); 302 let m = p.start();
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index 9f9e9cb0e..9fd3a235d 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -458,7 +458,7 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
458 assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::])); 458 assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::]));
459 let m = lhs.precede(p); 459 let m = lhs.precede(p);
460 p.bump(); 460 p.bump();
461 name_ref(p, false); 461 name_ref(p);
462 type_args::opt_type_arg_list(p, true); 462 type_args::opt_type_arg_list(p, true);
463 if p.at(T!['(']) { 463 if p.at(T!['(']) {
464 arg_list(p); 464 arg_list(p);
@@ -484,10 +484,8 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
484 assert!(p.at(T![.])); 484 assert!(p.at(T![.]));
485 let m = lhs.precede(p); 485 let m = lhs.precede(p);
486 p.bump(); 486 p.bump();
487 if p.at(IDENT) { 487 if p.at(IDENT) || p.at(INT_NUMBER) {
488 name_ref(p, false) 488 name_ref_or_index(p)
489 } else if p.at(INT_NUMBER) {
490 p.bump();
491 } else if p.at(FLOAT_NUMBER) { 489 } else if p.at(FLOAT_NUMBER) {
492 // FIXME: How to recover and instead parse INT + T![.]? 490 // FIXME: How to recover and instead parse INT + T![.]?
493 p.bump(); 491 p.bump();
@@ -587,7 +585,7 @@ pub(crate) fn named_field_list(p: &mut Parser) {
587 IDENT | INT_NUMBER | T![#] => { 585 IDENT | INT_NUMBER | T![#] => {
588 let m = p.start(); 586 let m = p.start();
589 attributes::outer_attributes(p); 587 attributes::outer_attributes(p);
590 name_ref(p, true); 588 name_ref_or_index(p);
591 if p.eat(T![:]) { 589 if p.eat(T![:]) {
592 expr(p); 590 expr(p);
593 } 591 }
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index b0081f396..543af7c4b 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -279,7 +279,7 @@ fn extern_crate_item(p: &mut Parser, m: Marker) {
279 p.bump(); 279 p.bump();
280 assert!(p.at(T![crate])); 280 assert!(p.at(T![crate]));
281 p.bump(); 281 p.bump();
282 name_ref(p, false); 282 name_ref(p);
283 opt_alias(p); 283 opt_alias(p);
284 p.expect(T![;]); 284 p.expect(T![;]);
285 m.complete(p, EXTERN_CRATE_ITEM); 285 m.complete(p, EXTERN_CRATE_ITEM);
diff --git a/crates/ra_parser/src/grammar/paths.rs b/crates/ra_parser/src/grammar/paths.rs
index 2c8f0f7e8..3537b0da1 100644
--- a/crates/ra_parser/src/grammar/paths.rs
+++ b/crates/ra_parser/src/grammar/paths.rs
@@ -71,7 +71,7 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
71 } 71 }
72 match p.current() { 72 match p.current() {
73 IDENT => { 73 IDENT => {
74 name_ref(p, false); 74 name_ref(p);
75 opt_path_type_args(p, mode); 75 opt_path_type_args(p, mode);
76 } 76 }
77 // test crate_path 77 // test crate_path
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs
index f1d999dea..3db08b280 100644
--- a/crates/ra_parser/src/grammar/type_args.rs
+++ b/crates/ra_parser/src/grammar/type_args.rs
@@ -38,12 +38,12 @@ fn type_arg(p: &mut Parser) {
38 // test associated_type_bounds 38 // test associated_type_bounds
39 // fn print_all<T: Iterator<Item: Display>>(printables: T) {} 39 // fn print_all<T: Iterator<Item: Display>>(printables: T) {}
40 IDENT if p.nth(1) == T![:] => { 40 IDENT if p.nth(1) == T![:] => {
41 name_ref(p, false); 41 name_ref(p);
42 type_params::bounds(p); 42 type_params::bounds(p);
43 m.complete(p, ASSOC_TYPE_ARG); 43 m.complete(p, ASSOC_TYPE_ARG);
44 } 44 }
45 IDENT if p.nth(1) == T![=] => { 45 IDENT if p.nth(1) == T![=] => {
46 name_ref(p, false); 46 name_ref(p);
47 p.bump(); 47 p.bump();
48 types::type_(p); 48 types::type_(p);
49 m.complete(p, ASSOC_TYPE_ARG); 49 m.complete(p, ASSOC_TYPE_ARG);
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs
index 1f904434e..2bb3c0a03 100644
--- a/crates/ra_syntax/src/validation.rs
+++ b/crates/ra_syntax/src/validation.rs
@@ -1,13 +1,12 @@
1mod block; 1mod block;
2mod field_expr;
3 2
4use ra_rustc_lexer::unescape; 3use ra_rustc_lexer::unescape;
5 4
6use crate::{ 5use crate::{
7 algo::visit::{visitor_ctx, VisitorCtx}, 6 algo::visit::{visitor_ctx, VisitorCtx},
8 ast, SyntaxError, SyntaxErrorKind, 7 ast, AstNode, SyntaxError, SyntaxErrorKind,
9 SyntaxKind::{BYTE, BYTE_STRING, CHAR, STRING}, 8 SyntaxKind::{BYTE, BYTE_STRING, CHAR, INT_NUMBER, STRING},
10 SyntaxNode, TextUnit, T, 9 SyntaxNode, SyntaxToken, TextUnit, T,
11}; 10};
12 11
13#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 12#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -101,7 +100,8 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
101 let _ = visitor_ctx(&mut errors) 100 let _ = visitor_ctx(&mut errors)
102 .visit::<ast::Literal, _>(validate_literal) 101 .visit::<ast::Literal, _>(validate_literal)
103 .visit::<ast::Block, _>(block::validate_block_node) 102 .visit::<ast::Block, _>(block::validate_block_node)
104 .visit::<ast::FieldExpr, _>(field_expr::validate_field_expr_node) 103 .visit::<ast::FieldExpr, _>(|it, errors| validate_numeric_name(it.name_ref(), errors))
104 .visit::<ast::NamedField, _>(|it, errors| validate_numeric_name(it.name_ref(), errors))
105 .accept(&node); 105 .accept(&node);
106 } 106 }
107 errors 107 errors
@@ -189,3 +189,18 @@ pub(crate) fn validate_block_structure(root: &SyntaxNode) {
189 } 189 }
190 } 190 }
191} 191}
192
193fn validate_numeric_name(name_ref: Option<ast::NameRef>, errors: &mut Vec<SyntaxError>) {
194 if let Some(int_token) = int_token(name_ref) {
195 if int_token.text().chars().any(|c| !c.is_digit(10)) {
196 errors.push(SyntaxError::new(
197 SyntaxErrorKind::InvalidTupleIndexFormat,
198 int_token.text_range(),
199 ));
200 }
201 }
202
203 fn int_token(name_ref: Option<ast::NameRef>) -> Option<SyntaxToken> {
204 name_ref?.syntax().first_child_or_token()?.into_token().filter(|it| it.kind() == INT_NUMBER)
205 }
206}
diff --git a/crates/ra_syntax/src/validation/field_expr.rs b/crates/ra_syntax/src/validation/field_expr.rs
deleted file mode 100644
index 004f199fd..000000000
--- a/crates/ra_syntax/src/validation/field_expr.rs
+++ /dev/null
@@ -1,13 +0,0 @@
1use crate::{
2 ast::{self, FieldKind},
3 SyntaxError,
4 SyntaxErrorKind::*,
5};
6
7pub(crate) fn validate_field_expr_node(node: ast::FieldExpr, errors: &mut Vec<SyntaxError>) {
8 if let Some(FieldKind::Index(idx)) = node.field_access() {
9 if idx.text().chars().any(|c| c < '0' || c > '9') {
10 errors.push(SyntaxError::new(InvalidTupleIndexFormat, idx.text_range()));
11 }
12 }
13}
diff --git a/crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.txt b/crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.txt
index a21b29c80..465e79e7b 100644
--- a/crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/err/0010_bad_tuple_index_expr.txt
@@ -30,7 +30,8 @@ SOURCE_FILE@[0; 47)
30 NAME_REF@[25; 26) 30 NAME_REF@[25; 26)
31 IDENT@[25; 26) "x" 31 IDENT@[25; 26) "x"
32 DOT@[26; 27) "." 32 DOT@[26; 27) "."
33 INT_NUMBER@[27; 31) "1i32" 33 NAME_REF@[27; 31)
34 INT_NUMBER@[27; 31) "1i32"
34 SEMI@[31; 32) ";" 35 SEMI@[31; 32) ";"
35 WHITESPACE@[32; 37) "\n " 36 WHITESPACE@[32; 37) "\n "
36 EXPR_STMT@[37; 44) 37 EXPR_STMT@[37; 44)
@@ -41,11 +42,11 @@ SOURCE_FILE@[0; 47)
41 NAME_REF@[37; 38) 42 NAME_REF@[37; 38)
42 IDENT@[37; 38) "x" 43 IDENT@[37; 38) "x"
43 DOT@[38; 39) "." 44 DOT@[38; 39) "."
44 INT_NUMBER@[39; 43) "0x01" 45 NAME_REF@[39; 43)
46 INT_NUMBER@[39; 43) "0x01"
45 SEMI@[43; 44) ";" 47 SEMI@[43; 44) ";"
46 WHITESPACE@[44; 45) "\n" 48 WHITESPACE@[44; 45) "\n"
47 R_CURLY@[45; 46) "}" 49 R_CURLY@[45; 46) "}"
48 WHITESPACE@[46; 47) "\n" 50 WHITESPACE@[46; 47) "\n"
49error [17; 19): Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix
50error [27; 31): Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix 51error [27; 31): Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix
51error [39; 43): Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix 52error [39; 43): Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.txt
index 78054ec5a..1d2cf2761 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0011_field_expr.txt
@@ -32,7 +32,8 @@ SOURCE_FILE@[0; 48)
32 NAME_REF@[26; 27) 32 NAME_REF@[26; 27)
33 IDENT@[26; 27) "x" 33 IDENT@[26; 27) "x"
34 DOT@[27; 28) "." 34 DOT@[27; 28) "."
35 INT_NUMBER@[28; 29) "0" 35 NAME_REF@[28; 29)
36 INT_NUMBER@[28; 29) "0"
36 DOT@[29; 30) "." 37 DOT@[29; 30) "."
37 NAME_REF@[30; 33) 38 NAME_REF@[30; 33)
38 IDENT@[30; 33) "bar" 39 IDENT@[30; 33) "bar"
@@ -47,7 +48,8 @@ SOURCE_FILE@[0; 48)
47 NAME_REF@[39; 40) 48 NAME_REF@[39; 40)
48 IDENT@[39; 40) "x" 49 IDENT@[39; 40) "x"
49 DOT@[40; 41) "." 50 DOT@[40; 41) "."
50 INT_NUMBER@[41; 42) "0" 51 NAME_REF@[41; 42)
52 INT_NUMBER@[41; 42) "0"
51 ARG_LIST@[42; 44) 53 ARG_LIST@[42; 44)
52 L_PAREN@[42; 43) "(" 54 L_PAREN@[42; 43) "("
53 R_PAREN@[43; 44) ")" 55 R_PAREN@[43; 44) ")"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.txt
index 99bd76ace..7adb662de 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0137_await_expr.txt
@@ -31,7 +31,8 @@ SOURCE_FILE@[0; 67)
31 NAME_REF@[28; 29) 31 NAME_REF@[28; 29)
32 IDENT@[28; 29) "x" 32 IDENT@[28; 29) "x"
33 DOT@[29; 30) "." 33 DOT@[29; 30) "."
34 INT_NUMBER@[30; 31) "0" 34 NAME_REF@[30; 31)
35 INT_NUMBER@[30; 31) "0"
35 DOT@[31; 32) "." 36 DOT@[31; 32) "."
36 AWAIT_KW@[32; 37) "await" 37 AWAIT_KW@[32; 37) "await"
37 SEMI@[37; 38) ";" 38 SEMI@[37; 38) ";"
@@ -48,7 +49,8 @@ SOURCE_FILE@[0; 67)
48 NAME_REF@[43; 44) 49 NAME_REF@[43; 44)
49 IDENT@[43; 44) "x" 50 IDENT@[43; 44) "x"
50 DOT@[44; 45) "." 51 DOT@[44; 45) "."
51 INT_NUMBER@[45; 46) "0" 52 NAME_REF@[45; 46)
53 INT_NUMBER@[45; 46) "0"
52 ARG_LIST@[46; 48) 54 ARG_LIST@[46; 48)
53 L_PAREN@[46; 47) "(" 55 L_PAREN@[46; 47) "("
54 R_PAREN@[47; 48) ")" 56 R_PAREN@[47; 48) ")"