diff options
author | Aleksey Kladov <[email protected]> | 2018-08-31 11:35:48 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-31 11:35:48 +0100 |
commit | 8fc7f438c4347e027deda5cda4bcd5e560610bb7 (patch) | |
tree | fea53412ee0462dbecc6071a85164c18bd5f9fa6 /crates | |
parent | faebae74e48e3e7e0d3dfddc5b5cf0b18535cc6b (diff) |
start item recovery
Diffstat (limited to 'crates')
-rw-r--r-- | crates/libsyntax2/src/grammar/items/mod.rs | 6 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/items/structs.rs | 4 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/items/traits.rs | 2 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/mod.rs | 8 | ||||
-rw-r--r-- | crates/libsyntax2/src/parser_api.rs | 6 | ||||
-rw-r--r-- | crates/libsyntax2/tests/data/parser/err/0020_fn_recover.rs | 3 | ||||
-rw-r--r-- | crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt | 20 |
7 files changed, 40 insertions, 9 deletions
diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index 7c6f7b63e..e672aa419 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs | |||
@@ -24,6 +24,10 @@ pub(super) enum ItemFlavor { | |||
24 | Mod, Trait | 24 | Mod, Trait |
25 | } | 25 | } |
26 | 26 | ||
27 | const ITEM_RECOVERY_SET: TokenSet = | ||
28 | token_set![FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW, | ||
29 | MOD_KW, PUB_KW, CRATE_KW]; | ||
30 | |||
27 | pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) { | 31 | pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) { |
28 | let m = p.start(); | 32 | let m = p.start(); |
29 | match maybe_item(p, flavor) { | 33 | match maybe_item(p, flavor) { |
@@ -231,7 +235,7 @@ fn fn_def(p: &mut Parser, flavor: ItemFlavor) { | |||
231 | assert!(p.at(FN_KW)); | 235 | assert!(p.at(FN_KW)); |
232 | p.bump(); | 236 | p.bump(); |
233 | 237 | ||
234 | name(p); | 238 | name_r(p, ITEM_RECOVERY_SET); |
235 | // test function_type_params | 239 | // test function_type_params |
236 | // fn foo<T: Clone + Copy>(){} | 240 | // fn foo<T: Clone + Copy>(){} |
237 | type_params::opt_type_param_list(p); | 241 | type_params::opt_type_param_list(p); |
diff --git a/crates/libsyntax2/src/grammar/items/structs.rs b/crates/libsyntax2/src/grammar/items/structs.rs index 180205393..f1e78865c 100644 --- a/crates/libsyntax2/src/grammar/items/structs.rs +++ b/crates/libsyntax2/src/grammar/items/structs.rs | |||
@@ -4,7 +4,7 @@ pub(super) fn struct_def(p: &mut Parser) { | |||
4 | assert!(p.at(STRUCT_KW)); | 4 | assert!(p.at(STRUCT_KW)); |
5 | p.bump(); | 5 | p.bump(); |
6 | 6 | ||
7 | name(p); | 7 | name_r(p, ITEM_RECOVERY_SET); |
8 | type_params::opt_type_param_list(p); | 8 | type_params::opt_type_param_list(p); |
9 | match p.current() { | 9 | match p.current() { |
10 | WHERE_KW => { | 10 | WHERE_KW => { |
@@ -41,7 +41,7 @@ pub(super) fn struct_def(p: &mut Parser) { | |||
41 | pub(super) fn enum_def(p: &mut Parser) { | 41 | pub(super) fn enum_def(p: &mut Parser) { |
42 | assert!(p.at(ENUM_KW)); | 42 | assert!(p.at(ENUM_KW)); |
43 | p.bump(); | 43 | p.bump(); |
44 | name(p); | 44 | name_r(p, ITEM_RECOVERY_SET); |
45 | type_params::opt_type_param_list(p); | 45 | type_params::opt_type_param_list(p); |
46 | type_params::opt_where_clause(p); | 46 | type_params::opt_where_clause(p); |
47 | if p.at(L_CURLY) { | 47 | if p.at(L_CURLY) { |
diff --git a/crates/libsyntax2/src/grammar/items/traits.rs b/crates/libsyntax2/src/grammar/items/traits.rs index 01b79e3c9..9d21d4d36 100644 --- a/crates/libsyntax2/src/grammar/items/traits.rs +++ b/crates/libsyntax2/src/grammar/items/traits.rs | |||
@@ -5,7 +5,7 @@ use super::*; | |||
5 | pub(super) fn trait_def(p: &mut Parser) { | 5 | pub(super) fn trait_def(p: &mut Parser) { |
6 | assert!(p.at(TRAIT_KW)); | 6 | assert!(p.at(TRAIT_KW)); |
7 | p.bump(); | 7 | p.bump(); |
8 | name(p); | 8 | name_r(p, ITEM_RECOVERY_SET); |
9 | type_params::opt_type_param_list(p); | 9 | type_params::opt_type_param_list(p); |
10 | if p.at(COLON) { | 10 | if p.at(COLON) { |
11 | type_params::bounds(p); | 11 | type_params::bounds(p); |
diff --git a/crates/libsyntax2/src/grammar/mod.rs b/crates/libsyntax2/src/grammar/mod.rs index 1acecac41..339664af3 100644 --- a/crates/libsyntax2/src/grammar/mod.rs +++ b/crates/libsyntax2/src/grammar/mod.rs | |||
@@ -129,16 +129,20 @@ fn opt_fn_ret_type(p: &mut Parser) -> bool { | |||
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | fn name(p: &mut Parser) { | 132 | fn name_r(p: &mut Parser, recovery: TokenSet) { |
133 | if p.at(IDENT) { | 133 | if p.at(IDENT) { |
134 | let m = p.start(); | 134 | let m = p.start(); |
135 | p.bump(); | 135 | p.bump(); |
136 | m.complete(p, NAME); | 136 | m.complete(p, NAME); |
137 | } else { | 137 | } else { |
138 | p.err_and_bump("expected a name"); | 138 | p.err_recover("expected a name", recovery); |
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | fn name(p: &mut Parser) { | ||
143 | name_r(p, TokenSet::EMPTY) | ||
144 | } | ||
145 | |||
142 | fn name_ref(p: &mut Parser) { | 146 | fn name_ref(p: &mut Parser) { |
143 | if p.at(IDENT) { | 147 | if p.at(IDENT) { |
144 | let m = p.start(); | 148 | let m = p.start(); |
diff --git a/crates/libsyntax2/src/parser_api.rs b/crates/libsyntax2/src/parser_api.rs index 70af474ae..9bc58e7f7 100644 --- a/crates/libsyntax2/src/parser_api.rs +++ b/crates/libsyntax2/src/parser_api.rs | |||
@@ -12,7 +12,7 @@ fn mask(kind: SyntaxKind) -> u128 { | |||
12 | } | 12 | } |
13 | 13 | ||
14 | impl TokenSet { | 14 | impl TokenSet { |
15 | const EMPTY: TokenSet = TokenSet(0); | 15 | pub const EMPTY: TokenSet = TokenSet(0); |
16 | 16 | ||
17 | pub fn contains(&self, kind: SyntaxKind) -> bool { | 17 | pub fn contains(&self, kind: SyntaxKind) -> bool { |
18 | self.0 & mask(kind) != 0 | 18 | self.0 & mask(kind) != 0 |
@@ -145,10 +145,10 @@ impl<'t> Parser<'t> { | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /// Create an error node and consume the next token. | 147 | /// Create an error node and consume the next token. |
148 | pub(crate) fn err_recover(&mut self, message: &str, recovery_set: TokenSet) { | 148 | pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) { |
149 | if self.at(SyntaxKind::L_CURLY) | 149 | if self.at(SyntaxKind::L_CURLY) |
150 | || self.at(SyntaxKind::R_CURLY) | 150 | || self.at(SyntaxKind::R_CURLY) |
151 | || recovery_set.contains(self.current()) { | 151 | || recovery.contains(self.current()) { |
152 | self.error(message); | 152 | self.error(message); |
153 | } else { | 153 | } else { |
154 | let m = self.start(); | 154 | let m = self.start(); |
diff --git a/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.rs b/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.rs new file mode 100644 index 000000000..3393b668b --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn | ||
2 | |||
3 | fn foo() {} | ||
diff --git a/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt b/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt new file mode 100644 index 000000000..b5218b0fa --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0020_fn_recover.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | ROOT@[0; 16) | ||
2 | FN_DEF@[0; 2) | ||
3 | FN_KW@[0; 2) | ||
4 | err: `expected a name` | ||
5 | err: `expected function arguments` | ||
6 | err: `expected a block` | ||
7 | WHITESPACE@[2; 4) | ||
8 | FN_DEF@[4; 15) | ||
9 | FN_KW@[4; 6) | ||
10 | WHITESPACE@[6; 7) | ||
11 | NAME@[7; 10) | ||
12 | IDENT@[7; 10) "foo" | ||
13 | PARAM_LIST@[10; 12) | ||
14 | L_PAREN@[10; 11) | ||
15 | R_PAREN@[11; 12) | ||
16 | WHITESPACE@[12; 13) | ||
17 | BLOCK@[13; 15) | ||
18 | L_CURLY@[13; 14) | ||
19 | R_CURLY@[14; 15) | ||
20 | WHITESPACE@[15; 16) | ||