aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/ast')
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs252
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs303
-rw-r--r--crates/ra_syntax/src/ast/generated.rs662
-rw-r--r--crates/ra_syntax/src/ast/tokens.rs113
-rw-r--r--crates/ra_syntax/src/ast/traits.rs154
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
3use crate::{
4 SyntaxToken, SyntaxElement, SmolStr,
5 ast::{self, AstNode, AstChildren, children, child_opt},
6 SyntaxKind::*
7};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum ElseBranch<'a> {
11 Block(&'a ast::Block),
12 IfExpr(&'a ast::IfExpr),
13}
14
15impl 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
35impl 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)]
42pub 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
51impl 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)]
67pub 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
132impl 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)]
197pub enum LiteralKind {
198 String,
199 ByteString,
200 Char,
201 Byte,
202 IntNumber { suffix: Option<SmolStr> },
203 FloatNumber { suffix: Option<SmolStr> },
204 Bool,
205}
206
207impl 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
248impl 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
4use itertools::Itertools;
5
6use crate::{
7 SmolStr, SyntaxToken,
8 ast::{self, AstNode, children, child_opt},
9 SyntaxKind::*,
10};
11
12impl 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
19impl 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
26impl 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)]
74pub enum PathSegmentKind<'a> {
75 Name(&'a ast::NameRef),
76 SelfKw,
77 SuperKw,
78 CrateKw,
79}
80
81impl 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
111impl ast::Path {
112 pub fn parent_path(&self) -> Option<&ast::Path> {
113 self.syntax().parent().and_then(ast::Path::cast)
114 }
115}
116
117impl 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
126impl ast::UseTree {
127 pub fn has_star(&self) -> bool {
128 self.syntax().children_with_tokens().any(|it| it.kind() == STAR)
129 }
130}
131
132impl 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
141impl 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)]
165pub enum StructKind<'a> {
166 Tuple(&'a ast::PosFieldDefList),
167 Named(&'a ast::NamedFieldDefList),
168 Unit,
169}
170
171impl 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
183impl ast::StructDef {
184 pub fn kind(&self) -> StructKind {
185 StructKind::from_node(self)
186 }
187}
188
189impl 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
202impl 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
211impl 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
220impl ast::RefPat {
221 pub fn is_mut(&self) -> bool {
222 self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW)
223 }
224}
225
226impl 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
236impl ast::PointerType {
237 pub fn is_mut(&self) -> bool {
238 self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW)
239 }
240}
241
242impl 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)]
249pub enum SelfParamKind {
250 /// self
251 Owned,
252 /// &self
253 Ref,
254 /// &mut self
255 MutRef,
256}
257
258impl 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
287impl 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
296impl 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)]
382pub struct Byte {
383 pub(crate) syntax: SyntaxNode,
384}
385unsafe impl TransparentNewType for Byte {
386 type Repr = rowan::SyntaxNode<RaTypes>;
387}
388
389impl 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
399impl ToOwned for Byte {
400 type Owned = TreeArc<Byte>;
401 fn to_owned(&self) -> TreeArc<Byte> { TreeArc::cast(self.syntax.to_owned()) }
402}
403
404
405impl ast::AstToken for Byte {}
406impl Byte {}
407
408// ByteString
409#[derive(Debug, PartialEq, Eq, Hash)]
410#[repr(transparent)]
411pub struct ByteString {
412 pub(crate) syntax: SyntaxNode,
413}
414unsafe impl TransparentNewType for ByteString {
415 type Repr = rowan::SyntaxNode<RaTypes>;
416}
417
418impl 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
428impl ToOwned for ByteString {
429 type Owned = TreeArc<ByteString>;
430 fn to_owned(&self) -> TreeArc<ByteString> { TreeArc::cast(self.syntax.to_owned()) }
431}
432
433
434impl ast::AstToken for ByteString {}
435impl 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)]
509pub struct Char {
510 pub(crate) syntax: SyntaxNode,
511}
512unsafe impl TransparentNewType for Char {
513 type Repr = rowan::SyntaxNode<RaTypes>;
514}
515
516impl 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
526impl ToOwned for Char {
527 type Owned = TreeArc<Char>;
528 fn to_owned(&self) -> TreeArc<Char> { TreeArc::cast(self.syntax.to_owned()) }
529}
530
531
532impl ast::AstToken for Char {}
533impl Char {}
534
535// Comment
536#[derive(Debug, PartialEq, Eq, Hash)]
537#[repr(transparent)]
538pub struct Comment {
539 pub(crate) syntax: SyntaxNode,
540}
541unsafe impl TransparentNewType for Comment {
542 type Repr = rowan::SyntaxNode<RaTypes>;
543}
544
545impl 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
555impl ToOwned for Comment {
556 type Owned = TreeArc<Comment>;
557 fn to_owned(&self) -> TreeArc<Comment> { TreeArc::cast(self.syntax.to_owned()) }
558}
559
560
561impl ast::AstToken for Comment {}
562impl 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 {}
629impl ast::AttrsOwner for ConstDef {} 513impl ast::AttrsOwner for ConstDef {}
630impl ast::DocCommentsOwner for ConstDef {} 514impl ast::DocCommentsOwner for ConstDef {}
631impl ast::TypeAscriptionOwner for ConstDef {} 515impl ast::TypeAscriptionOwner for ConstDef {}
632impl ConstDef {} 516impl 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
576impl ast::TypeBoundsOwner for DynTraitType {}
688impl DynTraitType {} 577impl 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}
834impl<'a> From<&'a TupleExpr> for &'a Expr { 724impl<'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}
859impl<'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
971impl AstNode for Expr { 866impl 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)]
1120pub struct FalseKw {
1121 pub(crate) syntax: SyntaxNode,
1122}
1123unsafe impl TransparentNewType for FalseKw {
1124 type Repr = rowan::SyntaxNode<RaTypes>;
1125}
1126
1127impl 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
1137impl ToOwned for FalseKw {
1138 type Owned = TreeArc<FalseKw>;
1139 fn to_owned(&self) -> TreeArc<FalseKw> { TreeArc::cast(self.syntax.to_owned()) }
1140}
1141
1142
1143impl ast::AstToken for FalseKw {}
1144impl 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)]
1254pub struct FloatNumber {
1255 pub(crate) syntax: SyntaxNode,
1256}
1257unsafe impl TransparentNewType for FloatNumber {
1258 type Repr = rowan::SyntaxNode<RaTypes>;
1259}
1260
1261impl 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
1271impl ToOwned for FloatNumber {
1272 type Owned = TreeArc<FloatNumber>;
1273 fn to_owned(&self) -> TreeArc<FloatNumber> { TreeArc::cast(self.syntax.to_owned()) }
1274}
1275
1276
1277impl ast::AstToken for FloatNumber {}
1278impl 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
1423impl ast::TypeBoundsOwner for ImplTraitType {}
1584impl ImplTraitType {} 1424impl ImplTraitType {}
1585 1425
1586// IndexExpr 1426// IndexExpr
@@ -1611,35 +1451,6 @@ impl ToOwned for IndexExpr {
1611 1451
1612impl IndexExpr {} 1452impl IndexExpr {}
1613 1453
1614// IntNumber
1615#[derive(Debug, PartialEq, Eq, Hash)]
1616#[repr(transparent)]
1617pub struct IntNumber {
1618 pub(crate) syntax: SyntaxNode,
1619}
1620unsafe impl TransparentNewType for IntNumber {
1621 type Repr = rowan::SyntaxNode<RaTypes>;
1622}
1623
1624impl 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
1634impl ToOwned for IntNumber {
1635 type Owned = TreeArc<IntNumber>;
1636 fn to_owned(&self) -> TreeArc<IntNumber> { TreeArc::cast(self.syntax.to_owned()) }
1637}
1638
1639
1640impl ast::AstToken for IntNumber {}
1641impl 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)]
1781pub struct Lifetime {
1782 pub(crate) syntax: SyntaxNode,
1783}
1784unsafe impl TransparentNewType for Lifetime {
1785 type Repr = rowan::SyntaxNode<RaTypes>;
1786}
1787
1788impl 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
1798impl ToOwned for Lifetime {
1799 type Owned = TreeArc<Lifetime>;
1800 fn to_owned(&self) -> TreeArc<Lifetime> { TreeArc::cast(self.syntax.to_owned()) }
1801}
1802
1803
1804impl ast::AstToken for Lifetime {}
1805impl 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
1833impl LifetimeArg { 1615impl 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
1865impl ast::AttrsOwner for LifetimeParam {} 1643impl ast::AttrsOwner for LifetimeParam {}
1866impl LifetimeParam { 1644impl 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
1898impl Literal { 1672impl 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)]
1907pub struct LiteralExpr {
1908 pub(crate) syntax: SyntaxNode,
1909}
1910unsafe impl TransparentNewType for LiteralExpr {
1911 type Repr = rowan::SyntaxNode<RaTypes>;
1912}
1913
1914#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1915pub 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}
1927impl<'a> From<&'a String> for &'a LiteralExpr {
1928 fn from(n: &'a String) -> &'a LiteralExpr {
1929 LiteralExpr::cast(&n.syntax).unwrap()
1930 }
1931}
1932impl<'a> From<&'a ByteString> for &'a LiteralExpr {
1933 fn from(n: &'a ByteString) -> &'a LiteralExpr {
1934 LiteralExpr::cast(&n.syntax).unwrap()
1935 }
1936}
1937impl<'a> From<&'a RawString> for &'a LiteralExpr {
1938 fn from(n: &'a RawString) -> &'a LiteralExpr {
1939 LiteralExpr::cast(&n.syntax).unwrap()
1940 }
1941}
1942impl<'a> From<&'a RawByteString> for &'a LiteralExpr {
1943 fn from(n: &'a RawByteString) -> &'a LiteralExpr {
1944 LiteralExpr::cast(&n.syntax).unwrap()
1945 }
1946}
1947impl<'a> From<&'a Char> for &'a LiteralExpr {
1948 fn from(n: &'a Char) -> &'a LiteralExpr {
1949 LiteralExpr::cast(&n.syntax).unwrap()
1950 }
1951}
1952impl<'a> From<&'a Byte> for &'a LiteralExpr {
1953 fn from(n: &'a Byte) -> &'a LiteralExpr {
1954 LiteralExpr::cast(&n.syntax).unwrap()
1955 }
1956}
1957impl<'a> From<&'a IntNumber> for &'a LiteralExpr {
1958 fn from(n: &'a IntNumber) -> &'a LiteralExpr {
1959 LiteralExpr::cast(&n.syntax).unwrap()
1960 }
1961}
1962impl<'a> From<&'a FloatNumber> for &'a LiteralExpr {
1963 fn from(n: &'a FloatNumber) -> &'a LiteralExpr {
1964 LiteralExpr::cast(&n.syntax).unwrap()
1965 }
1966}
1967impl<'a> From<&'a TrueKw> for &'a LiteralExpr {
1968 fn from(n: &'a TrueKw) -> &'a LiteralExpr {
1969 LiteralExpr::cast(&n.syntax).unwrap()
1970 }
1971}
1972impl<'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
1979impl 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
1998impl ToOwned for LiteralExpr {
1999 type Owned = TreeArc<LiteralExpr>;
2000 fn to_owned(&self) -> TreeArc<LiteralExpr> { TreeArc::cast(self.syntax.to_owned()) }
2001}
2002
2003impl 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
2021impl 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
3403impl RangePat {} 3054impl RangePat {}
3404 3055
3405// RawByteString
3406#[derive(Debug, PartialEq, Eq, Hash)]
3407#[repr(transparent)]
3408pub struct RawByteString {
3409 pub(crate) syntax: SyntaxNode,
3410}
3411unsafe impl TransparentNewType for RawByteString {
3412 type Repr = rowan::SyntaxNode<RaTypes>;
3413}
3414
3415impl 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
3425impl ToOwned for RawByteString {
3426 type Owned = TreeArc<RawByteString>;
3427 fn to_owned(&self) -> TreeArc<RawByteString> { TreeArc::cast(self.syntax.to_owned()) }
3428}
3429
3430
3431impl ast::AstToken for RawByteString {}
3432impl RawByteString {}
3433
3434// RawString
3435#[derive(Debug, PartialEq, Eq, Hash)]
3436#[repr(transparent)]
3437pub struct RawString {
3438 pub(crate) syntax: SyntaxNode,
3439}
3440unsafe impl TransparentNewType for RawString {
3441 type Repr = rowan::SyntaxNode<RaTypes>;
3442}
3443
3444impl 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
3454impl ToOwned for RawString {
3455 type Owned = TreeArc<RawString>;
3456 fn to_owned(&self) -> TreeArc<RawString> { TreeArc::cast(self.syntax.to_owned()) }
3457}
3458
3459
3460impl ast::AstToken for RawString {}
3461impl 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)]
3626pub struct SelfKw {
3627 pub(crate) syntax: SyntaxNode,
3628}
3629unsafe impl TransparentNewType for SelfKw {
3630 type Repr = rowan::SyntaxNode<RaTypes>;
3631}
3632
3633impl 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
3643impl ToOwned for SelfKw {
3644 type Owned = TreeArc<SelfKw>;
3645 fn to_owned(&self) -> TreeArc<SelfKw> { TreeArc::cast(self.syntax.to_owned()) }
3646}
3647
3648
3649impl 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
3677impl ast::TypeAscriptionOwner for SelfParam {} 3242impl ast::TypeAscriptionOwner for SelfParam {}
3678impl SelfParam { 3243impl 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 {}
3807impl ast::AttrsOwner for StaticDef {} 3368impl ast::AttrsOwner for StaticDef {}
3808impl ast::DocCommentsOwner for StaticDef {} 3369impl ast::DocCommentsOwner for StaticDef {}
3809impl ast::TypeAscriptionOwner for StaticDef {} 3370impl ast::TypeAscriptionOwner for StaticDef {}
3810impl StaticDef {} 3371impl 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
3865impl Stmt {} 3430impl Stmt {}
3866 3431
3867// String
3868#[derive(Debug, PartialEq, Eq, Hash)]
3869#[repr(transparent)]
3870pub struct String {
3871 pub(crate) syntax: SyntaxNode,
3872}
3873unsafe impl TransparentNewType for String {
3874 type Repr = rowan::SyntaxNode<RaTypes>;
3875}
3876
3877impl 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
3887impl ToOwned for String {
3888 type Owned = TreeArc<String>;
3889 fn to_owned(&self) -> TreeArc<String> { TreeArc::cast(self.syntax.to_owned()) }
3890}
3891
3892
3893impl ast::AstToken for String {}
3894impl 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 {}
4061impl ast::AttrsOwner for TraitDef {} 3597impl ast::AttrsOwner for TraitDef {}
4062impl ast::DocCommentsOwner for TraitDef {} 3598impl ast::DocCommentsOwner for TraitDef {}
4063impl ast::TypeParamsOwner for TraitDef {} 3599impl ast::TypeParamsOwner for TraitDef {}
3600impl ast::TypeBoundsOwner for TraitDef {}
4064impl TraitDef { 3601impl 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)]
4073pub struct TrueKw {
4074 pub(crate) syntax: SyntaxNode,
4075}
4076unsafe impl TransparentNewType for TrueKw {
4077 type Repr = rowan::SyntaxNode<RaTypes>;
4078}
4079
4080impl 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
4090impl ToOwned for TrueKw {
4091 type Owned = TreeArc<TrueKw>;
4092 fn to_owned(&self) -> TreeArc<TrueKw> { TreeArc::cast(self.syntax.to_owned()) }
4093}
4094
4095
4096impl ast::AstToken for TrueKw {}
4097impl 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 {}
4291impl ast::TypeParamsOwner for TypeAliasDef {} 3799impl ast::TypeParamsOwner for TypeAliasDef {}
4292impl ast::AttrsOwner for TypeAliasDef {} 3800impl ast::AttrsOwner for TypeAliasDef {}
4293impl ast::DocCommentsOwner for TypeAliasDef {} 3801impl ast::DocCommentsOwner for TypeAliasDef {}
3802impl ast::TypeBoundsOwner for TypeAliasDef {}
4294impl TypeAliasDef { 3803impl 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)]
3884pub struct TypeBound {
3885 pub(crate) syntax: SyntaxNode,
3886}
3887unsafe impl TransparentNewType for TypeBound {
3888 type Repr = rowan::SyntaxNode<RaTypes>;
3889}
3890
3891impl 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
3901impl ToOwned for TypeBound {
3902 type Owned = TreeArc<TypeBound>;
3903 fn to_owned(&self) -> TreeArc<TypeBound> { TreeArc::cast(self.syntax.to_owned()) }
3904}
3905
3906
3907impl 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)]
3916pub struct TypeBoundList {
3917 pub(crate) syntax: SyntaxNode,
3918}
3919unsafe impl TransparentNewType for TypeBoundList {
3920 type Repr = rowan::SyntaxNode<RaTypes>;
3921}
3922
3923impl 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
3933impl ToOwned for TypeBoundList {
3934 type Owned = TreeArc<TypeBoundList>;
3935 fn to_owned(&self) -> TreeArc<TypeBoundList> { TreeArc::cast(self.syntax.to_owned()) }
3936}
3937
3938
3939impl 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
4398impl ast::NameOwner for TypeParam {} 3971impl ast::NameOwner for TypeParam {}
4399impl ast::AttrsOwner for TypeParam {} 3972impl ast::AttrsOwner for TypeParam {}
3973impl ast::TypeBoundsOwner for TypeParam {}
4400impl TypeParam {} 3974impl TypeParam {}
4401 3975
4402// TypeParamList 3976// TypeParamList
@@ -4737,67 +4311,75 @@ impl ToOwned for WhereClause {
4737} 4311}
4738 4312
4739 4313
4740impl WhereClause {} 4314impl 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)]
4745pub struct WhileExpr { 4323pub struct WherePred {
4746 pub(crate) syntax: SyntaxNode, 4324 pub(crate) syntax: SyntaxNode,
4747} 4325}
4748unsafe impl TransparentNewType for WhileExpr { 4326unsafe impl TransparentNewType for WherePred {
4749 type Repr = rowan::SyntaxNode<RaTypes>; 4327 type Repr = rowan::SyntaxNode<RaTypes>;
4750} 4328}
4751 4329
4752impl AstNode for WhileExpr { 4330impl 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
4762impl ToOwned for WhileExpr { 4340impl 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
4768impl ast::LoopBodyOwner for WhileExpr {} 4346impl ast::TypeBoundsOwner for WherePred {}
4769impl WhileExpr { 4347impl 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)]
4778pub struct Whitespace { 4356pub struct WhileExpr {
4779 pub(crate) syntax: SyntaxNode, 4357 pub(crate) syntax: SyntaxNode,
4780} 4358}
4781unsafe impl TransparentNewType for Whitespace { 4359unsafe impl TransparentNewType for WhileExpr {
4782 type Repr = rowan::SyntaxNode<RaTypes>; 4360 type Repr = rowan::SyntaxNode<RaTypes>;
4783} 4361}
4784 4362
4785impl AstNode for Whitespace { 4363impl 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
4795impl ToOwned for Whitespace { 4373impl 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
4801impl ast::AstToken for Whitespace {} 4379impl ast::LoopBodyOwner for WhileExpr {}
4802impl Whitespace {} 4380impl 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
3use crate::{
4 SyntaxToken,
5 SyntaxKind::{COMMENT, WHITESPACE},
6 ast::AstToken,
7};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub struct Comment<'a>(SyntaxToken<'a>);
11
12impl<'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
25impl<'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)]
36pub struct CommentKind {
37 pub shape: CommentShape,
38 pub doc: Option<CommentPlacement>,
39}
40
41#[derive(Debug, PartialEq, Eq, Clone, Copy)]
42pub enum CommentShape {
43 Line,
44 Block,
45}
46
47impl 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)]
58pub enum CommentPlacement {
59 Inner,
60 Outer,
61}
62
63const 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
75fn 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
84fn 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
93pub struct Whitespace<'a>(SyntaxToken<'a>);
94
95impl<'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
108impl<'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
5use itertools::Itertools;
6
7use crate::{
8 syntax_node::{SyntaxNodeChildren, SyntaxElementChildren},
9 ast::{self, child_opt, children, AstNode, AstToken, AstChildren},
10};
11
12pub trait TypeAscriptionOwner: AstNode {
13 fn ascribed_type(&self) -> Option<&ast::TypeRef> {
14 child_opt(self)
15 }
16}
17
18pub trait NameOwner: AstNode {
19 fn name(&self) -> Option<&ast::Name> {
20 child_opt(self)
21 }
22}
23
24pub trait VisibilityOwner: AstNode {
25 fn visibility(&self) -> Option<&ast::Visibility> {
26 child_opt(self)
27 }
28}
29
30pub trait LoopBodyOwner: AstNode {
31 fn loop_body(&self) -> Option<&ast::Block> {
32 child_opt(self)
33 }
34}
35
36pub trait ArgListOwner: AstNode {
37 fn arg_list(&self) -> Option<&ast::ArgList> {
38 child_opt(self)
39 }
40}
41
42pub trait FnDefOwner: AstNode {
43 fn functions(&self) -> AstChildren<ast::FnDef> {
44 children(self)
45 }
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum ItemOrMacro<'a> {
50 Item(&'a ast::ModuleItem),
51 Macro(&'a ast::MacroCall),
52}
53
54pub 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)]
64pub struct ItemOrMacroIter<'a>(SyntaxNodeChildren<'a>);
65
66impl<'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
81pub 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
91pub trait TypeBoundsOwner: AstNode {
92 fn type_bound_list(&self) -> Option<&ast::TypeBoundList> {
93 child_opt(self)
94 }
95}
96
97pub 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
106pub 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
145pub struct CommentIter<'a> {
146 iter: SyntaxElementChildren<'a>,
147}
148
149impl<'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}