Move numeric names inside of NameRef

This commit is contained in:
Aleksey Kladov 2019-08-09 12:16:47 +02:00
parent 5f82012779
commit f3ee5a1509
10 changed files with 52 additions and 37 deletions

View File

@ -273,8 +273,8 @@ fn name(p: &mut Parser) {
name_r(p, TokenSet::empty()) name_r(p, TokenSet::empty())
} }
fn name_ref(p: &mut Parser, allow_numeric_names: bool) { fn name_ref(p: &mut Parser) {
if p.at(IDENT) || (allow_numeric_names && p.at(INT_NUMBER)) { if p.at(IDENT) {
let m = p.start(); let m = p.start();
p.bump(); p.bump();
m.complete(p, NAME_REF); 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) { fn error_block(p: &mut Parser, message: &str) {
assert!(p.at(T!['{'])); assert!(p.at(T!['{']));
let m = p.start(); let m = p.start();

View File

@ -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![::])); assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::]));
let m = lhs.precede(p); let m = lhs.precede(p);
p.bump(); p.bump();
name_ref(p, false); name_ref(p);
type_args::opt_type_arg_list(p, true); type_args::opt_type_arg_list(p, true);
if p.at(T!['(']) { if p.at(T!['(']) {
arg_list(p); arg_list(p);
@ -484,10 +484,8 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
assert!(p.at(T![.])); assert!(p.at(T![.]));
let m = lhs.precede(p); let m = lhs.precede(p);
p.bump(); p.bump();
if p.at(IDENT) { if p.at(IDENT) || p.at(INT_NUMBER) {
name_ref(p, false) name_ref_or_index(p)
} else if p.at(INT_NUMBER) {
p.bump();
} else if p.at(FLOAT_NUMBER) { } else if p.at(FLOAT_NUMBER) {
// FIXME: How to recover and instead parse INT + T![.]? // FIXME: How to recover and instead parse INT + T![.]?
p.bump(); p.bump();
@ -587,7 +585,7 @@ pub(crate) fn named_field_list(p: &mut Parser) {
IDENT | INT_NUMBER | T![#] => { IDENT | INT_NUMBER | T![#] => {
let m = p.start(); let m = p.start();
attributes::outer_attributes(p); attributes::outer_attributes(p);
name_ref(p, true); name_ref_or_index(p);
if p.eat(T![:]) { if p.eat(T![:]) {
expr(p); expr(p);
} }

View File

@ -279,7 +279,7 @@ fn extern_crate_item(p: &mut Parser, m: Marker) {
p.bump(); p.bump();
assert!(p.at(T![crate])); assert!(p.at(T![crate]));
p.bump(); p.bump();
name_ref(p, false); name_ref(p);
opt_alias(p); opt_alias(p);
p.expect(T![;]); p.expect(T![;]);
m.complete(p, EXTERN_CRATE_ITEM); m.complete(p, EXTERN_CRATE_ITEM);

View File

@ -71,7 +71,7 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
} }
match p.current() { match p.current() {
IDENT => { IDENT => {
name_ref(p, false); name_ref(p);
opt_path_type_args(p, mode); opt_path_type_args(p, mode);
} }
// test crate_path // test crate_path

View File

@ -38,12 +38,12 @@ fn type_arg(p: &mut Parser) {
// test associated_type_bounds // test associated_type_bounds
// fn print_all<T: Iterator<Item: Display>>(printables: T) {} // fn print_all<T: Iterator<Item: Display>>(printables: T) {}
IDENT if p.nth(1) == T![:] => { IDENT if p.nth(1) == T![:] => {
name_ref(p, false); name_ref(p);
type_params::bounds(p); type_params::bounds(p);
m.complete(p, ASSOC_TYPE_ARG); m.complete(p, ASSOC_TYPE_ARG);
} }
IDENT if p.nth(1) == T![=] => { IDENT if p.nth(1) == T![=] => {
name_ref(p, false); name_ref(p);
p.bump(); p.bump();
types::type_(p); types::type_(p);
m.complete(p, ASSOC_TYPE_ARG); m.complete(p, ASSOC_TYPE_ARG);

View File

@ -1,13 +1,12 @@
mod block; mod block;
mod field_expr;
use ra_rustc_lexer::unescape; use ra_rustc_lexer::unescape;
use crate::{ use crate::{
algo::visit::{visitor_ctx, VisitorCtx}, algo::visit::{visitor_ctx, VisitorCtx},
ast, SyntaxError, SyntaxErrorKind, ast, AstNode, SyntaxError, SyntaxErrorKind,
SyntaxKind::{BYTE, BYTE_STRING, CHAR, STRING}, SyntaxKind::{BYTE, BYTE_STRING, CHAR, INT_NUMBER, STRING},
SyntaxNode, TextUnit, T, SyntaxNode, SyntaxToken, TextUnit, T,
}; };
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -101,7 +100,8 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
let _ = visitor_ctx(&mut errors) let _ = visitor_ctx(&mut errors)
.visit::<ast::Literal, _>(validate_literal) .visit::<ast::Literal, _>(validate_literal)
.visit::<ast::Block, _>(block::validate_block_node) .visit::<ast::Block, _>(block::validate_block_node)
.visit::<ast::FieldExpr, _>(field_expr::validate_field_expr_node) .visit::<ast::FieldExpr, _>(|it, errors| validate_numeric_name(it.name_ref(), errors))
.visit::<ast::NamedField, _>(|it, errors| validate_numeric_name(it.name_ref(), errors))
.accept(&node); .accept(&node);
} }
errors errors
@ -189,3 +189,18 @@ pub(crate) fn validate_block_structure(root: &SyntaxNode) {
} }
} }
} }
fn validate_numeric_name(name_ref: Option<ast::NameRef>, errors: &mut Vec<SyntaxError>) {
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<ast::NameRef>) -> Option<SyntaxToken> {
name_ref?.syntax().first_child_or_token()?.into_token().filter(|it| it.kind() == INT_NUMBER)
}
}

View File

@ -1,13 +0,0 @@
use crate::{
ast::{self, FieldKind},
SyntaxError,
SyntaxErrorKind::*,
};
pub(crate) fn validate_field_expr_node(node: ast::FieldExpr, errors: &mut Vec<SyntaxError>) {
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()));
}
}
}

View File

@ -30,7 +30,8 @@ SOURCE_FILE@[0; 47)
NAME_REF@[25; 26) NAME_REF@[25; 26)
IDENT@[25; 26) "x" IDENT@[25; 26) "x"
DOT@[26; 27) "." DOT@[26; 27) "."
INT_NUMBER@[27; 31) "1i32" NAME_REF@[27; 31)
INT_NUMBER@[27; 31) "1i32"
SEMI@[31; 32) ";" SEMI@[31; 32) ";"
WHITESPACE@[32; 37) "\n " WHITESPACE@[32; 37) "\n "
EXPR_STMT@[37; 44) EXPR_STMT@[37; 44)
@ -41,11 +42,11 @@ SOURCE_FILE@[0; 47)
NAME_REF@[37; 38) NAME_REF@[37; 38)
IDENT@[37; 38) "x" IDENT@[37; 38) "x"
DOT@[38; 39) "." DOT@[38; 39) "."
INT_NUMBER@[39; 43) "0x01" NAME_REF@[39; 43)
INT_NUMBER@[39; 43) "0x01"
SEMI@[43; 44) ";" SEMI@[43; 44) ";"
WHITESPACE@[44; 45) "\n" WHITESPACE@[44; 45) "\n"
R_CURLY@[45; 46) "}" R_CURLY@[45; 46) "}"
WHITESPACE@[46; 47) "\n" 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 [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 error [39; 43): Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix

View File

@ -32,7 +32,8 @@ SOURCE_FILE@[0; 48)
NAME_REF@[26; 27) NAME_REF@[26; 27)
IDENT@[26; 27) "x" IDENT@[26; 27) "x"
DOT@[27; 28) "." DOT@[27; 28) "."
INT_NUMBER@[28; 29) "0" NAME_REF@[28; 29)
INT_NUMBER@[28; 29) "0"
DOT@[29; 30) "." DOT@[29; 30) "."
NAME_REF@[30; 33) NAME_REF@[30; 33)
IDENT@[30; 33) "bar" IDENT@[30; 33) "bar"
@ -47,7 +48,8 @@ SOURCE_FILE@[0; 48)
NAME_REF@[39; 40) NAME_REF@[39; 40)
IDENT@[39; 40) "x" IDENT@[39; 40) "x"
DOT@[40; 41) "." DOT@[40; 41) "."
INT_NUMBER@[41; 42) "0" NAME_REF@[41; 42)
INT_NUMBER@[41; 42) "0"
ARG_LIST@[42; 44) ARG_LIST@[42; 44)
L_PAREN@[42; 43) "(" L_PAREN@[42; 43) "("
R_PAREN@[43; 44) ")" R_PAREN@[43; 44) ")"

View File

@ -31,7 +31,8 @@ SOURCE_FILE@[0; 67)
NAME_REF@[28; 29) NAME_REF@[28; 29)
IDENT@[28; 29) "x" IDENT@[28; 29) "x"
DOT@[29; 30) "." DOT@[29; 30) "."
INT_NUMBER@[30; 31) "0" NAME_REF@[30; 31)
INT_NUMBER@[30; 31) "0"
DOT@[31; 32) "." DOT@[31; 32) "."
AWAIT_KW@[32; 37) "await" AWAIT_KW@[32; 37) "await"
SEMI@[37; 38) ";" SEMI@[37; 38) ";"
@ -48,7 +49,8 @@ SOURCE_FILE@[0; 67)
NAME_REF@[43; 44) NAME_REF@[43; 44)
IDENT@[43; 44) "x" IDENT@[43; 44) "x"
DOT@[44; 45) "." DOT@[44; 45) "."
INT_NUMBER@[45; 46) "0" NAME_REF@[45; 46)
INT_NUMBER@[45; 46) "0"
ARG_LIST@[46; 48) ARG_LIST@[46; 48)
L_PAREN@[46; 47) "(" L_PAREN@[46; 47) "("
R_PAREN@[47; 48) ")" R_PAREN@[47; 48) ")"