Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/parser/src/grammar/items.rs')
| -rw-r--r-- | crates/parser/src/grammar/items.rs | 179 |
1 files changed, 79 insertions, 100 deletions
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index 3421078bba..e0b740a815 100644 --- a/crates/parser/src/grammar/items.rs +++ b/crates/parser/src/grammar/items.rs @@ -44,7 +44,8 @@ pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) { let m = p.start(); attributes::outer_attrs(p); - let m = match maybe_item(p, m) { + + let m = match opt_item(p, m) { Ok(()) => { if p.at(T![;]) { p.err_and_bump( @@ -56,6 +57,7 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) { } Err(m) => m, }; + if paths::is_use_path_start(p) { match macro_call(p) { BlockLike::Block => (), @@ -64,30 +66,30 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) { } } m.complete(p, MACRO_CALL); - } else { - m.abandon(p); - if p.at(T!['{']) { - error_block(p, "expected an item"); - } else if p.at(T!['}']) && !stop_on_r_curly { + return; + } + + m.abandon(p); + match p.current() { + T!['{'] => error_block(p, "expected an item"), + T!['}'] if !stop_on_r_curly => { let e = p.start(); p.error("unmatched `}`"); p.bump(T!['}']); e.complete(p, ERROR); - } else if !p.at(EOF) && !p.at(T!['}']) { - p.err_and_bump("expected an item"); - } else { - p.error("expected an item"); } + EOF | T!['}'] => p.error("expected an item"), + _ => p.err_and_bump("expected an item"), } } /// Try to parse an item, completing `m` in case of success. -pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> { +pub(super) fn opt_item(p: &mut Parser, m: Marker) -> Result<(), Marker> { // test_err pub_expr // fn foo() { pub 92; } let has_visibility = opt_visibility(p); - let m = match items_without_modifiers(p, m) { + let m = match opt_item_without_modifiers(p, m) { Ok(()) => return Ok(()), Err(m) => m, }; @@ -235,48 +237,20 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> { Ok(()) } -fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { +fn opt_item_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { let la = p.nth(1); match p.current() { - // test extern_crate - // extern crate foo; T![extern] if la == T![crate] => extern_crate(p, m), T![use] => use_item::use_(p, m), T![mod] => mod_item(p, m), T![type] => type_alias(p, m), - - T![struct] => { - // test struct_items - // struct Foo; - // struct Foo {} - // struct Foo(); - // struct Foo(String, usize); - // struct Foo { - // a: i32, - // b: f32, - // } - adt::strukt(p, m); - } + T![struct] => adt::strukt(p, m), T![enum] => adt::enum_(p, m), - IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { - // test union_items - // union Foo {} - // union Foo { - // a: i32, - // b: f32, - // } - adt::union(p, m); - } + IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => adt::union(p, m), - // test pub_macro_def - // pub macro m($:ident) {} - T![macro] => { - macro_def(p, m); - } - IDENT if p.at_contextual_kw("macro_rules") && p.nth(1) == BANG => { - macro_rules(p, m); - } + T![macro] => macro_def(p, m), + IDENT if p.at_contextual_kw("macro_rules") && p.nth(1) == BANG => macro_rules(p, m), T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::konst(p, m), T![static] => consts::static_(p, m), @@ -286,14 +260,15 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { Ok(()) } +// test extern_crate +// extern crate foo; fn extern_crate(p: &mut Parser, m: Marker) { - assert!(p.at(T![extern])); p.bump(T![extern]); - - assert!(p.at(T![crate])); p.bump(T![crate]); if p.at(T![self]) { + // test extern_crate_self + // extern crate self; let m = p.start(); p.bump(T![self]); m.complete(p, NAME_REF); @@ -301,11 +276,62 @@ fn extern_crate(p: &mut Parser, m: Marker) { name_ref(p); } + // test extern_crate_rename + // extern crate foo as bar; opt_rename(p); p.expect(T![;]); m.complete(p, EXTERN_CRATE); } +// test mod_item +// mod a; +pub(crate) fn mod_item(p: &mut Parser, m: Marker) { + p.bump(T![mod]); + name(p); + if p.at(T!['{']) { + // test mod_item_curly + // mod b { } + item_list(p); + } else if !p.eat(T![;]) { + p.error("expected `;` or `{`"); + } + m.complete(p, MODULE); +} + +// test type_alias +// type Foo = Bar; +fn type_alias(p: &mut Parser, m: Marker) { + p.bump(T![type]); + + name(p); + + // test type_item_type_params + // type Result<T> = (); + type_params::opt_generic_param_list(p); + + if p.at(T![:]) { + type_params::bounds(p); + } + + // test type_item_where_clause + // type Foo where Foo: Copy = (); + type_params::opt_where_clause(p); + if p.eat(T![=]) { + types::type_(p); + } + p.expect(T![;]); + m.complete(p, TYPE_ALIAS); +} + +pub(crate) fn item_list(p: &mut Parser) { + assert!(p.at(T!['{'])); + let m = p.start(); + p.bump(T!['{']); + mod_contents(p, true); + p.expect(T!['}']); + m.complete(p, ITEM_LIST); +} + pub(crate) fn extern_item_list(p: &mut Parser) { assert!(p.at(T!['{'])); let m = p.start(); @@ -347,54 +373,6 @@ fn fn_(p: &mut Parser) { } } -// test type_item -// type Foo = Bar; -fn type_alias(p: &mut Parser, m: Marker) { - assert!(p.at(T![type])); - p.bump(T![type]); - - name(p); - - // test type_item_type_params - // type Result<T> = (); - type_params::opt_generic_param_list(p); - - if p.at(T![:]) { - type_params::bounds(p); - } - - // test type_item_where_clause - // type Foo where Foo: Copy = (); - type_params::opt_where_clause(p); - if p.eat(T![=]) { - types::type_(p); - } - p.expect(T![;]); - m.complete(p, TYPE_ALIAS); -} - -pub(crate) fn mod_item(p: &mut Parser, m: Marker) { - assert!(p.at(T![mod])); - p.bump(T![mod]); - - name(p); - if p.at(T!['{']) { - item_list(p); - } else if !p.eat(T![;]) { - p.error("expected `;` or `{`"); - } - m.complete(p, MODULE); -} - -pub(crate) fn item_list(p: &mut Parser) { - assert!(p.at(T!['{'])); - let m = p.start(); - p.bump(T!['{']); - mod_contents(p, true); - p.expect(T!['}']); - m.complete(p, ITEM_LIST); -} - fn macro_rules(p: &mut Parser, m: Marker) { assert!(p.at_contextual_kw("macro_rules")); p.bump_remap(T![macro_rules]); @@ -429,16 +407,15 @@ fn macro_rules(p: &mut Parser, m: Marker) { } // test macro_def -// macro m { ($i:ident) => {} } // macro m($i:ident) {} fn macro_def(p: &mut Parser, m: Marker) { p.expect(T![macro]); name_r(p, ITEM_RECOVERY_SET); if p.at(T!['{']) { + // test macro_def_curly + // macro m { ($i:ident) => {} } token_tree(p); - } else if !p.at(T!['(']) { - p.error("unmatched `(`"); - } else { + } else if p.at(T!['(']) { let m = p.start(); token_tree(p); match p.current() { @@ -446,6 +423,8 @@ fn macro_def(p: &mut Parser, m: Marker) { _ => p.error("expected `{`, `[`, `(`"), } m.complete(p, TOKEN_TREE); + } else { + p.error("unmatched `(`"); } m.complete(p, MACRO_DEF); |