start item recovery
This commit is contained in:
parent
faebae74e4
commit
8fc7f438c4
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -0,0 +1,3 @@
|
||||
fn
|
||||
|
||||
fn foo() {}
|
20
crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt
Normal file
20
crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt
Normal 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)
|
Loading…
Reference in New Issue
Block a user