rust-analyzer/src/parser/event_parser/grammar/items.rs

94 lines
2.3 KiB
Rust
Raw Normal View History

2018-01-07 18:46:10 +00:00
use super::*;
2018-01-09 19:35:55 +00:00
pub(super) fn mod_contents(p: &mut Parser) {
attributes::inner_attributes(p);
2018-01-08 18:57:19 +00:00
many(p, |p| {
skip_to_first(
2018-01-09 19:35:55 +00:00
p, item_first, mod_contents_item,
2018-01-08 18:57:19 +00:00
"expected item",
)
});
}
fn item_first(p: &Parser) -> bool {
2018-01-07 18:46:10 +00:00
match p.current() {
2018-01-12 19:05:46 +00:00
STRUCT_KW | FN_KW | EXTERN_KW | MOD_KW | USE_KW | POUND | PUB_KW => true,
2018-01-07 18:46:10 +00:00
_ => false,
}
}
2018-01-09 19:35:55 +00:00
fn mod_contents_item(p: &mut Parser) {
2018-01-08 18:57:19 +00:00
if item(p) {
if p.current() == SEMI {
node(p, ERROR, |p| {
p.error()
.message("expected item, found `;`\n\
consider removing this semicolon")
.emit();
p.bump();
})
}
}
}
fn item(p: &mut Parser) -> bool {
2018-01-12 17:32:37 +00:00
let attrs_start = p.mark();
2018-01-07 18:46:10 +00:00
attributes::outer_attributes(p);
visibility(p);
2018-01-08 19:20:58 +00:00
// node_if(p, USE_KW, USE_ITEM, use_item)
// || extern crate_fn
// || node_if(p, STATIC_KW, STATIC_ITEM, static_item)
// || node_if(p, CONST_KW, CONST_ITEM, const_item) or const FN!
// || unsafe trait, impl
// || node_if(p, FN_KW, FN_ITEM, fn_item)
// || node_if(p, TYPE_KW, TYPE_ITEM, type_item)
2018-01-12 17:32:37 +00:00
let item_start = p.mark();
let item_parsed = node_if(p, [EXTERN_KW, CRATE_KW], EXTERN_CRATE_ITEM, extern_crate_item)
2018-01-09 19:35:55 +00:00
|| node_if(p, MOD_KW, MOD_ITEM, mod_item)
2018-01-09 20:32:18 +00:00
|| node_if(p, USE_KW, USE_ITEM, use_item)
2018-01-08 21:06:42 +00:00
|| node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item)
2018-01-12 17:32:37 +00:00
|| node_if(p, FN_KW, FN_ITEM, fn_item);
if item_parsed && attrs_start != item_start {
p.forward_parent(attrs_start, item_start);
}
item_parsed
2018-01-07 18:46:10 +00:00
}
fn struct_item(p: &mut Parser) {
p.expect(IDENT)
&& p.curly_block(|p| comma_list(p, EOF, struct_field));
}
2018-01-08 21:06:42 +00:00
fn extern_crate_item(p: &mut Parser) {
p.expect(IDENT) && alias(p) && p.expect(SEMI);
}
2018-01-09 19:35:55 +00:00
fn mod_item(p: &mut Parser) {
if !p.expect(IDENT) {
return;
}
if p.eat(SEMI) {
return;
}
p.curly_block(mod_contents);
}
2018-01-09 20:32:18 +00:00
fn use_item(p: &mut Parser) {
paths::use_path(p);
p.expect(SEMI);
}
2018-01-07 18:46:10 +00:00
fn struct_field(p: &mut Parser) -> bool {
node_if(p, IDENT, STRUCT_FIELD, |p| {
p.expect(COLON) && p.expect(IDENT);
})
}
fn fn_item(p: &mut Parser) {
p.expect(IDENT) && p.expect(L_PAREN) && p.expect(R_PAREN)
2018-01-08 19:40:14 +00:00
&& p.curly_block(|_| ());
2018-01-07 18:46:10 +00:00
}