diff options
Diffstat (limited to 'crates/ra_syntax/src')
46 files changed, 9187 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/algo/mod.rs b/crates/ra_syntax/src/algo/mod.rs new file mode 100644 index 000000000..7287f5bb2 --- /dev/null +++ b/crates/ra_syntax/src/algo/mod.rs | |||
@@ -0,0 +1,129 @@ | |||
1 | pub mod walk; | ||
2 | pub mod visit; | ||
3 | |||
4 | use { | ||
5 | SyntaxNodeRef, TextUnit, TextRange, | ||
6 | text_utils::{contains_offset_nonstrict, is_subrange}, | ||
7 | }; | ||
8 | |||
9 | pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { | ||
10 | let range = node.range(); | ||
11 | assert!( | ||
12 | contains_offset_nonstrict(range, offset), | ||
13 | "Bad offset: range {:?} offset {:?}", range, offset | ||
14 | ); | ||
15 | if range.is_empty() { | ||
16 | return LeafAtOffset::None; | ||
17 | } | ||
18 | |||
19 | if node.is_leaf() { | ||
20 | return LeafAtOffset::Single(node); | ||
21 | } | ||
22 | |||
23 | let mut children = node.children() | ||
24 | .filter(|child| { | ||
25 | let child_range = child.range(); | ||
26 | !child_range.is_empty() && contains_offset_nonstrict(child_range, offset) | ||
27 | }); | ||
28 | |||
29 | let left = children.next().unwrap(); | ||
30 | let right = children.next(); | ||
31 | assert!(children.next().is_none()); | ||
32 | return if let Some(right) = right { | ||
33 | match (find_leaf_at_offset(left, offset), find_leaf_at_offset(right, offset)) { | ||
34 | (LeafAtOffset::Single(left), LeafAtOffset::Single(right)) => | ||
35 | LeafAtOffset::Between(left, right), | ||
36 | _ => unreachable!() | ||
37 | } | ||
38 | } else { | ||
39 | find_leaf_at_offset(left, offset) | ||
40 | }; | ||
41 | } | ||
42 | |||
43 | #[derive(Clone, Copy, Debug)] | ||
44 | pub enum LeafAtOffset<'a> { | ||
45 | None, | ||
46 | Single(SyntaxNodeRef<'a>), | ||
47 | Between(SyntaxNodeRef<'a>, SyntaxNodeRef<'a>) | ||
48 | } | ||
49 | |||
50 | impl<'a> LeafAtOffset<'a> { | ||
51 | pub fn right_biased(self) -> Option<SyntaxNodeRef<'a>> { | ||
52 | match self { | ||
53 | LeafAtOffset::None => None, | ||
54 | LeafAtOffset::Single(node) => Some(node), | ||
55 | LeafAtOffset::Between(_, right) => Some(right) | ||
56 | } | ||
57 | } | ||
58 | |||
59 | pub fn left_biased(self) -> Option<SyntaxNodeRef<'a>> { | ||
60 | match self { | ||
61 | LeafAtOffset::None => None, | ||
62 | LeafAtOffset::Single(node) => Some(node), | ||
63 | LeafAtOffset::Between(left, _) => Some(left) | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | |||
68 | impl<'f> Iterator for LeafAtOffset<'f> { | ||
69 | type Item = SyntaxNodeRef<'f>; | ||
70 | |||
71 | fn next(&mut self) -> Option<SyntaxNodeRef<'f>> { | ||
72 | match *self { | ||
73 | LeafAtOffset::None => None, | ||
74 | LeafAtOffset::Single(node) => { *self = LeafAtOffset::None; Some(node) } | ||
75 | LeafAtOffset::Between(left, right) => { *self = LeafAtOffset::Single(right); Some(left) } | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef { | ||
81 | assert!(is_subrange(root.range(), range)); | ||
82 | let (left, right) = match ( | ||
83 | find_leaf_at_offset(root, range.start()).right_biased(), | ||
84 | find_leaf_at_offset(root, range.end()).left_biased() | ||
85 | ) { | ||
86 | (Some(l), Some(r)) => (l, r), | ||
87 | _ => return root | ||
88 | }; | ||
89 | |||
90 | common_ancestor(left, right) | ||
91 | } | ||
92 | |||
93 | pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
94 | generate(Some(node), |&node| node.parent()) | ||
95 | } | ||
96 | |||
97 | #[derive(Debug)] | ||
98 | pub enum Direction { | ||
99 | Forward, | ||
100 | Backward, | ||
101 | } | ||
102 | |||
103 | pub fn siblings<'a>( | ||
104 | node: SyntaxNodeRef<'a>, | ||
105 | direction: Direction | ||
106 | ) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
107 | generate(Some(node), move |&node| match direction { | ||
108 | Direction::Forward => node.next_sibling(), | ||
109 | Direction::Backward => node.prev_sibling(), | ||
110 | }) | ||
111 | } | ||
112 | |||
113 | fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { | ||
114 | for p in ancestors(n1) { | ||
115 | if ancestors(n2).any(|a| a == p) { | ||
116 | return p; | ||
117 | } | ||
118 | } | ||
119 | panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) | ||
120 | } | ||
121 | |||
122 | pub fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item=T> { | ||
123 | ::itertools::unfold(seed, move |slot| { | ||
124 | slot.take().map(|curr| { | ||
125 | *slot = step(&curr); | ||
126 | curr | ||
127 | }) | ||
128 | }) | ||
129 | } | ||
diff --git a/crates/ra_syntax/src/algo/visit.rs b/crates/ra_syntax/src/algo/visit.rs new file mode 100644 index 000000000..9f1c127c7 --- /dev/null +++ b/crates/ra_syntax/src/algo/visit.rs | |||
@@ -0,0 +1,110 @@ | |||
1 | use std::marker::PhantomData; | ||
2 | use {SyntaxNodeRef, AstNode}; | ||
3 | |||
4 | |||
5 | pub fn visitor<'a, T>() -> impl Visitor<'a, Output=T> { | ||
6 | EmptyVisitor { ph: PhantomData } | ||
7 | } | ||
8 | |||
9 | pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output=T, Ctx=C> { | ||
10 | EmptyVisitorCtx { ph: PhantomData, ctx } | ||
11 | } | ||
12 | |||
13 | pub trait Visitor<'a>: Sized { | ||
14 | type Output; | ||
15 | fn accept(self, node: SyntaxNodeRef<'a>) -> Option<Self::Output>; | ||
16 | fn visit<N, F>(self, f: F) -> Vis<Self, N, F> | ||
17 | where N: AstNode<'a>, | ||
18 | F: FnOnce(N) -> Self::Output, | ||
19 | { | ||
20 | Vis { inner: self, f, ph: PhantomData } | ||
21 | } | ||
22 | } | ||
23 | |||
24 | pub trait VisitorCtx<'a>: Sized { | ||
25 | type Output; | ||
26 | type Ctx; | ||
27 | fn accept(self, node: SyntaxNodeRef<'a>) -> Result<Self::Output, Self::Ctx>; | ||
28 | fn visit<N, F>(self, f: F) -> VisCtx<Self, N, F> | ||
29 | where N: AstNode<'a>, | ||
30 | F: FnOnce(N, Self::Ctx) -> Self::Output, | ||
31 | { | ||
32 | VisCtx { inner: self, f, ph: PhantomData } | ||
33 | } | ||
34 | } | ||
35 | |||
36 | #[derive(Debug)] | ||
37 | struct EmptyVisitor<T> { | ||
38 | ph: PhantomData<fn() -> T> | ||
39 | } | ||
40 | |||
41 | impl<'a, T> Visitor<'a> for EmptyVisitor<T> { | ||
42 | type Output = T; | ||
43 | |||
44 | fn accept(self, _node: SyntaxNodeRef<'a>) -> Option<T> { | ||
45 | None | ||
46 | } | ||
47 | } | ||
48 | |||
49 | #[derive(Debug)] | ||
50 | struct EmptyVisitorCtx<T, C> { | ||
51 | ctx: C, | ||
52 | ph: PhantomData<fn() -> T>, | ||
53 | } | ||
54 | |||
55 | impl<'a, T, C> VisitorCtx<'a> for EmptyVisitorCtx<T, C> { | ||
56 | type Output = T; | ||
57 | type Ctx = C; | ||
58 | |||
59 | fn accept(self, _node: SyntaxNodeRef<'a>) -> Result<T, C> { | ||
60 | Err(self.ctx) | ||
61 | } | ||
62 | } | ||
63 | |||
64 | #[derive(Debug)] | ||
65 | pub struct Vis<V, N, F> { | ||
66 | inner: V, | ||
67 | f: F, | ||
68 | ph: PhantomData<fn(N)>, | ||
69 | } | ||
70 | |||
71 | impl<'a, V, N, F> Visitor<'a> for Vis<V, N, F> | ||
72 | where | ||
73 | V: Visitor<'a>, | ||
74 | N: AstNode<'a>, | ||
75 | F: FnOnce(N) -> <V as Visitor<'a>>::Output, | ||
76 | { | ||
77 | type Output = <V as Visitor<'a>>::Output; | ||
78 | |||
79 | fn accept(self, node: SyntaxNodeRef<'a>) -> Option<Self::Output> { | ||
80 | let Vis { inner, f, .. } = self; | ||
81 | inner.accept(node).or_else(|| N::cast(node).map(f)) | ||
82 | } | ||
83 | } | ||
84 | |||
85 | #[derive(Debug)] | ||
86 | pub struct VisCtx<V, N, F> { | ||
87 | inner: V, | ||
88 | f: F, | ||
89 | ph: PhantomData<fn(N)>, | ||
90 | } | ||
91 | |||
92 | impl<'a, V, N, F> VisitorCtx<'a> for VisCtx<V, N, F> | ||
93 | where | ||
94 | V: VisitorCtx<'a>, | ||
95 | N: AstNode<'a>, | ||
96 | F: FnOnce(N, <V as VisitorCtx<'a>>::Ctx) -> <V as VisitorCtx<'a>>::Output, | ||
97 | { | ||
98 | type Output = <V as VisitorCtx<'a>>::Output; | ||
99 | type Ctx = <V as VisitorCtx<'a>>::Ctx; | ||
100 | |||
101 | fn accept(self, node: SyntaxNodeRef<'a>) -> Result<Self::Output, Self::Ctx> { | ||
102 | let VisCtx { inner, f, .. } = self; | ||
103 | inner.accept(node).or_else(|ctx| | ||
104 | match N::cast(node) { | ||
105 | None => Err(ctx), | ||
106 | Some(node) => Ok(f(node, ctx)) | ||
107 | } | ||
108 | ) | ||
109 | } | ||
110 | } | ||
diff --git a/crates/ra_syntax/src/algo/walk.rs b/crates/ra_syntax/src/algo/walk.rs new file mode 100644 index 000000000..536ee705f --- /dev/null +++ b/crates/ra_syntax/src/algo/walk.rs | |||
@@ -0,0 +1,38 @@ | |||
1 | use { | ||
2 | SyntaxNodeRef, | ||
3 | algo::generate, | ||
4 | }; | ||
5 | |||
6 | pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> { | ||
7 | walk(root).filter_map(|event| match event { | ||
8 | WalkEvent::Enter(node) => Some(node), | ||
9 | WalkEvent::Exit(_) => None, | ||
10 | }) | ||
11 | } | ||
12 | |||
13 | #[derive(Debug, Copy, Clone)] | ||
14 | pub enum WalkEvent<'a> { | ||
15 | Enter(SyntaxNodeRef<'a>), | ||
16 | Exit(SyntaxNodeRef<'a>), | ||
17 | } | ||
18 | |||
19 | pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> { | ||
20 | generate(Some(WalkEvent::Enter(root)), move |pos| { | ||
21 | let next = match *pos { | ||
22 | WalkEvent::Enter(node) => match node.first_child() { | ||
23 | Some(child) => WalkEvent::Enter(child), | ||
24 | None => WalkEvent::Exit(node), | ||
25 | }, | ||
26 | WalkEvent::Exit(node) => { | ||
27 | if node == root { | ||
28 | return None; | ||
29 | } | ||
30 | match node.next_sibling() { | ||
31 | Some(sibling) => WalkEvent::Enter(sibling), | ||
32 | None => WalkEvent::Exit(node.parent().unwrap()), | ||
33 | } | ||
34 | } | ||
35 | }; | ||
36 | Some(next) | ||
37 | }) | ||
38 | } | ||
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs new file mode 100644 index 000000000..c945c094a --- /dev/null +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -0,0 +1,2142 @@ | |||
1 | use { | ||
2 | ast, | ||
3 | SyntaxNodeRef, AstNode, | ||
4 | SyntaxKind::*, | ||
5 | }; | ||
6 | |||
7 | // ArgList | ||
8 | #[derive(Debug, Clone, Copy)] | ||
9 | pub struct ArgList<'a> { | ||
10 | syntax: SyntaxNodeRef<'a>, | ||
11 | } | ||
12 | |||
13 | impl<'a> AstNode<'a> for ArgList<'a> { | ||
14 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
15 | match syntax.kind() { | ||
16 | ARG_LIST => Some(ArgList { syntax }), | ||
17 | _ => None, | ||
18 | } | ||
19 | } | ||
20 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
21 | } | ||
22 | |||
23 | impl<'a> ArgList<'a> { | ||
24 | pub fn args(self) -> impl Iterator<Item = Expr<'a>> + 'a { | ||
25 | super::children(self) | ||
26 | } | ||
27 | } | ||
28 | |||
29 | // ArrayExpr | ||
30 | #[derive(Debug, Clone, Copy)] | ||
31 | pub struct ArrayExpr<'a> { | ||
32 | syntax: SyntaxNodeRef<'a>, | ||
33 | } | ||
34 | |||
35 | impl<'a> AstNode<'a> for ArrayExpr<'a> { | ||
36 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
37 | match syntax.kind() { | ||
38 | ARRAY_EXPR => Some(ArrayExpr { syntax }), | ||
39 | _ => None, | ||
40 | } | ||
41 | } | ||
42 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
43 | } | ||
44 | |||
45 | impl<'a> ArrayExpr<'a> {} | ||
46 | |||
47 | // ArrayType | ||
48 | #[derive(Debug, Clone, Copy)] | ||
49 | pub struct ArrayType<'a> { | ||
50 | syntax: SyntaxNodeRef<'a>, | ||
51 | } | ||
52 | |||
53 | impl<'a> AstNode<'a> for ArrayType<'a> { | ||
54 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
55 | match syntax.kind() { | ||
56 | ARRAY_TYPE => Some(ArrayType { syntax }), | ||
57 | _ => None, | ||
58 | } | ||
59 | } | ||
60 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
61 | } | ||
62 | |||
63 | impl<'a> ArrayType<'a> {} | ||
64 | |||
65 | // Attr | ||
66 | #[derive(Debug, Clone, Copy)] | ||
67 | pub struct Attr<'a> { | ||
68 | syntax: SyntaxNodeRef<'a>, | ||
69 | } | ||
70 | |||
71 | impl<'a> AstNode<'a> for Attr<'a> { | ||
72 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
73 | match syntax.kind() { | ||
74 | ATTR => Some(Attr { syntax }), | ||
75 | _ => None, | ||
76 | } | ||
77 | } | ||
78 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
79 | } | ||
80 | |||
81 | impl<'a> Attr<'a> {pub fn value(self) -> Option<TokenTree<'a>> { | ||
82 | super::child_opt(self) | ||
83 | } | ||
84 | } | ||
85 | |||
86 | // BinExpr | ||
87 | #[derive(Debug, Clone, Copy)] | ||
88 | pub struct BinExpr<'a> { | ||
89 | syntax: SyntaxNodeRef<'a>, | ||
90 | } | ||
91 | |||
92 | impl<'a> AstNode<'a> for BinExpr<'a> { | ||
93 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
94 | match syntax.kind() { | ||
95 | BIN_EXPR => Some(BinExpr { syntax }), | ||
96 | _ => None, | ||
97 | } | ||
98 | } | ||
99 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
100 | } | ||
101 | |||
102 | impl<'a> BinExpr<'a> {} | ||
103 | |||
104 | // BindPat | ||
105 | #[derive(Debug, Clone, Copy)] | ||
106 | pub struct BindPat<'a> { | ||
107 | syntax: SyntaxNodeRef<'a>, | ||
108 | } | ||
109 | |||
110 | impl<'a> AstNode<'a> for BindPat<'a> { | ||
111 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
112 | match syntax.kind() { | ||
113 | BIND_PAT => Some(BindPat { syntax }), | ||
114 | _ => None, | ||
115 | } | ||
116 | } | ||
117 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
118 | } | ||
119 | |||
120 | impl<'a> ast::NameOwner<'a> for BindPat<'a> {} | ||
121 | impl<'a> BindPat<'a> {} | ||
122 | |||
123 | // Block | ||
124 | #[derive(Debug, Clone, Copy)] | ||
125 | pub struct Block<'a> { | ||
126 | syntax: SyntaxNodeRef<'a>, | ||
127 | } | ||
128 | |||
129 | impl<'a> AstNode<'a> for Block<'a> { | ||
130 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
131 | match syntax.kind() { | ||
132 | BLOCK => Some(Block { syntax }), | ||
133 | _ => None, | ||
134 | } | ||
135 | } | ||
136 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
137 | } | ||
138 | |||
139 | impl<'a> Block<'a> { | ||
140 | pub fn statements(self) -> impl Iterator<Item = Stmt<'a>> + 'a { | ||
141 | super::children(self) | ||
142 | } | ||
143 | pub fn expr(self) -> Option<Expr<'a>> { | ||
144 | super::child_opt(self) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | // BlockExpr | ||
149 | #[derive(Debug, Clone, Copy)] | ||
150 | pub struct BlockExpr<'a> { | ||
151 | syntax: SyntaxNodeRef<'a>, | ||
152 | } | ||
153 | |||
154 | impl<'a> AstNode<'a> for BlockExpr<'a> { | ||
155 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
156 | match syntax.kind() { | ||
157 | BLOCK_EXPR => Some(BlockExpr { syntax }), | ||
158 | _ => None, | ||
159 | } | ||
160 | } | ||
161 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
162 | } | ||
163 | |||
164 | impl<'a> BlockExpr<'a> {pub fn block(self) -> Option<Block<'a>> { | ||
165 | super::child_opt(self) | ||
166 | } | ||
167 | } | ||
168 | |||
169 | // BreakExpr | ||
170 | #[derive(Debug, Clone, Copy)] | ||
171 | pub struct BreakExpr<'a> { | ||
172 | syntax: SyntaxNodeRef<'a>, | ||
173 | } | ||
174 | |||
175 | impl<'a> AstNode<'a> for BreakExpr<'a> { | ||
176 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
177 | match syntax.kind() { | ||
178 | BREAK_EXPR => Some(BreakExpr { syntax }), | ||
179 | _ => None, | ||
180 | } | ||
181 | } | ||
182 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
183 | } | ||
184 | |||
185 | impl<'a> BreakExpr<'a> {} | ||
186 | |||
187 | // CallExpr | ||
188 | #[derive(Debug, Clone, Copy)] | ||
189 | pub struct CallExpr<'a> { | ||
190 | syntax: SyntaxNodeRef<'a>, | ||
191 | } | ||
192 | |||
193 | impl<'a> AstNode<'a> for CallExpr<'a> { | ||
194 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
195 | match syntax.kind() { | ||
196 | CALL_EXPR => Some(CallExpr { syntax }), | ||
197 | _ => None, | ||
198 | } | ||
199 | } | ||
200 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
201 | } | ||
202 | |||
203 | impl<'a> ast::ArgListOwner<'a> for CallExpr<'a> {} | ||
204 | impl<'a> CallExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> { | ||
205 | super::child_opt(self) | ||
206 | } | ||
207 | } | ||
208 | |||
209 | // CastExpr | ||
210 | #[derive(Debug, Clone, Copy)] | ||
211 | pub struct CastExpr<'a> { | ||
212 | syntax: SyntaxNodeRef<'a>, | ||
213 | } | ||
214 | |||
215 | impl<'a> AstNode<'a> for CastExpr<'a> { | ||
216 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
217 | match syntax.kind() { | ||
218 | CAST_EXPR => Some(CastExpr { syntax }), | ||
219 | _ => None, | ||
220 | } | ||
221 | } | ||
222 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
223 | } | ||
224 | |||
225 | impl<'a> CastExpr<'a> {} | ||
226 | |||
227 | // Condition | ||
228 | #[derive(Debug, Clone, Copy)] | ||
229 | pub struct Condition<'a> { | ||
230 | syntax: SyntaxNodeRef<'a>, | ||
231 | } | ||
232 | |||
233 | impl<'a> AstNode<'a> for Condition<'a> { | ||
234 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
235 | match syntax.kind() { | ||
236 | CONDITION => Some(Condition { syntax }), | ||
237 | _ => None, | ||
238 | } | ||
239 | } | ||
240 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
241 | } | ||
242 | |||
243 | impl<'a> Condition<'a> {pub fn pat(self) -> Option<Pat<'a>> { | ||
244 | super::child_opt(self) | ||
245 | } | ||
246 | pub fn expr(self) -> Option<Expr<'a>> { | ||
247 | super::child_opt(self) | ||
248 | } | ||
249 | } | ||
250 | |||
251 | // ConstDef | ||
252 | #[derive(Debug, Clone, Copy)] | ||
253 | pub struct ConstDef<'a> { | ||
254 | syntax: SyntaxNodeRef<'a>, | ||
255 | } | ||
256 | |||
257 | impl<'a> AstNode<'a> for ConstDef<'a> { | ||
258 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
259 | match syntax.kind() { | ||
260 | CONST_DEF => Some(ConstDef { syntax }), | ||
261 | _ => None, | ||
262 | } | ||
263 | } | ||
264 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
265 | } | ||
266 | |||
267 | impl<'a> ast::NameOwner<'a> for ConstDef<'a> {} | ||
268 | impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {} | ||
269 | impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {} | ||
270 | impl<'a> ConstDef<'a> {} | ||
271 | |||
272 | // ContinueExpr | ||
273 | #[derive(Debug, Clone, Copy)] | ||
274 | pub struct ContinueExpr<'a> { | ||
275 | syntax: SyntaxNodeRef<'a>, | ||
276 | } | ||
277 | |||
278 | impl<'a> AstNode<'a> for ContinueExpr<'a> { | ||
279 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
280 | match syntax.kind() { | ||
281 | CONTINUE_EXPR => Some(ContinueExpr { syntax }), | ||
282 | _ => None, | ||
283 | } | ||
284 | } | ||
285 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
286 | } | ||
287 | |||
288 | impl<'a> ContinueExpr<'a> {} | ||
289 | |||
290 | // DynTraitType | ||
291 | #[derive(Debug, Clone, Copy)] | ||
292 | pub struct DynTraitType<'a> { | ||
293 | syntax: SyntaxNodeRef<'a>, | ||
294 | } | ||
295 | |||
296 | impl<'a> AstNode<'a> for DynTraitType<'a> { | ||
297 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
298 | match syntax.kind() { | ||
299 | DYN_TRAIT_TYPE => Some(DynTraitType { syntax }), | ||
300 | _ => None, | ||
301 | } | ||
302 | } | ||
303 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
304 | } | ||
305 | |||
306 | impl<'a> DynTraitType<'a> {} | ||
307 | |||
308 | // EnumDef | ||
309 | #[derive(Debug, Clone, Copy)] | ||
310 | pub struct EnumDef<'a> { | ||
311 | syntax: SyntaxNodeRef<'a>, | ||
312 | } | ||
313 | |||
314 | impl<'a> AstNode<'a> for EnumDef<'a> { | ||
315 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
316 | match syntax.kind() { | ||
317 | ENUM_DEF => Some(EnumDef { syntax }), | ||
318 | _ => None, | ||
319 | } | ||
320 | } | ||
321 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
322 | } | ||
323 | |||
324 | impl<'a> ast::NameOwner<'a> for EnumDef<'a> {} | ||
325 | impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} | ||
326 | impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} | ||
327 | impl<'a> EnumDef<'a> {} | ||
328 | |||
329 | // Expr | ||
330 | #[derive(Debug, Clone, Copy)] | ||
331 | pub enum Expr<'a> { | ||
332 | TupleExpr(TupleExpr<'a>), | ||
333 | ArrayExpr(ArrayExpr<'a>), | ||
334 | ParenExpr(ParenExpr<'a>), | ||
335 | PathExpr(PathExpr<'a>), | ||
336 | LambdaExpr(LambdaExpr<'a>), | ||
337 | IfExpr(IfExpr<'a>), | ||
338 | LoopExpr(LoopExpr<'a>), | ||
339 | ForExpr(ForExpr<'a>), | ||
340 | WhileExpr(WhileExpr<'a>), | ||
341 | ContinueExpr(ContinueExpr<'a>), | ||
342 | BreakExpr(BreakExpr<'a>), | ||
343 | Label(Label<'a>), | ||
344 | BlockExpr(BlockExpr<'a>), | ||
345 | ReturnExpr(ReturnExpr<'a>), | ||
346 | MatchExpr(MatchExpr<'a>), | ||
347 | MatchArmList(MatchArmList<'a>), | ||
348 | MatchArm(MatchArm<'a>), | ||
349 | MatchGuard(MatchGuard<'a>), | ||
350 | StructLit(StructLit<'a>), | ||
351 | NamedFieldList(NamedFieldList<'a>), | ||
352 | NamedField(NamedField<'a>), | ||
353 | CallExpr(CallExpr<'a>), | ||
354 | IndexExpr(IndexExpr<'a>), | ||
355 | MethodCallExpr(MethodCallExpr<'a>), | ||
356 | FieldExpr(FieldExpr<'a>), | ||
357 | TryExpr(TryExpr<'a>), | ||
358 | CastExpr(CastExpr<'a>), | ||
359 | RefExpr(RefExpr<'a>), | ||
360 | PrefixExpr(PrefixExpr<'a>), | ||
361 | RangeExpr(RangeExpr<'a>), | ||
362 | BinExpr(BinExpr<'a>), | ||
363 | Literal(Literal<'a>), | ||
364 | } | ||
365 | |||
366 | impl<'a> AstNode<'a> for Expr<'a> { | ||
367 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
368 | match syntax.kind() { | ||
369 | TUPLE_EXPR => Some(Expr::TupleExpr(TupleExpr { syntax })), | ||
370 | ARRAY_EXPR => Some(Expr::ArrayExpr(ArrayExpr { syntax })), | ||
371 | PAREN_EXPR => Some(Expr::ParenExpr(ParenExpr { syntax })), | ||
372 | PATH_EXPR => Some(Expr::PathExpr(PathExpr { syntax })), | ||
373 | LAMBDA_EXPR => Some(Expr::LambdaExpr(LambdaExpr { syntax })), | ||
374 | IF_EXPR => Some(Expr::IfExpr(IfExpr { syntax })), | ||
375 | LOOP_EXPR => Some(Expr::LoopExpr(LoopExpr { syntax })), | ||
376 | FOR_EXPR => Some(Expr::ForExpr(ForExpr { syntax })), | ||
377 | WHILE_EXPR => Some(Expr::WhileExpr(WhileExpr { syntax })), | ||
378 | CONTINUE_EXPR => Some(Expr::ContinueExpr(ContinueExpr { syntax })), | ||
379 | BREAK_EXPR => Some(Expr::BreakExpr(BreakExpr { syntax })), | ||
380 | LABEL => Some(Expr::Label(Label { syntax })), | ||
381 | BLOCK_EXPR => Some(Expr::BlockExpr(BlockExpr { syntax })), | ||
382 | RETURN_EXPR => Some(Expr::ReturnExpr(ReturnExpr { syntax })), | ||
383 | MATCH_EXPR => Some(Expr::MatchExpr(MatchExpr { syntax })), | ||
384 | MATCH_ARM_LIST => Some(Expr::MatchArmList(MatchArmList { syntax })), | ||
385 | MATCH_ARM => Some(Expr::MatchArm(MatchArm { syntax })), | ||
386 | MATCH_GUARD => Some(Expr::MatchGuard(MatchGuard { syntax })), | ||
387 | STRUCT_LIT => Some(Expr::StructLit(StructLit { syntax })), | ||
388 | NAMED_FIELD_LIST => Some(Expr::NamedFieldList(NamedFieldList { syntax })), | ||
389 | NAMED_FIELD => Some(Expr::NamedField(NamedField { syntax })), | ||
390 | CALL_EXPR => Some(Expr::CallExpr(CallExpr { syntax })), | ||
391 | INDEX_EXPR => Some(Expr::IndexExpr(IndexExpr { syntax })), | ||
392 | METHOD_CALL_EXPR => Some(Expr::MethodCallExpr(MethodCallExpr { syntax })), | ||
393 | FIELD_EXPR => Some(Expr::FieldExpr(FieldExpr { syntax })), | ||
394 | TRY_EXPR => Some(Expr::TryExpr(TryExpr { syntax })), | ||
395 | CAST_EXPR => Some(Expr::CastExpr(CastExpr { syntax })), | ||
396 | REF_EXPR => Some(Expr::RefExpr(RefExpr { syntax })), | ||
397 | PREFIX_EXPR => Some(Expr::PrefixExpr(PrefixExpr { syntax })), | ||
398 | RANGE_EXPR => Some(Expr::RangeExpr(RangeExpr { syntax })), | ||
399 | BIN_EXPR => Some(Expr::BinExpr(BinExpr { syntax })), | ||
400 | LITERAL => Some(Expr::Literal(Literal { syntax })), | ||
401 | _ => None, | ||
402 | } | ||
403 | } | ||
404 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
405 | match self { | ||
406 | Expr::TupleExpr(inner) => inner.syntax(), | ||
407 | Expr::ArrayExpr(inner) => inner.syntax(), | ||
408 | Expr::ParenExpr(inner) => inner.syntax(), | ||
409 | Expr::PathExpr(inner) => inner.syntax(), | ||
410 | Expr::LambdaExpr(inner) => inner.syntax(), | ||
411 | Expr::IfExpr(inner) => inner.syntax(), | ||
412 | Expr::LoopExpr(inner) => inner.syntax(), | ||
413 | Expr::ForExpr(inner) => inner.syntax(), | ||
414 | Expr::WhileExpr(inner) => inner.syntax(), | ||
415 | Expr::ContinueExpr(inner) => inner.syntax(), | ||
416 | Expr::BreakExpr(inner) => inner.syntax(), | ||
417 | Expr::Label(inner) => inner.syntax(), | ||
418 | Expr::BlockExpr(inner) => inner.syntax(), | ||
419 | Expr::ReturnExpr(inner) => inner.syntax(), | ||
420 | Expr::MatchExpr(inner) => inner.syntax(), | ||
421 | Expr::MatchArmList(inner) => inner.syntax(), | ||
422 | Expr::MatchArm(inner) => inner.syntax(), | ||
423 | Expr::MatchGuard(inner) => inner.syntax(), | ||
424 | Expr::StructLit(inner) => inner.syntax(), | ||
425 | Expr::NamedFieldList(inner) => inner.syntax(), | ||
426 | Expr::NamedField(inner) => inner.syntax(), | ||
427 | Expr::CallExpr(inner) => inner.syntax(), | ||
428 | Expr::IndexExpr(inner) => inner.syntax(), | ||
429 | Expr::MethodCallExpr(inner) => inner.syntax(), | ||
430 | Expr::FieldExpr(inner) => inner.syntax(), | ||
431 | Expr::TryExpr(inner) => inner.syntax(), | ||
432 | Expr::CastExpr(inner) => inner.syntax(), | ||
433 | Expr::RefExpr(inner) => inner.syntax(), | ||
434 | Expr::PrefixExpr(inner) => inner.syntax(), | ||
435 | Expr::RangeExpr(inner) => inner.syntax(), | ||
436 | Expr::BinExpr(inner) => inner.syntax(), | ||
437 | Expr::Literal(inner) => inner.syntax(), | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | |||
442 | impl<'a> Expr<'a> {} | ||
443 | |||
444 | // ExprStmt | ||
445 | #[derive(Debug, Clone, Copy)] | ||
446 | pub struct ExprStmt<'a> { | ||
447 | syntax: SyntaxNodeRef<'a>, | ||
448 | } | ||
449 | |||
450 | impl<'a> AstNode<'a> for ExprStmt<'a> { | ||
451 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
452 | match syntax.kind() { | ||
453 | EXPR_STMT => Some(ExprStmt { syntax }), | ||
454 | _ => None, | ||
455 | } | ||
456 | } | ||
457 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
458 | } | ||
459 | |||
460 | impl<'a> ExprStmt<'a> {pub fn expr(self) -> Option<Expr<'a>> { | ||
461 | super::child_opt(self) | ||
462 | } | ||
463 | } | ||
464 | |||
465 | // ExternCrateItem | ||
466 | #[derive(Debug, Clone, Copy)] | ||
467 | pub struct ExternCrateItem<'a> { | ||
468 | syntax: SyntaxNodeRef<'a>, | ||
469 | } | ||
470 | |||
471 | impl<'a> AstNode<'a> for ExternCrateItem<'a> { | ||
472 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
473 | match syntax.kind() { | ||
474 | EXTERN_CRATE_ITEM => Some(ExternCrateItem { syntax }), | ||
475 | _ => None, | ||
476 | } | ||
477 | } | ||
478 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
479 | } | ||
480 | |||
481 | impl<'a> ExternCrateItem<'a> {} | ||
482 | |||
483 | // FieldExpr | ||
484 | #[derive(Debug, Clone, Copy)] | ||
485 | pub struct FieldExpr<'a> { | ||
486 | syntax: SyntaxNodeRef<'a>, | ||
487 | } | ||
488 | |||
489 | impl<'a> AstNode<'a> for FieldExpr<'a> { | ||
490 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
491 | match syntax.kind() { | ||
492 | FIELD_EXPR => Some(FieldExpr { syntax }), | ||
493 | _ => None, | ||
494 | } | ||
495 | } | ||
496 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
497 | } | ||
498 | |||
499 | impl<'a> FieldExpr<'a> {} | ||
500 | |||
501 | // FieldPatList | ||
502 | #[derive(Debug, Clone, Copy)] | ||
503 | pub struct FieldPatList<'a> { | ||
504 | syntax: SyntaxNodeRef<'a>, | ||
505 | } | ||
506 | |||
507 | impl<'a> AstNode<'a> for FieldPatList<'a> { | ||
508 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
509 | match syntax.kind() { | ||
510 | FIELD_PAT_LIST => Some(FieldPatList { syntax }), | ||
511 | _ => None, | ||
512 | } | ||
513 | } | ||
514 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
515 | } | ||
516 | |||
517 | impl<'a> FieldPatList<'a> {} | ||
518 | |||
519 | // FnDef | ||
520 | #[derive(Debug, Clone, Copy)] | ||
521 | pub struct FnDef<'a> { | ||
522 | syntax: SyntaxNodeRef<'a>, | ||
523 | } | ||
524 | |||
525 | impl<'a> AstNode<'a> for FnDef<'a> { | ||
526 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
527 | match syntax.kind() { | ||
528 | FN_DEF => Some(FnDef { syntax }), | ||
529 | _ => None, | ||
530 | } | ||
531 | } | ||
532 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
533 | } | ||
534 | |||
535 | impl<'a> ast::NameOwner<'a> for FnDef<'a> {} | ||
536 | impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {} | ||
537 | impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {} | ||
538 | impl<'a> FnDef<'a> {pub fn param_list(self) -> Option<ParamList<'a>> { | ||
539 | super::child_opt(self) | ||
540 | } | ||
541 | pub fn body(self) -> Option<Block<'a>> { | ||
542 | super::child_opt(self) | ||
543 | } | ||
544 | pub fn ret_type(self) -> Option<RetType<'a>> { | ||
545 | super::child_opt(self) | ||
546 | } | ||
547 | } | ||
548 | |||
549 | // FnPointerType | ||
550 | #[derive(Debug, Clone, Copy)] | ||
551 | pub struct FnPointerType<'a> { | ||
552 | syntax: SyntaxNodeRef<'a>, | ||
553 | } | ||
554 | |||
555 | impl<'a> AstNode<'a> for FnPointerType<'a> { | ||
556 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
557 | match syntax.kind() { | ||
558 | FN_POINTER_TYPE => Some(FnPointerType { syntax }), | ||
559 | _ => None, | ||
560 | } | ||
561 | } | ||
562 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
563 | } | ||
564 | |||
565 | impl<'a> FnPointerType<'a> {} | ||
566 | |||
567 | // ForExpr | ||
568 | #[derive(Debug, Clone, Copy)] | ||
569 | pub struct ForExpr<'a> { | ||
570 | syntax: SyntaxNodeRef<'a>, | ||
571 | } | ||
572 | |||
573 | impl<'a> AstNode<'a> for ForExpr<'a> { | ||
574 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
575 | match syntax.kind() { | ||
576 | FOR_EXPR => Some(ForExpr { syntax }), | ||
577 | _ => None, | ||
578 | } | ||
579 | } | ||
580 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
581 | } | ||
582 | |||
583 | impl<'a> ast::LoopBodyOwner<'a> for ForExpr<'a> {} | ||
584 | impl<'a> ForExpr<'a> {pub fn pat(self) -> Option<Pat<'a>> { | ||
585 | super::child_opt(self) | ||
586 | } | ||
587 | pub fn iterable(self) -> Option<Expr<'a>> { | ||
588 | super::child_opt(self) | ||
589 | } | ||
590 | } | ||
591 | |||
592 | // ForType | ||
593 | #[derive(Debug, Clone, Copy)] | ||
594 | pub struct ForType<'a> { | ||
595 | syntax: SyntaxNodeRef<'a>, | ||
596 | } | ||
597 | |||
598 | impl<'a> AstNode<'a> for ForType<'a> { | ||
599 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
600 | match syntax.kind() { | ||
601 | FOR_TYPE => Some(ForType { syntax }), | ||
602 | _ => None, | ||
603 | } | ||
604 | } | ||
605 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
606 | } | ||
607 | |||
608 | impl<'a> ForType<'a> {} | ||
609 | |||
610 | // IfExpr | ||
611 | #[derive(Debug, Clone, Copy)] | ||
612 | pub struct IfExpr<'a> { | ||
613 | syntax: SyntaxNodeRef<'a>, | ||
614 | } | ||
615 | |||
616 | impl<'a> AstNode<'a> for IfExpr<'a> { | ||
617 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
618 | match syntax.kind() { | ||
619 | IF_EXPR => Some(IfExpr { syntax }), | ||
620 | _ => None, | ||
621 | } | ||
622 | } | ||
623 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
624 | } | ||
625 | |||
626 | impl<'a> IfExpr<'a> {pub fn condition(self) -> Option<Condition<'a>> { | ||
627 | super::child_opt(self) | ||
628 | } | ||
629 | } | ||
630 | |||
631 | // ImplItem | ||
632 | #[derive(Debug, Clone, Copy)] | ||
633 | pub struct ImplItem<'a> { | ||
634 | syntax: SyntaxNodeRef<'a>, | ||
635 | } | ||
636 | |||
637 | impl<'a> AstNode<'a> for ImplItem<'a> { | ||
638 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
639 | match syntax.kind() { | ||
640 | IMPL_ITEM => Some(ImplItem { syntax }), | ||
641 | _ => None, | ||
642 | } | ||
643 | } | ||
644 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
645 | } | ||
646 | |||
647 | impl<'a> ImplItem<'a> {} | ||
648 | |||
649 | // ImplTraitType | ||
650 | #[derive(Debug, Clone, Copy)] | ||
651 | pub struct ImplTraitType<'a> { | ||
652 | syntax: SyntaxNodeRef<'a>, | ||
653 | } | ||
654 | |||
655 | impl<'a> AstNode<'a> for ImplTraitType<'a> { | ||
656 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
657 | match syntax.kind() { | ||
658 | IMPL_TRAIT_TYPE => Some(ImplTraitType { syntax }), | ||
659 | _ => None, | ||
660 | } | ||
661 | } | ||
662 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
663 | } | ||
664 | |||
665 | impl<'a> ImplTraitType<'a> {} | ||
666 | |||
667 | // IndexExpr | ||
668 | #[derive(Debug, Clone, Copy)] | ||
669 | pub struct IndexExpr<'a> { | ||
670 | syntax: SyntaxNodeRef<'a>, | ||
671 | } | ||
672 | |||
673 | impl<'a> AstNode<'a> for IndexExpr<'a> { | ||
674 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
675 | match syntax.kind() { | ||
676 | INDEX_EXPR => Some(IndexExpr { syntax }), | ||
677 | _ => None, | ||
678 | } | ||
679 | } | ||
680 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
681 | } | ||
682 | |||
683 | impl<'a> IndexExpr<'a> {} | ||
684 | |||
685 | // ItemList | ||
686 | #[derive(Debug, Clone, Copy)] | ||
687 | pub struct ItemList<'a> { | ||
688 | syntax: SyntaxNodeRef<'a>, | ||
689 | } | ||
690 | |||
691 | impl<'a> AstNode<'a> for ItemList<'a> { | ||
692 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
693 | match syntax.kind() { | ||
694 | ITEM_LIST => Some(ItemList { syntax }), | ||
695 | _ => None, | ||
696 | } | ||
697 | } | ||
698 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
699 | } | ||
700 | |||
701 | impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} | ||
702 | impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {} | ||
703 | impl<'a> ItemList<'a> {} | ||
704 | |||
705 | // Label | ||
706 | #[derive(Debug, Clone, Copy)] | ||
707 | pub struct Label<'a> { | ||
708 | syntax: SyntaxNodeRef<'a>, | ||
709 | } | ||
710 | |||
711 | impl<'a> AstNode<'a> for Label<'a> { | ||
712 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
713 | match syntax.kind() { | ||
714 | LABEL => Some(Label { syntax }), | ||
715 | _ => None, | ||
716 | } | ||
717 | } | ||
718 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
719 | } | ||
720 | |||
721 | impl<'a> Label<'a> {} | ||
722 | |||
723 | // LambdaExpr | ||
724 | #[derive(Debug, Clone, Copy)] | ||
725 | pub struct LambdaExpr<'a> { | ||
726 | syntax: SyntaxNodeRef<'a>, | ||
727 | } | ||
728 | |||
729 | impl<'a> AstNode<'a> for LambdaExpr<'a> { | ||
730 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
731 | match syntax.kind() { | ||
732 | LAMBDA_EXPR => Some(LambdaExpr { syntax }), | ||
733 | _ => None, | ||
734 | } | ||
735 | } | ||
736 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
737 | } | ||
738 | |||
739 | impl<'a> LambdaExpr<'a> {pub fn param_list(self) -> Option<ParamList<'a>> { | ||
740 | super::child_opt(self) | ||
741 | } | ||
742 | pub fn body(self) -> Option<Expr<'a>> { | ||
743 | super::child_opt(self) | ||
744 | } | ||
745 | } | ||
746 | |||
747 | // LetStmt | ||
748 | #[derive(Debug, Clone, Copy)] | ||
749 | pub struct LetStmt<'a> { | ||
750 | syntax: SyntaxNodeRef<'a>, | ||
751 | } | ||
752 | |||
753 | impl<'a> AstNode<'a> for LetStmt<'a> { | ||
754 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
755 | match syntax.kind() { | ||
756 | LET_STMT => Some(LetStmt { syntax }), | ||
757 | _ => None, | ||
758 | } | ||
759 | } | ||
760 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
761 | } | ||
762 | |||
763 | impl<'a> LetStmt<'a> {pub fn pat(self) -> Option<Pat<'a>> { | ||
764 | super::child_opt(self) | ||
765 | } | ||
766 | pub fn initializer(self) -> Option<Expr<'a>> { | ||
767 | super::child_opt(self) | ||
768 | } | ||
769 | } | ||
770 | |||
771 | // Lifetime | ||
772 | #[derive(Debug, Clone, Copy)] | ||
773 | pub struct Lifetime<'a> { | ||
774 | syntax: SyntaxNodeRef<'a>, | ||
775 | } | ||
776 | |||
777 | impl<'a> AstNode<'a> for Lifetime<'a> { | ||
778 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
779 | match syntax.kind() { | ||
780 | LIFETIME => Some(Lifetime { syntax }), | ||
781 | _ => None, | ||
782 | } | ||
783 | } | ||
784 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
785 | } | ||
786 | |||
787 | impl<'a> Lifetime<'a> {} | ||
788 | |||
789 | // LifetimeParam | ||
790 | #[derive(Debug, Clone, Copy)] | ||
791 | pub struct LifetimeParam<'a> { | ||
792 | syntax: SyntaxNodeRef<'a>, | ||
793 | } | ||
794 | |||
795 | impl<'a> AstNode<'a> for LifetimeParam<'a> { | ||
796 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
797 | match syntax.kind() { | ||
798 | LIFETIME_PARAM => Some(LifetimeParam { syntax }), | ||
799 | _ => None, | ||
800 | } | ||
801 | } | ||
802 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
803 | } | ||
804 | |||
805 | impl<'a> LifetimeParam<'a> {pub fn lifetime(self) -> Option<Lifetime<'a>> { | ||
806 | super::child_opt(self) | ||
807 | } | ||
808 | } | ||
809 | |||
810 | // Literal | ||
811 | #[derive(Debug, Clone, Copy)] | ||
812 | pub struct Literal<'a> { | ||
813 | syntax: SyntaxNodeRef<'a>, | ||
814 | } | ||
815 | |||
816 | impl<'a> AstNode<'a> for Literal<'a> { | ||
817 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
818 | match syntax.kind() { | ||
819 | LITERAL => Some(Literal { syntax }), | ||
820 | _ => None, | ||
821 | } | ||
822 | } | ||
823 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
824 | } | ||
825 | |||
826 | impl<'a> Literal<'a> {} | ||
827 | |||
828 | // LoopExpr | ||
829 | #[derive(Debug, Clone, Copy)] | ||
830 | pub struct LoopExpr<'a> { | ||
831 | syntax: SyntaxNodeRef<'a>, | ||
832 | } | ||
833 | |||
834 | impl<'a> AstNode<'a> for LoopExpr<'a> { | ||
835 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
836 | match syntax.kind() { | ||
837 | LOOP_EXPR => Some(LoopExpr { syntax }), | ||
838 | _ => None, | ||
839 | } | ||
840 | } | ||
841 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
842 | } | ||
843 | |||
844 | impl<'a> ast::LoopBodyOwner<'a> for LoopExpr<'a> {} | ||
845 | impl<'a> LoopExpr<'a> {} | ||
846 | |||
847 | // MatchArm | ||
848 | #[derive(Debug, Clone, Copy)] | ||
849 | pub struct MatchArm<'a> { | ||
850 | syntax: SyntaxNodeRef<'a>, | ||
851 | } | ||
852 | |||
853 | impl<'a> AstNode<'a> for MatchArm<'a> { | ||
854 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
855 | match syntax.kind() { | ||
856 | MATCH_ARM => Some(MatchArm { syntax }), | ||
857 | _ => None, | ||
858 | } | ||
859 | } | ||
860 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
861 | } | ||
862 | |||
863 | impl<'a> MatchArm<'a> { | ||
864 | pub fn pats(self) -> impl Iterator<Item = Pat<'a>> + 'a { | ||
865 | super::children(self) | ||
866 | } | ||
867 | pub fn guard(self) -> Option<MatchGuard<'a>> { | ||
868 | super::child_opt(self) | ||
869 | } | ||
870 | pub fn expr(self) -> Option<Expr<'a>> { | ||
871 | super::child_opt(self) | ||
872 | } | ||
873 | } | ||
874 | |||
875 | // MatchArmList | ||
876 | #[derive(Debug, Clone, Copy)] | ||
877 | pub struct MatchArmList<'a> { | ||
878 | syntax: SyntaxNodeRef<'a>, | ||
879 | } | ||
880 | |||
881 | impl<'a> AstNode<'a> for MatchArmList<'a> { | ||
882 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
883 | match syntax.kind() { | ||
884 | MATCH_ARM_LIST => Some(MatchArmList { syntax }), | ||
885 | _ => None, | ||
886 | } | ||
887 | } | ||
888 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
889 | } | ||
890 | |||
891 | impl<'a> MatchArmList<'a> { | ||
892 | pub fn arms(self) -> impl Iterator<Item = MatchArm<'a>> + 'a { | ||
893 | super::children(self) | ||
894 | } | ||
895 | } | ||
896 | |||
897 | // MatchExpr | ||
898 | #[derive(Debug, Clone, Copy)] | ||
899 | pub struct MatchExpr<'a> { | ||
900 | syntax: SyntaxNodeRef<'a>, | ||
901 | } | ||
902 | |||
903 | impl<'a> AstNode<'a> for MatchExpr<'a> { | ||
904 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
905 | match syntax.kind() { | ||
906 | MATCH_EXPR => Some(MatchExpr { syntax }), | ||
907 | _ => None, | ||
908 | } | ||
909 | } | ||
910 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
911 | } | ||
912 | |||
913 | impl<'a> MatchExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> { | ||
914 | super::child_opt(self) | ||
915 | } | ||
916 | pub fn match_arm_list(self) -> Option<MatchArmList<'a>> { | ||
917 | super::child_opt(self) | ||
918 | } | ||
919 | } | ||
920 | |||
921 | // MatchGuard | ||
922 | #[derive(Debug, Clone, Copy)] | ||
923 | pub struct MatchGuard<'a> { | ||
924 | syntax: SyntaxNodeRef<'a>, | ||
925 | } | ||
926 | |||
927 | impl<'a> AstNode<'a> for MatchGuard<'a> { | ||
928 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
929 | match syntax.kind() { | ||
930 | MATCH_GUARD => Some(MatchGuard { syntax }), | ||
931 | _ => None, | ||
932 | } | ||
933 | } | ||
934 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
935 | } | ||
936 | |||
937 | impl<'a> MatchGuard<'a> {} | ||
938 | |||
939 | // MethodCallExpr | ||
940 | #[derive(Debug, Clone, Copy)] | ||
941 | pub struct MethodCallExpr<'a> { | ||
942 | syntax: SyntaxNodeRef<'a>, | ||
943 | } | ||
944 | |||
945 | impl<'a> AstNode<'a> for MethodCallExpr<'a> { | ||
946 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
947 | match syntax.kind() { | ||
948 | METHOD_CALL_EXPR => Some(MethodCallExpr { syntax }), | ||
949 | _ => None, | ||
950 | } | ||
951 | } | ||
952 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
953 | } | ||
954 | |||
955 | impl<'a> ast::ArgListOwner<'a> for MethodCallExpr<'a> {} | ||
956 | impl<'a> MethodCallExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> { | ||
957 | super::child_opt(self) | ||
958 | } | ||
959 | } | ||
960 | |||
961 | // Module | ||
962 | #[derive(Debug, Clone, Copy)] | ||
963 | pub struct Module<'a> { | ||
964 | syntax: SyntaxNodeRef<'a>, | ||
965 | } | ||
966 | |||
967 | impl<'a> AstNode<'a> for Module<'a> { | ||
968 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
969 | match syntax.kind() { | ||
970 | MODULE => Some(Module { syntax }), | ||
971 | _ => None, | ||
972 | } | ||
973 | } | ||
974 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
975 | } | ||
976 | |||
977 | impl<'a> ast::NameOwner<'a> for Module<'a> {} | ||
978 | impl<'a> ast::AttrsOwner<'a> for Module<'a> {} | ||
979 | impl<'a> Module<'a> {pub fn item_list(self) -> Option<ItemList<'a>> { | ||
980 | super::child_opt(self) | ||
981 | } | ||
982 | } | ||
983 | |||
984 | // ModuleItem | ||
985 | #[derive(Debug, Clone, Copy)] | ||
986 | pub enum ModuleItem<'a> { | ||
987 | StructDef(StructDef<'a>), | ||
988 | EnumDef(EnumDef<'a>), | ||
989 | FnDef(FnDef<'a>), | ||
990 | TraitDef(TraitDef<'a>), | ||
991 | TypeDef(TypeDef<'a>), | ||
992 | ImplItem(ImplItem<'a>), | ||
993 | UseItem(UseItem<'a>), | ||
994 | ExternCrateItem(ExternCrateItem<'a>), | ||
995 | ConstDef(ConstDef<'a>), | ||
996 | StaticDef(StaticDef<'a>), | ||
997 | Module(Module<'a>), | ||
998 | } | ||
999 | |||
1000 | impl<'a> AstNode<'a> for ModuleItem<'a> { | ||
1001 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1002 | match syntax.kind() { | ||
1003 | STRUCT_DEF => Some(ModuleItem::StructDef(StructDef { syntax })), | ||
1004 | ENUM_DEF => Some(ModuleItem::EnumDef(EnumDef { syntax })), | ||
1005 | FN_DEF => Some(ModuleItem::FnDef(FnDef { syntax })), | ||
1006 | TRAIT_DEF => Some(ModuleItem::TraitDef(TraitDef { syntax })), | ||
1007 | TYPE_DEF => Some(ModuleItem::TypeDef(TypeDef { syntax })), | ||
1008 | IMPL_ITEM => Some(ModuleItem::ImplItem(ImplItem { syntax })), | ||
1009 | USE_ITEM => Some(ModuleItem::UseItem(UseItem { syntax })), | ||
1010 | EXTERN_CRATE_ITEM => Some(ModuleItem::ExternCrateItem(ExternCrateItem { syntax })), | ||
1011 | CONST_DEF => Some(ModuleItem::ConstDef(ConstDef { syntax })), | ||
1012 | STATIC_DEF => Some(ModuleItem::StaticDef(StaticDef { syntax })), | ||
1013 | MODULE => Some(ModuleItem::Module(Module { syntax })), | ||
1014 | _ => None, | ||
1015 | } | ||
1016 | } | ||
1017 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1018 | match self { | ||
1019 | ModuleItem::StructDef(inner) => inner.syntax(), | ||
1020 | ModuleItem::EnumDef(inner) => inner.syntax(), | ||
1021 | ModuleItem::FnDef(inner) => inner.syntax(), | ||
1022 | ModuleItem::TraitDef(inner) => inner.syntax(), | ||
1023 | ModuleItem::TypeDef(inner) => inner.syntax(), | ||
1024 | ModuleItem::ImplItem(inner) => inner.syntax(), | ||
1025 | ModuleItem::UseItem(inner) => inner.syntax(), | ||
1026 | ModuleItem::ExternCrateItem(inner) => inner.syntax(), | ||
1027 | ModuleItem::ConstDef(inner) => inner.syntax(), | ||
1028 | ModuleItem::StaticDef(inner) => inner.syntax(), | ||
1029 | ModuleItem::Module(inner) => inner.syntax(), | ||
1030 | } | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | impl<'a> ModuleItem<'a> {} | ||
1035 | |||
1036 | // Name | ||
1037 | #[derive(Debug, Clone, Copy)] | ||
1038 | pub struct Name<'a> { | ||
1039 | syntax: SyntaxNodeRef<'a>, | ||
1040 | } | ||
1041 | |||
1042 | impl<'a> AstNode<'a> for Name<'a> { | ||
1043 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1044 | match syntax.kind() { | ||
1045 | NAME => Some(Name { syntax }), | ||
1046 | _ => None, | ||
1047 | } | ||
1048 | } | ||
1049 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1050 | } | ||
1051 | |||
1052 | impl<'a> Name<'a> {} | ||
1053 | |||
1054 | // NameRef | ||
1055 | #[derive(Debug, Clone, Copy)] | ||
1056 | pub struct NameRef<'a> { | ||
1057 | syntax: SyntaxNodeRef<'a>, | ||
1058 | } | ||
1059 | |||
1060 | impl<'a> AstNode<'a> for NameRef<'a> { | ||
1061 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1062 | match syntax.kind() { | ||
1063 | NAME_REF => Some(NameRef { syntax }), | ||
1064 | _ => None, | ||
1065 | } | ||
1066 | } | ||
1067 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1068 | } | ||
1069 | |||
1070 | impl<'a> NameRef<'a> {} | ||
1071 | |||
1072 | // NamedField | ||
1073 | #[derive(Debug, Clone, Copy)] | ||
1074 | pub struct NamedField<'a> { | ||
1075 | syntax: SyntaxNodeRef<'a>, | ||
1076 | } | ||
1077 | |||
1078 | impl<'a> AstNode<'a> for NamedField<'a> { | ||
1079 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1080 | match syntax.kind() { | ||
1081 | NAMED_FIELD => Some(NamedField { syntax }), | ||
1082 | _ => None, | ||
1083 | } | ||
1084 | } | ||
1085 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1086 | } | ||
1087 | |||
1088 | impl<'a> NamedField<'a> {} | ||
1089 | |||
1090 | // NamedFieldDef | ||
1091 | #[derive(Debug, Clone, Copy)] | ||
1092 | pub struct NamedFieldDef<'a> { | ||
1093 | syntax: SyntaxNodeRef<'a>, | ||
1094 | } | ||
1095 | |||
1096 | impl<'a> AstNode<'a> for NamedFieldDef<'a> { | ||
1097 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1098 | match syntax.kind() { | ||
1099 | NAMED_FIELD_DEF => Some(NamedFieldDef { syntax }), | ||
1100 | _ => None, | ||
1101 | } | ||
1102 | } | ||
1103 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1104 | } | ||
1105 | |||
1106 | impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} | ||
1107 | impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} | ||
1108 | impl<'a> NamedFieldDef<'a> {} | ||
1109 | |||
1110 | // NamedFieldList | ||
1111 | #[derive(Debug, Clone, Copy)] | ||
1112 | pub struct NamedFieldList<'a> { | ||
1113 | syntax: SyntaxNodeRef<'a>, | ||
1114 | } | ||
1115 | |||
1116 | impl<'a> AstNode<'a> for NamedFieldList<'a> { | ||
1117 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1118 | match syntax.kind() { | ||
1119 | NAMED_FIELD_LIST => Some(NamedFieldList { syntax }), | ||
1120 | _ => None, | ||
1121 | } | ||
1122 | } | ||
1123 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1124 | } | ||
1125 | |||
1126 | impl<'a> NamedFieldList<'a> {} | ||
1127 | |||
1128 | // NeverType | ||
1129 | #[derive(Debug, Clone, Copy)] | ||
1130 | pub struct NeverType<'a> { | ||
1131 | syntax: SyntaxNodeRef<'a>, | ||
1132 | } | ||
1133 | |||
1134 | impl<'a> AstNode<'a> for NeverType<'a> { | ||
1135 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1136 | match syntax.kind() { | ||
1137 | NEVER_TYPE => Some(NeverType { syntax }), | ||
1138 | _ => None, | ||
1139 | } | ||
1140 | } | ||
1141 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1142 | } | ||
1143 | |||
1144 | impl<'a> NeverType<'a> {} | ||
1145 | |||
1146 | // NominalDef | ||
1147 | #[derive(Debug, Clone, Copy)] | ||
1148 | pub enum NominalDef<'a> { | ||
1149 | StructDef(StructDef<'a>), | ||
1150 | EnumDef(EnumDef<'a>), | ||
1151 | } | ||
1152 | |||
1153 | impl<'a> AstNode<'a> for NominalDef<'a> { | ||
1154 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1155 | match syntax.kind() { | ||
1156 | STRUCT_DEF => Some(NominalDef::StructDef(StructDef { syntax })), | ||
1157 | ENUM_DEF => Some(NominalDef::EnumDef(EnumDef { syntax })), | ||
1158 | _ => None, | ||
1159 | } | ||
1160 | } | ||
1161 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1162 | match self { | ||
1163 | NominalDef::StructDef(inner) => inner.syntax(), | ||
1164 | NominalDef::EnumDef(inner) => inner.syntax(), | ||
1165 | } | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | impl<'a> ast::NameOwner<'a> for NominalDef<'a> {} | ||
1170 | impl<'a> ast::TypeParamsOwner<'a> for NominalDef<'a> {} | ||
1171 | impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {} | ||
1172 | impl<'a> NominalDef<'a> {} | ||
1173 | |||
1174 | // Param | ||
1175 | #[derive(Debug, Clone, Copy)] | ||
1176 | pub struct Param<'a> { | ||
1177 | syntax: SyntaxNodeRef<'a>, | ||
1178 | } | ||
1179 | |||
1180 | impl<'a> AstNode<'a> for Param<'a> { | ||
1181 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1182 | match syntax.kind() { | ||
1183 | PARAM => Some(Param { syntax }), | ||
1184 | _ => None, | ||
1185 | } | ||
1186 | } | ||
1187 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1188 | } | ||
1189 | |||
1190 | impl<'a> Param<'a> {pub fn pat(self) -> Option<Pat<'a>> { | ||
1191 | super::child_opt(self) | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | // ParamList | ||
1196 | #[derive(Debug, Clone, Copy)] | ||
1197 | pub struct ParamList<'a> { | ||
1198 | syntax: SyntaxNodeRef<'a>, | ||
1199 | } | ||
1200 | |||
1201 | impl<'a> AstNode<'a> for ParamList<'a> { | ||
1202 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1203 | match syntax.kind() { | ||
1204 | PARAM_LIST => Some(ParamList { syntax }), | ||
1205 | _ => None, | ||
1206 | } | ||
1207 | } | ||
1208 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1209 | } | ||
1210 | |||
1211 | impl<'a> ParamList<'a> { | ||
1212 | pub fn params(self) -> impl Iterator<Item = Param<'a>> + 'a { | ||
1213 | super::children(self) | ||
1214 | } | ||
1215 | pub fn self_param(self) -> Option<SelfParam<'a>> { | ||
1216 | super::child_opt(self) | ||
1217 | } | ||
1218 | } | ||
1219 | |||
1220 | // ParenExpr | ||
1221 | #[derive(Debug, Clone, Copy)] | ||
1222 | pub struct ParenExpr<'a> { | ||
1223 | syntax: SyntaxNodeRef<'a>, | ||
1224 | } | ||
1225 | |||
1226 | impl<'a> AstNode<'a> for ParenExpr<'a> { | ||
1227 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1228 | match syntax.kind() { | ||
1229 | PAREN_EXPR => Some(ParenExpr { syntax }), | ||
1230 | _ => None, | ||
1231 | } | ||
1232 | } | ||
1233 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1234 | } | ||
1235 | |||
1236 | impl<'a> ParenExpr<'a> {} | ||
1237 | |||
1238 | // ParenType | ||
1239 | #[derive(Debug, Clone, Copy)] | ||
1240 | pub struct ParenType<'a> { | ||
1241 | syntax: SyntaxNodeRef<'a>, | ||
1242 | } | ||
1243 | |||
1244 | impl<'a> AstNode<'a> for ParenType<'a> { | ||
1245 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1246 | match syntax.kind() { | ||
1247 | PAREN_TYPE => Some(ParenType { syntax }), | ||
1248 | _ => None, | ||
1249 | } | ||
1250 | } | ||
1251 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1252 | } | ||
1253 | |||
1254 | impl<'a> ParenType<'a> {} | ||
1255 | |||
1256 | // Pat | ||
1257 | #[derive(Debug, Clone, Copy)] | ||
1258 | pub enum Pat<'a> { | ||
1259 | RefPat(RefPat<'a>), | ||
1260 | BindPat(BindPat<'a>), | ||
1261 | PlaceholderPat(PlaceholderPat<'a>), | ||
1262 | PathPat(PathPat<'a>), | ||
1263 | StructPat(StructPat<'a>), | ||
1264 | FieldPatList(FieldPatList<'a>), | ||
1265 | TupleStructPat(TupleStructPat<'a>), | ||
1266 | TuplePat(TuplePat<'a>), | ||
1267 | SlicePat(SlicePat<'a>), | ||
1268 | RangePat(RangePat<'a>), | ||
1269 | } | ||
1270 | |||
1271 | impl<'a> AstNode<'a> for Pat<'a> { | ||
1272 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1273 | match syntax.kind() { | ||
1274 | REF_PAT => Some(Pat::RefPat(RefPat { syntax })), | ||
1275 | BIND_PAT => Some(Pat::BindPat(BindPat { syntax })), | ||
1276 | PLACEHOLDER_PAT => Some(Pat::PlaceholderPat(PlaceholderPat { syntax })), | ||
1277 | PATH_PAT => Some(Pat::PathPat(PathPat { syntax })), | ||
1278 | STRUCT_PAT => Some(Pat::StructPat(StructPat { syntax })), | ||
1279 | FIELD_PAT_LIST => Some(Pat::FieldPatList(FieldPatList { syntax })), | ||
1280 | TUPLE_STRUCT_PAT => Some(Pat::TupleStructPat(TupleStructPat { syntax })), | ||
1281 | TUPLE_PAT => Some(Pat::TuplePat(TuplePat { syntax })), | ||
1282 | SLICE_PAT => Some(Pat::SlicePat(SlicePat { syntax })), | ||
1283 | RANGE_PAT => Some(Pat::RangePat(RangePat { syntax })), | ||
1284 | _ => None, | ||
1285 | } | ||
1286 | } | ||
1287 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1288 | match self { | ||
1289 | Pat::RefPat(inner) => inner.syntax(), | ||
1290 | Pat::BindPat(inner) => inner.syntax(), | ||
1291 | Pat::PlaceholderPat(inner) => inner.syntax(), | ||
1292 | Pat::PathPat(inner) => inner.syntax(), | ||
1293 | Pat::StructPat(inner) => inner.syntax(), | ||
1294 | Pat::FieldPatList(inner) => inner.syntax(), | ||
1295 | Pat::TupleStructPat(inner) => inner.syntax(), | ||
1296 | Pat::TuplePat(inner) => inner.syntax(), | ||
1297 | Pat::SlicePat(inner) => inner.syntax(), | ||
1298 | Pat::RangePat(inner) => inner.syntax(), | ||
1299 | } | ||
1300 | } | ||
1301 | } | ||
1302 | |||
1303 | impl<'a> Pat<'a> {} | ||
1304 | |||
1305 | // Path | ||
1306 | #[derive(Debug, Clone, Copy)] | ||
1307 | pub struct Path<'a> { | ||
1308 | syntax: SyntaxNodeRef<'a>, | ||
1309 | } | ||
1310 | |||
1311 | impl<'a> AstNode<'a> for Path<'a> { | ||
1312 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1313 | match syntax.kind() { | ||
1314 | PATH => Some(Path { syntax }), | ||
1315 | _ => None, | ||
1316 | } | ||
1317 | } | ||
1318 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1319 | } | ||
1320 | |||
1321 | impl<'a> Path<'a> {pub fn segment(self) -> Option<PathSegment<'a>> { | ||
1322 | super::child_opt(self) | ||
1323 | } | ||
1324 | } | ||
1325 | |||
1326 | // PathExpr | ||
1327 | #[derive(Debug, Clone, Copy)] | ||
1328 | pub struct PathExpr<'a> { | ||
1329 | syntax: SyntaxNodeRef<'a>, | ||
1330 | } | ||
1331 | |||
1332 | impl<'a> AstNode<'a> for PathExpr<'a> { | ||
1333 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1334 | match syntax.kind() { | ||
1335 | PATH_EXPR => Some(PathExpr { syntax }), | ||
1336 | _ => None, | ||
1337 | } | ||
1338 | } | ||
1339 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1340 | } | ||
1341 | |||
1342 | impl<'a> PathExpr<'a> {} | ||
1343 | |||
1344 | // PathPat | ||
1345 | #[derive(Debug, Clone, Copy)] | ||
1346 | pub struct PathPat<'a> { | ||
1347 | syntax: SyntaxNodeRef<'a>, | ||
1348 | } | ||
1349 | |||
1350 | impl<'a> AstNode<'a> for PathPat<'a> { | ||
1351 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1352 | match syntax.kind() { | ||
1353 | PATH_PAT => Some(PathPat { syntax }), | ||
1354 | _ => None, | ||
1355 | } | ||
1356 | } | ||
1357 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1358 | } | ||
1359 | |||
1360 | impl<'a> PathPat<'a> {} | ||
1361 | |||
1362 | // PathSegment | ||
1363 | #[derive(Debug, Clone, Copy)] | ||
1364 | pub struct PathSegment<'a> { | ||
1365 | syntax: SyntaxNodeRef<'a>, | ||
1366 | } | ||
1367 | |||
1368 | impl<'a> AstNode<'a> for PathSegment<'a> { | ||
1369 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1370 | match syntax.kind() { | ||
1371 | PATH_SEGMENT => Some(PathSegment { syntax }), | ||
1372 | _ => None, | ||
1373 | } | ||
1374 | } | ||
1375 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1376 | } | ||
1377 | |||
1378 | impl<'a> PathSegment<'a> {pub fn name_ref(self) -> Option<NameRef<'a>> { | ||
1379 | super::child_opt(self) | ||
1380 | } | ||
1381 | } | ||
1382 | |||
1383 | // PathType | ||
1384 | #[derive(Debug, Clone, Copy)] | ||
1385 | pub struct PathType<'a> { | ||
1386 | syntax: SyntaxNodeRef<'a>, | ||
1387 | } | ||
1388 | |||
1389 | impl<'a> AstNode<'a> for PathType<'a> { | ||
1390 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1391 | match syntax.kind() { | ||
1392 | PATH_TYPE => Some(PathType { syntax }), | ||
1393 | _ => None, | ||
1394 | } | ||
1395 | } | ||
1396 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1397 | } | ||
1398 | |||
1399 | impl<'a> PathType<'a> {} | ||
1400 | |||
1401 | // PlaceholderPat | ||
1402 | #[derive(Debug, Clone, Copy)] | ||
1403 | pub struct PlaceholderPat<'a> { | ||
1404 | syntax: SyntaxNodeRef<'a>, | ||
1405 | } | ||
1406 | |||
1407 | impl<'a> AstNode<'a> for PlaceholderPat<'a> { | ||
1408 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1409 | match syntax.kind() { | ||
1410 | PLACEHOLDER_PAT => Some(PlaceholderPat { syntax }), | ||
1411 | _ => None, | ||
1412 | } | ||
1413 | } | ||
1414 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1415 | } | ||
1416 | |||
1417 | impl<'a> PlaceholderPat<'a> {} | ||
1418 | |||
1419 | // PlaceholderType | ||
1420 | #[derive(Debug, Clone, Copy)] | ||
1421 | pub struct PlaceholderType<'a> { | ||
1422 | syntax: SyntaxNodeRef<'a>, | ||
1423 | } | ||
1424 | |||
1425 | impl<'a> AstNode<'a> for PlaceholderType<'a> { | ||
1426 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1427 | match syntax.kind() { | ||
1428 | PLACEHOLDER_TYPE => Some(PlaceholderType { syntax }), | ||
1429 | _ => None, | ||
1430 | } | ||
1431 | } | ||
1432 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1433 | } | ||
1434 | |||
1435 | impl<'a> PlaceholderType<'a> {} | ||
1436 | |||
1437 | // PointerType | ||
1438 | #[derive(Debug, Clone, Copy)] | ||
1439 | pub struct PointerType<'a> { | ||
1440 | syntax: SyntaxNodeRef<'a>, | ||
1441 | } | ||
1442 | |||
1443 | impl<'a> AstNode<'a> for PointerType<'a> { | ||
1444 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1445 | match syntax.kind() { | ||
1446 | POINTER_TYPE => Some(PointerType { syntax }), | ||
1447 | _ => None, | ||
1448 | } | ||
1449 | } | ||
1450 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1451 | } | ||
1452 | |||
1453 | impl<'a> PointerType<'a> {} | ||
1454 | |||
1455 | // PrefixExpr | ||
1456 | #[derive(Debug, Clone, Copy)] | ||
1457 | pub struct PrefixExpr<'a> { | ||
1458 | syntax: SyntaxNodeRef<'a>, | ||
1459 | } | ||
1460 | |||
1461 | impl<'a> AstNode<'a> for PrefixExpr<'a> { | ||
1462 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1463 | match syntax.kind() { | ||
1464 | PREFIX_EXPR => Some(PrefixExpr { syntax }), | ||
1465 | _ => None, | ||
1466 | } | ||
1467 | } | ||
1468 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1469 | } | ||
1470 | |||
1471 | impl<'a> PrefixExpr<'a> {} | ||
1472 | |||
1473 | // RangeExpr | ||
1474 | #[derive(Debug, Clone, Copy)] | ||
1475 | pub struct RangeExpr<'a> { | ||
1476 | syntax: SyntaxNodeRef<'a>, | ||
1477 | } | ||
1478 | |||
1479 | impl<'a> AstNode<'a> for RangeExpr<'a> { | ||
1480 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1481 | match syntax.kind() { | ||
1482 | RANGE_EXPR => Some(RangeExpr { syntax }), | ||
1483 | _ => None, | ||
1484 | } | ||
1485 | } | ||
1486 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1487 | } | ||
1488 | |||
1489 | impl<'a> RangeExpr<'a> {} | ||
1490 | |||
1491 | // RangePat | ||
1492 | #[derive(Debug, Clone, Copy)] | ||
1493 | pub struct RangePat<'a> { | ||
1494 | syntax: SyntaxNodeRef<'a>, | ||
1495 | } | ||
1496 | |||
1497 | impl<'a> AstNode<'a> for RangePat<'a> { | ||
1498 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1499 | match syntax.kind() { | ||
1500 | RANGE_PAT => Some(RangePat { syntax }), | ||
1501 | _ => None, | ||
1502 | } | ||
1503 | } | ||
1504 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1505 | } | ||
1506 | |||
1507 | impl<'a> RangePat<'a> {} | ||
1508 | |||
1509 | // RefExpr | ||
1510 | #[derive(Debug, Clone, Copy)] | ||
1511 | pub struct RefExpr<'a> { | ||
1512 | syntax: SyntaxNodeRef<'a>, | ||
1513 | } | ||
1514 | |||
1515 | impl<'a> AstNode<'a> for RefExpr<'a> { | ||
1516 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1517 | match syntax.kind() { | ||
1518 | REF_EXPR => Some(RefExpr { syntax }), | ||
1519 | _ => None, | ||
1520 | } | ||
1521 | } | ||
1522 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1523 | } | ||
1524 | |||
1525 | impl<'a> RefExpr<'a> {} | ||
1526 | |||
1527 | // RefPat | ||
1528 | #[derive(Debug, Clone, Copy)] | ||
1529 | pub struct RefPat<'a> { | ||
1530 | syntax: SyntaxNodeRef<'a>, | ||
1531 | } | ||
1532 | |||
1533 | impl<'a> AstNode<'a> for RefPat<'a> { | ||
1534 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1535 | match syntax.kind() { | ||
1536 | REF_PAT => Some(RefPat { syntax }), | ||
1537 | _ => None, | ||
1538 | } | ||
1539 | } | ||
1540 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1541 | } | ||
1542 | |||
1543 | impl<'a> RefPat<'a> {} | ||
1544 | |||
1545 | // ReferenceType | ||
1546 | #[derive(Debug, Clone, Copy)] | ||
1547 | pub struct ReferenceType<'a> { | ||
1548 | syntax: SyntaxNodeRef<'a>, | ||
1549 | } | ||
1550 | |||
1551 | impl<'a> AstNode<'a> for ReferenceType<'a> { | ||
1552 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1553 | match syntax.kind() { | ||
1554 | REFERENCE_TYPE => Some(ReferenceType { syntax }), | ||
1555 | _ => None, | ||
1556 | } | ||
1557 | } | ||
1558 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1559 | } | ||
1560 | |||
1561 | impl<'a> ReferenceType<'a> {} | ||
1562 | |||
1563 | // RetType | ||
1564 | #[derive(Debug, Clone, Copy)] | ||
1565 | pub struct RetType<'a> { | ||
1566 | syntax: SyntaxNodeRef<'a>, | ||
1567 | } | ||
1568 | |||
1569 | impl<'a> AstNode<'a> for RetType<'a> { | ||
1570 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1571 | match syntax.kind() { | ||
1572 | RET_TYPE => Some(RetType { syntax }), | ||
1573 | _ => None, | ||
1574 | } | ||
1575 | } | ||
1576 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1577 | } | ||
1578 | |||
1579 | impl<'a> RetType<'a> {} | ||
1580 | |||
1581 | // ReturnExpr | ||
1582 | #[derive(Debug, Clone, Copy)] | ||
1583 | pub struct ReturnExpr<'a> { | ||
1584 | syntax: SyntaxNodeRef<'a>, | ||
1585 | } | ||
1586 | |||
1587 | impl<'a> AstNode<'a> for ReturnExpr<'a> { | ||
1588 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1589 | match syntax.kind() { | ||
1590 | RETURN_EXPR => Some(ReturnExpr { syntax }), | ||
1591 | _ => None, | ||
1592 | } | ||
1593 | } | ||
1594 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1595 | } | ||
1596 | |||
1597 | impl<'a> ReturnExpr<'a> {} | ||
1598 | |||
1599 | // Root | ||
1600 | #[derive(Debug, Clone, Copy)] | ||
1601 | pub struct Root<'a> { | ||
1602 | syntax: SyntaxNodeRef<'a>, | ||
1603 | } | ||
1604 | |||
1605 | impl<'a> AstNode<'a> for Root<'a> { | ||
1606 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1607 | match syntax.kind() { | ||
1608 | ROOT => Some(Root { syntax }), | ||
1609 | _ => None, | ||
1610 | } | ||
1611 | } | ||
1612 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1613 | } | ||
1614 | |||
1615 | impl<'a> ast::ModuleItemOwner<'a> for Root<'a> {} | ||
1616 | impl<'a> ast::FnDefOwner<'a> for Root<'a> {} | ||
1617 | impl<'a> Root<'a> { | ||
1618 | pub fn modules(self) -> impl Iterator<Item = Module<'a>> + 'a { | ||
1619 | super::children(self) | ||
1620 | } | ||
1621 | } | ||
1622 | |||
1623 | // SelfParam | ||
1624 | #[derive(Debug, Clone, Copy)] | ||
1625 | pub struct SelfParam<'a> { | ||
1626 | syntax: SyntaxNodeRef<'a>, | ||
1627 | } | ||
1628 | |||
1629 | impl<'a> AstNode<'a> for SelfParam<'a> { | ||
1630 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1631 | match syntax.kind() { | ||
1632 | SELF_PARAM => Some(SelfParam { syntax }), | ||
1633 | _ => None, | ||
1634 | } | ||
1635 | } | ||
1636 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1637 | } | ||
1638 | |||
1639 | impl<'a> SelfParam<'a> {} | ||
1640 | |||
1641 | // SlicePat | ||
1642 | #[derive(Debug, Clone, Copy)] | ||
1643 | pub struct SlicePat<'a> { | ||
1644 | syntax: SyntaxNodeRef<'a>, | ||
1645 | } | ||
1646 | |||
1647 | impl<'a> AstNode<'a> for SlicePat<'a> { | ||
1648 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1649 | match syntax.kind() { | ||
1650 | SLICE_PAT => Some(SlicePat { syntax }), | ||
1651 | _ => None, | ||
1652 | } | ||
1653 | } | ||
1654 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1655 | } | ||
1656 | |||
1657 | impl<'a> SlicePat<'a> {} | ||
1658 | |||
1659 | // SliceType | ||
1660 | #[derive(Debug, Clone, Copy)] | ||
1661 | pub struct SliceType<'a> { | ||
1662 | syntax: SyntaxNodeRef<'a>, | ||
1663 | } | ||
1664 | |||
1665 | impl<'a> AstNode<'a> for SliceType<'a> { | ||
1666 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1667 | match syntax.kind() { | ||
1668 | SLICE_TYPE => Some(SliceType { syntax }), | ||
1669 | _ => None, | ||
1670 | } | ||
1671 | } | ||
1672 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1673 | } | ||
1674 | |||
1675 | impl<'a> SliceType<'a> {} | ||
1676 | |||
1677 | // StaticDef | ||
1678 | #[derive(Debug, Clone, Copy)] | ||
1679 | pub struct StaticDef<'a> { | ||
1680 | syntax: SyntaxNodeRef<'a>, | ||
1681 | } | ||
1682 | |||
1683 | impl<'a> AstNode<'a> for StaticDef<'a> { | ||
1684 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1685 | match syntax.kind() { | ||
1686 | STATIC_DEF => Some(StaticDef { syntax }), | ||
1687 | _ => None, | ||
1688 | } | ||
1689 | } | ||
1690 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1691 | } | ||
1692 | |||
1693 | impl<'a> ast::NameOwner<'a> for StaticDef<'a> {} | ||
1694 | impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {} | ||
1695 | impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {} | ||
1696 | impl<'a> StaticDef<'a> {} | ||
1697 | |||
1698 | // Stmt | ||
1699 | #[derive(Debug, Clone, Copy)] | ||
1700 | pub enum Stmt<'a> { | ||
1701 | ExprStmt(ExprStmt<'a>), | ||
1702 | LetStmt(LetStmt<'a>), | ||
1703 | } | ||
1704 | |||
1705 | impl<'a> AstNode<'a> for Stmt<'a> { | ||
1706 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1707 | match syntax.kind() { | ||
1708 | EXPR_STMT => Some(Stmt::ExprStmt(ExprStmt { syntax })), | ||
1709 | LET_STMT => Some(Stmt::LetStmt(LetStmt { syntax })), | ||
1710 | _ => None, | ||
1711 | } | ||
1712 | } | ||
1713 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1714 | match self { | ||
1715 | Stmt::ExprStmt(inner) => inner.syntax(), | ||
1716 | Stmt::LetStmt(inner) => inner.syntax(), | ||
1717 | } | ||
1718 | } | ||
1719 | } | ||
1720 | |||
1721 | impl<'a> Stmt<'a> {} | ||
1722 | |||
1723 | // StructDef | ||
1724 | #[derive(Debug, Clone, Copy)] | ||
1725 | pub struct StructDef<'a> { | ||
1726 | syntax: SyntaxNodeRef<'a>, | ||
1727 | } | ||
1728 | |||
1729 | impl<'a> AstNode<'a> for StructDef<'a> { | ||
1730 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1731 | match syntax.kind() { | ||
1732 | STRUCT_DEF => Some(StructDef { syntax }), | ||
1733 | _ => None, | ||
1734 | } | ||
1735 | } | ||
1736 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1737 | } | ||
1738 | |||
1739 | impl<'a> ast::NameOwner<'a> for StructDef<'a> {} | ||
1740 | impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} | ||
1741 | impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} | ||
1742 | impl<'a> StructDef<'a> { | ||
1743 | pub fn fields(self) -> impl Iterator<Item = NamedFieldDef<'a>> + 'a { | ||
1744 | super::children(self) | ||
1745 | } | ||
1746 | } | ||
1747 | |||
1748 | // StructLit | ||
1749 | #[derive(Debug, Clone, Copy)] | ||
1750 | pub struct StructLit<'a> { | ||
1751 | syntax: SyntaxNodeRef<'a>, | ||
1752 | } | ||
1753 | |||
1754 | impl<'a> AstNode<'a> for StructLit<'a> { | ||
1755 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1756 | match syntax.kind() { | ||
1757 | STRUCT_LIT => Some(StructLit { syntax }), | ||
1758 | _ => None, | ||
1759 | } | ||
1760 | } | ||
1761 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1762 | } | ||
1763 | |||
1764 | impl<'a> StructLit<'a> {} | ||
1765 | |||
1766 | // StructPat | ||
1767 | #[derive(Debug, Clone, Copy)] | ||
1768 | pub struct StructPat<'a> { | ||
1769 | syntax: SyntaxNodeRef<'a>, | ||
1770 | } | ||
1771 | |||
1772 | impl<'a> AstNode<'a> for StructPat<'a> { | ||
1773 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1774 | match syntax.kind() { | ||
1775 | STRUCT_PAT => Some(StructPat { syntax }), | ||
1776 | _ => None, | ||
1777 | } | ||
1778 | } | ||
1779 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1780 | } | ||
1781 | |||
1782 | impl<'a> StructPat<'a> {} | ||
1783 | |||
1784 | // TokenTree | ||
1785 | #[derive(Debug, Clone, Copy)] | ||
1786 | pub struct TokenTree<'a> { | ||
1787 | syntax: SyntaxNodeRef<'a>, | ||
1788 | } | ||
1789 | |||
1790 | impl<'a> AstNode<'a> for TokenTree<'a> { | ||
1791 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1792 | match syntax.kind() { | ||
1793 | TOKEN_TREE => Some(TokenTree { syntax }), | ||
1794 | _ => None, | ||
1795 | } | ||
1796 | } | ||
1797 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1798 | } | ||
1799 | |||
1800 | impl<'a> TokenTree<'a> {} | ||
1801 | |||
1802 | // TraitDef | ||
1803 | #[derive(Debug, Clone, Copy)] | ||
1804 | pub struct TraitDef<'a> { | ||
1805 | syntax: SyntaxNodeRef<'a>, | ||
1806 | } | ||
1807 | |||
1808 | impl<'a> AstNode<'a> for TraitDef<'a> { | ||
1809 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1810 | match syntax.kind() { | ||
1811 | TRAIT_DEF => Some(TraitDef { syntax }), | ||
1812 | _ => None, | ||
1813 | } | ||
1814 | } | ||
1815 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1816 | } | ||
1817 | |||
1818 | impl<'a> ast::NameOwner<'a> for TraitDef<'a> {} | ||
1819 | impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {} | ||
1820 | impl<'a> TraitDef<'a> {} | ||
1821 | |||
1822 | // TryExpr | ||
1823 | #[derive(Debug, Clone, Copy)] | ||
1824 | pub struct TryExpr<'a> { | ||
1825 | syntax: SyntaxNodeRef<'a>, | ||
1826 | } | ||
1827 | |||
1828 | impl<'a> AstNode<'a> for TryExpr<'a> { | ||
1829 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1830 | match syntax.kind() { | ||
1831 | TRY_EXPR => Some(TryExpr { syntax }), | ||
1832 | _ => None, | ||
1833 | } | ||
1834 | } | ||
1835 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1836 | } | ||
1837 | |||
1838 | impl<'a> TryExpr<'a> {} | ||
1839 | |||
1840 | // TupleExpr | ||
1841 | #[derive(Debug, Clone, Copy)] | ||
1842 | pub struct TupleExpr<'a> { | ||
1843 | syntax: SyntaxNodeRef<'a>, | ||
1844 | } | ||
1845 | |||
1846 | impl<'a> AstNode<'a> for TupleExpr<'a> { | ||
1847 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1848 | match syntax.kind() { | ||
1849 | TUPLE_EXPR => Some(TupleExpr { syntax }), | ||
1850 | _ => None, | ||
1851 | } | ||
1852 | } | ||
1853 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1854 | } | ||
1855 | |||
1856 | impl<'a> TupleExpr<'a> {} | ||
1857 | |||
1858 | // TuplePat | ||
1859 | #[derive(Debug, Clone, Copy)] | ||
1860 | pub struct TuplePat<'a> { | ||
1861 | syntax: SyntaxNodeRef<'a>, | ||
1862 | } | ||
1863 | |||
1864 | impl<'a> AstNode<'a> for TuplePat<'a> { | ||
1865 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1866 | match syntax.kind() { | ||
1867 | TUPLE_PAT => Some(TuplePat { syntax }), | ||
1868 | _ => None, | ||
1869 | } | ||
1870 | } | ||
1871 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1872 | } | ||
1873 | |||
1874 | impl<'a> TuplePat<'a> {} | ||
1875 | |||
1876 | // TupleStructPat | ||
1877 | #[derive(Debug, Clone, Copy)] | ||
1878 | pub struct TupleStructPat<'a> { | ||
1879 | syntax: SyntaxNodeRef<'a>, | ||
1880 | } | ||
1881 | |||
1882 | impl<'a> AstNode<'a> for TupleStructPat<'a> { | ||
1883 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1884 | match syntax.kind() { | ||
1885 | TUPLE_STRUCT_PAT => Some(TupleStructPat { syntax }), | ||
1886 | _ => None, | ||
1887 | } | ||
1888 | } | ||
1889 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1890 | } | ||
1891 | |||
1892 | impl<'a> TupleStructPat<'a> {} | ||
1893 | |||
1894 | // TupleType | ||
1895 | #[derive(Debug, Clone, Copy)] | ||
1896 | pub struct TupleType<'a> { | ||
1897 | syntax: SyntaxNodeRef<'a>, | ||
1898 | } | ||
1899 | |||
1900 | impl<'a> AstNode<'a> for TupleType<'a> { | ||
1901 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1902 | match syntax.kind() { | ||
1903 | TUPLE_TYPE => Some(TupleType { syntax }), | ||
1904 | _ => None, | ||
1905 | } | ||
1906 | } | ||
1907 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1908 | } | ||
1909 | |||
1910 | impl<'a> TupleType<'a> {} | ||
1911 | |||
1912 | // TypeDef | ||
1913 | #[derive(Debug, Clone, Copy)] | ||
1914 | pub struct TypeDef<'a> { | ||
1915 | syntax: SyntaxNodeRef<'a>, | ||
1916 | } | ||
1917 | |||
1918 | impl<'a> AstNode<'a> for TypeDef<'a> { | ||
1919 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1920 | match syntax.kind() { | ||
1921 | TYPE_DEF => Some(TypeDef { syntax }), | ||
1922 | _ => None, | ||
1923 | } | ||
1924 | } | ||
1925 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1926 | } | ||
1927 | |||
1928 | impl<'a> ast::NameOwner<'a> for TypeDef<'a> {} | ||
1929 | impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {} | ||
1930 | impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {} | ||
1931 | impl<'a> TypeDef<'a> {} | ||
1932 | |||
1933 | // TypeParam | ||
1934 | #[derive(Debug, Clone, Copy)] | ||
1935 | pub struct TypeParam<'a> { | ||
1936 | syntax: SyntaxNodeRef<'a>, | ||
1937 | } | ||
1938 | |||
1939 | impl<'a> AstNode<'a> for TypeParam<'a> { | ||
1940 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1941 | match syntax.kind() { | ||
1942 | TYPE_PARAM => Some(TypeParam { syntax }), | ||
1943 | _ => None, | ||
1944 | } | ||
1945 | } | ||
1946 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1947 | } | ||
1948 | |||
1949 | impl<'a> ast::NameOwner<'a> for TypeParam<'a> {} | ||
1950 | impl<'a> TypeParam<'a> {} | ||
1951 | |||
1952 | // TypeParamList | ||
1953 | #[derive(Debug, Clone, Copy)] | ||
1954 | pub struct TypeParamList<'a> { | ||
1955 | syntax: SyntaxNodeRef<'a>, | ||
1956 | } | ||
1957 | |||
1958 | impl<'a> AstNode<'a> for TypeParamList<'a> { | ||
1959 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1960 | match syntax.kind() { | ||
1961 | TYPE_PARAM_LIST => Some(TypeParamList { syntax }), | ||
1962 | _ => None, | ||
1963 | } | ||
1964 | } | ||
1965 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1966 | } | ||
1967 | |||
1968 | impl<'a> TypeParamList<'a> { | ||
1969 | pub fn type_params(self) -> impl Iterator<Item = TypeParam<'a>> + 'a { | ||
1970 | super::children(self) | ||
1971 | } | ||
1972 | |||
1973 | pub fn lifetime_params(self) -> impl Iterator<Item = LifetimeParam<'a>> + 'a { | ||
1974 | super::children(self) | ||
1975 | } | ||
1976 | } | ||
1977 | |||
1978 | // TypeRef | ||
1979 | #[derive(Debug, Clone, Copy)] | ||
1980 | pub enum TypeRef<'a> { | ||
1981 | ParenType(ParenType<'a>), | ||
1982 | TupleType(TupleType<'a>), | ||
1983 | NeverType(NeverType<'a>), | ||
1984 | PathType(PathType<'a>), | ||
1985 | PointerType(PointerType<'a>), | ||
1986 | ArrayType(ArrayType<'a>), | ||
1987 | SliceType(SliceType<'a>), | ||
1988 | ReferenceType(ReferenceType<'a>), | ||
1989 | PlaceholderType(PlaceholderType<'a>), | ||
1990 | FnPointerType(FnPointerType<'a>), | ||
1991 | ForType(ForType<'a>), | ||
1992 | ImplTraitType(ImplTraitType<'a>), | ||
1993 | DynTraitType(DynTraitType<'a>), | ||
1994 | } | ||
1995 | |||
1996 | impl<'a> AstNode<'a> for TypeRef<'a> { | ||
1997 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1998 | match syntax.kind() { | ||
1999 | PAREN_TYPE => Some(TypeRef::ParenType(ParenType { syntax })), | ||
2000 | TUPLE_TYPE => Some(TypeRef::TupleType(TupleType { syntax })), | ||
2001 | NEVER_TYPE => Some(TypeRef::NeverType(NeverType { syntax })), | ||
2002 | PATH_TYPE => Some(TypeRef::PathType(PathType { syntax })), | ||
2003 | POINTER_TYPE => Some(TypeRef::PointerType(PointerType { syntax })), | ||
2004 | ARRAY_TYPE => Some(TypeRef::ArrayType(ArrayType { syntax })), | ||
2005 | SLICE_TYPE => Some(TypeRef::SliceType(SliceType { syntax })), | ||
2006 | REFERENCE_TYPE => Some(TypeRef::ReferenceType(ReferenceType { syntax })), | ||
2007 | PLACEHOLDER_TYPE => Some(TypeRef::PlaceholderType(PlaceholderType { syntax })), | ||
2008 | FN_POINTER_TYPE => Some(TypeRef::FnPointerType(FnPointerType { syntax })), | ||
2009 | FOR_TYPE => Some(TypeRef::ForType(ForType { syntax })), | ||
2010 | IMPL_TRAIT_TYPE => Some(TypeRef::ImplTraitType(ImplTraitType { syntax })), | ||
2011 | DYN_TRAIT_TYPE => Some(TypeRef::DynTraitType(DynTraitType { syntax })), | ||
2012 | _ => None, | ||
2013 | } | ||
2014 | } | ||
2015 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
2016 | match self { | ||
2017 | TypeRef::ParenType(inner) => inner.syntax(), | ||
2018 | TypeRef::TupleType(inner) => inner.syntax(), | ||
2019 | TypeRef::NeverType(inner) => inner.syntax(), | ||
2020 | TypeRef::PathType(inner) => inner.syntax(), | ||
2021 | TypeRef::PointerType(inner) => inner.syntax(), | ||
2022 | TypeRef::ArrayType(inner) => inner.syntax(), | ||
2023 | TypeRef::SliceType(inner) => inner.syntax(), | ||
2024 | TypeRef::ReferenceType(inner) => inner.syntax(), | ||
2025 | TypeRef::PlaceholderType(inner) => inner.syntax(), | ||
2026 | TypeRef::FnPointerType(inner) => inner.syntax(), | ||
2027 | TypeRef::ForType(inner) => inner.syntax(), | ||
2028 | TypeRef::ImplTraitType(inner) => inner.syntax(), | ||
2029 | TypeRef::DynTraitType(inner) => inner.syntax(), | ||
2030 | } | ||
2031 | } | ||
2032 | } | ||
2033 | |||
2034 | impl<'a> TypeRef<'a> {} | ||
2035 | |||
2036 | // UseItem | ||
2037 | #[derive(Debug, Clone, Copy)] | ||
2038 | pub struct UseItem<'a> { | ||
2039 | syntax: SyntaxNodeRef<'a>, | ||
2040 | } | ||
2041 | |||
2042 | impl<'a> AstNode<'a> for UseItem<'a> { | ||
2043 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2044 | match syntax.kind() { | ||
2045 | USE_ITEM => Some(UseItem { syntax }), | ||
2046 | _ => None, | ||
2047 | } | ||
2048 | } | ||
2049 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2050 | } | ||
2051 | |||
2052 | impl<'a> UseItem<'a> {pub fn use_tree(self) -> Option<UseTree<'a>> { | ||
2053 | super::child_opt(self) | ||
2054 | } | ||
2055 | } | ||
2056 | |||
2057 | // UseTree | ||
2058 | #[derive(Debug, Clone, Copy)] | ||
2059 | pub struct UseTree<'a> { | ||
2060 | syntax: SyntaxNodeRef<'a>, | ||
2061 | } | ||
2062 | |||
2063 | impl<'a> AstNode<'a> for UseTree<'a> { | ||
2064 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2065 | match syntax.kind() { | ||
2066 | USE_TREE => Some(UseTree { syntax }), | ||
2067 | _ => None, | ||
2068 | } | ||
2069 | } | ||
2070 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2071 | } | ||
2072 | |||
2073 | impl<'a> UseTree<'a> {pub fn path(self) -> Option<Path<'a>> { | ||
2074 | super::child_opt(self) | ||
2075 | } | ||
2076 | pub fn use_tree_list(self) -> Option<UseTreeList<'a>> { | ||
2077 | super::child_opt(self) | ||
2078 | } | ||
2079 | } | ||
2080 | |||
2081 | // UseTreeList | ||
2082 | #[derive(Debug, Clone, Copy)] | ||
2083 | pub struct UseTreeList<'a> { | ||
2084 | syntax: SyntaxNodeRef<'a>, | ||
2085 | } | ||
2086 | |||
2087 | impl<'a> AstNode<'a> for UseTreeList<'a> { | ||
2088 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2089 | match syntax.kind() { | ||
2090 | USE_TREE_LIST => Some(UseTreeList { syntax }), | ||
2091 | _ => None, | ||
2092 | } | ||
2093 | } | ||
2094 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2095 | } | ||
2096 | |||
2097 | impl<'a> UseTreeList<'a> { | ||
2098 | pub fn use_trees(self) -> impl Iterator<Item = UseTree<'a>> + 'a { | ||
2099 | super::children(self) | ||
2100 | } | ||
2101 | } | ||
2102 | |||
2103 | // WhereClause | ||
2104 | #[derive(Debug, Clone, Copy)] | ||
2105 | pub struct WhereClause<'a> { | ||
2106 | syntax: SyntaxNodeRef<'a>, | ||
2107 | } | ||
2108 | |||
2109 | impl<'a> AstNode<'a> for WhereClause<'a> { | ||
2110 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2111 | match syntax.kind() { | ||
2112 | WHERE_CLAUSE => Some(WhereClause { syntax }), | ||
2113 | _ => None, | ||
2114 | } | ||
2115 | } | ||
2116 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2117 | } | ||
2118 | |||
2119 | impl<'a> WhereClause<'a> {} | ||
2120 | |||
2121 | // WhileExpr | ||
2122 | #[derive(Debug, Clone, Copy)] | ||
2123 | pub struct WhileExpr<'a> { | ||
2124 | syntax: SyntaxNodeRef<'a>, | ||
2125 | } | ||
2126 | |||
2127 | impl<'a> AstNode<'a> for WhileExpr<'a> { | ||
2128 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2129 | match syntax.kind() { | ||
2130 | WHILE_EXPR => Some(WhileExpr { syntax }), | ||
2131 | _ => None, | ||
2132 | } | ||
2133 | } | ||
2134 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2135 | } | ||
2136 | |||
2137 | impl<'a> ast::LoopBodyOwner<'a> for WhileExpr<'a> {} | ||
2138 | impl<'a> WhileExpr<'a> {pub fn condition(self) -> Option<Condition<'a>> { | ||
2139 | super::child_opt(self) | ||
2140 | } | ||
2141 | } | ||
2142 | |||
diff --git a/crates/ra_syntax/src/ast/generated.rs.tera b/crates/ra_syntax/src/ast/generated.rs.tera new file mode 100644 index 000000000..a72e9b732 --- /dev/null +++ b/crates/ra_syntax/src/ast/generated.rs.tera | |||
@@ -0,0 +1,83 @@ | |||
1 | use { | ||
2 | ast, | ||
3 | SyntaxNodeRef, AstNode, | ||
4 | SyntaxKind::*, | ||
5 | }; | ||
6 | {% for node, methods in ast %} | ||
7 | // {{ node }} | ||
8 | {%- if methods.enum %} | ||
9 | #[derive(Debug, Clone, Copy)] | ||
10 | pub enum {{ node }}<'a> { | ||
11 | {%- for kind in methods.enum %} | ||
12 | {{ kind }}({{ kind }}<'a>), | ||
13 | {%- endfor %} | ||
14 | } | ||
15 | |||
16 | impl<'a> AstNode<'a> for {{ node }}<'a> { | ||
17 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
18 | match syntax.kind() { | ||
19 | {%- for kind in methods.enum %} | ||
20 | {{ kind | SCREAM }} => Some({{ node }}::{{ kind }}({{ kind }} { syntax })), | ||
21 | {%- endfor %} | ||
22 | _ => None, | ||
23 | } | ||
24 | } | ||
25 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
26 | match self { | ||
27 | {%- for kind in methods.enum %} | ||
28 | {{ node }}::{{ kind }}(inner) => inner.syntax(), | ||
29 | {%- endfor %} | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | {% else %} | ||
34 | #[derive(Debug, Clone, Copy)] | ||
35 | pub struct {{ node }}<'a> { | ||
36 | syntax: SyntaxNodeRef<'a>, | ||
37 | } | ||
38 | |||
39 | impl<'a> AstNode<'a> for {{ node }}<'a> { | ||
40 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
41 | match syntax.kind() { | ||
42 | {{ node | SCREAM }} => Some({{ node }} { syntax }), | ||
43 | _ => None, | ||
44 | } | ||
45 | } | ||
46 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
47 | } | ||
48 | {% endif %} | ||
49 | {% if methods.traits -%} | ||
50 | {%- for t in methods.traits -%} | ||
51 | impl<'a> ast::{{ t }}<'a> for {{ node }}<'a> {} | ||
52 | {% endfor -%} | ||
53 | {%- endif -%} | ||
54 | |||
55 | impl<'a> {{ node }}<'a> { | ||
56 | {%- if methods.collections -%} | ||
57 | {%- for m in methods.collections -%} | ||
58 | {%- set method_name = m.0 -%} | ||
59 | {%- set ChildName = m.1 %} | ||
60 | pub fn {{ method_name }}(self) -> impl Iterator<Item = {{ ChildName }}<'a>> + 'a { | ||
61 | super::children(self) | ||
62 | } | ||
63 | {% endfor -%} | ||
64 | {%- endif -%} | ||
65 | |||
66 | {%- if methods.options -%} | ||
67 | {%- for m in methods.options -%} | ||
68 | |||
69 | {%- if m is string -%} | ||
70 | {%- set method_name = m | snake -%} | ||
71 | {%- set ChildName = m %} | ||
72 | {%- else -%} | ||
73 | {%- set method_name = m.0 -%} | ||
74 | {%- set ChildName = m.1 %} | ||
75 | {%- endif -%} | ||
76 | |||
77 | pub fn {{ method_name }}(self) -> Option<{{ ChildName }}<'a>> { | ||
78 | super::child_opt(self) | ||
79 | } | ||
80 | {% endfor -%} | ||
81 | {%- endif -%} | ||
82 | } | ||
83 | {% endfor %} | ||
diff --git a/crates/ra_syntax/src/ast/mod.rs b/crates/ra_syntax/src/ast/mod.rs new file mode 100644 index 000000000..a6da82957 --- /dev/null +++ b/crates/ra_syntax/src/ast/mod.rs | |||
@@ -0,0 +1,206 @@ | |||
1 | mod generated; | ||
2 | |||
3 | use std::marker::PhantomData; | ||
4 | |||
5 | use itertools::Itertools; | ||
6 | use smol_str::SmolStr; | ||
7 | |||
8 | use { | ||
9 | SyntaxNodeRef, SyntaxKind::*, | ||
10 | yellow::{RefRoot, SyntaxNodeChildren}, | ||
11 | }; | ||
12 | pub use self::generated::*; | ||
13 | |||
14 | pub trait AstNode<'a>: Clone + Copy + 'a { | ||
15 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> | ||
16 | where Self: Sized; | ||
17 | fn syntax(self) -> SyntaxNodeRef<'a>; | ||
18 | } | ||
19 | |||
20 | pub trait NameOwner<'a>: AstNode<'a> { | ||
21 | fn name(self) -> Option<Name<'a>> { | ||
22 | child_opt(self) | ||
23 | } | ||
24 | } | ||
25 | |||
26 | pub trait LoopBodyOwner<'a>: AstNode<'a> { | ||
27 | fn loop_body(self) -> Option<Block<'a>> { | ||
28 | child_opt(self) | ||
29 | } | ||
30 | } | ||
31 | |||
32 | pub trait ArgListOwner<'a>: AstNode<'a> { | ||
33 | fn arg_list(self) -> Option<ArgList<'a>> { | ||
34 | child_opt(self) | ||
35 | } | ||
36 | } | ||
37 | |||
38 | pub trait FnDefOwner<'a>: AstNode<'a> { | ||
39 | fn functions(self) -> AstChildren<'a, FnDef<'a>> { | ||
40 | children(self) | ||
41 | } | ||
42 | } | ||
43 | |||
44 | pub trait ModuleItemOwner<'a>: AstNode<'a> { | ||
45 | fn items(self) -> AstChildren<'a, ModuleItem<'a>> { | ||
46 | children(self) | ||
47 | } | ||
48 | } | ||
49 | |||
50 | pub trait TypeParamsOwner<'a>: AstNode<'a> { | ||
51 | fn type_param_list(self) -> Option<TypeParamList<'a>> { | ||
52 | child_opt(self) | ||
53 | } | ||
54 | |||
55 | fn where_clause(self) -> Option<WhereClause<'a>> { | ||
56 | child_opt(self) | ||
57 | } | ||
58 | } | ||
59 | |||
60 | pub trait AttrsOwner<'a>: AstNode<'a> { | ||
61 | fn attrs(self) -> AstChildren<'a, Attr<'a>> { | ||
62 | children(self) | ||
63 | } | ||
64 | } | ||
65 | |||
66 | impl<'a> FnDef<'a> { | ||
67 | pub fn has_atom_attr(&self, atom: &str) -> bool { | ||
68 | self.attrs() | ||
69 | .filter_map(|x| x.as_atom()) | ||
70 | .any(|x| x == atom) | ||
71 | } | ||
72 | } | ||
73 | |||
74 | impl<'a> Attr<'a> { | ||
75 | pub fn as_atom(&self) -> Option<SmolStr> { | ||
76 | let tt = self.value()?; | ||
77 | let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; | ||
78 | if attr.kind() == IDENT { | ||
79 | Some(attr.leaf_text().unwrap()) | ||
80 | } else { | ||
81 | None | ||
82 | } | ||
83 | } | ||
84 | |||
85 | pub fn as_call(&self) -> Option<(SmolStr, TokenTree<'a>)> { | ||
86 | let tt = self.value()?; | ||
87 | let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; | ||
88 | let args = TokenTree::cast(args)?; | ||
89 | if attr.kind() == IDENT { | ||
90 | Some((attr.leaf_text().unwrap(), args)) | ||
91 | } else { | ||
92 | None | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | |||
97 | impl<'a> Lifetime<'a> { | ||
98 | pub fn text(&self) -> SmolStr { | ||
99 | self.syntax().leaf_text().unwrap() | ||
100 | } | ||
101 | } | ||
102 | |||
103 | impl<'a> Name<'a> { | ||
104 | pub fn text(&self) -> SmolStr { | ||
105 | let ident = self.syntax().first_child() | ||
106 | .unwrap(); | ||
107 | ident.leaf_text().unwrap() | ||
108 | } | ||
109 | } | ||
110 | |||
111 | impl<'a> NameRef<'a> { | ||
112 | pub fn text(&self) -> SmolStr { | ||
113 | let ident = self.syntax().first_child() | ||
114 | .unwrap(); | ||
115 | ident.leaf_text().unwrap() | ||
116 | } | ||
117 | } | ||
118 | |||
119 | impl<'a> ImplItem<'a> { | ||
120 | pub fn target_type(self) -> Option<TypeRef<'a>> { | ||
121 | match self.target() { | ||
122 | (Some(t), None) | (_, Some(t)) => Some(t), | ||
123 | _ => None, | ||
124 | } | ||
125 | } | ||
126 | |||
127 | pub fn target_trait(self) -> Option<TypeRef<'a>> { | ||
128 | match self.target() { | ||
129 | (Some(t), Some(_)) => Some(t), | ||
130 | _ => None, | ||
131 | } | ||
132 | } | ||
133 | |||
134 | fn target(self) -> (Option<TypeRef<'a>>, Option<TypeRef<'a>>) { | ||
135 | let mut types = children(self); | ||
136 | let first = types.next(); | ||
137 | let second = types.next(); | ||
138 | (first, second) | ||
139 | } | ||
140 | } | ||
141 | |||
142 | impl<'a> Module<'a> { | ||
143 | pub fn has_semi(self) -> bool { | ||
144 | match self.syntax().last_child() { | ||
145 | None => false, | ||
146 | Some(node) => node.kind() == SEMI, | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | impl<'a> LetStmt<'a> { | ||
152 | pub fn has_semi(self) -> bool { | ||
153 | match self.syntax().last_child() { | ||
154 | None => false, | ||
155 | Some(node) => node.kind() == SEMI, | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | |||
160 | impl<'a> IfExpr<'a> { | ||
161 | pub fn then_branch(self) -> Option<Block<'a>> { | ||
162 | self.blocks().nth(0) | ||
163 | } | ||
164 | pub fn else_branch(self) -> Option<Block<'a>> { | ||
165 | self.blocks().nth(1) | ||
166 | } | ||
167 | fn blocks(self) -> AstChildren<'a, Block<'a>> { | ||
168 | children(self) | ||
169 | } | ||
170 | } | ||
171 | |||
172 | fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option<C> { | ||
173 | children(parent).next() | ||
174 | } | ||
175 | |||
176 | fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> AstChildren<'a, C> { | ||
177 | AstChildren::new(parent.syntax()) | ||
178 | } | ||
179 | |||
180 | |||
181 | #[derive(Debug)] | ||
182 | pub struct AstChildren<'a, N> { | ||
183 | inner: SyntaxNodeChildren<RefRoot<'a>>, | ||
184 | ph: PhantomData<N>, | ||
185 | } | ||
186 | |||
187 | impl<'a, N> AstChildren<'a, N> { | ||
188 | fn new(parent: SyntaxNodeRef<'a>) -> Self { | ||
189 | AstChildren { | ||
190 | inner: parent.children(), | ||
191 | ph: PhantomData, | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
196 | impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> { | ||
197 | type Item = N; | ||
198 | fn next(&mut self) -> Option<N> { | ||
199 | loop { | ||
200 | match N::cast(self.inner.next()?) { | ||
201 | Some(n) => return Some(n), | ||
202 | None => (), | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | } | ||
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron new file mode 100644 index 000000000..77ae4c7db --- /dev/null +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -0,0 +1,538 @@ | |||
1 | Grammar( | ||
2 | single_byte_tokens: [ | ||
3 | [";", "SEMI"], | ||
4 | [",", "COMMA"], | ||
5 | ["(", "L_PAREN"], | ||
6 | [")", "R_PAREN"], | ||
7 | ["{", "L_CURLY"], | ||
8 | ["}", "R_CURLY"], | ||
9 | ["[", "L_BRACK"], | ||
10 | ["]", "R_BRACK"], | ||
11 | ["<", "L_ANGLE"], | ||
12 | [">", "R_ANGLE"], | ||
13 | ["@", "AT"], | ||
14 | ["#", "POUND"], | ||
15 | ["~", "TILDE"], | ||
16 | ["?", "QUESTION"], | ||
17 | ["$", "DOLLAR"], | ||
18 | ["&", "AMP"], | ||
19 | ["|", "PIPE"], | ||
20 | ["+", "PLUS"], | ||
21 | ["*", "STAR"], | ||
22 | ["/", "SLASH"], | ||
23 | ["^", "CARET"], | ||
24 | ["%", "PERCENT"], | ||
25 | ], | ||
26 | multi_byte_tokens: [ | ||
27 | [".", "DOT"], | ||
28 | ["..", "DOTDOT"], | ||
29 | ["...", "DOTDOTDOT"], | ||
30 | ["..=", "DOTDOTEQ"], | ||
31 | [":", "COLON"], | ||
32 | ["::", "COLONCOLON"], | ||
33 | ["=", "EQ"], | ||
34 | ["==", "EQEQ"], | ||
35 | ["=>", "FAT_ARROW"], | ||
36 | ["!", "EXCL"], | ||
37 | ["!=", "NEQ"], | ||
38 | ["-", "MINUS"], | ||
39 | ["->", "THIN_ARROW"], | ||
40 | ["<=", "LTEQ"], | ||
41 | [">=", "GTEQ"], | ||
42 | ["+=", "PLUSEQ"], | ||
43 | ["-=", "MINUSEQ"], | ||
44 | ["|=", "PIPEEQ"], | ||
45 | ["&=", "AMPEQ"], | ||
46 | ["^=", "CARETEQ"], | ||
47 | ["/=", "SLASHEQ"], | ||
48 | ["*=", "STAREQ"], | ||
49 | ["&&", "AMPAMP"], | ||
50 | ["||", "PIPEPIPE"], | ||
51 | ["<<", "SHL"], | ||
52 | [">>", "SHR"], | ||
53 | ["<<=", "SHLEQ"], | ||
54 | [">>=", "SHREQ"], | ||
55 | ], | ||
56 | keywords: [ | ||
57 | "use", | ||
58 | "fn", | ||
59 | "struct", | ||
60 | "enum", | ||
61 | "trait", | ||
62 | "impl", | ||
63 | "dyn", | ||
64 | "true", | ||
65 | "false", | ||
66 | "as", | ||
67 | "extern", | ||
68 | "crate", | ||
69 | "mod", | ||
70 | "pub", | ||
71 | "self", | ||
72 | "super", | ||
73 | "in", | ||
74 | "where", | ||
75 | "for", | ||
76 | "loop", | ||
77 | "while", | ||
78 | "continue", | ||
79 | "break", | ||
80 | "if", | ||
81 | "else", | ||
82 | "match", | ||
83 | "const", | ||
84 | "static", | ||
85 | "mut", | ||
86 | "unsafe", | ||
87 | "type", | ||
88 | "ref", | ||
89 | "let", | ||
90 | "move", | ||
91 | "return", | ||
92 | ], | ||
93 | contextual_keywords: [ | ||
94 | "auto", | ||
95 | "default", | ||
96 | "union", | ||
97 | ], | ||
98 | tokens: [ | ||
99 | "ERROR", | ||
100 | "IDENT", | ||
101 | "UNDERSCORE", | ||
102 | "WHITESPACE", | ||
103 | "INT_NUMBER", | ||
104 | "FLOAT_NUMBER", | ||
105 | "LIFETIME", | ||
106 | "CHAR", | ||
107 | "BYTE", | ||
108 | "STRING", | ||
109 | "RAW_STRING", | ||
110 | "BYTE_STRING", | ||
111 | "RAW_BYTE_STRING", | ||
112 | "COMMENT", | ||
113 | "DOC_COMMENT", | ||
114 | "SHEBANG", | ||
115 | ], | ||
116 | nodes: [ | ||
117 | "ROOT", | ||
118 | |||
119 | "STRUCT_DEF", | ||
120 | "ENUM_DEF", | ||
121 | "FN_DEF", | ||
122 | "RET_TYPE", | ||
123 | "EXTERN_CRATE_ITEM", | ||
124 | "MODULE", | ||
125 | "USE_ITEM", | ||
126 | "STATIC_DEF", | ||
127 | "CONST_DEF", | ||
128 | "TRAIT_DEF", | ||
129 | "IMPL_ITEM", | ||
130 | "TYPE_DEF", | ||
131 | "MACRO_CALL", | ||
132 | "TOKEN_TREE", | ||
133 | |||
134 | "PAREN_TYPE", | ||
135 | "TUPLE_TYPE", | ||
136 | "NEVER_TYPE", | ||
137 | "PATH_TYPE", | ||
138 | "POINTER_TYPE", | ||
139 | "ARRAY_TYPE", | ||
140 | "SLICE_TYPE", | ||
141 | "REFERENCE_TYPE", | ||
142 | "PLACEHOLDER_TYPE", | ||
143 | "FN_POINTER_TYPE", | ||
144 | "FOR_TYPE", | ||
145 | "IMPL_TRAIT_TYPE", | ||
146 | "DYN_TRAIT_TYPE", | ||
147 | |||
148 | "REF_PAT", | ||
149 | "BIND_PAT", | ||
150 | "PLACEHOLDER_PAT", | ||
151 | "PATH_PAT", | ||
152 | "STRUCT_PAT", | ||
153 | "FIELD_PAT_LIST", | ||
154 | "TUPLE_STRUCT_PAT", | ||
155 | "TUPLE_PAT", | ||
156 | "SLICE_PAT", | ||
157 | "RANGE_PAT", | ||
158 | |||
159 | // atoms | ||
160 | "TUPLE_EXPR", | ||
161 | "ARRAY_EXPR", | ||
162 | "PAREN_EXPR", | ||
163 | "PATH_EXPR", | ||
164 | "LAMBDA_EXPR", | ||
165 | "IF_EXPR", | ||
166 | "WHILE_EXPR", | ||
167 | "CONDITION", | ||
168 | "LOOP_EXPR", | ||
169 | "FOR_EXPR", | ||
170 | "CONTINUE_EXPR", | ||
171 | "BREAK_EXPR", | ||
172 | "LABEL", | ||
173 | "BLOCK_EXPR", | ||
174 | "RETURN_EXPR", | ||
175 | "MATCH_EXPR", | ||
176 | "MATCH_ARM_LIST", | ||
177 | "MATCH_ARM", | ||
178 | "MATCH_GUARD", | ||
179 | "STRUCT_LIT", | ||
180 | "NAMED_FIELD_LIST", | ||
181 | "NAMED_FIELD", | ||
182 | |||
183 | // postfix | ||
184 | "CALL_EXPR", | ||
185 | "INDEX_EXPR", | ||
186 | "METHOD_CALL_EXPR", | ||
187 | "FIELD_EXPR", | ||
188 | "TRY_EXPR", | ||
189 | "CAST_EXPR", | ||
190 | |||
191 | // unary | ||
192 | "REF_EXPR", | ||
193 | "PREFIX_EXPR", | ||
194 | |||
195 | "RANGE_EXPR", // just weird | ||
196 | "BIN_EXPR", | ||
197 | |||
198 | "BLOCK", | ||
199 | "EXTERN_BLOCK", | ||
200 | "EXTERN_ITEM_LIST", | ||
201 | "ENUM_VARIANT", | ||
202 | "NAMED_FIELD_DEF_LIST", | ||
203 | "NAMED_FIELD_DEF", | ||
204 | "POS_FIELD_LIST", | ||
205 | "POS_FIELD", | ||
206 | "ENUM_VARIANT_LIST", | ||
207 | "ITEM_LIST", | ||
208 | "ATTR", | ||
209 | "META_ITEM", // not an item actually | ||
210 | "USE_TREE", | ||
211 | "USE_TREE_LIST", | ||
212 | "PATH", | ||
213 | "PATH_SEGMENT", | ||
214 | "LITERAL", | ||
215 | "ALIAS", | ||
216 | "VISIBILITY", | ||
217 | "WHERE_CLAUSE", | ||
218 | "WHERE_PRED", | ||
219 | "ABI", | ||
220 | "NAME", | ||
221 | "NAME_REF", | ||
222 | |||
223 | "LET_STMT", | ||
224 | "EXPR_STMT", | ||
225 | |||
226 | "TYPE_PARAM_LIST", | ||
227 | "LIFETIME_PARAM", | ||
228 | "TYPE_PARAM", | ||
229 | "TYPE_ARG_LIST", | ||
230 | "LIFETIME_ARG", | ||
231 | "TYPE_ARG", | ||
232 | "ASSOC_TYPE_ARG", | ||
233 | |||
234 | "PARAM_LIST", | ||
235 | "PARAM", | ||
236 | "SELF_PARAM", | ||
237 | "ARG_LIST", | ||
238 | ], | ||
239 | ast: { | ||
240 | "Root": ( | ||
241 | traits: [ "ModuleItemOwner", "FnDefOwner" ], | ||
242 | collections: [ | ||
243 | ["modules", "Module"], | ||
244 | ] | ||
245 | ), | ||
246 | "FnDef": ( | ||
247 | traits: [ | ||
248 | "NameOwner", | ||
249 | "TypeParamsOwner", | ||
250 | "AttrsOwner", | ||
251 | ], | ||
252 | options: [ "ParamList", ["body", "Block"], "RetType" ], | ||
253 | ), | ||
254 | "RetType": (), | ||
255 | "StructDef": ( | ||
256 | traits: [ | ||
257 | "NameOwner", | ||
258 | "TypeParamsOwner", | ||
259 | "AttrsOwner", | ||
260 | ], | ||
261 | collections: [ | ||
262 | ["fields", "NamedFieldDef"] | ||
263 | ] | ||
264 | ), | ||
265 | "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"] ), | ||
266 | "EnumDef": ( traits: [ | ||
267 | "NameOwner", | ||
268 | "TypeParamsOwner", | ||
269 | "AttrsOwner", | ||
270 | ] ), | ||
271 | "TraitDef": ( traits: ["NameOwner", "AttrsOwner"] ), | ||
272 | "Module": ( | ||
273 | traits: ["NameOwner", "AttrsOwner" ], | ||
274 | options: [ "ItemList" ] | ||
275 | ), | ||
276 | "ItemList": ( | ||
277 | traits: [ "FnDefOwner", "ModuleItemOwner" ], | ||
278 | ), | ||
279 | "ConstDef": ( traits: [ | ||
280 | "NameOwner", | ||
281 | "TypeParamsOwner", | ||
282 | "AttrsOwner", | ||
283 | ] ), | ||
284 | "StaticDef": ( traits: [ | ||
285 | "NameOwner", | ||
286 | "TypeParamsOwner", | ||
287 | "AttrsOwner", | ||
288 | ] ), | ||
289 | "TypeDef": ( traits: [ | ||
290 | "NameOwner", | ||
291 | "TypeParamsOwner", | ||
292 | "AttrsOwner", | ||
293 | ] ), | ||
294 | "ImplItem": (), | ||
295 | |||
296 | "ParenType": (), | ||
297 | "TupleType": (), | ||
298 | "NeverType": (), | ||
299 | "PathType": (), | ||
300 | "PointerType": (), | ||
301 | "ArrayType": (), | ||
302 | "SliceType": (), | ||
303 | "ReferenceType": (), | ||
304 | "PlaceholderType": (), | ||
305 | "FnPointerType": (), | ||
306 | "ForType": (), | ||
307 | "ImplTraitType": (), | ||
308 | "DynTraitType": (), | ||
309 | |||
310 | "TypeRef": ( enum: [ | ||
311 | "ParenType", | ||
312 | "TupleType", | ||
313 | "NeverType", | ||
314 | "PathType", | ||
315 | "PointerType", | ||
316 | "ArrayType", | ||
317 | "SliceType", | ||
318 | "ReferenceType", | ||
319 | "PlaceholderType", | ||
320 | "FnPointerType", | ||
321 | "ForType", | ||
322 | "ImplTraitType", | ||
323 | "DynTraitType", | ||
324 | ]), | ||
325 | |||
326 | "NominalDef": ( | ||
327 | enum: ["StructDef", "EnumDef"], | ||
328 | traits: [ | ||
329 | "NameOwner", | ||
330 | "TypeParamsOwner", | ||
331 | "AttrsOwner" | ||
332 | ], | ||
333 | ), | ||
334 | "ModuleItem": ( | ||
335 | enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplItem", | ||
336 | "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ] | ||
337 | ), | ||
338 | |||
339 | "TupleExpr": (), | ||
340 | "ArrayExpr": (), | ||
341 | "ParenExpr": (), | ||
342 | "PathExpr": (), | ||
343 | "LambdaExpr": ( | ||
344 | options: [ | ||
345 | "ParamList", | ||
346 | ["body", "Expr"], | ||
347 | ] | ||
348 | ), | ||
349 | "IfExpr": ( | ||
350 | options: [ "Condition" ] | ||
351 | ), | ||
352 | "LoopExpr": ( | ||
353 | traits: ["LoopBodyOwner"], | ||
354 | ), | ||
355 | "ForExpr": ( | ||
356 | traits: ["LoopBodyOwner"], | ||
357 | options: [ | ||
358 | "Pat", | ||
359 | ["iterable", "Expr"], | ||
360 | ] | ||
361 | ), | ||
362 | "WhileExpr": ( | ||
363 | traits: ["LoopBodyOwner"], | ||
364 | options: [ "Condition" ] | ||
365 | ), | ||
366 | "ContinueExpr": (), | ||
367 | "BreakExpr": (), | ||
368 | "Label": (), | ||
369 | "BlockExpr": ( | ||
370 | options: [ "Block" ] | ||
371 | ), | ||
372 | "ReturnExpr": (), | ||
373 | "MatchExpr": ( | ||
374 | options: [ "Expr", "MatchArmList" ], | ||
375 | ), | ||
376 | "MatchArmList": ( | ||
377 | collections: [ ["arms", "MatchArm"] ], | ||
378 | ), | ||
379 | "MatchArm": ( | ||
380 | options: [ | ||
381 | [ "guard", "MatchGuard" ], | ||
382 | "Expr", | ||
383 | ], | ||
384 | collections: [ [ "pats", "Pat" ] ] | ||
385 | ), | ||
386 | "MatchGuard": (), | ||
387 | "StructLit": (), | ||
388 | "NamedFieldList": (), | ||
389 | "NamedField": (), | ||
390 | "CallExpr": ( | ||
391 | traits: ["ArgListOwner"], | ||
392 | options: [ "Expr" ], | ||
393 | ), | ||
394 | "MethodCallExpr": ( | ||
395 | traits: ["ArgListOwner"], | ||
396 | options: [ "Expr" ], | ||
397 | ), | ||
398 | "IndexExpr": (), | ||
399 | "FieldExpr": (), | ||
400 | "TryExpr": (), | ||
401 | "CastExpr": (), | ||
402 | "RefExpr": (), | ||
403 | "PrefixExpr": (), | ||
404 | "RangeExpr": (), | ||
405 | "BinExpr": (), | ||
406 | "Literal": (), | ||
407 | |||
408 | "Expr": ( | ||
409 | enum: [ | ||
410 | "TupleExpr", | ||
411 | "ArrayExpr", | ||
412 | "ParenExpr", | ||
413 | "PathExpr", | ||
414 | "LambdaExpr", | ||
415 | "IfExpr", | ||
416 | "LoopExpr", | ||
417 | "ForExpr", | ||
418 | "WhileExpr", | ||
419 | "ContinueExpr", | ||
420 | "BreakExpr", | ||
421 | "Label", | ||
422 | "BlockExpr", | ||
423 | "ReturnExpr", | ||
424 | "MatchExpr", | ||
425 | "MatchArmList", | ||
426 | "MatchArm", | ||
427 | "MatchGuard", | ||
428 | "StructLit", | ||
429 | "NamedFieldList", | ||
430 | "NamedField", | ||
431 | "CallExpr", | ||
432 | "IndexExpr", | ||
433 | "MethodCallExpr", | ||
434 | "FieldExpr", | ||
435 | "TryExpr", | ||
436 | "CastExpr", | ||
437 | "RefExpr", | ||
438 | "PrefixExpr", | ||
439 | "RangeExpr", | ||
440 | "BinExpr", | ||
441 | "Literal", | ||
442 | ], | ||
443 | ), | ||
444 | |||
445 | "RefPat": (), | ||
446 | "BindPat": ( traits: ["NameOwner"] ), | ||
447 | "PlaceholderPat": (), | ||
448 | "PathPat": (), | ||
449 | "StructPat": (), | ||
450 | "FieldPatList": (), | ||
451 | "TupleStructPat": (), | ||
452 | "TuplePat": (), | ||
453 | "SlicePat": (), | ||
454 | "RangePat": (), | ||
455 | |||
456 | "Pat": ( | ||
457 | enum: [ | ||
458 | "RefPat", | ||
459 | "BindPat", | ||
460 | "PlaceholderPat", | ||
461 | "PathPat", | ||
462 | "StructPat", | ||
463 | "FieldPatList", | ||
464 | "TupleStructPat", | ||
465 | "TuplePat", | ||
466 | "SlicePat", | ||
467 | "RangePat", | ||
468 | ], | ||
469 | ), | ||
470 | |||
471 | "Name": (), | ||
472 | "NameRef": (), | ||
473 | "Attr": ( options: [ ["value", "TokenTree"] ] ), | ||
474 | "TokenTree": (), | ||
475 | "TypeParamList": ( | ||
476 | collections: [ | ||
477 | ["type_params", "TypeParam" ], | ||
478 | ["lifetime_params", "LifetimeParam" ], | ||
479 | ] | ||
480 | ), | ||
481 | "TypeParam": ( traits: ["NameOwner"] ), | ||
482 | "LifetimeParam": ( options: [ "Lifetime" ] ), | ||
483 | "Lifetime": (), | ||
484 | "WhereClause": (), | ||
485 | "ExprStmt": ( | ||
486 | options: [ ["expr", "Expr"] ] | ||
487 | ), | ||
488 | "LetStmt": ( options: [ | ||
489 | ["pat", "Pat"], | ||
490 | ["initializer", "Expr"], | ||
491 | ]), | ||
492 | "Condition": ( | ||
493 | options: [ "Pat", "Expr" ] | ||
494 | ), | ||
495 | "Stmt": ( | ||
496 | enum: ["ExprStmt", "LetStmt"], | ||
497 | ), | ||
498 | "Block": ( | ||
499 | options: [ "Expr" ], | ||
500 | collections: [ | ||
501 | ["statements", "Stmt"], | ||
502 | ] | ||
503 | ), | ||
504 | "ParamList": ( | ||
505 | options: [ "SelfParam" ], | ||
506 | collections: [ | ||
507 | ["params", "Param"] | ||
508 | ] | ||
509 | ), | ||
510 | "SelfParam": (), | ||
511 | "Param": ( | ||
512 | options: [ "Pat" ], | ||
513 | ), | ||
514 | "UseItem": ( | ||
515 | options: [ "UseTree" ] | ||
516 | ), | ||
517 | "UseTree": ( | ||
518 | options: [ "Path", "UseTreeList" ] | ||
519 | ), | ||
520 | "UseTreeList": ( | ||
521 | collections: [["use_trees", "UseTree"]] | ||
522 | ), | ||
523 | "ExternCrateItem": (), | ||
524 | "ArgList": ( | ||
525 | collections: [ | ||
526 | ["args", "Expr"] | ||
527 | ] | ||
528 | ), | ||
529 | "Path": ( | ||
530 | options: [ | ||
531 | ["segment", "PathSegment"] | ||
532 | ] | ||
533 | ), | ||
534 | "PathSegment": ( | ||
535 | options: [ "NameRef" ] | ||
536 | ), | ||
537 | }, | ||
538 | ) | ||
diff --git a/crates/ra_syntax/src/grammar/attributes.rs b/crates/ra_syntax/src/grammar/attributes.rs new file mode 100644 index 000000000..cd30e8a45 --- /dev/null +++ b/crates/ra_syntax/src/grammar/attributes.rs | |||
@@ -0,0 +1,31 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn inner_attributes(p: &mut Parser) { | ||
4 | while p.current() == POUND && p.nth(1) == EXCL { | ||
5 | attribute(p, true) | ||
6 | } | ||
7 | } | ||
8 | |||
9 | pub(super) fn outer_attributes(p: &mut Parser) { | ||
10 | while p.at(POUND) { | ||
11 | attribute(p, false) | ||
12 | } | ||
13 | } | ||
14 | |||
15 | fn attribute(p: &mut Parser, inner: bool) { | ||
16 | let attr = p.start(); | ||
17 | assert!(p.at(POUND)); | ||
18 | p.bump(); | ||
19 | |||
20 | if inner { | ||
21 | assert!(p.at(EXCL)); | ||
22 | p.bump(); | ||
23 | } | ||
24 | |||
25 | if p.at(L_BRACK) { | ||
26 | items::token_tree(p); | ||
27 | } else { | ||
28 | p.error("expected `[`"); | ||
29 | } | ||
30 | attr.complete(p, ATTR); | ||
31 | } | ||
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs new file mode 100644 index 000000000..f01df56bc --- /dev/null +++ b/crates/ra_syntax/src/grammar/expressions/atom.rs | |||
@@ -0,0 +1,400 @@ | |||
1 | use super::*; | ||
2 | |||
3 | // test expr_literals | ||
4 | // fn foo() { | ||
5 | // let _ = true; | ||
6 | // let _ = false; | ||
7 | // let _ = 1; | ||
8 | // let _ = 2.0; | ||
9 | // let _ = b'a'; | ||
10 | // let _ = 'b'; | ||
11 | // let _ = "c"; | ||
12 | // let _ = r"d"; | ||
13 | // let _ = b"e"; | ||
14 | // let _ = br"f"; | ||
15 | // } | ||
16 | pub(crate) const LITERAL_FIRST: TokenSet = | ||
17 | token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, | ||
18 | STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING]; | ||
19 | |||
20 | pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> { | ||
21 | if !p.at_ts(LITERAL_FIRST) { | ||
22 | return None; | ||
23 | } | ||
24 | let m = p.start(); | ||
25 | p.bump(); | ||
26 | Some(m.complete(p, LITERAL)) | ||
27 | } | ||
28 | |||
29 | pub(super) const ATOM_EXPR_FIRST: TokenSet = | ||
30 | token_set_union![ | ||
31 | LITERAL_FIRST, | ||
32 | token_set![L_CURLY, L_PAREN, L_BRACK, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, | ||
33 | RETURN_KW, IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ], | ||
34 | ]; | ||
35 | |||
36 | const EXPR_RECOVERY_SET: TokenSet = | ||
37 | token_set![LET_KW]; | ||
38 | |||
39 | pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | ||
40 | match literal(p) { | ||
41 | Some(m) => return Some(m), | ||
42 | None => (), | ||
43 | } | ||
44 | if paths::is_path_start(p) || p.at(L_ANGLE) { | ||
45 | return Some(path_expr(p, r)); | ||
46 | } | ||
47 | let la = p.nth(1); | ||
48 | let done = match p.current() { | ||
49 | L_PAREN => tuple_expr(p), | ||
50 | L_BRACK => array_expr(p), | ||
51 | PIPE => lambda_expr(p), | ||
52 | MOVE_KW if la == PIPE => lambda_expr(p), | ||
53 | IF_KW => if_expr(p), | ||
54 | |||
55 | LOOP_KW => loop_expr(p, None), | ||
56 | FOR_KW => for_expr(p, None), | ||
57 | WHILE_KW => while_expr(p, None), | ||
58 | LIFETIME if la == COLON => { | ||
59 | let m = p.start(); | ||
60 | label(p); | ||
61 | match p.current() { | ||
62 | LOOP_KW => loop_expr(p, Some(m)), | ||
63 | FOR_KW => for_expr(p, Some(m)), | ||
64 | WHILE_KW => while_expr(p, Some(m)), | ||
65 | L_CURLY => block_expr(p, Some(m)), | ||
66 | _ => { | ||
67 | // test misplaced_label_err | ||
68 | // fn main() { | ||
69 | // 'loop: impl | ||
70 | // } | ||
71 | p.error("expected a loop"); | ||
72 | m.complete(p, ERROR); | ||
73 | return None; | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
78 | MATCH_KW => match_expr(p), | ||
79 | UNSAFE_KW if la == L_CURLY => { | ||
80 | let m = p.start(); | ||
81 | p.bump(); | ||
82 | block_expr(p, Some(m)) | ||
83 | }, | ||
84 | L_CURLY => block_expr(p, None), | ||
85 | RETURN_KW => return_expr(p), | ||
86 | CONTINUE_KW => continue_expr(p), | ||
87 | BREAK_KW => break_expr(p), | ||
88 | _ => { | ||
89 | p.err_recover("expected expression", EXPR_RECOVERY_SET); | ||
90 | return None; | ||
91 | } | ||
92 | }; | ||
93 | Some(done) | ||
94 | } | ||
95 | |||
96 | // test tuple_expr | ||
97 | // fn foo() { | ||
98 | // (); | ||
99 | // (1); | ||
100 | // (1,); | ||
101 | // } | ||
102 | fn tuple_expr(p: &mut Parser) -> CompletedMarker { | ||
103 | assert!(p.at(L_PAREN)); | ||
104 | let m = p.start(); | ||
105 | p.expect(L_PAREN); | ||
106 | |||
107 | let mut saw_comma = false; | ||
108 | let mut saw_expr = false; | ||
109 | while !p.at(EOF) && !p.at(R_PAREN) { | ||
110 | saw_expr = true; | ||
111 | if !p.at_ts(EXPR_FIRST) { | ||
112 | p.error("expected expression"); | ||
113 | break; | ||
114 | } | ||
115 | expr(p); | ||
116 | if !p.at(R_PAREN) { | ||
117 | saw_comma = true; | ||
118 | p.expect(COMMA); | ||
119 | } | ||
120 | } | ||
121 | p.expect(R_PAREN); | ||
122 | m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR }) | ||
123 | } | ||
124 | |||
125 | // test array_expr | ||
126 | // fn foo() { | ||
127 | // []; | ||
128 | // [1]; | ||
129 | // [1, 2,]; | ||
130 | // [1; 2]; | ||
131 | // } | ||
132 | fn array_expr(p: &mut Parser) -> CompletedMarker { | ||
133 | assert!(p.at(L_BRACK)); | ||
134 | let m = p.start(); | ||
135 | p.bump(); | ||
136 | if p.eat(R_BRACK) { | ||
137 | return m.complete(p, ARRAY_EXPR); | ||
138 | } | ||
139 | expr(p); | ||
140 | if p.eat(SEMI) { | ||
141 | expr(p); | ||
142 | p.expect(R_BRACK); | ||
143 | return m.complete(p, ARRAY_EXPR); | ||
144 | } | ||
145 | while !p.at(EOF) && !p.at(R_BRACK) { | ||
146 | p.expect(COMMA); | ||
147 | if p.at(R_BRACK) { | ||
148 | break; | ||
149 | } | ||
150 | if !p.at_ts(EXPR_FIRST) { | ||
151 | p.error("expected expression"); | ||
152 | break; | ||
153 | } | ||
154 | expr(p); | ||
155 | } | ||
156 | p.expect(R_BRACK); | ||
157 | m.complete(p, ARRAY_EXPR) | ||
158 | } | ||
159 | |||
160 | // test lambda_expr | ||
161 | // fn foo() { | ||
162 | // || (); | ||
163 | // || -> i32 { 92 }; | ||
164 | // |x| x; | ||
165 | // move |x: i32,| x; | ||
166 | // } | ||
167 | fn lambda_expr(p: &mut Parser) -> CompletedMarker { | ||
168 | assert!(p.at(PIPE) || (p.at(MOVE_KW) && p.nth(1) == PIPE)); | ||
169 | let m = p.start(); | ||
170 | p.eat(MOVE_KW); | ||
171 | params::param_list_opt_types(p); | ||
172 | if opt_fn_ret_type(p) { | ||
173 | if !p.at(L_CURLY) { | ||
174 | p.error("expected `{`"); | ||
175 | } | ||
176 | } | ||
177 | expr(p); | ||
178 | m.complete(p, LAMBDA_EXPR) | ||
179 | } | ||
180 | |||
181 | // test if_expr | ||
182 | // fn foo() { | ||
183 | // if true {}; | ||
184 | // if true {} else {}; | ||
185 | // if true {} else if false {} else {}; | ||
186 | // if S {}; | ||
187 | // } | ||
188 | fn if_expr(p: &mut Parser) -> CompletedMarker { | ||
189 | assert!(p.at(IF_KW)); | ||
190 | let m = p.start(); | ||
191 | p.bump(); | ||
192 | cond(p); | ||
193 | block(p); | ||
194 | if p.at(ELSE_KW) { | ||
195 | p.bump(); | ||
196 | if p.at(IF_KW) { | ||
197 | if_expr(p); | ||
198 | } else { | ||
199 | block(p); | ||
200 | } | ||
201 | } | ||
202 | m.complete(p, IF_EXPR) | ||
203 | } | ||
204 | |||
205 | // test label | ||
206 | // fn foo() { | ||
207 | // 'a: loop {} | ||
208 | // 'b: while true {} | ||
209 | // 'c: for x in () {} | ||
210 | // } | ||
211 | fn label(p: &mut Parser) { | ||
212 | assert!(p.at(LIFETIME) && p.nth(1) == COLON); | ||
213 | let m = p.start(); | ||
214 | p.bump(); | ||
215 | p.bump(); | ||
216 | m.complete(p, LABEL); | ||
217 | } | ||
218 | |||
219 | // test loop_expr | ||
220 | // fn foo() { | ||
221 | // loop {}; | ||
222 | // } | ||
223 | fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
224 | assert!(p.at(LOOP_KW)); | ||
225 | let m = m.unwrap_or_else(|| p.start()); | ||
226 | p.bump(); | ||
227 | block(p); | ||
228 | m.complete(p, LOOP_EXPR) | ||
229 | } | ||
230 | |||
231 | // test while_expr | ||
232 | // fn foo() { | ||
233 | // while true {}; | ||
234 | // while let Some(x) = it.next() {}; | ||
235 | // } | ||
236 | fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
237 | assert!(p.at(WHILE_KW)); | ||
238 | let m = m.unwrap_or_else(|| p.start()); | ||
239 | p.bump(); | ||
240 | cond(p); | ||
241 | block(p); | ||
242 | m.complete(p, WHILE_EXPR) | ||
243 | } | ||
244 | |||
245 | // test for_expr | ||
246 | // fn foo() { | ||
247 | // for x in [] {}; | ||
248 | // } | ||
249 | fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
250 | assert!(p.at(FOR_KW)); | ||
251 | let m = m.unwrap_or_else(|| p.start()); | ||
252 | p.bump(); | ||
253 | patterns::pattern(p); | ||
254 | p.expect(IN_KW); | ||
255 | expr_no_struct(p); | ||
256 | block(p); | ||
257 | m.complete(p, FOR_EXPR) | ||
258 | } | ||
259 | |||
260 | // test cond | ||
261 | // fn foo() { if let Some(_) = None {} } | ||
262 | fn cond(p: &mut Parser) { | ||
263 | let m = p.start(); | ||
264 | if p.eat(LET_KW) { | ||
265 | patterns::pattern(p); | ||
266 | p.expect(EQ); | ||
267 | } | ||
268 | expr_no_struct(p); | ||
269 | m.complete(p, CONDITION); | ||
270 | } | ||
271 | |||
272 | // test match_expr | ||
273 | // fn foo() { | ||
274 | // match () { }; | ||
275 | // match S {}; | ||
276 | // } | ||
277 | fn match_expr(p: &mut Parser) -> CompletedMarker { | ||
278 | assert!(p.at(MATCH_KW)); | ||
279 | let m = p.start(); | ||
280 | p.bump(); | ||
281 | expr_no_struct(p); | ||
282 | if p.at(L_CURLY) { | ||
283 | match_arm_list(p); | ||
284 | } else { | ||
285 | p.error("expected `{`") | ||
286 | } | ||
287 | m.complete(p, MATCH_EXPR) | ||
288 | } | ||
289 | |||
290 | pub(crate) fn match_arm_list(p: &mut Parser) { | ||
291 | assert!(p.at(L_CURLY)); | ||
292 | let m = p.start(); | ||
293 | p.eat(L_CURLY); | ||
294 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
295 | if p.at(L_CURLY) { | ||
296 | error_block(p, "expected match arm"); | ||
297 | continue; | ||
298 | } | ||
299 | // test match_arms_commas | ||
300 | // fn foo() { | ||
301 | // match () { | ||
302 | // _ => (), | ||
303 | // _ => {} | ||
304 | // _ => () | ||
305 | // } | ||
306 | // } | ||
307 | if match_arm(p).is_block() { | ||
308 | p.eat(COMMA); | ||
309 | } else if !p.at(R_CURLY) { | ||
310 | p.expect(COMMA); | ||
311 | } | ||
312 | } | ||
313 | p.expect(R_CURLY); | ||
314 | m.complete(p, MATCH_ARM_LIST); | ||
315 | } | ||
316 | |||
317 | // test match_arm | ||
318 | // fn foo() { | ||
319 | // match () { | ||
320 | // _ => (), | ||
321 | // X | Y if Z => (), | ||
322 | // }; | ||
323 | // } | ||
324 | fn match_arm(p: &mut Parser) -> BlockLike { | ||
325 | let m = p.start(); | ||
326 | patterns::pattern_r(p, TokenSet::EMPTY); | ||
327 | while p.eat(PIPE) { | ||
328 | patterns::pattern(p); | ||
329 | } | ||
330 | if p.eat(IF_KW) { | ||
331 | expr_no_struct(p); | ||
332 | } | ||
333 | p.expect(FAT_ARROW); | ||
334 | let ret = expr_stmt(p); | ||
335 | m.complete(p, MATCH_ARM); | ||
336 | ret | ||
337 | } | ||
338 | |||
339 | // test block_expr | ||
340 | // fn foo() { | ||
341 | // {}; | ||
342 | // unsafe {}; | ||
343 | // 'label: {}; | ||
344 | // } | ||
345 | fn block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
346 | assert!(p.at(L_CURLY)); | ||
347 | let m = m.unwrap_or_else(|| p.start()); | ||
348 | block(p); | ||
349 | m.complete(p, BLOCK_EXPR) | ||
350 | } | ||
351 | |||
352 | // test return_expr | ||
353 | // fn foo() { | ||
354 | // return; | ||
355 | // return 92; | ||
356 | // } | ||
357 | fn return_expr(p: &mut Parser) -> CompletedMarker { | ||
358 | assert!(p.at(RETURN_KW)); | ||
359 | let m = p.start(); | ||
360 | p.bump(); | ||
361 | if p.at_ts(EXPR_FIRST) { | ||
362 | expr(p); | ||
363 | } | ||
364 | m.complete(p, RETURN_EXPR) | ||
365 | } | ||
366 | |||
367 | // test continue_expr | ||
368 | // fn foo() { | ||
369 | // loop { | ||
370 | // continue; | ||
371 | // continue 'l; | ||
372 | // } | ||
373 | // } | ||
374 | fn continue_expr(p: &mut Parser) -> CompletedMarker { | ||
375 | assert!(p.at(CONTINUE_KW)); | ||
376 | let m = p.start(); | ||
377 | p.bump(); | ||
378 | p.eat(LIFETIME); | ||
379 | m.complete(p, CONTINUE_EXPR) | ||
380 | } | ||
381 | |||
382 | // test break_expr | ||
383 | // fn foo() { | ||
384 | // loop { | ||
385 | // break; | ||
386 | // break 'l; | ||
387 | // break 92; | ||
388 | // break 'l 92; | ||
389 | // } | ||
390 | // } | ||
391 | fn break_expr(p: &mut Parser) -> CompletedMarker { | ||
392 | assert!(p.at(BREAK_KW)); | ||
393 | let m = p.start(); | ||
394 | p.bump(); | ||
395 | p.eat(LIFETIME); | ||
396 | if p.at_ts(EXPR_FIRST) { | ||
397 | expr(p); | ||
398 | } | ||
399 | m.complete(p, BREAK_EXPR) | ||
400 | } | ||
diff --git a/crates/ra_syntax/src/grammar/expressions/mod.rs b/crates/ra_syntax/src/grammar/expressions/mod.rs new file mode 100644 index 000000000..20e0fa328 --- /dev/null +++ b/crates/ra_syntax/src/grammar/expressions/mod.rs | |||
@@ -0,0 +1,450 @@ | |||
1 | mod atom; | ||
2 | |||
3 | use super::*; | ||
4 | pub(super) use self::atom::{literal, LITERAL_FIRST}; | ||
5 | pub(crate) use self::atom::match_arm_list; | ||
6 | |||
7 | const EXPR_FIRST: TokenSet = LHS_FIRST; | ||
8 | |||
9 | pub(super) fn expr(p: &mut Parser) -> BlockLike { | ||
10 | let r = Restrictions { forbid_structs: false, prefer_stmt: false }; | ||
11 | expr_bp(p, r, 1) | ||
12 | } | ||
13 | |||
14 | pub(super) fn expr_stmt(p: &mut Parser) -> BlockLike { | ||
15 | let r = Restrictions { forbid_structs: false, prefer_stmt: true }; | ||
16 | expr_bp(p, r, 1) | ||
17 | } | ||
18 | |||
19 | fn expr_no_struct(p: &mut Parser) { | ||
20 | let r = Restrictions { forbid_structs: true, prefer_stmt: false }; | ||
21 | expr_bp(p, r, 1); | ||
22 | } | ||
23 | |||
24 | // test block | ||
25 | // fn a() {} | ||
26 | // fn b() { let _ = 1; } | ||
27 | // fn c() { 1; 2; } | ||
28 | // fn d() { 1; 2 } | ||
29 | pub(crate) fn block(p: &mut Parser) { | ||
30 | if !p.at(L_CURLY) { | ||
31 | p.error("expected a block"); | ||
32 | return; | ||
33 | } | ||
34 | let m = p.start(); | ||
35 | p.bump(); | ||
36 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
37 | match p.current() { | ||
38 | LET_KW => let_stmt(p), | ||
39 | _ => { | ||
40 | // test block_items | ||
41 | // fn a() { fn b() {} } | ||
42 | let m = p.start(); | ||
43 | match items::maybe_item(p, items::ItemFlavor::Mod) { | ||
44 | items::MaybeItem::Item(kind) => { | ||
45 | m.complete(p, kind); | ||
46 | } | ||
47 | items::MaybeItem::Modifiers => { | ||
48 | m.abandon(p); | ||
49 | p.error("expected an item"); | ||
50 | } | ||
51 | // test pub_expr | ||
52 | // fn foo() { pub 92; } //FIXME | ||
53 | items::MaybeItem::None => { | ||
54 | let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; | ||
55 | if p.at(R_CURLY) { | ||
56 | m.abandon(p); | ||
57 | } else { | ||
58 | if is_blocklike { | ||
59 | p.eat(SEMI); | ||
60 | } else { | ||
61 | p.expect(SEMI); | ||
62 | } | ||
63 | m.complete(p, EXPR_STMT); | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | p.expect(R_CURLY); | ||
71 | m.complete(p, BLOCK); | ||
72 | |||
73 | // test let_stmt; | ||
74 | // fn foo() { | ||
75 | // let a; | ||
76 | // let b: i32; | ||
77 | // let c = 92; | ||
78 | // let d: i32 = 92; | ||
79 | // } | ||
80 | fn let_stmt(p: &mut Parser) { | ||
81 | assert!(p.at(LET_KW)); | ||
82 | let m = p.start(); | ||
83 | p.bump(); | ||
84 | patterns::pattern(p); | ||
85 | if p.at(COLON) { | ||
86 | types::ascription(p); | ||
87 | } | ||
88 | if p.eat(EQ) { | ||
89 | expressions::expr(p); | ||
90 | } | ||
91 | p.expect(SEMI); | ||
92 | m.complete(p, LET_STMT); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | #[derive(Clone, Copy)] | ||
97 | struct Restrictions { | ||
98 | forbid_structs: bool, | ||
99 | prefer_stmt: bool, | ||
100 | } | ||
101 | |||
102 | enum Op { | ||
103 | Simple, | ||
104 | Composite(SyntaxKind, u8), | ||
105 | } | ||
106 | |||
107 | fn current_op(p: &Parser) -> (u8, Op) { | ||
108 | if let Some(t) = p.next3() { | ||
109 | match t { | ||
110 | (L_ANGLE, L_ANGLE, EQ) => | ||
111 | return (1, Op::Composite(SHLEQ, 3)), | ||
112 | (R_ANGLE, R_ANGLE, EQ) => | ||
113 | return (1, Op::Composite(SHREQ, 3)), | ||
114 | _ => (), | ||
115 | } | ||
116 | } | ||
117 | |||
118 | if let Some(t) = p.next2() { | ||
119 | match t { | ||
120 | (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)), | ||
121 | (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)), | ||
122 | (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)), | ||
123 | (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)), | ||
124 | (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)), | ||
125 | (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)), | ||
126 | (CARET, EQ) => return (1, Op::Composite(CARETEQ, 2)), | ||
127 | (PIPE, PIPE) => return (3, Op::Composite(PIPEPIPE, 2)), | ||
128 | (AMP, AMP) => return (4, Op::Composite(AMPAMP, 2)), | ||
129 | (L_ANGLE, EQ) => return (5, Op::Composite(LTEQ, 2)), | ||
130 | (R_ANGLE, EQ) => return (5, Op::Composite(GTEQ, 2)), | ||
131 | (L_ANGLE, L_ANGLE) => return (9, Op::Composite(SHL, 2)), | ||
132 | (R_ANGLE, R_ANGLE) => return (9, Op::Composite(SHR, 2)), | ||
133 | _ => (), | ||
134 | } | ||
135 | } | ||
136 | |||
137 | let bp = match p.current() { | ||
138 | EQ => 1, | ||
139 | DOTDOT => 2, | ||
140 | EQEQ | NEQ | L_ANGLE | R_ANGLE => 5, | ||
141 | PIPE => 6, | ||
142 | CARET => 7, | ||
143 | AMP => 8, | ||
144 | MINUS | PLUS => 10, | ||
145 | STAR | SLASH | PERCENT => 11, | ||
146 | _ => 0, | ||
147 | }; | ||
148 | (bp, Op::Simple) | ||
149 | } | ||
150 | |||
151 | // Parses expression with binding power of at least bp. | ||
152 | fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike { | ||
153 | let mut lhs = match lhs(p, r) { | ||
154 | Some(lhs) => { | ||
155 | // test stmt_bin_expr_ambiguity | ||
156 | // fn foo() { | ||
157 | // let _ = {1} & 2; | ||
158 | // {1} &2; | ||
159 | // } | ||
160 | if r.prefer_stmt && is_block(lhs.kind()) { | ||
161 | return BlockLike::Block; | ||
162 | } | ||
163 | lhs | ||
164 | } | ||
165 | None => return BlockLike::NotBlock, | ||
166 | }; | ||
167 | |||
168 | loop { | ||
169 | let is_range = p.current() == DOTDOT; | ||
170 | let (op_bp, op) = current_op(p); | ||
171 | if op_bp < bp { | ||
172 | break; | ||
173 | } | ||
174 | let m = lhs.precede(p); | ||
175 | match op { | ||
176 | Op::Simple => p.bump(), | ||
177 | Op::Composite(kind, n) => { | ||
178 | p.bump_compound(kind, n); | ||
179 | } | ||
180 | } | ||
181 | expr_bp(p, r, op_bp + 1); | ||
182 | lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); | ||
183 | } | ||
184 | BlockLike::NotBlock | ||
185 | } | ||
186 | |||
187 | // test no_semi_after_block | ||
188 | // fn foo() { | ||
189 | // if true {} | ||
190 | // loop {} | ||
191 | // match () {} | ||
192 | // while true {} | ||
193 | // for _ in () {} | ||
194 | // {} | ||
195 | // {} | ||
196 | // } | ||
197 | fn is_block(kind: SyntaxKind) -> bool { | ||
198 | match kind { | ||
199 | IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => true, | ||
200 | _ => false, | ||
201 | } | ||
202 | } | ||
203 | |||
204 | const LHS_FIRST: TokenSet = | ||
205 | token_set_union![ | ||
206 | token_set![AMP, STAR, EXCL, DOTDOT, MINUS], | ||
207 | atom::ATOM_EXPR_FIRST, | ||
208 | ]; | ||
209 | |||
210 | fn lhs(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | ||
211 | let m; | ||
212 | let kind = match p.current() { | ||
213 | // test ref_expr | ||
214 | // fn foo() { | ||
215 | // let _ = &1; | ||
216 | // let _ = &mut &f(); | ||
217 | // } | ||
218 | AMP => { | ||
219 | m = p.start(); | ||
220 | p.bump(); | ||
221 | p.eat(MUT_KW); | ||
222 | REF_EXPR | ||
223 | } | ||
224 | // test unary_expr | ||
225 | // fn foo() { | ||
226 | // **&1; | ||
227 | // !!true; | ||
228 | // --1; | ||
229 | // } | ||
230 | STAR | EXCL | MINUS => { | ||
231 | m = p.start(); | ||
232 | p.bump(); | ||
233 | PREFIX_EXPR | ||
234 | } | ||
235 | // test full_range_expr | ||
236 | // fn foo() { xs[..]; } | ||
237 | DOTDOT => { | ||
238 | m = p.start(); | ||
239 | p.bump(); | ||
240 | if p.at_ts(EXPR_FIRST) { | ||
241 | expr_bp(p, r, 2); | ||
242 | } | ||
243 | return Some(m.complete(p, RANGE_EXPR)); | ||
244 | } | ||
245 | _ => { | ||
246 | let lhs = atom::atom_expr(p, r)?; | ||
247 | return Some(postfix_expr(p, r, lhs)); | ||
248 | } | ||
249 | }; | ||
250 | expr_bp(p, r, 255); | ||
251 | Some(m.complete(p, kind)) | ||
252 | } | ||
253 | |||
254 | fn postfix_expr(p: &mut Parser, r: Restrictions, mut lhs: CompletedMarker) -> CompletedMarker { | ||
255 | let mut allow_calls = !r.prefer_stmt || !is_block(lhs.kind()); | ||
256 | loop { | ||
257 | lhs = match p.current() { | ||
258 | // test stmt_postfix_expr_ambiguity | ||
259 | // fn foo() { | ||
260 | // match () { | ||
261 | // _ => {} | ||
262 | // () => {} | ||
263 | // [] => {} | ||
264 | // } | ||
265 | // } | ||
266 | L_PAREN if allow_calls => call_expr(p, lhs), | ||
267 | L_BRACK if allow_calls => index_expr(p, lhs), | ||
268 | DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON { | ||
269 | method_call_expr(p, lhs) | ||
270 | } else { | ||
271 | field_expr(p, lhs) | ||
272 | }, | ||
273 | DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), | ||
274 | // test postfix_range | ||
275 | // fn foo() { let x = 1..; } | ||
276 | DOTDOT if !EXPR_FIRST.contains(p.nth(1)) => { | ||
277 | let m = lhs.precede(p); | ||
278 | p.bump(); | ||
279 | m.complete(p, RANGE_EXPR) | ||
280 | } | ||
281 | QUESTION => try_expr(p, lhs), | ||
282 | AS_KW => cast_expr(p, lhs), | ||
283 | _ => break, | ||
284 | }; | ||
285 | allow_calls = true | ||
286 | } | ||
287 | lhs | ||
288 | } | ||
289 | |||
290 | // test call_expr | ||
291 | // fn foo() { | ||
292 | // let _ = f(); | ||
293 | // let _ = f()(1)(1, 2,); | ||
294 | // } | ||
295 | fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
296 | assert!(p.at(L_PAREN)); | ||
297 | let m = lhs.precede(p); | ||
298 | arg_list(p); | ||
299 | m.complete(p, CALL_EXPR) | ||
300 | } | ||
301 | |||
302 | // test index_expr | ||
303 | // fn foo() { | ||
304 | // x[1][2]; | ||
305 | // } | ||
306 | fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
307 | assert!(p.at(L_BRACK)); | ||
308 | let m = lhs.precede(p); | ||
309 | p.bump(); | ||
310 | expr(p); | ||
311 | p.expect(R_BRACK); | ||
312 | m.complete(p, INDEX_EXPR) | ||
313 | } | ||
314 | |||
315 | // test method_call_expr | ||
316 | // fn foo() { | ||
317 | // x.foo(); | ||
318 | // y.bar::<T>(1, 2,); | ||
319 | // } | ||
320 | fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
321 | assert!( | ||
322 | p.at(DOT) && p.nth(1) == IDENT | ||
323 | && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) | ||
324 | ); | ||
325 | let m = lhs.precede(p); | ||
326 | p.bump(); | ||
327 | name_ref(p); | ||
328 | type_args::opt_type_arg_list(p, true); | ||
329 | if p.at(L_PAREN) { | ||
330 | arg_list(p); | ||
331 | } | ||
332 | m.complete(p, METHOD_CALL_EXPR) | ||
333 | } | ||
334 | |||
335 | // test field_expr | ||
336 | // fn foo() { | ||
337 | // x.foo; | ||
338 | // x.0.bar; | ||
339 | // } | ||
340 | fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
341 | assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER)); | ||
342 | let m = lhs.precede(p); | ||
343 | p.bump(); | ||
344 | if p.at(IDENT) { | ||
345 | name_ref(p) | ||
346 | } else { | ||
347 | p.bump() | ||
348 | } | ||
349 | m.complete(p, FIELD_EXPR) | ||
350 | } | ||
351 | |||
352 | // test try_expr | ||
353 | // fn foo() { | ||
354 | // x?; | ||
355 | // } | ||
356 | fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
357 | assert!(p.at(QUESTION)); | ||
358 | let m = lhs.precede(p); | ||
359 | p.bump(); | ||
360 | m.complete(p, TRY_EXPR) | ||
361 | } | ||
362 | |||
363 | // test cast_expr | ||
364 | // fn foo() { | ||
365 | // 82 as i32; | ||
366 | // } | ||
367 | fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
368 | assert!(p.at(AS_KW)); | ||
369 | let m = lhs.precede(p); | ||
370 | p.bump(); | ||
371 | types::type_(p); | ||
372 | m.complete(p, CAST_EXPR) | ||
373 | } | ||
374 | |||
375 | fn arg_list(p: &mut Parser) { | ||
376 | assert!(p.at(L_PAREN)); | ||
377 | let m = p.start(); | ||
378 | p.bump(); | ||
379 | while !p.at(R_PAREN) && !p.at(EOF) { | ||
380 | if !p.at_ts(EXPR_FIRST) { | ||
381 | p.error("expected expression"); | ||
382 | break; | ||
383 | } | ||
384 | expr(p); | ||
385 | if !p.at(R_PAREN) && !p.expect(COMMA) { | ||
386 | break; | ||
387 | } | ||
388 | } | ||
389 | p.eat(R_PAREN); | ||
390 | m.complete(p, ARG_LIST); | ||
391 | } | ||
392 | |||
393 | // test path_expr | ||
394 | // fn foo() { | ||
395 | // let _ = a; | ||
396 | // let _ = a::b; | ||
397 | // let _ = ::a::<b>; | ||
398 | // let _ = format!(); | ||
399 | // } | ||
400 | fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { | ||
401 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); | ||
402 | let m = p.start(); | ||
403 | paths::expr_path(p); | ||
404 | match p.current() { | ||
405 | L_CURLY if !r.forbid_structs => { | ||
406 | named_field_list(p); | ||
407 | m.complete(p, STRUCT_LIT) | ||
408 | } | ||
409 | EXCL => { | ||
410 | items::macro_call_after_excl(p); | ||
411 | m.complete(p, MACRO_CALL) | ||
412 | } | ||
413 | _ => m.complete(p, PATH_EXPR) | ||
414 | } | ||
415 | } | ||
416 | |||
417 | // test struct_lit | ||
418 | // fn foo() { | ||
419 | // S {}; | ||
420 | // S { x, y: 32, }; | ||
421 | // S { x, y: 32, ..Default::default() }; | ||
422 | // } | ||
423 | pub(crate) fn named_field_list(p: &mut Parser) { | ||
424 | assert!(p.at(L_CURLY)); | ||
425 | let m = p.start(); | ||
426 | p.bump(); | ||
427 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
428 | match p.current() { | ||
429 | IDENT => { | ||
430 | let m = p.start(); | ||
431 | name_ref(p); | ||
432 | if p.eat(COLON) { | ||
433 | expr(p); | ||
434 | } | ||
435 | m.complete(p, NAMED_FIELD); | ||
436 | } | ||
437 | DOTDOT => { | ||
438 | p.bump(); | ||
439 | expr(p); | ||
440 | } | ||
441 | L_CURLY => error_block(p, "expected a field"), | ||
442 | _ => p.err_and_bump("expected identifier"), | ||
443 | } | ||
444 | if !p.at(R_CURLY) { | ||
445 | p.expect(COMMA); | ||
446 | } | ||
447 | } | ||
448 | p.expect(R_CURLY); | ||
449 | m.complete(p, NAMED_FIELD_LIST); | ||
450 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/consts.rs b/crates/ra_syntax/src/grammar/items/consts.rs new file mode 100644 index 000000000..5a5852f83 --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/consts.rs | |||
@@ -0,0 +1,21 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn static_def(p: &mut Parser) { | ||
4 | const_or_static(p, STATIC_KW) | ||
5 | } | ||
6 | |||
7 | pub(super) fn const_def(p: &mut Parser) { | ||
8 | const_or_static(p, CONST_KW) | ||
9 | } | ||
10 | |||
11 | fn const_or_static(p: &mut Parser, kw: SyntaxKind) { | ||
12 | assert!(p.at(kw)); | ||
13 | p.bump(); | ||
14 | p.eat(MUT_KW); // TODO: validator to forbid const mut | ||
15 | name(p); | ||
16 | types::ascription(p); | ||
17 | if p.eat(EQ) { | ||
18 | expressions::expr(p); | ||
19 | } | ||
20 | p.expect(SEMI); | ||
21 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/mod.rs b/crates/ra_syntax/src/grammar/items/mod.rs new file mode 100644 index 000000000..2567313ab --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/mod.rs | |||
@@ -0,0 +1,393 @@ | |||
1 | |||
2 | mod consts; | ||
3 | mod nominal; | ||
4 | mod traits; | ||
5 | mod use_item; | ||
6 | |||
7 | use super::*; | ||
8 | pub(crate) use self::{ | ||
9 | expressions::{named_field_list, match_arm_list}, | ||
10 | nominal::{enum_variant_list, named_field_def_list}, | ||
11 | traits::{trait_item_list, impl_item_list}, | ||
12 | use_item::use_tree_list, | ||
13 | }; | ||
14 | |||
15 | // test mod_contents | ||
16 | // fn foo() {} | ||
17 | // macro_rules! foo {} | ||
18 | // foo::bar!(); | ||
19 | // super::baz! {} | ||
20 | // struct S; | ||
21 | pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { | ||
22 | attributes::inner_attributes(p); | ||
23 | while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { | ||
24 | item_or_macro(p, stop_on_r_curly, ItemFlavor::Mod) | ||
25 | } | ||
26 | } | ||
27 | |||
28 | pub(super) enum ItemFlavor { | ||
29 | Mod, Trait | ||
30 | } | ||
31 | |||
32 | const ITEM_RECOVERY_SET: TokenSet = | ||
33 | token_set![FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW, | ||
34 | MOD_KW, PUB_KW, CRATE_KW]; | ||
35 | |||
36 | pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) { | ||
37 | let m = p.start(); | ||
38 | match maybe_item(p, flavor) { | ||
39 | MaybeItem::Item(kind) => { | ||
40 | m.complete(p, kind); | ||
41 | } | ||
42 | MaybeItem::None => { | ||
43 | if paths::is_path_start(p) { | ||
44 | match macro_call(p) { | ||
45 | BlockLike::Block => (), | ||
46 | BlockLike::NotBlock => { | ||
47 | p.expect(SEMI); | ||
48 | } | ||
49 | } | ||
50 | m.complete(p, MACRO_CALL); | ||
51 | } else { | ||
52 | m.abandon(p); | ||
53 | if p.at(L_CURLY) { | ||
54 | error_block(p, "expected an item"); | ||
55 | } else if p.at(R_CURLY) && !stop_on_r_curly { | ||
56 | let e = p.start(); | ||
57 | p.error("unmatched `}`"); | ||
58 | p.bump(); | ||
59 | e.complete(p, ERROR); | ||
60 | } else if !p.at(EOF) && !p.at(R_CURLY) { | ||
61 | p.err_and_bump("expected an item"); | ||
62 | } else { | ||
63 | p.error("expected an item"); | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | MaybeItem::Modifiers => { | ||
68 | p.error("expected fn, trait or impl"); | ||
69 | m.complete(p, ERROR); | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | pub(super) enum MaybeItem { | ||
75 | None, | ||
76 | Item(SyntaxKind), | ||
77 | Modifiers, | ||
78 | } | ||
79 | |||
80 | pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { | ||
81 | attributes::outer_attributes(p); | ||
82 | opt_visibility(p); | ||
83 | if let Some(kind) = items_without_modifiers(p) { | ||
84 | return MaybeItem::Item(kind); | ||
85 | } | ||
86 | |||
87 | let mut has_mods = false; | ||
88 | // modifiers | ||
89 | has_mods |= p.eat(CONST_KW); | ||
90 | |||
91 | // test unsafe_block_in_mod | ||
92 | // fn foo(){} unsafe { } fn bar(){} | ||
93 | if p.at(UNSAFE_KW) && p.nth(1) != L_CURLY { | ||
94 | p.eat(UNSAFE_KW); | ||
95 | has_mods = true; | ||
96 | } | ||
97 | if p.at(EXTERN_KW) { | ||
98 | has_mods = true; | ||
99 | abi(p); | ||
100 | } | ||
101 | if p.at(IDENT) && p.at_contextual_kw("auto") && p.nth(1) == TRAIT_KW { | ||
102 | p.bump_remap(AUTO_KW); | ||
103 | has_mods = true; | ||
104 | } | ||
105 | if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == IMPL_KW { | ||
106 | p.bump_remap(DEFAULT_KW); | ||
107 | has_mods = true; | ||
108 | } | ||
109 | |||
110 | // items | ||
111 | let kind = match p.current() { | ||
112 | // test extern_fn | ||
113 | // extern fn foo() {} | ||
114 | |||
115 | // test const_fn | ||
116 | // const fn foo() {} | ||
117 | |||
118 | // test const_unsafe_fn | ||
119 | // const unsafe fn foo() {} | ||
120 | |||
121 | // test unsafe_extern_fn | ||
122 | // unsafe extern "C" fn foo() {} | ||
123 | |||
124 | // test unsafe_fn | ||
125 | // unsafe fn foo() {} | ||
126 | FN_KW => { | ||
127 | fn_def(p, flavor); | ||
128 | FN_DEF | ||
129 | } | ||
130 | |||
131 | // test unsafe_trait | ||
132 | // unsafe trait T {} | ||
133 | |||
134 | // test auto_trait | ||
135 | // auto trait T {} | ||
136 | |||
137 | // test unsafe_auto_trait | ||
138 | // unsafe auto trait T {} | ||
139 | TRAIT_KW => { | ||
140 | traits::trait_def(p); | ||
141 | TRAIT_DEF | ||
142 | } | ||
143 | |||
144 | // test unsafe_impl | ||
145 | // unsafe impl Foo {} | ||
146 | |||
147 | // test default_impl | ||
148 | // default impl Foo {} | ||
149 | |||
150 | // test unsafe_default_impl | ||
151 | // unsafe default impl Foo {} | ||
152 | IMPL_KW => { | ||
153 | traits::impl_item(p); | ||
154 | IMPL_ITEM | ||
155 | } | ||
156 | _ => return if has_mods { | ||
157 | MaybeItem::Modifiers | ||
158 | } else { | ||
159 | MaybeItem::None | ||
160 | } | ||
161 | }; | ||
162 | |||
163 | MaybeItem::Item(kind) | ||
164 | } | ||
165 | |||
166 | fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> { | ||
167 | let la = p.nth(1); | ||
168 | let kind = match p.current() { | ||
169 | // test extern_crate | ||
170 | // extern crate foo; | ||
171 | EXTERN_KW if la == CRATE_KW => { | ||
172 | extern_crate_item(p); | ||
173 | EXTERN_CRATE_ITEM | ||
174 | } | ||
175 | TYPE_KW => { | ||
176 | type_def(p); | ||
177 | TYPE_DEF | ||
178 | } | ||
179 | MOD_KW => { | ||
180 | mod_item(p); | ||
181 | MODULE | ||
182 | } | ||
183 | STRUCT_KW => { | ||
184 | // test struct_items | ||
185 | // struct Foo; | ||
186 | // struct Foo {} | ||
187 | // struct Foo(); | ||
188 | // struct Foo(String, usize); | ||
189 | // struct Foo { | ||
190 | // a: i32, | ||
191 | // b: f32, | ||
192 | // } | ||
193 | nominal::struct_def(p, STRUCT_KW); | ||
194 | if p.at(SEMI) { | ||
195 | p.err_and_bump( | ||
196 | "expected item, found `;`\n\ | ||
197 | consider removing this semicolon" | ||
198 | ); | ||
199 | } | ||
200 | STRUCT_DEF | ||
201 | } | ||
202 | IDENT if p.at_contextual_kw("union") => { | ||
203 | // test union_items | ||
204 | // union Foo {} | ||
205 | // union Foo { | ||
206 | // a: i32, | ||
207 | // b: f32, | ||
208 | // } | ||
209 | nominal::struct_def(p, UNION_KW); | ||
210 | STRUCT_DEF | ||
211 | } | ||
212 | ENUM_KW => { | ||
213 | nominal::enum_def(p); | ||
214 | ENUM_DEF | ||
215 | } | ||
216 | USE_KW => { | ||
217 | use_item::use_item(p); | ||
218 | USE_ITEM | ||
219 | } | ||
220 | CONST_KW if (la == IDENT || la == MUT_KW) => { | ||
221 | consts::const_def(p); | ||
222 | CONST_DEF | ||
223 | } | ||
224 | STATIC_KW => { | ||
225 | consts::static_def(p); | ||
226 | STATIC_DEF | ||
227 | } | ||
228 | // test extern_block | ||
229 | // extern {} | ||
230 | EXTERN_KW if la == L_CURLY || ((la == STRING || la == RAW_STRING) && p.nth(2) == L_CURLY) => { | ||
231 | abi(p); | ||
232 | extern_item_list(p); | ||
233 | EXTERN_BLOCK | ||
234 | } | ||
235 | _ => return None, | ||
236 | }; | ||
237 | Some(kind) | ||
238 | } | ||
239 | |||
240 | fn extern_crate_item(p: &mut Parser) { | ||
241 | assert!(p.at(EXTERN_KW)); | ||
242 | p.bump(); | ||
243 | assert!(p.at(CRATE_KW)); | ||
244 | p.bump(); | ||
245 | name(p); | ||
246 | opt_alias(p); | ||
247 | p.expect(SEMI); | ||
248 | } | ||
249 | |||
250 | pub(crate) fn extern_item_list(p: &mut Parser) { | ||
251 | assert!(p.at(L_CURLY)); | ||
252 | let m = p.start(); | ||
253 | p.bump(); | ||
254 | mod_contents(p, true); | ||
255 | p.expect(R_CURLY); | ||
256 | m.complete(p, EXTERN_ITEM_LIST); | ||
257 | } | ||
258 | |||
259 | fn fn_def(p: &mut Parser, flavor: ItemFlavor) { | ||
260 | assert!(p.at(FN_KW)); | ||
261 | p.bump(); | ||
262 | |||
263 | name_r(p, ITEM_RECOVERY_SET); | ||
264 | // test function_type_params | ||
265 | // fn foo<T: Clone + Copy>(){} | ||
266 | type_params::opt_type_param_list(p); | ||
267 | |||
268 | if p.at(L_PAREN) { | ||
269 | match flavor { | ||
270 | ItemFlavor::Mod => | ||
271 | params::param_list(p), | ||
272 | ItemFlavor::Trait => | ||
273 | params::param_list_opt_patterns(p), | ||
274 | } | ||
275 | } else { | ||
276 | p.error("expected function arguments"); | ||
277 | } | ||
278 | // test function_ret_type | ||
279 | // fn foo() {} | ||
280 | // fn bar() -> () {} | ||
281 | opt_fn_ret_type(p); | ||
282 | |||
283 | // test function_where_clause | ||
284 | // fn foo<T>() where T: Copy {} | ||
285 | type_params::opt_where_clause(p); | ||
286 | |||
287 | // test fn_decl | ||
288 | // trait T { fn foo(); } | ||
289 | if p.at(SEMI) { | ||
290 | p.bump(); | ||
291 | } else { | ||
292 | expressions::block(p) | ||
293 | } | ||
294 | } | ||
295 | |||
296 | // test type_item | ||
297 | // type Foo = Bar; | ||
298 | fn type_def(p: &mut Parser) { | ||
299 | assert!(p.at(TYPE_KW)); | ||
300 | p.bump(); | ||
301 | |||
302 | name(p); | ||
303 | |||
304 | // test type_item_type_params | ||
305 | // type Result<T> = (); | ||
306 | type_params::opt_type_param_list(p); | ||
307 | |||
308 | if p.at(COLON) { | ||
309 | type_params::bounds(p); | ||
310 | } | ||
311 | |||
312 | // test type_item_where_clause | ||
313 | // type Foo where Foo: Copy = (); | ||
314 | type_params::opt_where_clause(p); | ||
315 | |||
316 | if p.eat(EQ) { | ||
317 | types::type_(p); | ||
318 | } | ||
319 | p.expect(SEMI); | ||
320 | } | ||
321 | |||
322 | pub(crate) fn mod_item(p: &mut Parser) { | ||
323 | assert!(p.at(MOD_KW)); | ||
324 | p.bump(); | ||
325 | |||
326 | name(p); | ||
327 | if p.at(L_CURLY) { | ||
328 | mod_item_list(p); | ||
329 | } else if !p.eat(SEMI) { | ||
330 | p.error("expected `;` or `{`"); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | pub(crate) fn mod_item_list(p: &mut Parser) { | ||
335 | assert!(p.at(L_CURLY)); | ||
336 | let m = p.start(); | ||
337 | p.bump(); | ||
338 | mod_contents(p, true); | ||
339 | p.expect(R_CURLY); | ||
340 | m.complete(p, ITEM_LIST); | ||
341 | } | ||
342 | |||
343 | fn macro_call(p: &mut Parser) -> BlockLike { | ||
344 | assert!(paths::is_path_start(p)); | ||
345 | paths::use_path(p); | ||
346 | macro_call_after_excl(p) | ||
347 | } | ||
348 | |||
349 | pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { | ||
350 | p.expect(EXCL); | ||
351 | p.eat(IDENT); | ||
352 | let flavor = match p.current() { | ||
353 | L_CURLY => { | ||
354 | token_tree(p); | ||
355 | BlockLike::Block | ||
356 | } | ||
357 | L_PAREN | L_BRACK => { | ||
358 | token_tree(p); | ||
359 | BlockLike::NotBlock | ||
360 | } | ||
361 | _ => { | ||
362 | p.error("expected `{`, `[`, `(`"); | ||
363 | BlockLike::NotBlock | ||
364 | }, | ||
365 | }; | ||
366 | |||
367 | flavor | ||
368 | } | ||
369 | |||
370 | pub(crate) fn token_tree(p: &mut Parser) { | ||
371 | let closing_paren_kind = match p.current() { | ||
372 | L_CURLY => R_CURLY, | ||
373 | L_PAREN => R_PAREN, | ||
374 | L_BRACK => R_BRACK, | ||
375 | _ => unreachable!(), | ||
376 | }; | ||
377 | let m = p.start(); | ||
378 | p.bump(); | ||
379 | while !p.at(EOF) && !p.at(closing_paren_kind) { | ||
380 | match p.current() { | ||
381 | L_CURLY | L_PAREN | L_BRACK => token_tree(p), | ||
382 | R_CURLY => { | ||
383 | p.error("unmatched `}`"); | ||
384 | m.complete(p, TOKEN_TREE); | ||
385 | return; | ||
386 | } | ||
387 | R_PAREN | R_BRACK => p.err_and_bump("unmatched brace"), | ||
388 | _ => p.bump() | ||
389 | } | ||
390 | }; | ||
391 | p.expect(closing_paren_kind); | ||
392 | m.complete(p, TOKEN_TREE); | ||
393 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/nominal.rs b/crates/ra_syntax/src/grammar/items/nominal.rs new file mode 100644 index 000000000..8d02ad555 --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/nominal.rs | |||
@@ -0,0 +1,154 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { | ||
4 | assert!(p.at(STRUCT_KW) || p.at_contextual_kw("union")); | ||
5 | p.bump_remap(kind); | ||
6 | |||
7 | name_r(p, ITEM_RECOVERY_SET); | ||
8 | type_params::opt_type_param_list(p); | ||
9 | match p.current() { | ||
10 | WHERE_KW => { | ||
11 | type_params::opt_where_clause(p); | ||
12 | match p.current() { | ||
13 | SEMI => { | ||
14 | p.bump(); | ||
15 | return; | ||
16 | } | ||
17 | L_CURLY => named_field_def_list(p), | ||
18 | _ => { | ||
19 | //TODO: special case `(` error message | ||
20 | p.error("expected `;` or `{`"); | ||
21 | return; | ||
22 | } | ||
23 | } | ||
24 | } | ||
25 | SEMI if kind == STRUCT_KW => { | ||
26 | p.bump(); | ||
27 | return; | ||
28 | } | ||
29 | L_CURLY => named_field_def_list(p), | ||
30 | L_PAREN if kind == STRUCT_KW => { | ||
31 | pos_field_list(p); | ||
32 | p.expect(SEMI); | ||
33 | } | ||
34 | _ if kind == STRUCT_KW => { | ||
35 | p.error("expected `;`, `{`, or `(`"); | ||
36 | return; | ||
37 | } | ||
38 | _ => { | ||
39 | p.error("expected `{`"); | ||
40 | return; | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | |||
45 | pub(super) fn enum_def(p: &mut Parser) { | ||
46 | assert!(p.at(ENUM_KW)); | ||
47 | p.bump(); | ||
48 | name_r(p, ITEM_RECOVERY_SET); | ||
49 | type_params::opt_type_param_list(p); | ||
50 | type_params::opt_where_clause(p); | ||
51 | if p.at(L_CURLY) { | ||
52 | enum_variant_list(p); | ||
53 | } else { | ||
54 | p.error("expected `{`") | ||
55 | } | ||
56 | } | ||
57 | |||
58 | pub(crate) fn enum_variant_list(p: &mut Parser) { | ||
59 | assert!(p.at(L_CURLY)); | ||
60 | let m = p.start(); | ||
61 | p.bump(); | ||
62 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
63 | if p.at(L_CURLY) { | ||
64 | error_block(p, "expected enum variant"); | ||
65 | continue; | ||
66 | } | ||
67 | let var = p.start(); | ||
68 | attributes::outer_attributes(p); | ||
69 | if p.at(IDENT) { | ||
70 | name(p); | ||
71 | match p.current() { | ||
72 | L_CURLY => named_field_def_list(p), | ||
73 | L_PAREN => pos_field_list(p), | ||
74 | EQ => { | ||
75 | p.bump(); | ||
76 | expressions::expr(p); | ||
77 | } | ||
78 | _ => (), | ||
79 | } | ||
80 | var.complete(p, ENUM_VARIANT); | ||
81 | } else { | ||
82 | var.abandon(p); | ||
83 | p.err_and_bump("expected enum variant"); | ||
84 | } | ||
85 | if !p.at(R_CURLY) { | ||
86 | p.expect(COMMA); | ||
87 | } | ||
88 | } | ||
89 | p.expect(R_CURLY); | ||
90 | m.complete(p, ENUM_VARIANT_LIST); | ||
91 | } | ||
92 | |||
93 | pub(crate) fn named_field_def_list(p: &mut Parser) { | ||
94 | assert!(p.at(L_CURLY)); | ||
95 | let m = p.start(); | ||
96 | p.bump(); | ||
97 | while !p.at(R_CURLY) && !p.at(EOF) { | ||
98 | if p.at(L_CURLY) { | ||
99 | error_block(p, "expected field"); | ||
100 | continue; | ||
101 | } | ||
102 | named_field_def(p); | ||
103 | if !p.at(R_CURLY) { | ||
104 | p.expect(COMMA); | ||
105 | } | ||
106 | } | ||
107 | p.expect(R_CURLY); | ||
108 | m.complete(p, NAMED_FIELD_DEF_LIST); | ||
109 | |||
110 | fn named_field_def(p: &mut Parser) { | ||
111 | let m = p.start(); | ||
112 | // test field_attrs | ||
113 | // struct S { | ||
114 | // #[serde(with = "url_serde")] | ||
115 | // pub uri: Uri, | ||
116 | // } | ||
117 | attributes::outer_attributes(p); | ||
118 | opt_visibility(p); | ||
119 | if p.at(IDENT) { | ||
120 | name(p); | ||
121 | p.expect(COLON); | ||
122 | types::type_(p); | ||
123 | m.complete(p, NAMED_FIELD_DEF); | ||
124 | } else { | ||
125 | m.abandon(p); | ||
126 | p.err_and_bump("expected field declaration"); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | fn pos_field_list(p: &mut Parser) { | ||
132 | assert!(p.at(L_PAREN)); | ||
133 | let m = p.start(); | ||
134 | if !p.expect(L_PAREN) { | ||
135 | return; | ||
136 | } | ||
137 | while !p.at(R_PAREN) && !p.at(EOF) { | ||
138 | let m = p.start(); | ||
139 | opt_visibility(p); | ||
140 | if !p.at_ts(types::TYPE_FIRST) { | ||
141 | p.error("expected a type"); | ||
142 | m.complete(p, ERROR); | ||
143 | break; | ||
144 | } | ||
145 | types::type_(p); | ||
146 | m.complete(p, POS_FIELD); | ||
147 | |||
148 | if !p.at(R_PAREN) { | ||
149 | p.expect(COMMA); | ||
150 | } | ||
151 | } | ||
152 | p.expect(R_PAREN); | ||
153 | m.complete(p, POS_FIELD_LIST); | ||
154 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/traits.rs b/crates/ra_syntax/src/grammar/items/traits.rs new file mode 100644 index 000000000..c21cfb1a9 --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/traits.rs | |||
@@ -0,0 +1,117 @@ | |||
1 | use super::*; | ||
2 | |||
3 | // test trait_item | ||
4 | // trait T<U>: Hash + Clone where U: Copy {} | ||
5 | pub(super) fn trait_def(p: &mut Parser) { | ||
6 | assert!(p.at(TRAIT_KW)); | ||
7 | p.bump(); | ||
8 | name_r(p, ITEM_RECOVERY_SET); | ||
9 | type_params::opt_type_param_list(p); | ||
10 | if p.at(COLON) { | ||
11 | type_params::bounds(p); | ||
12 | } | ||
13 | type_params::opt_where_clause(p); | ||
14 | if p.at(L_CURLY) { | ||
15 | trait_item_list(p); | ||
16 | } else { | ||
17 | p.error("expected `{`"); | ||
18 | } | ||
19 | } | ||
20 | |||
21 | // test trait_item_list | ||
22 | // impl F { | ||
23 | // type A: Clone; | ||
24 | // const B: i32; | ||
25 | // fn foo() {} | ||
26 | // fn bar(&self); | ||
27 | // } | ||
28 | pub(crate) fn trait_item_list(p: &mut Parser) { | ||
29 | assert!(p.at(L_CURLY)); | ||
30 | let m = p.start(); | ||
31 | p.bump(); | ||
32 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
33 | if p.at(L_CURLY) { | ||
34 | error_block(p, "expected an item"); | ||
35 | continue; | ||
36 | } | ||
37 | item_or_macro(p, true, ItemFlavor::Trait); | ||
38 | } | ||
39 | p.expect(R_CURLY); | ||
40 | m.complete(p, ITEM_LIST); | ||
41 | } | ||
42 | |||
43 | // test impl_item | ||
44 | // impl Foo {} | ||
45 | pub(super) fn impl_item(p: &mut Parser) { | ||
46 | assert!(p.at(IMPL_KW)); | ||
47 | p.bump(); | ||
48 | if choose_type_params_over_qpath(p) { | ||
49 | type_params::opt_type_param_list(p); | ||
50 | } | ||
51 | |||
52 | // TODO: never type | ||
53 | // impl ! {} | ||
54 | |||
55 | // test impl_item_neg | ||
56 | // impl !Send for X {} | ||
57 | p.eat(EXCL); | ||
58 | types::type_(p); | ||
59 | if p.eat(FOR_KW) { | ||
60 | types::type_(p); | ||
61 | } | ||
62 | type_params::opt_where_clause(p); | ||
63 | if p.at(L_CURLY) { | ||
64 | impl_item_list(p); | ||
65 | } else { | ||
66 | p.error("expected `{`"); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | // test impl_item_list | ||
71 | // impl F { | ||
72 | // type A = i32; | ||
73 | // const B: i32 = 92; | ||
74 | // fn foo() {} | ||
75 | // fn bar(&self) {} | ||
76 | // } | ||
77 | pub(crate) fn impl_item_list(p: &mut Parser) { | ||
78 | assert!(p.at(L_CURLY)); | ||
79 | let m = p.start(); | ||
80 | p.bump(); | ||
81 | |||
82 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
83 | if p.at(L_CURLY) { | ||
84 | error_block(p, "expected an item"); | ||
85 | continue; | ||
86 | } | ||
87 | item_or_macro(p, true, ItemFlavor::Mod); | ||
88 | } | ||
89 | p.expect(R_CURLY); | ||
90 | m.complete(p, ITEM_LIST); | ||
91 | } | ||
92 | |||
93 | fn choose_type_params_over_qpath(p: &Parser) -> bool { | ||
94 | // There's an ambiguity between generic parameters and qualified paths in impls. | ||
95 | // If we see `<` it may start both, so we have to inspect some following tokens. | ||
96 | // The following combinations can only start generics, | ||
97 | // but not qualified paths (with one exception): | ||
98 | // `<` `>` - empty generic parameters | ||
99 | // `<` `#` - generic parameters with attributes | ||
100 | // `<` (LIFETIME|IDENT) `>` - single generic parameter | ||
101 | // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list | ||
102 | // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds | ||
103 | // `<` (LIFETIME|IDENT) `=` - generic parameter with a default | ||
104 | // The only truly ambiguous case is | ||
105 | // `<` IDENT `>` `::` IDENT ... | ||
106 | // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`) | ||
107 | // because this is what almost always expected in practice, qualified paths in impls | ||
108 | // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment. | ||
109 | if !p.at(L_ANGLE) { | ||
110 | return false; | ||
111 | } | ||
112 | if p.nth(1) == POUND || p.nth(1) == R_ANGLE { | ||
113 | return true; | ||
114 | } | ||
115 | (p.nth(1) == LIFETIME || p.nth(1) == IDENT) | ||
116 | && (p.nth(2) == R_ANGLE || p.nth(2) == COMMA || p.nth(2) == COLON || p.nth(2) == EQ) | ||
117 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/use_item.rs b/crates/ra_syntax/src/grammar/items/use_item.rs new file mode 100644 index 000000000..1ee4349fd --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/use_item.rs | |||
@@ -0,0 +1,68 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn use_item(p: &mut Parser) { | ||
4 | assert!(p.at(USE_KW)); | ||
5 | p.bump(); | ||
6 | use_tree(p); | ||
7 | p.expect(SEMI); | ||
8 | } | ||
9 | |||
10 | fn use_tree(p: &mut Parser) { | ||
11 | let la = p.nth(1); | ||
12 | let m = p.start(); | ||
13 | match (p.current(), la) { | ||
14 | (STAR, _) => p.bump(), | ||
15 | (COLONCOLON, STAR) => { | ||
16 | p.bump(); | ||
17 | p.bump(); | ||
18 | } | ||
19 | (L_CURLY, _) | (COLONCOLON, L_CURLY) => { | ||
20 | if p.at(COLONCOLON) { | ||
21 | p.bump(); | ||
22 | } | ||
23 | use_tree_list(p); | ||
24 | } | ||
25 | _ if paths::is_path_start(p) => { | ||
26 | paths::use_path(p); | ||
27 | match p.current() { | ||
28 | AS_KW => { | ||
29 | opt_alias(p); | ||
30 | } | ||
31 | COLONCOLON => { | ||
32 | p.bump(); | ||
33 | match p.current() { | ||
34 | STAR => { | ||
35 | p.bump(); | ||
36 | } | ||
37 | L_CURLY => use_tree_list(p), | ||
38 | _ => { | ||
39 | // is this unreachable? | ||
40 | p.error("expected `{` or `*`"); | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | _ => (), | ||
45 | } | ||
46 | } | ||
47 | _ => { | ||
48 | m.abandon(p); | ||
49 | p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`"); | ||
50 | return; | ||
51 | } | ||
52 | } | ||
53 | m.complete(p, USE_TREE); | ||
54 | } | ||
55 | |||
56 | pub(crate) fn use_tree_list(p: &mut Parser) { | ||
57 | assert!(p.at(L_CURLY)); | ||
58 | let m = p.start(); | ||
59 | p.bump(); | ||
60 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
61 | use_tree(p); | ||
62 | if !p.at(R_CURLY) { | ||
63 | p.expect(COMMA); | ||
64 | } | ||
65 | } | ||
66 | p.expect(R_CURLY); | ||
67 | m.complete(p, USE_TREE_LIST); | ||
68 | } | ||
diff --git a/crates/ra_syntax/src/grammar/mod.rs b/crates/ra_syntax/src/grammar/mod.rs new file mode 100644 index 000000000..2cb11dc1e --- /dev/null +++ b/crates/ra_syntax/src/grammar/mod.rs | |||
@@ -0,0 +1,188 @@ | |||
1 | //! This is the actual "grammar" of the Rust language. | ||
2 | //! | ||
3 | //! Each function in this module and its children corresponds | ||
4 | //! to a production of the format grammar. Submodules roughly | ||
5 | //! correspond to different *areas* of the grammar. By convention, | ||
6 | //! each submodule starts with `use super::*` import and exports | ||
7 | //! "public" productions via `pub(super)`. | ||
8 | //! | ||
9 | //! See docs for `Parser` to learn about API, available to the grammar, | ||
10 | //! and see docs for `Event` to learn how this actually manages to | ||
11 | //! produce parse trees. | ||
12 | //! | ||
13 | //! Code in this module also contains inline tests, which start with | ||
14 | //! `// test name-of-the-test` comment and look like this: | ||
15 | //! | ||
16 | //! ``` | ||
17 | //! // test function_with_zero_parameters | ||
18 | //! // fn foo() {} | ||
19 | //! ``` | ||
20 | //! | ||
21 | //! After adding a new inline-test, run `cargo collect-tests` to extract | ||
22 | //! it as a standalone text-fixture into `tests/data/parser/inline`, and | ||
23 | //! run `cargo test` once to create the "gold" value. | ||
24 | mod attributes; | ||
25 | mod expressions; | ||
26 | mod items; | ||
27 | mod params; | ||
28 | mod paths; | ||
29 | mod patterns; | ||
30 | mod type_args; | ||
31 | mod type_params; | ||
32 | mod types; | ||
33 | |||
34 | use { | ||
35 | token_set::TokenSet, | ||
36 | parser_api::{Marker, CompletedMarker, Parser}, | ||
37 | SyntaxKind::{self, *}, | ||
38 | }; | ||
39 | pub(crate) use self::{ | ||
40 | expressions::{ | ||
41 | block, | ||
42 | }, | ||
43 | items::{ | ||
44 | enum_variant_list, | ||
45 | extern_item_list, | ||
46 | impl_item_list, | ||
47 | match_arm_list, | ||
48 | mod_item_list, | ||
49 | named_field_def_list, | ||
50 | named_field_list, | ||
51 | token_tree, | ||
52 | trait_item_list, | ||
53 | use_tree_list, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | pub(crate) fn root(p: &mut Parser) { | ||
58 | let m = p.start(); | ||
59 | p.eat(SHEBANG); | ||
60 | items::mod_contents(p, false); | ||
61 | m.complete(p, ROOT); | ||
62 | } | ||
63 | |||
64 | |||
65 | #[derive(Clone, Copy, PartialEq, Eq)] | ||
66 | enum BlockLike { | ||
67 | Block, | ||
68 | NotBlock, | ||
69 | } | ||
70 | |||
71 | impl BlockLike { | ||
72 | fn is_block(self) -> bool { self == BlockLike::Block } | ||
73 | } | ||
74 | |||
75 | fn opt_visibility(p: &mut Parser) { | ||
76 | match p.current() { | ||
77 | PUB_KW => { | ||
78 | let m = p.start(); | ||
79 | p.bump(); | ||
80 | if p.at(L_PAREN) { | ||
81 | match p.nth(1) { | ||
82 | // test crate_visibility | ||
83 | // pub(crate) struct S; | ||
84 | // pub(self) struct S; | ||
85 | // pub(self) struct S; | ||
86 | // pub(self) struct S; | ||
87 | CRATE_KW | SELF_KW | SUPER_KW => { | ||
88 | p.bump(); | ||
89 | p.bump(); | ||
90 | p.expect(R_PAREN); | ||
91 | } | ||
92 | IN_KW => { | ||
93 | p.bump(); | ||
94 | p.bump(); | ||
95 | paths::use_path(p); | ||
96 | p.expect(R_PAREN); | ||
97 | } | ||
98 | _ => (), | ||
99 | } | ||
100 | } | ||
101 | m.complete(p, VISIBILITY); | ||
102 | } | ||
103 | // test crate_keyword_vis | ||
104 | // crate fn main() { } | ||
105 | CRATE_KW => { | ||
106 | let m = p.start(); | ||
107 | p.bump(); | ||
108 | m.complete(p, VISIBILITY); | ||
109 | } | ||
110 | _ => (), | ||
111 | } | ||
112 | } | ||
113 | |||
114 | fn opt_alias(p: &mut Parser) { | ||
115 | if p.at(AS_KW) { | ||
116 | let m = p.start(); | ||
117 | p.bump(); | ||
118 | name(p); | ||
119 | m.complete(p, ALIAS); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | fn abi(p: &mut Parser) { | ||
124 | assert!(p.at(EXTERN_KW)); | ||
125 | let abi = p.start(); | ||
126 | p.bump(); | ||
127 | match p.current() { | ||
128 | STRING | RAW_STRING => p.bump(), | ||
129 | _ => (), | ||
130 | } | ||
131 | abi.complete(p, ABI); | ||
132 | } | ||
133 | |||
134 | fn opt_fn_ret_type(p: &mut Parser) -> bool { | ||
135 | if p.at(THIN_ARROW) { | ||
136 | let |