From e5702675155a5db137af65cf9d62cba4a6cea6c0 Mon Sep 17 00:00:00 2001 From: pcpthm Date: Sun, 17 Mar 2019 22:04:25 +0900 Subject: Refactor maybe_item to use Marker argument --- crates/ra_parser/src/grammar/expressions.rs | 72 +++++++++++------------ crates/ra_parser/src/grammar/items.rs | 89 ++++++++++++++--------------- 2 files changed, 75 insertions(+), 86 deletions(-) (limited to 'crates/ra_parser/src/grammar') diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index a0d5a99cb..9839846f1 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -54,7 +54,7 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { // test block_items // fn a() { fn b() {} } - let m = p.start(); + let mut m = p.start(); let has_attrs = p.at(POUND); attributes::outer_attributes(p); if p.at(LET_KW) { @@ -62,47 +62,41 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { continue; } - match items::maybe_item(p, items::ItemFlavor::Mod) { - items::MaybeItem::Item(kind) => { - m.complete(p, kind); - } - items::MaybeItem::Modifiers => { + m = match items::maybe_item(p, m, items::ItemFlavor::Mod) { + Some(m) => m, + None => continue, + }; + + // 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"); + } else { + let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; + if p.at(R_CURLY) { m.abandon(p); - p.error("expected an item"); - } - // test pub_expr - // fn foo() { pub 92; } //FIXME - items::MaybeItem::None => { - if has_attrs { - m.abandon(p); - p.error("expected a let statement or an item after attributes in block"); + } else { + // test no_semi_after_block + // fn foo() { + // if true {} + // loop {} + // match () {} + // while true {} + // for _ in () {} + // {} + // {} + // macro_rules! test { + // () => {} + // } + // test!{} + // } + if is_blocklike { + p.eat(SEMI); } else { - let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; - if p.at(R_CURLY) { - m.abandon(p); - } else { - // test no_semi_after_block - // fn foo() { - // if true {} - // loop {} - // match () {} - // while true {} - // for _ in () {} - // {} - // {} - // macro_rules! test { - // () => {} - // } - // test!{} - // } - if is_blocklike { - p.eat(SEMI); - } else { - p.expect(SEMI); - } - m.complete(p, EXPR_STMT); - } + p.expect(SEMI); } + m.complete(p, EXPR_STMT); } } } diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index a057c8167..5411589dd 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs @@ -35,54 +35,42 @@ pub(super) const ITEM_RECOVERY_SET: TokenSet = token_set![ ]; pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) { - let m = p.start(); + let mut m = p.start(); attributes::outer_attributes(p); - match maybe_item(p, flavor) { - MaybeItem::Item(kind) => { - m.complete(p, kind); - } - MaybeItem::None => { - if paths::is_path_start(p) { - match macro_call(p) { - BlockLike::Block => (), - BlockLike::NotBlock => { - p.expect(SEMI); - } - } - m.complete(p, MACRO_CALL); - } else { - m.abandon(p); - if p.at(L_CURLY) { - error_block(p, "expected an item"); - } else if p.at(R_CURLY) && !stop_on_r_curly { - let e = p.start(); - p.error("unmatched `}`"); - p.bump(); - e.complete(p, ERROR); - } else if !p.at(EOF) && !p.at(R_CURLY) { - p.err_and_bump("expected an item"); - } else { - p.error("expected an item"); - } + m = match maybe_item(p, m, flavor) { + Some(m) => m, + None => return, + }; + if paths::is_path_start(p) { + match macro_call(p) { + BlockLike::Block => (), + BlockLike::NotBlock => { + p.expect(SEMI); } } - MaybeItem::Modifiers => { - p.error("expected fn, trait or impl"); - m.complete(p, ERROR); + m.complete(p, MACRO_CALL); + } else { + m.abandon(p); + if p.at(L_CURLY) { + error_block(p, "expected an item"); + } else if p.at(R_CURLY) && !stop_on_r_curly { + let e = p.start(); + p.error("unmatched `}`"); + p.bump(); + e.complete(p, ERROR); + } else if !p.at(EOF) && !p.at(R_CURLY) { + p.err_and_bump("expected an item"); + } else { + p.error("expected an item"); } } } -pub(super) enum MaybeItem { - None, - Item(SyntaxKind), - Modifiers, -} - -pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { +pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Option { opt_visibility(p); if let Some(kind) = items_without_modifiers(p) { - return MaybeItem::Item(kind); + m.complete(p, kind); + return None; } let mut has_mods = false; @@ -115,7 +103,7 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { } // items - let kind = match p.current() { + match p.current() { // test async_fn // async fn foo() {} @@ -135,7 +123,8 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { // unsafe fn foo() {} FN_KW => { fn_def(p, flavor); - FN_DEF + m.complete(p, FN_DEF); + None } // test unsafe_trait @@ -148,7 +137,8 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { // unsafe auto trait T {} TRAIT_KW => { traits::trait_def(p); - TRAIT_DEF + m.complete(p, TRAIT_DEF); + None } // test unsafe_impl @@ -161,14 +151,19 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { // unsafe default impl Foo {} IMPL_KW => { traits::impl_block(p); - IMPL_BLOCK + m.complete(p, IMPL_BLOCK); + None } _ => { - return if has_mods { MaybeItem::Modifiers } else { MaybeItem::None }; + if has_mods { + p.error("expected fn, trait or impl"); + m.complete(p, ERROR); + None + } else { + Some(m) + } } - }; - - MaybeItem::Item(kind) + } } fn items_without_modifiers(p: &mut Parser) -> Option { -- cgit v1.2.3