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 +- 6 files changed, 61 insertions(+), 71 deletions(-) (limited to 'crates/ra_parser/src') 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;` -- cgit v1.2.3