From f3ee5a15090d8ba6ec220e1f907ed3af27e57734 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 9 Aug 2019 12:16:47 +0200 Subject: [PATCH] Move numeric names inside of `NameRef` --- crates/ra_parser/src/grammar.rs | 14 +++++++++-- crates/ra_parser/src/grammar/expressions.rs | 10 +++----- crates/ra_parser/src/grammar/items.rs | 2 +- crates/ra_parser/src/grammar/paths.rs | 2 +- crates/ra_parser/src/grammar/type_args.rs | 4 +-- crates/ra_syntax/src/validation.rs | 25 +++++++++++++++---- crates/ra_syntax/src/validation/field_expr.rs | 13 ---------- .../inline/err/0010_bad_tuple_index_expr.txt | 7 +++--- .../parser/inline/ok/0011_field_expr.txt | 6 +++-- .../parser/inline/ok/0137_await_expr.txt | 6 +++-- 10 files changed, 52 insertions(+), 37 deletions(-) delete mode 100644 crates/ra_syntax/src/validation/field_expr.rs diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index 2ee121ccd09..beedac45725 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs @@ -273,8 +273,8 @@ fn name(p: &mut Parser) { name_r(p, TokenSet::empty()) } -fn name_ref(p: &mut Parser, allow_numeric_names: bool) { - if p.at(IDENT) || (allow_numeric_names && p.at(INT_NUMBER)) { +fn name_ref(p: &mut Parser) { + if p.at(IDENT) { let m = p.start(); p.bump(); m.complete(p, NAME_REF); @@ -287,6 +287,16 @@ fn name_ref(p: &mut Parser, allow_numeric_names: bool) { } } +fn name_ref_or_index(p: &mut Parser) { + if p.at(IDENT) || p.at(INT_NUMBER) { + let m = p.start(); + p.bump(); + m.complete(p, NAME_REF); + } else { + p.err_and_bump("expected identifier"); + } +} + fn error_block(p: &mut Parser, message: &str) { assert!(p.at(T!['{'])); let m = p.start(); diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 9f9e9cb0eed..9fd3a235d12 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 { assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::])); let m = lhs.precede(p); p.bump(); - name_ref(p, false); + name_ref(p); type_args::opt_type_arg_list(p, true); if p.at(T!['(']) { arg_list(p); @@ -484,10 +484,8 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { assert!(p.at(T![.])); let m = lhs.precede(p); p.bump(); - if p.at(IDENT) { - name_ref(p, false) - } else if p.at(INT_NUMBER) { - p.bump(); + if p.at(IDENT) || p.at(INT_NUMBER) { + name_ref_or_index(p) } else if p.at(FLOAT_NUMBER) { // FIXME: How to recover and instead parse INT + T![.]? p.bump(); @@ -587,7 +585,7 @@ pub(crate) fn named_field_list(p: &mut Parser) { IDENT | INT_NUMBER | T![#] => { let m = p.start(); attributes::outer_attributes(p); - name_ref(p, true); + name_ref_or_index(p); if p.eat(T![:]) { expr(p); } diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index b0081f39607..543af7c4bb1 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) { p.bump(); assert!(p.at(T![crate])); p.bump(); - name_ref(p, false); + name_ref(p); opt_alias(p); p.expect(T![;]); 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 2c8f0f7e824..3537b0da117 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) { } match p.current() { IDENT => { - name_ref(p, false); + name_ref(p); opt_path_type_args(p, mode); } // test crate_path diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs index f1d999dead6..3db08b280d7 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) { // test associated_type_bounds // fn print_all>(printables: T) {} IDENT if p.nth(1) == T![:] => { - name_ref(p, false); + name_ref(p); type_params::bounds(p); m.complete(p, ASSOC_TYPE_ARG); } IDENT if p.nth(1) == T![=] => { - name_ref(p, false); + name_ref(p); p.bump(); types::type_(p); m.complete(p, ASSOC_TYPE_ARG); diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 1f904434e8a..2bb3c0a03eb 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs @@ -1,13 +1,12 @@ mod block; -mod field_expr; use ra_rustc_lexer::unescape; use crate::{ algo::visit::{visitor_ctx, VisitorCtx}, - ast, SyntaxError, SyntaxErrorKind, - SyntaxKind::{BYTE, BYTE_STRING, CHAR, STRING}, - SyntaxNode, TextUnit, T, + ast, AstNode, SyntaxError, SyntaxErrorKind, + SyntaxKind::{BYTE, BYTE_STRING, CHAR, INT_NUMBER, STRING}, + SyntaxNode, SyntaxToken, TextUnit, T, }; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -101,7 +100,8 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec { let _ = visitor_ctx(&mut errors) .visit::(validate_literal) .visit::(block::validate_block_node) - .visit::(field_expr::validate_field_expr_node) + .visit::(|it, errors| validate_numeric_name(it.name_ref(), errors)) + .visit::(|it, errors| validate_numeric_name(it.name_ref(), errors)) .accept(&node); } errors @@ -189,3 +189,18 @@ pub(crate) fn validate_block_structure(root: &SyntaxNode) { } } } + +fn validate_numeric_name(name_ref: Option, errors: &mut Vec) { + if let Some(int_token) = int_token(name_ref) { + if int_token.text().chars().any(|c| !c.is_digit(10)) { + errors.push(SyntaxError::new( + SyntaxErrorKind::InvalidTupleIndexFormat, + int_token.text_range(), + )); + } + } + + fn int_token(name_ref: Option) -> Option { + name_ref?.syntax().first_child_or_token()?.into_token().filter(|it| it.kind() == INT_NUMBER) + } +} 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 004f199fd53..00000000000 --- a/crates/ra_syntax/src/validation/field_expr.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::{ - ast::{self, FieldKind}, - SyntaxError, - SyntaxErrorKind::*, -}; - -pub(crate) fn validate_field_expr_node(node: ast::FieldExpr, errors: &mut Vec) { - if let Some(FieldKind::Index(idx)) = node.field_access() { - if idx.text().chars().any(|c| c < '0' || c > '9') { - errors.push(SyntaxError::new(InvalidTupleIndexFormat, idx.text_range())); - } - } -} 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 a21b29c80ac..465e79e7b28 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) NAME_REF@[25; 26) IDENT@[25; 26) "x" DOT@[26; 27) "." - INT_NUMBER@[27; 31) "1i32" + NAME_REF@[27; 31) + INT_NUMBER@[27; 31) "1i32" SEMI@[31; 32) ";" WHITESPACE@[32; 37) "\n " EXPR_STMT@[37; 44) @@ -41,11 +42,11 @@ SOURCE_FILE@[0; 47) NAME_REF@[37; 38) IDENT@[37; 38) "x" DOT@[38; 39) "." - INT_NUMBER@[39; 43) "0x01" + NAME_REF@[39; 43) + INT_NUMBER@[39; 43) "0x01" SEMI@[43; 44) ";" WHITESPACE@[44; 45) "\n" R_CURLY@[45; 46) "}" WHITESPACE@[46; 47) "\n" -error [17; 19): Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix error [27; 31): Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix error [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 78054ec5a2c..1d2cf276156 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) NAME_REF@[26; 27) IDENT@[26; 27) "x" DOT@[27; 28) "." - INT_NUMBER@[28; 29) "0" + NAME_REF@[28; 29) + INT_NUMBER@[28; 29) "0" DOT@[29; 30) "." NAME_REF@[30; 33) IDENT@[30; 33) "bar" @@ -47,7 +48,8 @@ SOURCE_FILE@[0; 48) NAME_REF@[39; 40) IDENT@[39; 40) "x" DOT@[40; 41) "." - INT_NUMBER@[41; 42) "0" + NAME_REF@[41; 42) + INT_NUMBER@[41; 42) "0" ARG_LIST@[42; 44) L_PAREN@[42; 43) "(" 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 99bd76ace38..7adb662de71 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) NAME_REF@[28; 29) IDENT@[28; 29) "x" DOT@[29; 30) "." - INT_NUMBER@[30; 31) "0" + NAME_REF@[30; 31) + INT_NUMBER@[30; 31) "0" DOT@[31; 32) "." AWAIT_KW@[32; 37) "await" SEMI@[37; 38) ";" @@ -48,7 +49,8 @@ SOURCE_FILE@[0; 67) NAME_REF@[43; 44) IDENT@[43; 44) "x" DOT@[44; 45) "." - INT_NUMBER@[45; 46) "0" + NAME_REF@[45; 46) + INT_NUMBER@[45; 46) "0" ARG_LIST@[46; 48) L_PAREN@[46; 47) "(" R_PAREN@[47; 48) ")"