diff options
Diffstat (limited to 'crates/ra_syntax/src/ast')
-rw-r--r-- | crates/ra_syntax/src/ast/expr_extensions.rs | 252 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/extensions.rs | 303 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 662 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/tokens.rs | 113 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/traits.rs | 154 |
5 files changed, 944 insertions, 540 deletions
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs new file mode 100644 index 000000000..1d8313810 --- /dev/null +++ b/crates/ra_syntax/src/ast/expr_extensions.rs | |||
@@ -0,0 +1,252 @@ | |||
1 | //! Various extension methods to ast Expr Nodes, which are hard to code-generate. | ||
2 | |||
3 | use crate::{ | ||
4 | SyntaxToken, SyntaxElement, SmolStr, | ||
5 | ast::{self, AstNode, AstChildren, children, child_opt}, | ||
6 | SyntaxKind::* | ||
7 | }; | ||
8 | |||
9 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
10 | pub enum ElseBranch<'a> { | ||
11 | Block(&'a ast::Block), | ||
12 | IfExpr(&'a ast::IfExpr), | ||
13 | } | ||
14 | |||
15 | impl ast::IfExpr { | ||
16 | pub fn then_branch(&self) -> Option<&ast::Block> { | ||
17 | self.blocks().nth(0) | ||
18 | } | ||
19 | pub fn else_branch(&self) -> Option<ElseBranch> { | ||
20 | let res = match self.blocks().nth(1) { | ||
21 | Some(block) => ElseBranch::Block(block), | ||
22 | None => { | ||
23 | let elif: &ast::IfExpr = child_opt(self)?; | ||
24 | ElseBranch::IfExpr(elif) | ||
25 | } | ||
26 | }; | ||
27 | Some(res) | ||
28 | } | ||
29 | |||
30 | fn blocks(&self) -> AstChildren<ast::Block> { | ||
31 | children(self) | ||
32 | } | ||
33 | } | ||
34 | |||
35 | impl ast::RefExpr { | ||
36 | pub fn is_mut(&self) -> bool { | ||
37 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | ||
38 | } | ||
39 | } | ||
40 | |||
41 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
42 | pub enum PrefixOp { | ||
43 | /// The `*` operator for dereferencing | ||
44 | Deref, | ||
45 | /// The `!` operator for logical inversion | ||
46 | Not, | ||
47 | /// The `-` operator for negation | ||
48 | Neg, | ||
49 | } | ||
50 | |||
51 | impl ast::PrefixExpr { | ||
52 | pub fn op_kind(&self) -> Option<PrefixOp> { | ||
53 | match self.op_token()?.kind() { | ||
54 | STAR => Some(PrefixOp::Deref), | ||
55 | EXCL => Some(PrefixOp::Not), | ||
56 | MINUS => Some(PrefixOp::Neg), | ||
57 | _ => None, | ||
58 | } | ||
59 | } | ||
60 | |||
61 | pub fn op_token(&self) -> Option<SyntaxToken> { | ||
62 | self.syntax().first_child_or_token()?.as_token() | ||
63 | } | ||
64 | } | ||
65 | |||
66 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
67 | pub enum BinOp { | ||
68 | /// The `||` operator for boolean OR | ||
69 | BooleanOr, | ||
70 | /// The `&&` operator for boolean AND | ||
71 | BooleanAnd, | ||
72 | /// The `==` operator for equality testing | ||
73 | EqualityTest, | ||
74 | /// The `!=` operator for equality testing | ||
75 | NegatedEqualityTest, | ||
76 | /// The `<=` operator for lesser-equal testing | ||
77 | LesserEqualTest, | ||
78 | /// The `>=` operator for greater-equal testing | ||
79 | GreaterEqualTest, | ||
80 | /// The `<` operator for comparison | ||
81 | LesserTest, | ||
82 | /// The `>` operator for comparison | ||
83 | GreaterTest, | ||
84 | /// The `+` operator for addition | ||
85 | Addition, | ||
86 | /// The `*` operator for multiplication | ||
87 | Multiplication, | ||
88 | /// The `-` operator for subtraction | ||
89 | Subtraction, | ||
90 | /// The `/` operator for division | ||
91 | Division, | ||
92 | /// The `%` operator for remainder after division | ||
93 | Remainder, | ||
94 | /// The `<<` operator for left shift | ||
95 | LeftShift, | ||
96 | /// The `>>` operator for right shift | ||
97 | RightShift, | ||
98 | /// The `^` operator for bitwise XOR | ||
99 | BitwiseXor, | ||
100 | /// The `|` operator for bitwise OR | ||
101 | BitwiseOr, | ||
102 | /// The `&` operator for bitwise AND | ||
103 | BitwiseAnd, | ||
104 | /// The `..` operator for right-open ranges | ||
105 | RangeRightOpen, | ||
106 | /// The `..=` operator for right-closed ranges | ||
107 | RangeRightClosed, | ||
108 | /// The `=` operator for assignment | ||
109 | Assignment, | ||
110 | /// The `+=` operator for assignment after addition | ||
111 | AddAssign, | ||
112 | /// The `/=` operator for assignment after division | ||
113 | DivAssign, | ||
114 | /// The `*=` operator for assignment after multiplication | ||
115 | MulAssign, | ||
116 | /// The `%=` operator for assignment after remainders | ||
117 | RemAssign, | ||
118 | /// The `>>=` operator for assignment after shifting right | ||
119 | ShrAssign, | ||
120 | /// The `<<=` operator for assignment after shifting left | ||
121 | ShlAssign, | ||
122 | /// The `-=` operator for assignment after subtraction | ||
123 | SubAssign, | ||
124 | /// The `|=` operator for assignment after bitwise OR | ||
125 | BitOrAssign, | ||
126 | /// The `&=` operator for assignment after bitwise AND | ||
127 | BitAndAssign, | ||
128 | /// The `^=` operator for assignment after bitwise XOR | ||
129 | BitXorAssign, | ||
130 | } | ||
131 | |||
132 | impl ast::BinExpr { | ||
133 | fn op_details(&self) -> Option<(SyntaxToken, BinOp)> { | ||
134 | self.syntax().children_with_tokens().filter_map(|it| it.as_token()).find_map(|c| { | ||
135 | match c.kind() { | ||
136 | PIPEPIPE => Some((c, BinOp::BooleanOr)), | ||
137 | AMPAMP => Some((c, BinOp::BooleanAnd)), | ||
138 | EQEQ => Some((c, BinOp::EqualityTest)), | ||
139 | NEQ => Some((c, BinOp::NegatedEqualityTest)), | ||
140 | LTEQ => Some((c, BinOp::LesserEqualTest)), | ||
141 | GTEQ => Some((c, BinOp::GreaterEqualTest)), | ||
142 | L_ANGLE => Some((c, BinOp::LesserTest)), | ||
143 | R_ANGLE => Some((c, BinOp::GreaterTest)), | ||
144 | PLUS => Some((c, BinOp::Addition)), | ||
145 | STAR => Some((c, BinOp::Multiplication)), | ||
146 | MINUS => Some((c, BinOp::Subtraction)), | ||
147 | SLASH => Some((c, BinOp::Division)), | ||
148 | PERCENT => Some((c, BinOp::Remainder)), | ||
149 | SHL => Some((c, BinOp::LeftShift)), | ||
150 | SHR => Some((c, BinOp::RightShift)), | ||
151 | CARET => Some((c, BinOp::BitwiseXor)), | ||
152 | PIPE => Some((c, BinOp::BitwiseOr)), | ||
153 | AMP => Some((c, BinOp::BitwiseAnd)), | ||
154 | DOTDOT => Some((c, BinOp::RangeRightOpen)), | ||
155 | DOTDOTEQ => Some((c, BinOp::RangeRightClosed)), | ||
156 | EQ => Some((c, BinOp::Assignment)), | ||
157 | PLUSEQ => Some((c, BinOp::AddAssign)), | ||
158 | SLASHEQ => Some((c, BinOp::DivAssign)), | ||
159 | STAREQ => Some((c, BinOp::MulAssign)), | ||
160 | PERCENTEQ => Some((c, BinOp::RemAssign)), | ||
161 | SHREQ => Some((c, BinOp::ShrAssign)), | ||
162 | SHLEQ => Some((c, BinOp::ShlAssign)), | ||
163 | MINUSEQ => Some((c, BinOp::SubAssign)), | ||
164 | PIPEEQ => Some((c, BinOp::BitOrAssign)), | ||
165 | AMPEQ => Some((c, BinOp::BitAndAssign)), | ||
166 | CARETEQ => Some((c, BinOp::BitXorAssign)), | ||
167 | _ => None, | ||
168 | } | ||
169 | }) | ||
170 | } | ||
171 | |||
172 | pub fn op_kind(&self) -> Option<BinOp> { | ||
173 | self.op_details().map(|t| t.1) | ||
174 | } | ||
175 | |||
176 | pub fn op_token(&self) -> Option<SyntaxToken> { | ||
177 | self.op_details().map(|t| t.0) | ||
178 | } | ||
179 | |||
180 | pub fn lhs(&self) -> Option<&ast::Expr> { | ||
181 | children(self).nth(0) | ||
182 | } | ||
183 | |||
184 | pub fn rhs(&self) -> Option<&ast::Expr> { | ||
185 | children(self).nth(1) | ||
186 | } | ||
187 | |||
188 | pub fn sub_exprs(&self) -> (Option<&ast::Expr>, Option<&ast::Expr>) { | ||
189 | let mut children = children(self); | ||
190 | let first = children.next(); | ||
191 | let second = children.next(); | ||
192 | (first, second) | ||
193 | } | ||
194 | } | ||
195 | |||
196 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
197 | pub enum LiteralKind { | ||
198 | String, | ||
199 | ByteString, | ||
200 | Char, | ||
201 | Byte, | ||
202 | IntNumber { suffix: Option<SmolStr> }, | ||
203 | FloatNumber { suffix: Option<SmolStr> }, | ||
204 | Bool, | ||
205 | } | ||
206 | |||
207 | impl ast::Literal { | ||
208 | pub fn token(&self) -> SyntaxToken { | ||
209 | match self.syntax().first_child_or_token().unwrap() { | ||
210 | SyntaxElement::Token(token) => token, | ||
211 | _ => unreachable!(), | ||
212 | } | ||
213 | } | ||
214 | |||
215 | pub fn kind(&self) -> LiteralKind { | ||
216 | match self.token().kind() { | ||
217 | INT_NUMBER => { | ||
218 | let allowed_suffix_list = [ | ||
219 | "isize", "i128", "i64", "i32", "i16", "i8", "usize", "u128", "u64", "u32", | ||
220 | "u16", "u8", | ||
221 | ]; | ||
222 | let text = self.token().text().to_string(); | ||
223 | let suffix = allowed_suffix_list | ||
224 | .iter() | ||
225 | .find(|&s| text.ends_with(s)) | ||
226 | .map(|&suf| SmolStr::new(suf)); | ||
227 | LiteralKind::IntNumber { suffix } | ||
228 | } | ||
229 | FLOAT_NUMBER => { | ||
230 | let allowed_suffix_list = ["f64", "f32"]; | ||
231 | let text = self.token().text().to_string(); | ||
232 | let suffix = allowed_suffix_list | ||
233 | .iter() | ||
234 | .find(|&s| text.ends_with(s)) | ||
235 | .map(|&suf| SmolStr::new(suf)); | ||
236 | LiteralKind::FloatNumber { suffix: suffix } | ||
237 | } | ||
238 | STRING | RAW_STRING => LiteralKind::String, | ||
239 | TRUE_KW | FALSE_KW => LiteralKind::Bool, | ||
240 | BYTE_STRING | RAW_BYTE_STRING => LiteralKind::ByteString, | ||
241 | CHAR => LiteralKind::Char, | ||
242 | BYTE => LiteralKind::Byte, | ||
243 | _ => unreachable!(), | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | |||
248 | impl ast::NamedField { | ||
249 | pub fn parent_struct_lit(&self) -> &ast::StructLit { | ||
250 | self.syntax().ancestors().find_map(ast::StructLit::cast).unwrap() | ||
251 | } | ||
252 | } | ||
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs new file mode 100644 index 000000000..aec57c380 --- /dev/null +++ b/crates/ra_syntax/src/ast/extensions.rs | |||
@@ -0,0 +1,303 @@ | |||
1 | //! Various extension methods to ast Nodes, which are hard to code-generate. | ||
2 | //! Extensions for various expressions live in a sibling `expr_extensions` module. | ||
3 | |||
4 | use itertools::Itertools; | ||
5 | |||
6 | use crate::{ | ||
7 | SmolStr, SyntaxToken, | ||
8 | ast::{self, AstNode, children, child_opt}, | ||
9 | SyntaxKind::*, | ||
10 | }; | ||
11 | |||
12 | impl ast::Name { | ||
13 | pub fn text(&self) -> &SmolStr { | ||
14 | let ident = self.syntax().first_child_or_token().unwrap().as_token().unwrap(); | ||
15 | ident.text() | ||
16 | } | ||
17 | } | ||
18 | |||
19 | impl ast::NameRef { | ||
20 | pub fn text(&self) -> &SmolStr { | ||
21 | let ident = self.syntax().first_child_or_token().unwrap().as_token().unwrap(); | ||
22 | ident.text() | ||
23 | } | ||
24 | } | ||
25 | |||
26 | impl ast::Attr { | ||
27 | pub fn is_inner(&self) -> bool { | ||
28 | let tt = match self.value() { | ||
29 | None => return false, | ||
30 | Some(tt) => tt, | ||
31 | }; | ||
32 | |||
33 | let prev = match tt.syntax().prev_sibling() { | ||
34 | None => return false, | ||
35 | Some(prev) => prev, | ||
36 | }; | ||
37 | |||
38 | prev.kind() == EXCL | ||
39 | } | ||
40 | |||
41 | pub fn as_atom(&self) -> Option<SmolStr> { | ||
42 | let tt = self.value()?; | ||
43 | let (_bra, attr, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; | ||
44 | if attr.kind() == IDENT { | ||
45 | Some(attr.as_token()?.text().clone()) | ||
46 | } else { | ||
47 | None | ||
48 | } | ||
49 | } | ||
50 | |||
51 | pub fn as_call(&self) -> Option<(SmolStr, &ast::TokenTree)> { | ||
52 | let tt = self.value()?; | ||
53 | let (_bra, attr, args, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; | ||
54 | let args = ast::TokenTree::cast(args.as_node()?)?; | ||
55 | if attr.kind() == IDENT { | ||
56 | Some((attr.as_token()?.text().clone(), args)) | ||
57 | } else { | ||
58 | None | ||
59 | } | ||
60 | } | ||
61 | |||
62 | pub fn as_named(&self) -> Option<SmolStr> { | ||
63 | let tt = self.value()?; | ||
64 | let attr = tt.syntax().children_with_tokens().nth(1)?; | ||
65 | if attr.kind() == IDENT { | ||
66 | Some(attr.as_token()?.text().clone()) | ||
67 | } else { | ||
68 | None | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | |||
73 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
74 | pub enum PathSegmentKind<'a> { | ||
75 | Name(&'a ast::NameRef), | ||
76 | SelfKw, | ||
77 | SuperKw, | ||
78 | CrateKw, | ||
79 | } | ||
80 | |||
81 | impl ast::PathSegment { | ||
82 | pub fn parent_path(&self) -> &ast::Path { | ||
83 | self.syntax() | ||
84 | .parent() | ||
85 | .and_then(ast::Path::cast) | ||
86 | .expect("segments are always nested in paths") | ||
87 | } | ||
88 | |||
89 | pub fn kind(&self) -> Option<PathSegmentKind> { | ||
90 | let res = if let Some(name_ref) = self.name_ref() { | ||
91 | PathSegmentKind::Name(name_ref) | ||
92 | } else { | ||
93 | match self.syntax().first_child_or_token()?.kind() { | ||
94 | SELF_KW => PathSegmentKind::SelfKw, | ||
95 | SUPER_KW => PathSegmentKind::SuperKw, | ||
96 | CRATE_KW => PathSegmentKind::CrateKw, | ||
97 | _ => return None, | ||
98 | } | ||
99 | }; | ||
100 | Some(res) | ||
101 | } | ||
102 | |||
103 | pub fn has_colon_colon(&self) -> bool { | ||
104 | match self.syntax.first_child_or_token().map(|s| s.kind()) { | ||
105 | Some(COLONCOLON) => true, | ||
106 | _ => false, | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | |||
111 | impl ast::Path { | ||
112 | pub fn parent_path(&self) -> Option<&ast::Path> { | ||
113 | self.syntax().parent().and_then(ast::Path::cast) | ||
114 | } | ||
115 | } | ||
116 | |||
117 | impl ast::Module { | ||
118 | pub fn has_semi(&self) -> bool { | ||
119 | match self.syntax().last_child_or_token() { | ||
120 | None => false, | ||
121 | Some(node) => node.kind() == SEMI, | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | |||
126 | impl ast::UseTree { | ||
127 | pub fn has_star(&self) -> bool { | ||
128 | self.syntax().children_with_tokens().any(|it| it.kind() == STAR) | ||
129 | } | ||
130 | } | ||
131 | |||
132 | impl ast::UseTreeList { | ||
133 | pub fn parent_use_tree(&self) -> &ast::UseTree { | ||
134 | self.syntax() | ||
135 | .parent() | ||
136 | .and_then(ast::UseTree::cast) | ||
137 | .expect("UseTreeLists are always nested in UseTrees") | ||
138 | } | ||
139 | } | ||
140 | |||
141 | impl ast::ImplBlock { | ||
142 | pub fn target_type(&self) -> Option<&ast::TypeRef> { | ||
143 | match self.target() { | ||
144 | (Some(t), None) | (_, Some(t)) => Some(t), | ||
145 | _ => None, | ||
146 | } | ||
147 | } | ||
148 | |||
149 | pub fn target_trait(&self) -> Option<&ast::TypeRef> { | ||
150 | match self.target() { | ||
151 | (Some(t), Some(_)) => Some(t), | ||
152 | _ => None, | ||
153 | } | ||
154 | } | ||
155 | |||
156 | fn target(&self) -> (Option<&ast::TypeRef>, Option<&ast::TypeRef>) { | ||
157 | let mut types = children(self); | ||
158 | let first = types.next(); | ||
159 | let second = types.next(); | ||
160 | (first, second) | ||
161 | } | ||
162 | } | ||
163 | |||
164 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
165 | pub enum StructKind<'a> { | ||
166 | Tuple(&'a ast::PosFieldDefList), | ||
167 | Named(&'a ast::NamedFieldDefList), | ||
168 | Unit, | ||
169 | } | ||
170 | |||
171 | impl StructKind<'_> { | ||
172 | fn from_node<N: AstNode>(node: &N) -> StructKind { | ||
173 | if let Some(nfdl) = child_opt::<_, ast::NamedFieldDefList>(node) { | ||
174 | StructKind::Named(nfdl) | ||
175 | } else if let Some(pfl) = child_opt::<_, ast::PosFieldDefList>(node) { | ||
176 | StructKind::Tuple(pfl) | ||
177 | } else { | ||
178 | StructKind::Unit | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | |||
183 | impl ast::StructDef { | ||
184 | pub fn kind(&self) -> StructKind { | ||
185 | StructKind::from_node(self) | ||
186 | } | ||
187 | } | ||
188 | |||
189 | impl ast::EnumVariant { | ||
190 | pub fn parent_enum(&self) -> &ast::EnumDef { | ||
191 | self.syntax() | ||
192 | .parent() | ||
193 | .and_then(|it| it.parent()) | ||
194 | .and_then(ast::EnumDef::cast) | ||
195 | .expect("EnumVariants are always nested in Enums") | ||
196 | } | ||
197 | pub fn kind(&self) -> StructKind { | ||
198 | StructKind::from_node(self) | ||
199 | } | ||
200 | } | ||
201 | |||
202 | impl ast::LetStmt { | ||
203 | pub fn has_semi(&self) -> bool { | ||
204 | match self.syntax().last_child_or_token() { | ||
205 | None => false, | ||
206 | Some(node) => node.kind() == SEMI, | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
211 | impl ast::ExprStmt { | ||
212 | pub fn has_semi(&self) -> bool { | ||
213 | match self.syntax().last_child_or_token() { | ||
214 | None => false, | ||
215 | Some(node) => node.kind() == SEMI, | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | |||
220 | impl ast::RefPat { | ||
221 | pub fn is_mut(&self) -> bool { | ||
222 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | ||
223 | } | ||
224 | } | ||
225 | |||
226 | impl ast::BindPat { | ||
227 | pub fn is_mutable(&self) -> bool { | ||
228 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | ||
229 | } | ||
230 | |||
231 | pub fn is_ref(&self) -> bool { | ||
232 | self.syntax().children_with_tokens().any(|n| n.kind() == REF_KW) | ||
233 | } | ||
234 | } | ||
235 | |||
236 | impl ast::PointerType { | ||
237 | pub fn is_mut(&self) -> bool { | ||
238 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | ||
239 | } | ||
240 | } | ||
241 | |||
242 | impl ast::ReferenceType { | ||
243 | pub fn is_mut(&self) -> bool { | ||
244 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | ||
245 | } | ||
246 | } | ||
247 | |||
248 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
249 | pub enum SelfParamKind { | ||
250 | /// self | ||
251 | Owned, | ||
252 | /// &self | ||
253 | Ref, | ||
254 | /// &mut self | ||
255 | MutRef, | ||
256 | } | ||
257 | |||
258 | impl ast::SelfParam { | ||
259 | pub fn self_kw_token(&self) -> SyntaxToken { | ||
260 | self.syntax() | ||
261 | .children_with_tokens() | ||
262 | .filter_map(|it| it.as_token()) | ||
263 | .find(|it| it.kind() == SELF_KW) | ||
264 | .expect("invalid tree: self param must have self") | ||
265 | } | ||
266 | |||
267 | pub fn kind(&self) -> SelfParamKind { | ||
268 | let borrowed = self.syntax().children_with_tokens().any(|n| n.kind() == AMP); | ||
269 | if borrowed { | ||
270 | // check for a `mut` coming after the & -- `mut &self` != `&mut self` | ||
271 | if self | ||
272 | .syntax() | ||
273 | .children_with_tokens() | ||
274 | .skip_while(|n| n.kind() != AMP) | ||
275 | .any(|n| n.kind() == MUT_KW) | ||
276 | { | ||
277 | SelfParamKind::MutRef | ||
278 | } else { | ||
279 | SelfParamKind::Ref | ||
280 | } | ||
281 | } else { | ||
282 | SelfParamKind::Owned | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | |||
287 | impl ast::LifetimeParam { | ||
288 | pub fn lifetime_token(&self) -> Option<SyntaxToken> { | ||
289 | self.syntax() | ||
290 | .children_with_tokens() | ||
291 | .filter_map(|it| it.as_token()) | ||
292 | .find(|it| it.kind() == LIFETIME) | ||
293 | } | ||
294 | } | ||
295 | |||
296 | impl ast::WherePred { | ||
297 | pub fn lifetime_token(&self) -> Option<SyntaxToken> { | ||
298 | self.syntax() | ||
299 | .children_with_tokens() | ||
300 | .filter_map(|it| it.as_token()) | ||
301 | .find(|it| it.kind() == LIFETIME) | ||
302 | } | ||
303 | } | ||
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 47a37e4d1..0376c91c8 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -376,64 +376,6 @@ impl BreakExpr { | |||
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
379 | // Byte | ||
380 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
381 | #[repr(transparent)] | ||
382 | pub struct Byte { | ||
383 | pub(crate) syntax: SyntaxNode, | ||
384 | } | ||
385 | unsafe impl TransparentNewType for Byte { | ||
386 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
387 | } | ||
388 | |||
389 | impl AstNode for Byte { | ||
390 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
391 | match syntax.kind() { | ||
392 | BYTE => Some(Byte::from_repr(syntax.into_repr())), | ||
393 | _ => None, | ||
394 | } | ||
395 | } | ||
396 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
397 | } | ||
398 | |||
399 | impl ToOwned for Byte { | ||
400 | type Owned = TreeArc<Byte>; | ||
401 | fn to_owned(&self) -> TreeArc<Byte> { TreeArc::cast(self.syntax.to_owned()) } | ||
402 | } | ||
403 | |||
404 | |||
405 | impl ast::AstToken for Byte {} | ||
406 | impl Byte {} | ||
407 | |||
408 | // ByteString | ||
409 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
410 | #[repr(transparent)] | ||
411 | pub struct ByteString { | ||
412 | pub(crate) syntax: SyntaxNode, | ||
413 | } | ||
414 | unsafe impl TransparentNewType for ByteString { | ||
415 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
416 | } | ||
417 | |||
418 | impl AstNode for ByteString { | ||
419 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
420 | match syntax.kind() { | ||
421 | BYTE_STRING => Some(ByteString::from_repr(syntax.into_repr())), | ||
422 | _ => None, | ||
423 | } | ||
424 | } | ||
425 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
426 | } | ||
427 | |||
428 | impl ToOwned for ByteString { | ||
429 | type Owned = TreeArc<ByteString>; | ||
430 | fn to_owned(&self) -> TreeArc<ByteString> { TreeArc::cast(self.syntax.to_owned()) } | ||
431 | } | ||
432 | |||
433 | |||
434 | impl ast::AstToken for ByteString {} | ||
435 | impl ByteString {} | ||
436 | |||
437 | // CallExpr | 379 | // CallExpr |
438 | #[derive(Debug, PartialEq, Eq, Hash)] | 380 | #[derive(Debug, PartialEq, Eq, Hash)] |
439 | #[repr(transparent)] | 381 | #[repr(transparent)] |
@@ -503,64 +445,6 @@ impl CastExpr { | |||
503 | } | 445 | } |
504 | } | 446 | } |
505 | 447 | ||
506 | // Char | ||
507 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
508 | #[repr(transparent)] | ||
509 | pub struct Char { | ||
510 | pub(crate) syntax: SyntaxNode, | ||
511 | } | ||
512 | unsafe impl TransparentNewType for Char { | ||
513 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
514 | } | ||
515 | |||
516 | impl AstNode for Char { | ||
517 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
518 | match syntax.kind() { | ||
519 | CHAR => Some(Char::from_repr(syntax.into_repr())), | ||
520 | _ => None, | ||
521 | } | ||
522 | } | ||
523 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
524 | } | ||
525 | |||
526 | impl ToOwned for Char { | ||
527 | type Owned = TreeArc<Char>; | ||
528 | fn to_owned(&self) -> TreeArc<Char> { TreeArc::cast(self.syntax.to_owned()) } | ||
529 | } | ||
530 | |||
531 | |||
532 | impl ast::AstToken for Char {} | ||
533 | impl Char {} | ||
534 | |||
535 | // Comment | ||
536 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
537 | #[repr(transparent)] | ||
538 | pub struct Comment { | ||
539 | pub(crate) syntax: SyntaxNode, | ||
540 | } | ||
541 | unsafe impl TransparentNewType for Comment { | ||
542 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
543 | } | ||
544 | |||
545 | impl AstNode for Comment { | ||
546 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
547 | match syntax.kind() { | ||
548 | COMMENT => Some(Comment::from_repr(syntax.into_repr())), | ||
549 | _ => None, | ||
550 | } | ||
551 | } | ||
552 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
553 | } | ||
554 | |||
555 | impl ToOwned for Comment { | ||
556 | type Owned = TreeArc<Comment>; | ||
557 | fn to_owned(&self) -> TreeArc<Comment> { TreeArc::cast(self.syntax.to_owned()) } | ||
558 | } | ||
559 | |||
560 | |||
561 | impl ast::AstToken for Comment {} | ||
562 | impl Comment {} | ||
563 | |||
564 | // Condition | 448 | // Condition |
565 | #[derive(Debug, PartialEq, Eq, Hash)] | 449 | #[derive(Debug, PartialEq, Eq, Hash)] |
566 | #[repr(transparent)] | 450 | #[repr(transparent)] |
@@ -629,7 +513,11 @@ impl ast::TypeParamsOwner for ConstDef {} | |||
629 | impl ast::AttrsOwner for ConstDef {} | 513 | impl ast::AttrsOwner for ConstDef {} |
630 | impl ast::DocCommentsOwner for ConstDef {} | 514 | impl ast::DocCommentsOwner for ConstDef {} |
631 | impl ast::TypeAscriptionOwner for ConstDef {} | 515 | impl ast::TypeAscriptionOwner for ConstDef {} |
632 | impl ConstDef {} | 516 | impl ConstDef { |
517 | pub fn body(&self) -> Option<&Expr> { | ||
518 | super::child_opt(self) | ||
519 | } | ||
520 | } | ||
633 | 521 | ||
634 | // ContinueExpr | 522 | // ContinueExpr |
635 | #[derive(Debug, PartialEq, Eq, Hash)] | 523 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -685,6 +573,7 @@ impl ToOwned for DynTraitType { | |||
685 | } | 573 | } |
686 | 574 | ||
687 | 575 | ||
576 | impl ast::TypeBoundsOwner for DynTraitType {} | ||
688 | impl DynTraitType {} | 577 | impl DynTraitType {} |
689 | 578 | ||
690 | // EnumDef | 579 | // EnumDef |
@@ -830,6 +719,7 @@ pub enum ExprKind<'a> { | |||
830 | RangeExpr(&'a RangeExpr), | 719 | RangeExpr(&'a RangeExpr), |
831 | BinExpr(&'a BinExpr), | 720 | BinExpr(&'a BinExpr), |
832 | Literal(&'a Literal), | 721 | Literal(&'a Literal), |
722 | MacroCall(&'a MacroCall), | ||
833 | } | 723 | } |
834 | impl<'a> From<&'a TupleExpr> for &'a Expr { | 724 | impl<'a> From<&'a TupleExpr> for &'a Expr { |
835 | fn from(n: &'a TupleExpr) -> &'a Expr { | 725 | fn from(n: &'a TupleExpr) -> &'a Expr { |
@@ -966,6 +856,11 @@ impl<'a> From<&'a Literal> for &'a Expr { | |||
966 | Expr::cast(&n.syntax).unwrap() | 856 | Expr::cast(&n.syntax).unwrap() |
967 | } | 857 | } |
968 | } | 858 | } |
859 | impl<'a> From<&'a MacroCall> for &'a Expr { | ||
860 | fn from(n: &'a MacroCall) -> &'a Expr { | ||
861 | Expr::cast(&n.syntax).unwrap() | ||
862 | } | ||
863 | } | ||
969 | 864 | ||
970 | 865 | ||
971 | impl AstNode for Expr { | 866 | impl AstNode for Expr { |
@@ -997,7 +892,8 @@ impl AstNode for Expr { | |||
997 | | PREFIX_EXPR | 892 | | PREFIX_EXPR |
998 | | RANGE_EXPR | 893 | | RANGE_EXPR |
999 | | BIN_EXPR | 894 | | BIN_EXPR |
1000 | | LITERAL => Some(Expr::from_repr(syntax.into_repr())), | 895 | | LITERAL |
896 | | MACRO_CALL => Some(Expr::from_repr(syntax.into_repr())), | ||
1001 | _ => None, | 897 | _ => None, |
1002 | } | 898 | } |
1003 | } | 899 | } |
@@ -1039,6 +935,7 @@ impl Expr { | |||
1039 | RANGE_EXPR => ExprKind::RangeExpr(RangeExpr::cast(&self.syntax).unwrap()), | 935 | RANGE_EXPR => ExprKind::RangeExpr(RangeExpr::cast(&self.syntax).unwrap()), |
1040 | BIN_EXPR => ExprKind::BinExpr(BinExpr::cast(&self.syntax).unwrap()), | 936 | BIN_EXPR => ExprKind::BinExpr(BinExpr::cast(&self.syntax).unwrap()), |
1041 | LITERAL => ExprKind::Literal(Literal::cast(&self.syntax).unwrap()), | 937 | LITERAL => ExprKind::Literal(Literal::cast(&self.syntax).unwrap()), |
938 | MACRO_CALL => ExprKind::MacroCall(MacroCall::cast(&self.syntax).unwrap()), | ||
1042 | _ => unreachable!(), | 939 | _ => unreachable!(), |
1043 | } | 940 | } |
1044 | } | 941 | } |
@@ -1114,35 +1011,6 @@ impl ExternCrateItem { | |||
1114 | } | 1011 | } |
1115 | } | 1012 | } |
1116 | 1013 | ||
1117 | // FalseKw | ||
1118 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
1119 | #[repr(transparent)] | ||
1120 | pub struct FalseKw { | ||
1121 | pub(crate) syntax: SyntaxNode, | ||
1122 | } | ||
1123 | unsafe impl TransparentNewType for FalseKw { | ||
1124 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
1125 | } | ||
1126 | |||
1127 | impl AstNode for FalseKw { | ||
1128 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
1129 | match syntax.kind() { | ||
1130 | FALSE_KW => Some(FalseKw::from_repr(syntax.into_repr())), | ||
1131 | _ => None, | ||
1132 | } | ||
1133 | } | ||
1134 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1135 | } | ||
1136 | |||
1137 | impl ToOwned for FalseKw { | ||
1138 | type Owned = TreeArc<FalseKw>; | ||
1139 | fn to_owned(&self) -> TreeArc<FalseKw> { TreeArc::cast(self.syntax.to_owned()) } | ||
1140 | } | ||
1141 | |||
1142 | |||
1143 | impl ast::AstToken for FalseKw {} | ||
1144 | impl FalseKw {} | ||
1145 | |||
1146 | // FieldExpr | 1014 | // FieldExpr |
1147 | #[derive(Debug, PartialEq, Eq, Hash)] | 1015 | #[derive(Debug, PartialEq, Eq, Hash)] |
1148 | #[repr(transparent)] | 1016 | #[repr(transparent)] |
@@ -1248,35 +1116,6 @@ impl FieldPatList { | |||
1248 | } | 1116 | } |
1249 | } | 1117 | } |
1250 | 1118 | ||
1251 | // FloatNumber | ||
1252 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
1253 | #[repr(transparent)] | ||
1254 | pub struct FloatNumber { | ||
1255 | pub(crate) syntax: SyntaxNode, | ||
1256 | } | ||
1257 | unsafe impl TransparentNewType for FloatNumber { | ||
1258 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
1259 | } | ||
1260 | |||
1261 | impl AstNode for FloatNumber { | ||
1262 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
1263 | match syntax.kind() { | ||
1264 | FLOAT_NUMBER => Some(FloatNumber::from_repr(syntax.into_repr())), | ||
1265 | _ => None, | ||
1266 | } | ||
1267 | } | ||
1268 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1269 | } | ||
1270 | |||
1271 | impl ToOwned for FloatNumber { | ||
1272 | type Owned = TreeArc<FloatNumber>; | ||
1273 | fn to_owned(&self) -> TreeArc<FloatNumber> { TreeArc::cast(self.syntax.to_owned()) } | ||
1274 | } | ||
1275 | |||
1276 | |||
1277 | impl ast::AstToken for FloatNumber {} | ||
1278 | impl FloatNumber {} | ||
1279 | |||
1280 | // FnDef | 1119 | // FnDef |
1281 | #[derive(Debug, PartialEq, Eq, Hash)] | 1120 | #[derive(Debug, PartialEq, Eq, Hash)] |
1282 | #[repr(transparent)] | 1121 | #[repr(transparent)] |
@@ -1581,6 +1420,7 @@ impl ToOwned for ImplTraitType { | |||
1581 | } | 1420 | } |
1582 | 1421 | ||
1583 | 1422 | ||
1423 | impl ast::TypeBoundsOwner for ImplTraitType {} | ||
1584 | impl ImplTraitType {} | 1424 | impl ImplTraitType {} |
1585 | 1425 | ||
1586 | // IndexExpr | 1426 | // IndexExpr |
@@ -1611,35 +1451,6 @@ impl ToOwned for IndexExpr { | |||
1611 | 1451 | ||
1612 | impl IndexExpr {} | 1452 | impl IndexExpr {} |
1613 | 1453 | ||
1614 | // IntNumber | ||
1615 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
1616 | #[repr(transparent)] | ||
1617 | pub struct IntNumber { | ||
1618 | pub(crate) syntax: SyntaxNode, | ||
1619 | } | ||
1620 | unsafe impl TransparentNewType for IntNumber { | ||
1621 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
1622 | } | ||
1623 | |||
1624 | impl AstNode for IntNumber { | ||
1625 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
1626 | match syntax.kind() { | ||
1627 | INT_NUMBER => Some(IntNumber::from_repr(syntax.into_repr())), | ||
1628 | _ => None, | ||
1629 | } | ||
1630 | } | ||
1631 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1632 | } | ||
1633 | |||
1634 | impl ToOwned for IntNumber { | ||
1635 | type Owned = TreeArc<IntNumber>; | ||
1636 | fn to_owned(&self) -> TreeArc<IntNumber> { TreeArc::cast(self.syntax.to_owned()) } | ||
1637 | } | ||
1638 | |||
1639 | |||
1640 | impl ast::AstToken for IntNumber {} | ||
1641 | impl IntNumber {} | ||
1642 | |||
1643 | // ItemList | 1454 | // ItemList |
1644 | #[derive(Debug, PartialEq, Eq, Hash)] | 1455 | #[derive(Debug, PartialEq, Eq, Hash)] |
1645 | #[repr(transparent)] | 1456 | #[repr(transparent)] |
@@ -1775,35 +1586,6 @@ impl LetStmt { | |||
1775 | } | 1586 | } |
1776 | } | 1587 | } |
1777 | 1588 | ||
1778 | // Lifetime | ||
1779 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
1780 | #[repr(transparent)] | ||
1781 | pub struct Lifetime { | ||
1782 | pub(crate) syntax: SyntaxNode, | ||
1783 | } | ||
1784 | unsafe impl TransparentNewType for Lifetime { | ||
1785 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
1786 | } | ||
1787 | |||
1788 | impl AstNode for Lifetime { | ||
1789 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
1790 | match syntax.kind() { | ||
1791 | LIFETIME => Some(Lifetime::from_repr(syntax.into_repr())), | ||
1792 | _ => None, | ||
1793 | } | ||
1794 | } | ||
1795 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1796 | } | ||
1797 | |||
1798 | impl ToOwned for Lifetime { | ||
1799 | type Owned = TreeArc<Lifetime>; | ||
1800 | fn to_owned(&self) -> TreeArc<Lifetime> { TreeArc::cast(self.syntax.to_owned()) } | ||
1801 | } | ||
1802 | |||
1803 | |||
1804 | impl ast::AstToken for Lifetime {} | ||
1805 | impl Lifetime {} | ||
1806 | |||
1807 | // LifetimeArg | 1589 | // LifetimeArg |
1808 | #[derive(Debug, PartialEq, Eq, Hash)] | 1590 | #[derive(Debug, PartialEq, Eq, Hash)] |
1809 | #[repr(transparent)] | 1591 | #[repr(transparent)] |
@@ -1830,11 +1612,7 @@ impl ToOwned for LifetimeArg { | |||
1830 | } | 1612 | } |
1831 | 1613 | ||
1832 | 1614 | ||
1833 | impl LifetimeArg { | 1615 | impl LifetimeArg {} |
1834 | pub fn lifetime(&self) -> Option<&Lifetime> { | ||
1835 | super::child_opt(self) | ||
1836 | } | ||
1837 | } | ||
1838 | 1616 | ||
1839 | // LifetimeParam | 1617 | // LifetimeParam |
1840 | #[derive(Debug, PartialEq, Eq, Hash)] | 1618 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -1863,11 +1641,7 @@ impl ToOwned for LifetimeParam { | |||
1863 | 1641 | ||
1864 | 1642 | ||
1865 | impl ast::AttrsOwner for LifetimeParam {} | 1643 | impl ast::AttrsOwner for LifetimeParam {} |
1866 | impl LifetimeParam { | 1644 | impl LifetimeParam {} |
1867 | pub fn lifetime(&self) -> Option<&Lifetime> { | ||
1868 | super::child_opt(self) | ||
1869 | } | ||
1870 | } | ||
1871 | 1645 | ||
1872 | // Literal | 1646 | // Literal |
1873 | #[derive(Debug, PartialEq, Eq, Hash)] | 1647 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -1895,130 +1669,7 @@ impl ToOwned for Literal { | |||
1895 | } | 1669 | } |
1896 | 1670 | ||
1897 | 1671 | ||
1898 | impl Literal { | 1672 | impl Literal {} |
1899 | pub fn literal_expr(&self) -> Option<&LiteralExpr> { | ||
1900 | super::child_opt(self) | ||
1901 | } | ||
1902 | } | ||
1903 | |||
1904 | // LiteralExpr | ||
1905 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
1906 | #[repr(transparent)] | ||
1907 | pub struct LiteralExpr { | ||
1908 | pub(crate) syntax: SyntaxNode, | ||
1909 | } | ||
1910 | unsafe impl TransparentNewType for LiteralExpr { | ||
1911 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
1912 | } | ||
1913 | |||
1914 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
1915 | pub enum LiteralExprKind<'a> { | ||
1916 | String(&'a String), | ||
1917 | ByteString(&'a ByteString), | ||
1918 | RawString(&'a RawString), | ||
1919 | RawByteString(&'a RawByteString), | ||
1920 | Char(&'a Char), | ||
1921 | Byte(&'a Byte), | ||
1922 | IntNumber(&'a IntNumber), | ||
1923 | FloatNumber(&'a FloatNumber), | ||
1924 | TrueKw(&'a TrueKw), | ||
1925 | FalseKw(&'a FalseKw), | ||
1926 | } | ||
1927 | impl<'a> From<&'a String> for &'a LiteralExpr { | ||
1928 | fn from(n: &'a String) -> &'a LiteralExpr { | ||
1929 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1930 | } | ||
1931 | } | ||
1932 | impl<'a> From<&'a ByteString> for &'a LiteralExpr { | ||
1933 | fn from(n: &'a ByteString) -> &'a LiteralExpr { | ||
1934 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1935 | } | ||
1936 | } | ||
1937 | impl<'a> From<&'a RawString> for &'a LiteralExpr { | ||
1938 | fn from(n: &'a RawString) -> &'a LiteralExpr { | ||
1939 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1940 | } | ||
1941 | } | ||
1942 | impl<'a> From<&'a RawByteString> for &'a LiteralExpr { | ||
1943 | fn from(n: &'a RawByteString) -> &'a LiteralExpr { | ||
1944 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1945 | } | ||
1946 | } | ||
1947 | impl<'a> From<&'a Char> for &'a LiteralExpr { | ||
1948 | fn from(n: &'a Char) -> &'a LiteralExpr { | ||
1949 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1950 | } | ||
1951 | } | ||
1952 | impl<'a> From<&'a Byte> for &'a LiteralExpr { | ||
1953 | fn from(n: &'a Byte) -> &'a LiteralExpr { | ||
1954 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1955 | } | ||
1956 | } | ||
1957 | impl<'a> From<&'a IntNumber> for &'a LiteralExpr { | ||
1958 | fn from(n: &'a IntNumber) -> &'a LiteralExpr { | ||
1959 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1960 | } | ||
1961 | } | ||
1962 | impl<'a> From<&'a FloatNumber> for &'a LiteralExpr { | ||
1963 | fn from(n: &'a FloatNumber) -> &'a LiteralExpr { | ||
1964 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1965 | } | ||
1966 | } | ||
1967 | impl<'a> From<&'a TrueKw> for &'a LiteralExpr { | ||
1968 | fn from(n: &'a TrueKw) -> &'a LiteralExpr { | ||
1969 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1970 | } | ||
1971 | } | ||
1972 | impl<'a> From<&'a FalseKw> for &'a LiteralExpr { | ||
1973 | fn from(n: &'a FalseKw) -> &'a LiteralExpr { | ||
1974 | LiteralExpr::cast(&n.syntax).unwrap() | ||
1975 | } | ||
1976 | } | ||
1977 | |||
1978 | |||
1979 | impl AstNode for LiteralExpr { | ||
1980 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
1981 | match syntax.kind() { | ||
1982 | | STRING | ||
1983 | | BYTE_STRING | ||
1984 | | RAW_STRING | ||
1985 | | RAW_BYTE_STRING | ||
1986 | | CHAR | ||
1987 | | BYTE | ||
1988 | | INT_NUMBER | ||
1989 | | FLOAT_NUMBER | ||
1990 | | TRUE_KW | ||
1991 | | FALSE_KW => Some(LiteralExpr::from_repr(syntax.into_repr())), | ||
1992 | _ => None, | ||
1993 | } | ||
1994 | } | ||
1995 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1996 | } | ||
1997 | |||
1998 | impl ToOwned for LiteralExpr { | ||
1999 | type Owned = TreeArc<LiteralExpr>; | ||
2000 | fn to_owned(&self) -> TreeArc<LiteralExpr> { TreeArc::cast(self.syntax.to_owned()) } | ||
2001 | } | ||
2002 | |||
2003 | impl LiteralExpr { | ||
2004 | pub fn kind(&self) -> LiteralExprKind { | ||
2005 | match self.syntax.kind() { | ||
2006 | STRING => LiteralExprKind::String(String::cast(&self.syntax).unwrap()), | ||
2007 | BYTE_STRING => LiteralExprKind::ByteString(ByteString::cast(&self.syntax).unwrap()), | ||
2008 | RAW_STRING => LiteralExprKind::RawString(RawString::cast(&self.syntax).unwrap()), | ||
2009 | RAW_BYTE_STRING => LiteralExprKind::RawByteString(RawByteString::cast(&self.syntax).unwrap()), | ||
2010 | CHAR => LiteralExprKind::Char(Char::cast(&self.syntax).unwrap()), | ||
2011 | BYTE => LiteralExprKind::Byte(Byte::cast(&self.syntax).unwrap()), | ||
2012 | INT_NUMBER => LiteralExprKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()), | ||
2013 | FLOAT_NUMBER => LiteralExprKind::FloatNumber(FloatNumber::cast(&self.syntax).unwrap()), | ||
2014 | TRUE_KW => LiteralExprKind::TrueKw(TrueKw::cast(&self.syntax).unwrap()), | ||
2015 | FALSE_KW => LiteralExprKind::FalseKw(FalseKw::cast(&self.syntax).unwrap()), | ||
2016 | _ => unreachable!(), | ||
2017 | } | ||
2018 | } | ||
2019 | } | ||
2020 | |||
2021 | impl LiteralExpr {} | ||
2022 | 1673 | ||
2023 | // LiteralPat | 1674 | // LiteralPat |
2024 | #[derive(Debug, PartialEq, Eq, Hash)] | 1675 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -3402,64 +3053,6 @@ impl ToOwned for RangePat { | |||
3402 | 3053 | ||
3403 | impl RangePat {} | 3054 | impl RangePat {} |
3404 | 3055 | ||
3405 | // RawByteString | ||
3406 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
3407 | #[repr(transparent)] | ||
3408 | pub struct RawByteString { | ||
3409 | pub(crate) syntax: SyntaxNode, | ||
3410 | } | ||
3411 | unsafe impl TransparentNewType for RawByteString { | ||
3412 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
3413 | } | ||
3414 | |||
3415 | impl AstNode for RawByteString { | ||
3416 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
3417 | match syntax.kind() { | ||
3418 | RAW_BYTE_STRING => Some(RawByteString::from_repr(syntax.into_repr())), | ||
3419 | _ => None, | ||
3420 | } | ||
3421 | } | ||
3422 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
3423 | } | ||
3424 | |||
3425 | impl ToOwned for RawByteString { | ||
3426 | type Owned = TreeArc<RawByteString>; | ||
3427 | fn to_owned(&self) -> TreeArc<RawByteString> { TreeArc::cast(self.syntax.to_owned()) } | ||
3428 | } | ||
3429 | |||
3430 | |||
3431 | impl ast::AstToken for RawByteString {} | ||
3432 | impl RawByteString {} | ||
3433 | |||
3434 | // RawString | ||
3435 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
3436 | #[repr(transparent)] | ||
3437 | pub struct RawString { | ||
3438 | pub(crate) syntax: SyntaxNode, | ||
3439 | } | ||
3440 | unsafe impl TransparentNewType for RawString { | ||
3441 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
3442 | } | ||
3443 | |||
3444 | impl AstNode for RawString { | ||
3445 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
3446 | match syntax.kind() { | ||
3447 | RAW_STRING => Some(RawString::from_repr(syntax.into_repr())), | ||
3448 | _ => None, | ||
3449 | } | ||
3450 | } | ||
3451 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
3452 | } | ||
3453 | |||
3454 | impl ToOwned for RawString { | ||
3455 | type Owned = TreeArc<RawString>; | ||
3456 | fn to_owned(&self) -> TreeArc<RawString> { TreeArc::cast(self.syntax.to_owned()) } | ||
3457 | } | ||
3458 | |||
3459 | |||
3460 | impl ast::AstToken for RawString {} | ||
3461 | impl RawString {} | ||
3462 | |||
3463 | // RefExpr | 3056 | // RefExpr |
3464 | #[derive(Debug, PartialEq, Eq, Hash)] | 3057 | #[derive(Debug, PartialEq, Eq, Hash)] |
3465 | #[repr(transparent)] | 3058 | #[repr(transparent)] |
@@ -3620,34 +3213,6 @@ impl ReturnExpr { | |||
3620 | } | 3213 | } |
3621 | } | 3214 | } |
3622 | 3215 | ||
3623 | // SelfKw | ||
3624 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
3625 | #[repr(transparent)] | ||
3626 | pub struct SelfKw { | ||
3627 | pub(crate) syntax: SyntaxNode, | ||
3628 | } | ||
3629 | unsafe impl TransparentNewType for SelfKw { | ||
3630 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
3631 | } | ||
3632 | |||
3633 | impl AstNode for SelfKw { | ||
3634 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
3635 | match syntax.kind() { | ||
3636 | SELF_KW => Some(SelfKw::from_repr(syntax.into_repr())), | ||
3637 | _ => None, | ||
3638 | } | ||
3639 | } | ||
3640 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
3641 | } | ||
3642 | |||
3643 | impl ToOwned for SelfKw { | ||
3644 | type Owned = TreeArc<SelfKw>; | ||
3645 | fn to_owned(&self) -> TreeArc<SelfKw> { TreeArc::cast(self.syntax.to_owned()) } | ||
3646 | } | ||
3647 | |||
3648 | |||
3649 | impl SelfKw {} | ||
3650 | |||
3651 | // SelfParam | 3216 | // SelfParam |
3652 | #[derive(Debug, PartialEq, Eq, Hash)] | 3217 | #[derive(Debug, PartialEq, Eq, Hash)] |
3653 | #[repr(transparent)] | 3218 | #[repr(transparent)] |
@@ -3675,11 +3240,7 @@ impl ToOwned for SelfParam { | |||
3675 | 3240 | ||
3676 | 3241 | ||
3677 | impl ast::TypeAscriptionOwner for SelfParam {} | 3242 | impl ast::TypeAscriptionOwner for SelfParam {} |
3678 | impl SelfParam { | 3243 | impl SelfParam {} |
3679 | pub fn self_kw(&self) -> Option<&SelfKw> { | ||
3680 | super::child_opt(self) | ||
3681 | } | ||
3682 | } | ||
3683 | 3244 | ||
3684 | // SlicePat | 3245 | // SlicePat |
3685 | #[derive(Debug, PartialEq, Eq, Hash)] | 3246 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -3807,7 +3368,11 @@ impl ast::TypeParamsOwner for StaticDef {} | |||
3807 | impl ast::AttrsOwner for StaticDef {} | 3368 | impl ast::AttrsOwner for StaticDef {} |
3808 | impl ast::DocCommentsOwner for StaticDef {} | 3369 | impl ast::DocCommentsOwner for StaticDef {} |
3809 | impl ast::TypeAscriptionOwner for StaticDef {} | 3370 | impl ast::TypeAscriptionOwner for StaticDef {} |
3810 | impl StaticDef {} | 3371 | impl StaticDef { |
3372 | pub fn body(&self) -> Option<&Expr> { | ||
3373 | super::child_opt(self) | ||
3374 | } | ||
3375 | } | ||
3811 | 3376 | ||
3812 | // Stmt | 3377 | // Stmt |
3813 | #[derive(Debug, PartialEq, Eq, Hash)] | 3378 | #[derive(Debug, PartialEq, Eq, Hash)] |
@@ -3864,35 +3429,6 @@ impl Stmt { | |||
3864 | 3429 | ||
3865 | impl Stmt {} | 3430 | impl Stmt {} |
3866 | 3431 | ||
3867 | // String | ||
3868 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
3869 | #[repr(transparent)] | ||
3870 | pub struct String { | ||
3871 | pub(crate) syntax: SyntaxNode, | ||
3872 | } | ||
3873 | unsafe impl TransparentNewType for String { | ||
3874 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
3875 | } | ||
3876 | |||
3877 | impl AstNode for String { | ||
3878 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
3879 | match syntax.kind() { | ||
3880 | STRING => Some(String::from_repr(syntax.into_repr())), | ||
3881 | _ => None, | ||
3882 | } | ||
3883 | } | ||
3884 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
3885 | } | ||
3886 | |||
3887 | impl ToOwned for String { | ||
3888 | type Owned = TreeArc<String>; | ||
3889 | fn to_owned(&self) -> TreeArc<String> { TreeArc::cast(self.syntax.to_owned()) } | ||
3890 | } | ||
3891 | |||
3892 | |||
3893 | impl ast::AstToken for String {} | ||
3894 | impl String {} | ||
3895 | |||
3896 | // StructDef | 3432 | // StructDef |
3897 | #[derive(Debug, PartialEq, Eq, Hash)] | 3433 | #[derive(Debug, PartialEq, Eq, Hash)] |
3898 | #[repr(transparent)] | 3434 | #[repr(transparent)] |
@@ -4061,41 +3597,13 @@ impl ast::NameOwner for TraitDef {} | |||
4061 | impl ast::AttrsOwner for TraitDef {} | 3597 | impl ast::AttrsOwner for TraitDef {} |
4062 | impl ast::DocCommentsOwner for TraitDef {} | 3598 | impl ast::DocCommentsOwner for TraitDef {} |
4063 | impl ast::TypeParamsOwner for TraitDef {} | 3599 | impl ast::TypeParamsOwner for TraitDef {} |
3600 | impl ast::TypeBoundsOwner for TraitDef {} | ||
4064 | impl TraitDef { | 3601 | impl TraitDef { |
4065 | pub fn item_list(&self) -> Option<&ItemList> { | 3602 | pub fn item_list(&self) -> Option<&ItemList> { |
4066 | super::child_opt(self) | 3603 | super::child_opt(self) |
4067 | } | 3604 | } |
4068 | } | 3605 | } |
4069 | 3606 | ||
4070 | // TrueKw | ||
4071 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
4072 | #[repr(transparent)] | ||
4073 | pub struct TrueKw { | ||
4074 | pub(crate) syntax: SyntaxNode, | ||
4075 | } | ||
4076 | unsafe impl TransparentNewType for TrueKw { | ||
4077 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
4078 | } | ||
4079 | |||
4080 | impl AstNode for TrueKw { | ||
4081 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
4082 | match syntax.kind() { | ||
4083 | TRUE_KW => Some(TrueKw::from_repr(syntax.into_repr())), | ||
4084 | _ => None, | ||
4085 | } | ||
4086 | } | ||
4087 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
4088 | } | ||
4089 | |||
4090 | impl ToOwned for TrueKw { | ||
4091 | type Owned = TreeArc<TrueKw>; | ||
4092 | fn to_owned(&self) -> TreeArc<TrueKw> { TreeArc::cast(self.syntax.to_owned()) } | ||
4093 | } | ||
4094 | |||
4095 | |||
4096 | impl ast::AstToken for TrueKw {} | ||
4097 | impl TrueKw {} | ||
4098 | |||
4099 | // TryExpr | 3607 | // TryExpr |
4100 | #[derive(Debug, PartialEq, Eq, Hash)] | 3608 | #[derive(Debug, PartialEq, Eq, Hash)] |
4101 | #[repr(transparent)] | 3609 | #[repr(transparent)] |
@@ -4291,6 +3799,7 @@ impl ast::NameOwner for TypeAliasDef {} | |||
4291 | impl ast::TypeParamsOwner for TypeAliasDef {} | 3799 | impl ast::TypeParamsOwner for TypeAliasDef {} |
4292 | impl ast::AttrsOwner for TypeAliasDef {} | 3800 | impl ast::AttrsOwner for TypeAliasDef {} |
4293 | impl ast::DocCommentsOwner for TypeAliasDef {} | 3801 | impl ast::DocCommentsOwner for TypeAliasDef {} |
3802 | impl ast::TypeBoundsOwner for TypeAliasDef {} | ||
4294 | impl TypeAliasDef { | 3803 | impl TypeAliasDef { |
4295 | pub fn type_ref(&self) -> Option<&TypeRef> { | 3804 | pub fn type_ref(&self) -> Option<&TypeRef> { |
4296 | super::child_opt(self) | 3805 | super::child_opt(self) |
@@ -4369,6 +3878,70 @@ impl TypeArgList { | |||
4369 | } | 3878 | } |
4370 | } | 3879 | } |
4371 | 3880 | ||
3881 | // TypeBound | ||
3882 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
3883 | #[repr(transparent)] | ||
3884 | pub struct TypeBound { | ||
3885 | pub(crate) syntax: SyntaxNode, | ||
3886 | } | ||
3887 | unsafe impl TransparentNewType for TypeBound { | ||
3888 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
3889 | } | ||
3890 | |||
3891 | impl AstNode for TypeBound { | ||
3892 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
3893 | match syntax.kind() { | ||
3894 | TYPE_BOUND => Some(TypeBound::from_repr(syntax.into_repr())), | ||
3895 | _ => None, | ||
3896 | } | ||
3897 | } | ||
3898 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
3899 | } | ||
3900 | |||
3901 | impl ToOwned for TypeBound { | ||
3902 | type Owned = TreeArc<TypeBound>; | ||
3903 | fn to_owned(&self) -> TreeArc<TypeBound> { TreeArc::cast(self.syntax.to_owned()) } | ||
3904 | } | ||
3905 | |||
3906 | |||
3907 | impl TypeBound { | ||
3908 | pub fn type_ref(&self) -> Option<&TypeRef> { | ||
3909 | super::child_opt(self) | ||
3910 | } | ||
3911 | } | ||
3912 | |||
3913 | // TypeBoundList | ||
3914 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
3915 | #[repr(transparent)] | ||
3916 | pub struct TypeBoundList { | ||
3917 | pub(crate) syntax: SyntaxNode, | ||
3918 | } | ||
3919 | unsafe impl TransparentNewType for TypeBoundList { | ||
3920 | type Repr = rowan::SyntaxNode<RaTypes>; | ||
3921 | } | ||
3922 | |||
3923 | impl AstNode for TypeBoundList { | ||
3924 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
3925 | match syntax.kind() { | ||
3926 | TYPE_BOUND_LIST => Some(TypeBoundList::from_repr(syntax.into_repr())), | ||
3927 | _ => None, | ||
3928 | } | ||
3929 | } | ||
3930 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
3931 | } | ||
3932 | |||
3933 | impl ToOwned for TypeBoundList { | ||
3934 | type Owned = TreeArc<TypeBoundList>; | ||
3935 | fn to_owned(&self) -> TreeArc<TypeBoundList> { TreeArc::cast(self.syntax.to_owned()) } | ||
3936 | } | ||
3937 | |||
3938 | |||
3939 | impl TypeBoundList { | ||
3940 | pub fn bounds(&self) -> impl Iterator<Item = &TypeBound> { | ||
3941 | super::children(self) | ||
3942 | } | ||
3943 | } | ||
3944 | |||
4372 | // TypeParam | 3945 | // TypeParam |
4373 | #[derive(Debug, PartialEq, Eq, Hash)] | 3946 | #[derive(Debug, PartialEq, Eq, Hash)] |
4374 | #[repr(transparent)] | 3947 | #[repr(transparent)] |
@@ -4397,6 +3970,7 @@ impl ToOwned for TypeParam { | |||
4397 | 3970 | ||
4398 | impl ast::NameOwner for TypeParam {} | 3971 | impl ast::NameOwner for TypeParam {} |
4399 | impl ast::AttrsOwner for TypeParam {} | 3972 | impl ast::AttrsOwner for TypeParam {} |
3973 | impl ast::TypeBoundsOwner for TypeParam {} | ||
4400 | impl TypeParam {} | 3974 | impl TypeParam {} |
4401 | 3975 | ||
4402 | // TypeParamList | 3976 | // TypeParamList |
@@ -4737,67 +4311,75 @@ impl ToOwned for WhereClause { | |||
4737 | } | 4311 | } |
4738 | 4312 | ||
4739 | 4313 | ||
4740 | impl WhereClause {} | 4314 | impl WhereClause { |
4315 | pub fn predicates(&self) -> impl Iterator<Item = &WherePred> { | ||
4316 | super::children(self) | ||
4317 | } | ||
4318 | } | ||
4741 | 4319 | ||
4742 | // WhileExpr | 4320 | // WherePred |
4743 | #[derive(Debug, PartialEq, Eq, Hash)] | 4321 | #[derive(Debug, PartialEq, Eq, Hash)] |
4744 | #[repr(transparent)] | 4322 | #[repr(transparent)] |
4745 | pub struct WhileExpr { | 4323 | pub struct WherePred { |
4746 | pub(crate) syntax: SyntaxNode, | 4324 | pub(crate) syntax: SyntaxNode, |
4747 | } | 4325 | } |
4748 | unsafe impl TransparentNewType for WhileExpr { | 4326 | unsafe impl TransparentNewType for WherePred { |
4749 | type Repr = rowan::SyntaxNode<RaTypes>; | 4327 | type Repr = rowan::SyntaxNode<RaTypes>; |
4750 | } | 4328 | } |
4751 | 4329 | ||
4752 | impl AstNode for WhileExpr { | 4330 | impl AstNode for WherePred { |
4753 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | 4331 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { |
4754 | match syntax.kind() { | 4332 | match syntax.kind() { |
4755 | WHILE_EXPR => Some(WhileExpr::from_repr(syntax.into_repr())), | 4333 | WHERE_PRED => Some(WherePred::from_repr(syntax.into_repr())), |
4756 | _ => None, | 4334 | _ => None, |
4757 | } | 4335 | } |
4758 | } | 4336 | } |
4759 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 4337 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
4760 | } | 4338 | } |
4761 | 4339 | ||
4762 | impl ToOwned for WhileExpr { | 4340 | impl ToOwned for WherePred { |
4763 | type Owned = TreeArc<WhileExpr>; | 4341 | type Owned = TreeArc<WherePred>; |
4764 | fn to_owned(&self) -> TreeArc<WhileExpr> { TreeArc::cast(self.syntax.to_owned()) } | 4342 | fn to_owned(&self) -> TreeArc<WherePred> { TreeArc::cast(self.syntax.to_owned()) } |
4765 | } | 4343 | } |
4766 | 4344 | ||
4767 | 4345 | ||
4768 | impl ast::LoopBodyOwner for WhileExpr {} | 4346 | impl ast::TypeBoundsOwner for WherePred {} |
4769 | impl WhileExpr { | 4347 | impl WherePred { |
4770 | pub fn condition(&self) -> Option<&Condition> { | 4348 | pub fn type_ref(&self) -> Option<&TypeRef> { |
4771 | super::child_opt(self) | 4349 | super::child_opt(self) |
4772 | } | 4350 | } |
4773 | } | 4351 | } |
4774 | 4352 | ||
4775 | // Whitespace | 4353 | // WhileExpr |
4776 | #[derive(Debug, PartialEq, Eq, Hash)] | 4354 | #[derive(Debug, PartialEq, Eq, Hash)] |
4777 | #[repr(transparent)] | 4355 | #[repr(transparent)] |
4778 | pub struct Whitespace { | 4356 | pub struct WhileExpr { |
4779 | pub(crate) syntax: SyntaxNode, | 4357 | pub(crate) syntax: SyntaxNode, |
4780 | } | 4358 | } |
4781 | unsafe impl TransparentNewType for Whitespace { | 4359 | unsafe impl TransparentNewType for WhileExpr { |
4782 | type Repr = rowan::SyntaxNode<RaTypes>; | 4360 | type Repr = rowan::SyntaxNode<RaTypes>; |
4783 | } | 4361 | } |
4784 | 4362 | ||
4785 | impl AstNode for Whitespace { | 4363 | impl AstNode for WhileExpr { |
4786 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | 4364 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { |
4787 | match syntax.kind() { | 4365 | match syntax.kind() { |
4788 | WHITESPACE => Some(Whitespace::from_repr(syntax.into_repr())), | 4366 | WHILE_EXPR => Some(WhileExpr::from_repr(syntax.into_repr())), |
4789 | _ => None, | 4367 | _ => None, |
4790 | } | 4368 | } |
4791 | } | 4369 | } |
4792 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 4370 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
4793 | } | 4371 | } |
4794 | 4372 | ||
4795 | impl ToOwned for Whitespace { | 4373 | impl ToOwned for WhileExpr { |
4796 | type Owned = TreeArc<Whitespace>; | 4374 | type Owned = TreeArc<WhileExpr>; |
4797 | fn to_owned(&self) -> TreeArc<Whitespace> { TreeArc::cast(self.syntax.to_owned()) } | 4375 | fn to_owned(&self) -> TreeArc<WhileExpr> { TreeArc::cast(self.syntax.to_owned()) } |
4798 | } | 4376 | } |
4799 | 4377 | ||
4800 | 4378 | ||
4801 | impl ast::AstToken for Whitespace {} | 4379 | impl ast::LoopBodyOwner for WhileExpr {} |
4802 | impl Whitespace {} | 4380 | impl WhileExpr { |
4381 | pub fn condition(&self) -> Option<&Condition> { | ||
4382 | super::child_opt(self) | ||
4383 | } | ||
4384 | } | ||
4803 | 4385 | ||
diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs new file mode 100644 index 000000000..08882ea69 --- /dev/null +++ b/crates/ra_syntax/src/ast/tokens.rs | |||
@@ -0,0 +1,113 @@ | |||
1 | //! There are many AstNodes, but only a few tokens, so we hand-write them here. | ||
2 | |||
3 | use crate::{ | ||
4 | SyntaxToken, | ||
5 | SyntaxKind::{COMMENT, WHITESPACE}, | ||
6 | ast::AstToken, | ||
7 | }; | ||
8 | |||
9 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
10 | pub struct Comment<'a>(SyntaxToken<'a>); | ||
11 | |||
12 | impl<'a> AstToken<'a> for Comment<'a> { | ||
13 | fn cast(token: SyntaxToken<'a>) -> Option<Self> { | ||
14 | if token.kind() == COMMENT { | ||
15 | Some(Comment(token)) | ||
16 | } else { | ||
17 | None | ||
18 | } | ||
19 | } | ||
20 | fn syntax(&self) -> SyntaxToken<'a> { | ||
21 | self.0 | ||
22 | } | ||
23 | } | ||
24 | |||
25 | impl<'a> Comment<'a> { | ||
26 | pub fn kind(&self) -> CommentKind { | ||
27 | kind_by_prefix(self.text()) | ||
28 | } | ||
29 | |||
30 | pub fn prefix(&self) -> &'static str { | ||
31 | prefix_by_kind(self.kind()) | ||
32 | } | ||
33 | } | ||
34 | |||
35 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
36 | pub struct CommentKind { | ||
37 | pub shape: CommentShape, | ||
38 | pub doc: Option<CommentPlacement>, | ||
39 | } | ||
40 | |||
41 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
42 | pub enum CommentShape { | ||
43 | Line, | ||
44 | Block, | ||
45 | } | ||
46 | |||
47 | impl CommentShape { | ||
48 | pub fn is_line(self) -> bool { | ||
49 | self == CommentShape::Line | ||
50 | } | ||
51 | |||
52 | pub fn is_block(self) -> bool { | ||
53 | self == CommentShape::Block | ||
54 | } | ||
55 | } | ||
56 | |||
57 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
58 | pub enum CommentPlacement { | ||
59 | Inner, | ||
60 | Outer, | ||
61 | } | ||
62 | |||
63 | const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = { | ||
64 | use {CommentShape::*, CommentPlacement::*}; | ||
65 | &[ | ||
66 | ("///", CommentKind { shape: Line, doc: Some(Outer) }), | ||
67 | ("//!", CommentKind { shape: Line, doc: Some(Inner) }), | ||
68 | ("/**", CommentKind { shape: Block, doc: Some(Outer) }), | ||
69 | ("/*!", CommentKind { shape: Block, doc: Some(Inner) }), | ||
70 | ("//", CommentKind { shape: Line, doc: None }), | ||
71 | ("/*", CommentKind { shape: Block, doc: None }), | ||
72 | ] | ||
73 | }; | ||
74 | |||
75 | fn kind_by_prefix(text: &str) -> CommentKind { | ||
76 | for (prefix, kind) in COMMENT_PREFIX_TO_KIND.iter() { | ||
77 | if text.starts_with(prefix) { | ||
78 | return *kind; | ||
79 | } | ||
80 | } | ||
81 | panic!("bad comment text: {:?}", text) | ||
82 | } | ||
83 | |||
84 | fn prefix_by_kind(kind: CommentKind) -> &'static str { | ||
85 | for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() { | ||
86 | if *k == kind { | ||
87 | return prefix; | ||
88 | } | ||
89 | } | ||
90 | unreachable!() | ||
91 | } | ||
92 | |||
93 | pub struct Whitespace<'a>(SyntaxToken<'a>); | ||
94 | |||
95 | impl<'a> AstToken<'a> for Whitespace<'a> { | ||
96 | fn cast(token: SyntaxToken<'a>) -> Option<Self> { | ||
97 | if token.kind() == WHITESPACE { | ||
98 | Some(Whitespace(token)) | ||
99 | } else { | ||
100 | None | ||
101 | } | ||
102 | } | ||
103 | fn syntax(&self) -> SyntaxToken<'a> { | ||
104 | self.0 | ||
105 | } | ||
106 | } | ||
107 | |||
108 | impl<'a> Whitespace<'a> { | ||
109 | pub fn spans_multiple_lines(&self) -> bool { | ||
110 | let text = self.text(); | ||
111 | text.find('\n').map_or(false, |idx| text[idx + 1..].contains('\n')) | ||
112 | } | ||
113 | } | ||
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs new file mode 100644 index 000000000..aaf07d731 --- /dev/null +++ b/crates/ra_syntax/src/ast/traits.rs | |||
@@ -0,0 +1,154 @@ | |||
1 | //! Various traits that are implemented by ast nodes. | ||
2 | //! | ||
3 | //! The implementations are usually trivial, and live in generated.rs | ||
4 | |||
5 | use itertools::Itertools; | ||
6 | |||
7 | use crate::{ | ||
8 | syntax_node::{SyntaxNodeChildren, SyntaxElementChildren}, | ||
9 | ast::{self, child_opt, children, AstNode, AstToken, AstChildren}, | ||
10 | }; | ||
11 | |||
12 | pub trait TypeAscriptionOwner: AstNode { | ||
13 | fn ascribed_type(&self) -> Option<&ast::TypeRef> { | ||
14 | child_opt(self) | ||
15 | } | ||
16 | } | ||
17 | |||
18 | pub trait NameOwner: AstNode { | ||
19 | fn name(&self) -> Option<&ast::Name> { | ||
20 | child_opt(self) | ||
21 | } | ||
22 | } | ||
23 | |||
24 | pub trait VisibilityOwner: AstNode { | ||
25 | fn visibility(&self) -> Option<&ast::Visibility> { | ||
26 | child_opt(self) | ||
27 | } | ||
28 | } | ||
29 | |||
30 | pub trait LoopBodyOwner: AstNode { | ||
31 | fn loop_body(&self) -> Option<&ast::Block> { | ||
32 | child_opt(self) | ||
33 | } | ||
34 | } | ||
35 | |||
36 | pub trait ArgListOwner: AstNode { | ||
37 | fn arg_list(&self) -> Option<&ast::ArgList> { | ||
38 | child_opt(self) | ||
39 | } | ||
40 | } | ||
41 | |||
42 | pub trait FnDefOwner: AstNode { | ||
43 | fn functions(&self) -> AstChildren<ast::FnDef> { | ||
44 | children(self) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
49 | pub enum ItemOrMacro<'a> { | ||
50 | Item(&'a ast::ModuleItem), | ||
51 | Macro(&'a ast::MacroCall), | ||
52 | } | ||
53 | |||
54 | pub trait ModuleItemOwner: AstNode { | ||
55 | fn items(&self) -> AstChildren<ast::ModuleItem> { | ||
56 | children(self) | ||
57 | } | ||
58 | fn items_with_macros(&self) -> ItemOrMacroIter { | ||
59 | ItemOrMacroIter(self.syntax().children()) | ||
60 | } | ||
61 | } | ||
62 | |||
63 | #[derive(Debug)] | ||
64 | pub struct ItemOrMacroIter<'a>(SyntaxNodeChildren<'a>); | ||
65 | |||
66 | impl<'a> Iterator for ItemOrMacroIter<'a> { | ||
67 | type Item = ItemOrMacro<'a>; | ||
68 | fn next(&mut self) -> Option<ItemOrMacro<'a>> { | ||
69 | loop { | ||
70 | let n = self.0.next()?; | ||
71 | if let Some(item) = ast::ModuleItem::cast(n) { | ||
72 | return Some(ItemOrMacro::Item(item)); | ||
73 | } | ||
74 | if let Some(call) = ast::MacroCall::cast(n) { | ||
75 | return Some(ItemOrMacro::Macro(call)); | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | |||
81 | pub trait TypeParamsOwner: AstNode { | ||
82 | fn type_param_list(&self) -> Option<&ast::TypeParamList> { | ||
83 | child_opt(self) | ||
84 | } | ||
85 | |||
86 | fn where_clause(&self) -> Option<&ast::WhereClause> { | ||
87 | child_opt(self) | ||
88 | } | ||
89 | } | ||
90 | |||
91 | pub trait TypeBoundsOwner: AstNode { | ||
92 | fn type_bound_list(&self) -> Option<&ast::TypeBoundList> { | ||
93 | child_opt(self) | ||
94 | } | ||
95 | } | ||
96 | |||
97 | pub trait AttrsOwner: AstNode { | ||
98 | fn attrs(&self) -> AstChildren<ast::Attr> { | ||
99 | children(self) | ||
100 | } | ||
101 | fn has_atom_attr(&self, atom: &str) -> bool { | ||
102 | self.attrs().filter_map(|x| x.as_atom()).any(|x| x == atom) | ||
103 | } | ||
104 | } | ||
105 | |||
106 | pub trait DocCommentsOwner: AstNode { | ||
107 | fn doc_comments(&self) -> CommentIter { | ||
108 | CommentIter { iter: self.syntax().children_with_tokens() } | ||
109 | } | ||
110 | |||
111 | /// Returns the textual content of a doc comment block as a single string. | ||
112 | /// That is, strips leading `///` (+ optional 1 character of whitespace) | ||
113 | /// and joins lines. | ||
114 | fn doc_comment_text(&self) -> Option<String> { | ||
115 | let mut has_comments = false; | ||
116 | let docs = self | ||
117 | .doc_comments() | ||
118 | .filter(|comment| comment.kind().doc.is_some()) | ||
119 | .map(|comment| { | ||
120 | has_comments = true; | ||
121 | let prefix_len = comment.prefix().len(); | ||
122 | |||
123 | let line = comment.text().as_str(); | ||
124 | |||
125 | // Determine if the prefix or prefix + 1 char is stripped | ||
126 | let pos = | ||
127 | if line.chars().nth(prefix_len).map(|c| c.is_whitespace()).unwrap_or(false) { | ||
128 | prefix_len + 1 | ||
129 | } else { | ||
130 | prefix_len | ||
131 | }; | ||
132 | |||
133 | line[pos..].to_owned() | ||
134 | }) | ||
135 | .join("\n"); | ||
136 | |||
137 | if has_comments { | ||
138 | Some(docs) | ||
139 | } else { | ||
140 | None | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | |||
145 | pub struct CommentIter<'a> { | ||
146 | iter: SyntaxElementChildren<'a>, | ||
147 | } | ||
148 | |||
149 | impl<'a> Iterator for CommentIter<'a> { | ||
150 | type Item = ast::Comment<'a>; | ||
151 | fn next(&mut self) -> Option<ast::Comment<'a>> { | ||
152 | self.iter.by_ref().find_map(|el| el.as_token().and_then(ast::Comment::cast)) | ||
153 | } | ||
154 | } | ||