From 76075c74103b3204ebc1bde54a330629d9e00811 Mon Sep 17 00:00:00 2001 From: pcpthm Date: Mon, 18 Mar 2019 14:34:08 +0900 Subject: Use Marker argument for item parsers - Fix pub_expr - Fix incorrect parsing of crate::path --- crates/ra_parser/src/grammar.rs | 12 ++- crates/ra_parser/src/grammar/expressions.rs | 2 - crates/ra_parser/src/grammar/items.rs | 93 ++++++++++------------ crates/ra_parser/src/grammar/items/consts.rs | 11 +-- crates/ra_parser/src/grammar/items/nominal.rs | 11 +-- crates/ra_parser/src/grammar/items/use_item.rs | 3 +- .../tests/data/parser/err/0003_C++_semicolon.txt | 6 +- .../tests/data/parser/inline/err/0008_pub_expr.rs | 1 + .../tests/data/parser/inline/err/0008_pub_expr.txt | 25 ++++++ .../tests/data/parser/inline/ok/0035_pub_expr.rs | 1 - .../tests/data/parser/inline/ok/0035_pub_expr.txt | 25 ------ .../parser/inline/ok/0040_crate_keyword_vis.rs | 2 + .../parser/inline/ok/0040_crate_keyword_vis.txt | 46 ++++++++++- .../parser/inline/ok/0125_crate_keyword_path.rs | 1 + .../parser/inline/ok/0125_crate_keyword_path.txt | 31 ++++++++ 15 files changed, 169 insertions(+), 101 deletions(-) create mode 100644 crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.rs create mode 100644 crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt delete mode 100644 crates/ra_syntax/tests/data/parser/inline/ok/0035_pub_expr.rs delete mode 100644 crates/ra_syntax/tests/data/parser/inline/ok/0035_pub_expr.txt create mode 100644 crates/ra_syntax/tests/data/parser/inline/ok/0125_crate_keyword_path.rs create mode 100644 crates/ra_syntax/tests/data/parser/inline/ok/0125_crate_keyword_path.txt (limited to 'crates') diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index c9941fe93..e428faffb 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs @@ -86,7 +86,7 @@ impl BlockLike { } } -fn opt_visibility(p: &mut Parser) { +fn opt_visibility(p: &mut Parser) -> bool { match p.current() { PUB_KW => { let m = p.start(); @@ -116,13 +116,19 @@ fn opt_visibility(p: &mut Parser) { } // test crate_keyword_vis // crate fn main() { } - CRATE_KW => { + // struct S { crate field: u32 } + // struct T(crate u32); + // + // test crate_keyword_path + // fn foo() { crate::foo(); } + CRATE_KW if p.nth(1) != COLONCOLON => { let m = p.start(); p.bump(); m.complete(p, VISIBILITY); } - _ => (), + _ => return false, } + true } fn opt_alias(p: &mut Parser) { diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 6d3e379a3..d8e825f46 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -67,8 +67,6 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { Err(m) => m, }; - // test pub_expr - // fn foo() { pub 92; } //FIXME if has_attrs { m.abandon(p); p.error("expected a let statement or an item after attributes in block"); diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index 94b93a02b..c24e6d1e0 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs @@ -67,11 +67,14 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemF } pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Result<(), Marker> { - opt_visibility(p); - if let Some(kind) = items_without_modifiers(p) { - m.complete(p, kind); - return Ok(()); - } + // test_err pub_expr + // fn foo() { pub 92; } + let has_visibility = opt_visibility(p); + + let m = match items_without_modifiers(p, m) { + Ok(()) => return Ok(()), + Err(m) => m, + }; let mut has_mods = false; @@ -152,10 +155,14 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul m.complete(p, IMPL_BLOCK); } _ => { - if !has_mods { + if !has_visibility && !has_mods { return Err(m); } else { - p.error("expected fn, trait or impl"); + if has_mods { + p.error("expected fn, trait or impl"); + } else { + p.error("expected an item"); + } m.complete(p, ERROR); } } @@ -163,23 +170,14 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul Ok(()) } -fn items_without_modifiers(p: &mut Parser) -> Option { +fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { let la = p.nth(1); - let kind = match p.current() { + match p.current() { // test extern_crate // extern crate foo; - EXTERN_KW if la == CRATE_KW => { - extern_crate_item(p); - EXTERN_CRATE_ITEM - } - TYPE_KW => { - type_def(p); - TYPE_ALIAS_DEF - } - MOD_KW => { - mod_item(p); - MODULE - } + EXTERN_KW if la == CRATE_KW => extern_crate_item(p, m), + TYPE_KW => type_def(p, m), + MOD_KW => mod_item(p, m), STRUCT_KW => { // test struct_items // struct Foo; @@ -190,14 +188,7 @@ fn items_without_modifiers(p: &mut Parser) -> Option { // a: i32, // b: f32, // } - nominal::struct_def(p, STRUCT_KW); - if p.at(SEMI) { - p.err_and_bump( - "expected item, found `;`\n\ - consider removing this semicolon", - ); - } - STRUCT_DEF + nominal::struct_def(p, m, STRUCT_KW); } IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { // test union_items @@ -206,25 +197,12 @@ fn items_without_modifiers(p: &mut Parser) -> Option { // a: i32, // b: f32, // } - nominal::struct_def(p, UNION_KW); - STRUCT_DEF - } - ENUM_KW => { - nominal::enum_def(p); - ENUM_DEF - } - USE_KW => { - use_item::use_item(p); - USE_ITEM - } - CONST_KW if (la == IDENT || la == MUT_KW) => { - consts::const_def(p); - CONST_DEF - } - STATIC_KW => { - consts::static_def(p); - STATIC_DEF + nominal::struct_def(p, m, UNION_KW); } + ENUM_KW => nominal::enum_def(p, m), + USE_KW => use_item::use_item(p, m), + CONST_KW if (la == IDENT || la == MUT_KW) => consts::const_def(p, m), + STATIC_KW => consts::static_def(p, m), // test extern_block // extern {} EXTERN_KW @@ -232,14 +210,20 @@ fn items_without_modifiers(p: &mut Parser) -> Option { { abi(p); extern_item_list(p); - EXTERN_BLOCK + m.complete(p, EXTERN_BLOCK); } - _ => return None, + _ => return Err(m), }; - Some(kind) + if p.at(SEMI) { + p.err_and_bump( + "expected item, found `;`\n\ + consider removing this semicolon", + ); + } + Ok(()) } -fn extern_crate_item(p: &mut Parser) { +fn extern_crate_item(p: &mut Parser, m: Marker) { assert!(p.at(EXTERN_KW)); p.bump(); assert!(p.at(CRATE_KW)); @@ -247,6 +231,7 @@ fn extern_crate_item(p: &mut Parser) { name_ref(p); opt_alias(p); p.expect(SEMI); + m.complete(p, EXTERN_CRATE_ITEM); } pub(crate) fn extern_item_list(p: &mut Parser) { @@ -295,7 +280,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) { // test type_item // type Foo = Bar; -fn type_def(p: &mut Parser) { +fn type_def(p: &mut Parser, m: Marker) { assert!(p.at(TYPE_KW)); p.bump(); @@ -317,9 +302,10 @@ fn type_def(p: &mut Parser) { types::type_(p); } p.expect(SEMI); + m.complete(p, TYPE_ALIAS_DEF); } -pub(crate) fn mod_item(p: &mut Parser) { +pub(crate) fn mod_item(p: &mut Parser, m: Marker) { assert!(p.at(MOD_KW)); p.bump(); @@ -329,6 +315,7 @@ pub(crate) fn mod_item(p: &mut Parser) { } else if !p.eat(SEMI) { p.error("expected `;` or `{`"); } + m.complete(p, MODULE); } pub(crate) fn mod_item_list(p: &mut Parser) { diff --git a/crates/ra_parser/src/grammar/items/consts.rs b/crates/ra_parser/src/grammar/items/consts.rs index 5a5852f83..e6e6011c6 100644 --- a/crates/ra_parser/src/grammar/items/consts.rs +++ b/crates/ra_parser/src/grammar/items/consts.rs @@ -1,14 +1,14 @@ use super::*; -pub(super) fn static_def(p: &mut Parser) { - const_or_static(p, STATIC_KW) +pub(super) fn static_def(p: &mut Parser, m: Marker) { + const_or_static(p, m, STATIC_KW, STATIC_DEF) } -pub(super) fn const_def(p: &mut Parser) { - const_or_static(p, CONST_KW) +pub(super) fn const_def(p: &mut Parser, m: Marker) { + const_or_static(p, m, CONST_KW, CONST_DEF) } -fn const_or_static(p: &mut Parser, kw: SyntaxKind) { +fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { assert!(p.at(kw)); p.bump(); p.eat(MUT_KW); // TODO: validator to forbid const mut @@ -18,4 +18,5 @@ fn const_or_static(p: &mut Parser, kw: SyntaxKind) { expressions::expr(p); } p.expect(SEMI); + m.complete(p, def); } diff --git a/crates/ra_parser/src/grammar/items/nominal.rs b/crates/ra_parser/src/grammar/items/nominal.rs index ff9b38f9c..a3579eebd 100644 --- a/crates/ra_parser/src/grammar/items/nominal.rs +++ b/crates/ra_parser/src/grammar/items/nominal.rs @@ -1,6 +1,6 @@ use super::*; -pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { +pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) { assert!(p.at(STRUCT_KW) || p.at_contextual_kw("union")); p.bump_remap(kind); @@ -12,19 +12,16 @@ pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { match p.current() { SEMI => { p.bump(); - return; } L_CURLY => named_field_def_list(p), _ => { //TODO: special case `(` error message p.error("expected `;` or `{`"); - return; } } } SEMI if kind == STRUCT_KW => { p.bump(); - return; } L_CURLY => named_field_def_list(p), L_PAREN if kind == STRUCT_KW => { @@ -37,16 +34,15 @@ pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { } _ if kind == STRUCT_KW => { p.error("expected `;`, `{`, or `(`"); - return; } _ => { p.error("expected `{`"); - return; } } + m.complete(p, STRUCT_DEF); } -pub(super) fn enum_def(p: &mut Parser) { +pub(super) fn enum_def(p: &mut Parser, m: Marker) { assert!(p.at(ENUM_KW)); p.bump(); name_r(p, ITEM_RECOVERY_SET); @@ -57,6 +53,7 @@ pub(super) fn enum_def(p: &mut Parser) { } else { p.error("expected `{`") } + m.complete(p, ENUM_DEF); } pub(crate) fn enum_variant_list(p: &mut Parser) { diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs index b36612726..ea2f94604 100644 --- a/crates/ra_parser/src/grammar/items/use_item.rs +++ b/crates/ra_parser/src/grammar/items/use_item.rs @@ -1,10 +1,11 @@ use super::*; -pub(super) fn use_item(p: &mut Parser) { +pub(super) fn use_item(p: &mut Parser, m: Marker) { assert!(p.at(USE_KW)); p.bump(); use_tree(p); p.expect(SEMI); + m.complete(p, USE_ITEM); } /// Parse a use 'tree', such as `some::path` in `use some::path;` diff --git a/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt index e9400d03b..b87fe46bd 100644 --- a/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt +++ b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt @@ -1,5 +1,5 @@ SOURCE_FILE@[0; 40) - STRUCT_DEF@[0; 40) + STRUCT_DEF@[0; 39) STRUCT_KW@[0; 6) WHITESPACE@[6; 7) NAME@[7; 8) @@ -35,5 +35,5 @@ SOURCE_FILE@[0; 40) R_CURLY@[38; 39) err: `expected item, found `;` consider removing this semicolon` - ERROR@[39; 40) - SEMI@[39; 40) + ERROR@[39; 40) + SEMI@[39; 40) diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.rs b/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.rs new file mode 100644 index 000000000..2976f6862 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.rs @@ -0,0 +1 @@ +fn foo() { pub 92; } diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt b/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt new file mode 100644 index 000000000..e65d9c9e1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/err/0008_pub_expr.txt @@ -0,0 +1,25 @@ +SOURCE_FILE@[0; 21) + FN_DEF@[0; 20) + FN_KW@[0; 2) + WHITESPACE@[2; 3) + NAME@[3; 6) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 8) + L_PAREN@[6; 7) + R_PAREN@[7; 8) + WHITESPACE@[8; 9) + BLOCK@[9; 20) + L_CURLY@[9; 10) + WHITESPACE@[10; 11) + ERROR@[11; 14) + VISIBILITY@[11; 14) + PUB_KW@[11; 14) + err: `expected an item` + WHITESPACE@[14; 15) + EXPR_STMT@[15; 18) + LITERAL@[15; 17) + INT_NUMBER@[15; 17) "92" + SEMI@[17; 18) + WHITESPACE@[18; 19) + R_CURLY@[19; 20) + WHITESPACE@[20; 21) diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0035_pub_expr.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0035_pub_expr.rs deleted file mode 100644 index d9d99d2d3..000000000 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0035_pub_expr.rs +++ /dev/null @@ -1 +0,0 @@ -fn foo() { pub 92; } //FIXME diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0035_pub_expr.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0035_pub_expr.txt deleted file mode 100644 index de20eee7a..000000000 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0035_pub_expr.txt +++ /dev/null @@ -1,25 +0,0 @@ -SOURCE_FILE@[0; 29) - FN_DEF@[0; 20) - FN_KW@[0; 2) - WHITESPACE@[2; 3) - NAME@[3; 6) - IDENT@[3; 6) "foo" - PARAM_LIST@[6; 8) - L_PAREN@[6; 7) - R_PAREN@[7; 8) - WHITESPACE@[8; 9) - BLOCK@[9; 20) - L_CURLY@[9; 10) - WHITESPACE@[10; 11) - EXPR_STMT@[11; 18) - VISIBILITY@[11; 14) - PUB_KW@[11; 14) - WHITESPACE@[14; 15) - LITERAL@[15; 17) - INT_NUMBER@[15; 17) "92" - SEMI@[17; 18) - WHITESPACE@[18; 19) - R_CURLY@[19; 20) - WHITESPACE@[20; 21) - COMMENT@[21; 28) - WHITESPACE@[28; 29) diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0040_crate_keyword_vis.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0040_crate_keyword_vis.rs index 660d927cf..e2b5f2161 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0040_crate_keyword_vis.rs +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0040_crate_keyword_vis.rs @@ -1 +1,3 @@ crate fn main() { } +struct S { crate field: u32 } +struct T(crate u32); diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0040_crate_keyword_vis.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0040_crate_keyword_vis.txt index ff5add838..695734d54 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0040_crate_keyword_vis.txt +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0040_crate_keyword_vis.txt @@ -1,4 +1,4 @@ -SOURCE_FILE@[0; 20) +SOURCE_FILE@[0; 71) FN_DEF@[0; 19) VISIBILITY@[0; 5) CRATE_KW@[0; 5) @@ -16,3 +16,47 @@ SOURCE_FILE@[0; 20) WHITESPACE@[17; 18) R_CURLY@[18; 19) WHITESPACE@[19; 20) + STRUCT_DEF@[20; 49) + STRUCT_KW@[20; 26) + WHITESPACE@[26; 27) + NAME@[27; 28) + IDENT@[27; 28) "S" + WHITESPACE@[28; 29) + NAMED_FIELD_DEF_LIST@[29; 49) + L_CURLY@[29; 30) + WHITESPACE@[30; 31) + NAMED_FIELD_DEF@[31; 47) + VISIBILITY@[31; 36) + CRATE_KW@[31; 36) + WHITESPACE@[36; 37) + NAME@[37; 42) + IDENT@[37; 42) "field" + COLON@[42; 43) + WHITESPACE@[43; 44) + PATH_TYPE@[44; 47) + PATH@[44; 47) + PATH_SEGMENT@[44; 47) + NAME_REF@[44; 47) + IDENT@[44; 47) "u32" + WHITESPACE@[47; 48) + R_CURLY@[48; 49) + WHITESPACE@[49; 50) + STRUCT_DEF@[50; 70) + STRUCT_KW@[50; 56) + WHITESPACE@[56; 57) + NAME@[57; 58) + IDENT@[57; 58) "T" + POS_FIELD_DEF_LIST@[58; 69) + L_PAREN@[58; 59) + POS_FIELD_DEF@[59; 68) + VISIBILITY@[59; 64) + CRATE_KW@[59; 64) + WHITESPACE@[64; 65) + PATH_TYPE@[65; 68) + PATH@[65; 68) + PATH_SEGMENT@[65; 68) + NAME_REF@[65; 68) + IDENT@[65; 68) "u32" + R_PAREN@[68; 69) + SEMI@[69; 70) + WHITESPACE@[70; 71) diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0125_crate_keyword_path.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0125_crate_keyword_path.rs new file mode 100644 index 000000000..0f454d121 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0125_crate_keyword_path.rs @@ -0,0 +1 @@ +fn foo() { crate::foo(); } diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0125_crate_keyword_path.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0125_crate_keyword_path.txt new file mode 100644 index 000000000..7c637b079 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0125_crate_keyword_path.txt @@ -0,0 +1,31 @@ +SOURCE_FILE@[0; 27) + FN_DEF@[0; 26) + FN_KW@[0; 2) + WHITESPACE@[2; 3) + NAME@[3; 6) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 8) + L_PAREN@[6; 7) + R_PAREN@[7; 8) + WHITESPACE@[8; 9) + BLOCK@[9; 26) + L_CURLY@[9; 10) + WHITESPACE@[10; 11) + EXPR_STMT@[11; 24) + CALL_EXPR@[11; 23) + PATH_EXPR@[11; 21) + PATH@[11; 21) + PATH@[11; 16) + PATH_SEGMENT@[11; 16) + CRATE_KW@[11; 16) + COLONCOLON@[16; 18) + PATH_SEGMENT@[18; 21) + NAME_REF@[18; 21) + IDENT@[18; 21) "foo" + ARG_LIST@[21; 23) + L_PAREN@[21; 22) + R_PAREN@[22; 23) + SEMI@[23; 24) + WHITESPACE@[24; 25) + R_CURLY@[25; 26) + WHITESPACE@[26; 27) -- cgit v1.2.3