diff options
Diffstat (limited to 'crates/libsyntax2/src')
-rw-r--r-- | crates/libsyntax2/src/ast/generated.rs | 78 | ||||
-rw-r--r-- | crates/libsyntax2/src/ast/mod.rs | 9 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar.ron | 10 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar/expressions/atom.rs | 5 | ||||
-rw-r--r-- | crates/libsyntax2/src/parser_api.rs | 19 |
5 files changed, 113 insertions, 8 deletions
diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index f99d1274a..6181aada8 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs | |||
@@ -439,6 +439,24 @@ impl<'a> ExprStmt<'a> { | |||
439 | } | 439 | } |
440 | } | 440 | } |
441 | 441 | ||
442 | // ExternCrateItem | ||
443 | #[derive(Debug, Clone, Copy)] | ||
444 | pub struct ExternCrateItem<'a> { | ||
445 | syntax: SyntaxNodeRef<'a>, | ||
446 | } | ||
447 | |||
448 | impl<'a> AstNode<'a> for ExternCrateItem<'a> { | ||
449 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
450 | match syntax.kind() { | ||
451 | EXTERN_CRATE_ITEM => Some(ExternCrateItem { syntax }), | ||
452 | _ => None, | ||
453 | } | ||
454 | } | ||
455 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
456 | } | ||
457 | |||
458 | impl<'a> ExternCrateItem<'a> {} | ||
459 | |||
442 | // FieldExpr | 460 | // FieldExpr |
443 | #[derive(Debug, Clone, Copy)] | 461 | #[derive(Debug, Clone, Copy)] |
444 | pub struct FieldExpr<'a> { | 462 | pub struct FieldExpr<'a> { |
@@ -839,11 +857,51 @@ impl<'a> AstNode<'a> for Module<'a> { | |||
839 | impl<'a> ast::NameOwner<'a> for Module<'a> {} | 857 | impl<'a> ast::NameOwner<'a> for Module<'a> {} |
840 | impl<'a> ast::AttrsOwner<'a> for Module<'a> {} | 858 | impl<'a> ast::AttrsOwner<'a> for Module<'a> {} |
841 | impl<'a> Module<'a> { | 859 | impl<'a> Module<'a> { |
842 | pub fn modules(self) -> impl Iterator<Item = Module<'a>> + 'a { | 860 | pub fn items(self) -> impl Iterator<Item = ModuleItem<'a>> + 'a { |
843 | super::children(self) | 861 | super::children(self) |
844 | } | 862 | } |
845 | } | 863 | } |
846 | 864 | ||
865 | // ModuleItem | ||
866 | #[derive(Debug, Clone, Copy)] | ||
867 | pub enum ModuleItem<'a> { | ||
868 | StructDef(StructDef<'a>), | ||
869 | EnumDef(EnumDef<'a>), | ||
870 | FnDef(FnDef<'a>), | ||
871 | TraitDef(TraitDef<'a>), | ||
872 | ImplItem(ImplItem<'a>), | ||
873 | UseItem(UseItem<'a>), | ||
874 | ExternCrateItem(ExternCrateItem<'a>), | ||
875 | } | ||
876 | |||
877 | impl<'a> AstNode<'a> for ModuleItem<'a> { | ||
878 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
879 | match syntax.kind() { | ||
880 | STRUCT_DEF => Some(ModuleItem::StructDef(StructDef { syntax })), | ||
881 | ENUM_DEF => Some(ModuleItem::EnumDef(EnumDef { syntax })), | ||
882 | FN_DEF => Some(ModuleItem::FnDef(FnDef { syntax })), | ||
883 | TRAIT_DEF => Some(ModuleItem::TraitDef(TraitDef { syntax })), | ||
884 | IMPL_ITEM => Some(ModuleItem::ImplItem(ImplItem { syntax })), | ||
885 | USE_ITEM => Some(ModuleItem::UseItem(UseItem { syntax })), | ||
886 | EXTERN_CRATE_ITEM => Some(ModuleItem::ExternCrateItem(ExternCrateItem { syntax })), | ||
887 | _ => None, | ||
888 | } | ||
889 | } | ||
890 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
891 | match self { | ||
892 | ModuleItem::StructDef(inner) => inner.syntax(), | ||
893 | ModuleItem::EnumDef(inner) => inner.syntax(), | ||
894 | ModuleItem::FnDef(inner) => inner.syntax(), | ||
895 | ModuleItem::TraitDef(inner) => inner.syntax(), | ||
896 | ModuleItem::ImplItem(inner) => inner.syntax(), | ||
897 | ModuleItem::UseItem(inner) => inner.syntax(), | ||
898 | ModuleItem::ExternCrateItem(inner) => inner.syntax(), | ||
899 | } | ||
900 | } | ||
901 | } | ||
902 | |||
903 | impl<'a> ModuleItem<'a> {} | ||
904 | |||
847 | // Name | 905 | // Name |
848 | #[derive(Debug, Clone, Copy)] | 906 | #[derive(Debug, Clone, Copy)] |
849 | pub struct Name<'a> { | 907 | pub struct Name<'a> { |
@@ -1762,6 +1820,24 @@ impl<'a> AstNode<'a> for TypeRef<'a> { | |||
1762 | 1820 | ||
1763 | impl<'a> TypeRef<'a> {} | 1821 | impl<'a> TypeRef<'a> {} |
1764 | 1822 | ||
1823 | // UseItem | ||
1824 | #[derive(Debug, Clone, Copy)] | ||
1825 | pub struct UseItem<'a> { | ||
1826 | syntax: SyntaxNodeRef<'a>, | ||
1827 | } | ||
1828 | |||
1829 | impl<'a> AstNode<'a> for UseItem<'a> { | ||
1830 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1831 | match syntax.kind() { | ||
1832 | USE_ITEM => Some(UseItem { syntax }), | ||
1833 | _ => None, | ||
1834 | } | ||
1835 | } | ||
1836 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1837 | } | ||
1838 | |||
1839 | impl<'a> UseItem<'a> {} | ||
1840 | |||
1765 | // WhereClause | 1841 | // WhereClause |
1766 | #[derive(Debug, Clone, Copy)] | 1842 | #[derive(Debug, Clone, Copy)] |
1767 | pub struct WhereClause<'a> { | 1843 | pub struct WhereClause<'a> { |
diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs index 2ebee6a4f..9941138a7 100644 --- a/crates/libsyntax2/src/ast/mod.rs +++ b/crates/libsyntax2/src/ast/mod.rs | |||
@@ -115,6 +115,15 @@ impl<'a> Module<'a> { | |||
115 | } | 115 | } |
116 | } | 116 | } |
117 | 117 | ||
118 | impl<'a> LetStmt<'a> { | ||
119 | pub fn has_semi(self) -> bool { | ||
120 | match self.syntax().last_child() { | ||
121 | None => false, | ||
122 | Some(node) => node.kind() == SEMI, | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
118 | impl<'a> IfExpr<'a> { | 127 | impl<'a> IfExpr<'a> { |
119 | pub fn then_branch(self) -> Option<Block<'a>> { | 128 | pub fn then_branch(self) -> Option<Block<'a>> { |
120 | self.blocks().nth(0) | 129 | self.blocks().nth(0) |
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index a98e9e2fd..7217a4633 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron | |||
@@ -273,7 +273,7 @@ Grammar( | |||
273 | "Module": ( | 273 | "Module": ( |
274 | traits: ["NameOwner", "AttrsOwner"], | 274 | traits: ["NameOwner", "AttrsOwner"], |
275 | collections: [ | 275 | collections: [ |
276 | ["modules", "Module"] | 276 | ["items", "ModuleItem"] |
277 | ] | 277 | ] |
278 | ), | 278 | ), |
279 | "ConstDef": ( traits: [ | 279 | "ConstDef": ( traits: [ |
@@ -331,6 +331,10 @@ Grammar( | |||
331 | "AttrsOwner" | 331 | "AttrsOwner" |
332 | ], | 332 | ], |
333 | ), | 333 | ), |
334 | "ModuleItem": ( | ||
335 | enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "ImplItem", | ||
336 | "UseItem", "ExternCrateItem" ] | ||
337 | ), | ||
334 | 338 | ||
335 | "TupleExpr": (), | 339 | "TupleExpr": (), |
336 | "ArrayExpr": (), | 340 | "ArrayExpr": (), |
@@ -479,6 +483,8 @@ Grammar( | |||
479 | ), | 483 | ), |
480 | "Param": ( | 484 | "Param": ( |
481 | options: [["pat", "Pat"]], | 485 | options: [["pat", "Pat"]], |
482 | ) | 486 | ), |
487 | "UseItem": (), | ||
488 | "ExternCrateItem": (), | ||
483 | }, | 489 | }, |
484 | ) | 490 | ) |
diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index ab4aa49d2..0769bb5a8 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs | |||
@@ -33,6 +33,9 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = | |||
33 | RETURN_KW, IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ], | 33 | RETURN_KW, IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ], |
34 | ]; | 34 | ]; |
35 | 35 | ||
36 | const EXPR_RECOVERY_SET: TokenSet = | ||
37 | token_set![LET_KW]; | ||
38 | |||
36 | pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | 39 | pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { |
37 | match literal(p) { | 40 | match literal(p) { |
38 | Some(m) => return Some(m), | 41 | Some(m) => return Some(m), |
@@ -73,7 +76,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMark | |||
73 | CONTINUE_KW => continue_expr(p), | 76 | CONTINUE_KW => continue_expr(p), |
74 | BREAK_KW => break_expr(p), | 77 | BREAK_KW => break_expr(p), |
75 | _ => { | 78 | _ => { |
76 | p.err_and_bump("expected expression"); | 79 | p.err_recover("expected expression", EXPR_RECOVERY_SET); |
77 | return None; | 80 | return None; |
78 | } | 81 | } |
79 | }; | 82 | }; |
diff --git a/crates/libsyntax2/src/parser_api.rs b/crates/libsyntax2/src/parser_api.rs index 0a3b29b70..10b9b64ac 100644 --- a/crates/libsyntax2/src/parser_api.rs +++ b/crates/libsyntax2/src/parser_api.rs | |||
@@ -12,6 +12,8 @@ fn mask(kind: SyntaxKind) -> u128 { | |||
12 | } | 12 | } |
13 | 13 | ||
14 | impl TokenSet { | 14 | impl TokenSet { |
15 | const EMPTY: TokenSet = TokenSet(0); | ||
16 | |||
15 | pub fn contains(&self, kind: SyntaxKind) -> bool { | 17 | pub fn contains(&self, kind: SyntaxKind) -> bool { |
16 | self.0 & mask(kind) != 0 | 18 | self.0 & mask(kind) != 0 |
17 | } | 19 | } |
@@ -139,12 +141,21 @@ impl<'t> Parser<'t> { | |||
139 | 141 | ||
140 | /// Create an error node and consume the next token. | 142 | /// Create an error node and consume the next token. |
141 | pub(crate) fn err_and_bump(&mut self, message: &str) { | 143 | pub(crate) fn err_and_bump(&mut self, message: &str) { |
142 | let m = self.start(); | 144 | self.err_recover(message, TokenSet::EMPTY); |
143 | self.error(message); | 145 | } |
144 | if !self.at(SyntaxKind::L_CURLY) && !self.at(SyntaxKind::R_CURLY) { | 146 | |
147 | /// Create an error node and consume the next token. | ||
148 | pub(crate) fn err_recover(&mut self, message: &str, recovery_set: TokenSet) { | ||
149 | if self.at(SyntaxKind::L_CURLY) | ||
150 | || self.at(SyntaxKind::R_CURLY) | ||
151 | || recovery_set.contains(self.current()) { | ||
152 | self.error(message); | ||
153 | } else { | ||
154 | let m = self.start(); | ||
155 | self.error(message); | ||
145 | self.bump(); | 156 | self.bump(); |
157 | m.complete(self, ERROR); | ||
146 | } | 158 | } |
147 | m.complete(self, ERROR); | ||
148 | } | 159 | } |
149 | } | 160 | } |
150 | 161 | ||