start item recovery

This commit is contained in:
Aleksey Kladov 2018-08-31 13:35:48 +03:00
parent faebae74e4
commit 8fc7f438c4
7 changed files with 40 additions and 9 deletions

View File

@ -24,6 +24,10 @@ pub(super) enum ItemFlavor {
Mod, Trait
}
const ITEM_RECOVERY_SET: TokenSet =
token_set![FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW,
MOD_KW, PUB_KW, CRATE_KW];
pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) {
let m = p.start();
match maybe_item(p, flavor) {
@ -231,7 +235,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) {
assert!(p.at(FN_KW));
p.bump();
name(p);
name_r(p, ITEM_RECOVERY_SET);
// test function_type_params
// fn foo<T: Clone + Copy>(){}
type_params::opt_type_param_list(p);

View File

@ -4,7 +4,7 @@ pub(super) fn struct_def(p: &mut Parser) {
assert!(p.at(STRUCT_KW));
p.bump();
name(p);
name_r(p, ITEM_RECOVERY_SET);
type_params::opt_type_param_list(p);
match p.current() {
WHERE_KW => {
@ -41,7 +41,7 @@ pub(super) fn struct_def(p: &mut Parser) {
pub(super) fn enum_def(p: &mut Parser) {
assert!(p.at(ENUM_KW));
p.bump();
name(p);
name_r(p, ITEM_RECOVERY_SET);
type_params::opt_type_param_list(p);
type_params::opt_where_clause(p);
if p.at(L_CURLY) {

View File

@ -5,7 +5,7 @@
pub(super) fn trait_def(p: &mut Parser) {
assert!(p.at(TRAIT_KW));
p.bump();
name(p);
name_r(p, ITEM_RECOVERY_SET);
type_params::opt_type_param_list(p);
if p.at(COLON) {
type_params::bounds(p);

View File

@ -129,16 +129,20 @@ fn opt_fn_ret_type(p: &mut Parser) -> bool {
}
}
fn name(p: &mut Parser) {
fn name_r(p: &mut Parser, recovery: TokenSet) {
if p.at(IDENT) {
let m = p.start();
p.bump();
m.complete(p, NAME);
} else {
p.err_and_bump("expected a name");
p.err_recover("expected a name", recovery);
}
}
fn name(p: &mut Parser) {
name_r(p, TokenSet::EMPTY)
}
fn name_ref(p: &mut Parser) {
if p.at(IDENT) {
let m = p.start();

View File

@ -12,7 +12,7 @@ fn mask(kind: SyntaxKind) -> u128 {
}
impl TokenSet {
const EMPTY: TokenSet = TokenSet(0);
pub const EMPTY: TokenSet = TokenSet(0);
pub fn contains(&self, kind: SyntaxKind) -> bool {
self.0 & mask(kind) != 0
@ -145,10 +145,10 @@ pub(crate) fn err_and_bump(&mut self, message: &str) {
}
/// Create an error node and consume the next token.
pub(crate) fn err_recover(&mut self, message: &str, recovery_set: TokenSet) {
pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
if self.at(SyntaxKind::L_CURLY)
|| self.at(SyntaxKind::R_CURLY)
|| recovery_set.contains(self.current()) {
|| recovery.contains(self.current()) {
self.error(message);
} else {
let m = self.start();

View File

@ -0,0 +1,3 @@
fn
fn foo() {}

View File

@ -0,0 +1,20 @@
ROOT@[0; 16)
FN_DEF@[0; 2)
FN_KW@[0; 2)
err: `expected a name`
err: `expected function arguments`
err: `expected a block`
WHITESPACE@[2; 4)
FN_DEF@[4; 15)
FN_KW@[4; 6)
WHITESPACE@[6; 7)
NAME@[7; 10)
IDENT@[7; 10) "foo"
PARAM_LIST@[10; 12)
L_PAREN@[10; 11)
R_PAREN@[11; 12)
WHITESPACE@[12; 13)
BLOCK@[13; 15)
L_CURLY@[13; 14)
R_CURLY@[14; 15)
WHITESPACE@[15; 16)