From 0d724ea572a5dd26acbbf2eb4538eabe454fb894 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 25 Dec 2018 14:48:54 +0100 Subject: Improve parsing of incomplete field accesses in preparation for field completion We need to be able to get the receiver even if there is no field name yet, and currently "a." wouldn't get parsed as a field name at all. This seems to help. --- crates/ra_syntax/src/grammar/expressions.rs | 16 +++++----- .../tests/data/parser/err/0029_field_completion.rs | 3 ++ .../data/parser/err/0029_field_completion.txt | 35 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs create mode 100644 crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt (limited to 'crates') diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs index da78d85a2..2d1f17491 100644 --- a/crates/ra_syntax/src/grammar/expressions.rs +++ b/crates/ra_syntax/src/grammar/expressions.rs @@ -283,14 +283,10 @@ fn postfix_expr( // } L_PAREN if allow_calls => call_expr(p, lhs), L_BRACK if allow_calls => index_expr(p, lhs), - DOT if p.nth(1) == IDENT => { - if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON { - method_call_expr(p, lhs) - } else { - field_expr(p, lhs) - } + DOT if p.nth(1) == IDENT && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) => { + method_call_expr(p, lhs) } - DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), + DOT => field_expr(p, lhs), // test postfix_range // fn foo() { let x = 1..; } DOTDOT | DOTDOTEQ if !EXPR_FIRST.contains(p.nth(1)) => { @@ -355,13 +351,15 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { // x.0.bar; // } fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER)); + assert!(p.at(DOT)); let m = lhs.precede(p); p.bump(); if p.at(IDENT) { name_ref(p) - } else { + } else if p.at(INT_NUMBER) { p.bump() + } else { + p.error("expected field name or number") } m.complete(p, FIELD_EXPR) } diff --git a/crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs new file mode 100644 index 000000000..a7cdc17bb --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs @@ -0,0 +1,3 @@ +fn foo(a: A) { + a. +} diff --git a/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt new file mode 100644 index 000000000..fd2a3f37b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt @@ -0,0 +1,35 @@ +SOURCE_FILE@[0; 24) + FN_DEF@[0; 23) + FN_KW@[0; 2) + WHITESPACE@[2; 3) + NAME@[3; 6) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 12) + L_PAREN@[6; 7) + PARAM@[7; 11) + BIND_PAT@[7; 8) + NAME@[7; 8) + IDENT@[7; 8) "a" + COLON@[8; 9) + WHITESPACE@[9; 10) + PATH_TYPE@[10; 11) + PATH@[10; 11) + PATH_SEGMENT@[10; 11) + NAME_REF@[10; 11) + IDENT@[10; 11) "A" + R_PAREN@[11; 12) + WHITESPACE@[12; 13) + BLOCK@[13; 23) + L_CURLY@[13; 14) + WHITESPACE@[14; 19) + FIELD_EXPR@[19; 21) + PATH_EXPR@[19; 20) + PATH@[19; 20) + PATH_SEGMENT@[19; 20) + NAME_REF@[19; 20) + IDENT@[19; 20) "a" + DOT@[20; 21) + err: `expected field name or number` + WHITESPACE@[21; 22) + R_CURLY@[22; 23) + WHITESPACE@[23; 24) -- cgit v1.2.3