]> git.lizzy.rs Git - rust.git/commitdiff
Improve parsing of incomplete field accesses in preparation for field completion
authorFlorian Diebold <flodiebold@gmail.com>
Tue, 25 Dec 2018 13:48:54 +0000 (14:48 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Tue, 25 Dec 2018 14:16:42 +0000 (15:16 +0100)
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
crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs [new file with mode: 0644]
crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt [new file with mode: 0644]

index da78d85a2f9f49f94a518a1f2c74287ea8d6d336..2d1f174912c62cfd65bfc41d4c3141d305295231 100644 (file)
@@ -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 (file)
index 0000000..a7cdc17
--- /dev/null
@@ -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 (file)
index 0000000..fd2a3f3
--- /dev/null
@@ -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)