]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs
:arrow_up: rust-analyzer
[rust.git] / src / tools / rust-analyzer / crates / syntax / src / ast / node_ext.rs
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 //! These methods should only do simple, shallow tasks related to the syntax of the node itself.
5
6 use std::{borrow::Cow, fmt, iter::successors};
7
8 use itertools::Itertools;
9 use parser::SyntaxKind;
10 use rowan::{GreenNodeData, GreenTokenData};
11
12 use crate::{
13     ast::{self, support, AstNode, AstToken, HasAttrs, HasGenericParams, HasName, SyntaxNode},
14     NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, TokenText, T,
15 };
16
17 impl ast::Lifetime {
18     pub fn text(&self) -> TokenText<'_> {
19         text_of_first_token(self.syntax())
20     }
21 }
22
23 impl ast::Name {
24     pub fn text(&self) -> TokenText<'_> {
25         text_of_first_token(self.syntax())
26     }
27 }
28
29 impl ast::NameRef {
30     pub fn text(&self) -> TokenText<'_> {
31         text_of_first_token(self.syntax())
32     }
33
34     pub fn as_tuple_field(&self) -> Option<usize> {
35         self.text().parse().ok()
36     }
37
38     pub fn token_kind(&self) -> SyntaxKind {
39         self.syntax().first_token().map_or(SyntaxKind::ERROR, |it| it.kind())
40     }
41 }
42
43 fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> {
44     fn first_token(green_ref: &GreenNodeData) -> &GreenTokenData {
45         green_ref.children().next().and_then(NodeOrToken::into_token).unwrap()
46     }
47
48     match node.green() {
49         Cow::Borrowed(green_ref) => TokenText::borrowed(first_token(green_ref).text()),
50         Cow::Owned(green) => TokenText::owned(first_token(&green).to_owned()),
51     }
52 }
53
54 impl ast::HasModuleItem for ast::StmtList {}
55
56 impl ast::BlockExpr {
57     // FIXME: remove all these methods, they belong to ast::StmtList
58     pub fn statements(&self) -> impl Iterator<Item = ast::Stmt> {
59         self.stmt_list().into_iter().flat_map(|it| it.statements())
60     }
61     pub fn tail_expr(&self) -> Option<ast::Expr> {
62         self.stmt_list()?.tail_expr()
63     }
64 }
65
66 #[derive(Debug, PartialEq, Eq, Clone)]
67 pub enum Macro {
68     MacroRules(ast::MacroRules),
69     MacroDef(ast::MacroDef),
70 }
71
72 impl From<ast::MacroRules> for Macro {
73     fn from(it: ast::MacroRules) -> Self {
74         Macro::MacroRules(it)
75     }
76 }
77
78 impl From<ast::MacroDef> for Macro {
79     fn from(it: ast::MacroDef) -> Self {
80         Macro::MacroDef(it)
81     }
82 }
83
84 impl AstNode for Macro {
85     fn can_cast(kind: SyntaxKind) -> bool {
86         matches!(kind, SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF)
87     }
88     fn cast(syntax: SyntaxNode) -> Option<Self> {
89         let res = match syntax.kind() {
90             SyntaxKind::MACRO_RULES => Macro::MacroRules(ast::MacroRules { syntax }),
91             SyntaxKind::MACRO_DEF => Macro::MacroDef(ast::MacroDef { syntax }),
92             _ => return None,
93         };
94         Some(res)
95     }
96     fn syntax(&self) -> &SyntaxNode {
97         match self {
98             Macro::MacroRules(it) => it.syntax(),
99             Macro::MacroDef(it) => it.syntax(),
100         }
101     }
102 }
103
104 impl HasName for Macro {
105     fn name(&self) -> Option<ast::Name> {
106         match self {
107             Macro::MacroRules(mac) => mac.name(),
108             Macro::MacroDef(mac) => mac.name(),
109         }
110     }
111 }
112
113 impl HasAttrs for Macro {}
114
115 impl From<ast::AssocItem> for ast::Item {
116     fn from(assoc: ast::AssocItem) -> Self {
117         match assoc {
118             ast::AssocItem::Const(it) => ast::Item::Const(it),
119             ast::AssocItem::Fn(it) => ast::Item::Fn(it),
120             ast::AssocItem::MacroCall(it) => ast::Item::MacroCall(it),
121             ast::AssocItem::TypeAlias(it) => ast::Item::TypeAlias(it),
122         }
123     }
124 }
125
126 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
127 pub enum AttrKind {
128     Inner,
129     Outer,
130 }
131
132 impl AttrKind {
133     /// Returns `true` if the attr_kind is [`Inner`](Self::Inner).
134     pub fn is_inner(&self) -> bool {
135         matches!(self, Self::Inner)
136     }
137
138     /// Returns `true` if the attr_kind is [`Outer`](Self::Outer).
139     pub fn is_outer(&self) -> bool {
140         matches!(self, Self::Outer)
141     }
142 }
143
144 impl ast::Attr {
145     pub fn as_simple_atom(&self) -> Option<SmolStr> {
146         let meta = self.meta()?;
147         if meta.eq_token().is_some() || meta.token_tree().is_some() {
148             return None;
149         }
150         self.simple_name()
151     }
152
153     pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
154         let tt = self.meta()?.token_tree()?;
155         Some((self.simple_name()?, tt))
156     }
157
158     pub fn simple_name(&self) -> Option<SmolStr> {
159         let path = self.meta()?.path()?;
160         match (path.segment(), path.qualifier()) {
161             (Some(segment), None) => Some(segment.syntax().first_token()?.text().into()),
162             _ => None,
163         }
164     }
165
166     pub fn kind(&self) -> AttrKind {
167         match self.excl_token() {
168             Some(_) => AttrKind::Inner,
169             None => AttrKind::Outer,
170         }
171     }
172
173     pub fn path(&self) -> Option<ast::Path> {
174         self.meta()?.path()
175     }
176
177     pub fn expr(&self) -> Option<ast::Expr> {
178         self.meta()?.expr()
179     }
180
181     pub fn token_tree(&self) -> Option<ast::TokenTree> {
182         self.meta()?.token_tree()
183     }
184 }
185
186 #[derive(Debug, Clone, PartialEq, Eq)]
187 pub enum PathSegmentKind {
188     Name(ast::NameRef),
189     Type { type_ref: Option<ast::Type>, trait_ref: Option<ast::PathType> },
190     SelfTypeKw,
191     SelfKw,
192     SuperKw,
193     CrateKw,
194 }
195
196 impl ast::PathSegment {
197     pub fn parent_path(&self) -> ast::Path {
198         self.syntax()
199             .parent()
200             .and_then(ast::Path::cast)
201             .expect("segments are always nested in paths")
202     }
203
204     pub fn crate_token(&self) -> Option<SyntaxToken> {
205         self.name_ref().and_then(|it| it.crate_token())
206     }
207
208     pub fn self_token(&self) -> Option<SyntaxToken> {
209         self.name_ref().and_then(|it| it.self_token())
210     }
211
212     pub fn self_type_token(&self) -> Option<SyntaxToken> {
213         self.name_ref().and_then(|it| it.Self_token())
214     }
215
216     pub fn super_token(&self) -> Option<SyntaxToken> {
217         self.name_ref().and_then(|it| it.super_token())
218     }
219
220     pub fn kind(&self) -> Option<PathSegmentKind> {
221         let res = if let Some(name_ref) = self.name_ref() {
222             match name_ref.token_kind() {
223                 T![Self] => PathSegmentKind::SelfTypeKw,
224                 T![self] => PathSegmentKind::SelfKw,
225                 T![super] => PathSegmentKind::SuperKw,
226                 T![crate] => PathSegmentKind::CrateKw,
227                 _ => PathSegmentKind::Name(name_ref),
228             }
229         } else {
230             match self.syntax().first_child_or_token()?.kind() {
231                 T![<] => {
232                     // <T> or <T as Trait>
233                     // T is any TypeRef, Trait has to be a PathType
234                     let mut type_refs =
235                         self.syntax().children().filter(|node| ast::Type::can_cast(node.kind()));
236                     let type_ref = type_refs.next().and_then(ast::Type::cast);
237                     let trait_ref = type_refs.next().and_then(ast::PathType::cast);
238                     PathSegmentKind::Type { type_ref, trait_ref }
239                 }
240                 _ => return None,
241             }
242         };
243         Some(res)
244     }
245 }
246
247 impl ast::Path {
248     pub fn parent_path(&self) -> Option<ast::Path> {
249         self.syntax().parent().and_then(ast::Path::cast)
250     }
251
252     pub fn as_single_segment(&self) -> Option<ast::PathSegment> {
253         match self.qualifier() {
254             Some(_) => None,
255             None => self.segment(),
256         }
257     }
258
259     pub fn as_single_name_ref(&self) -> Option<ast::NameRef> {
260         match self.qualifier() {
261             Some(_) => None,
262             None => self.segment()?.name_ref(),
263         }
264     }
265
266     pub fn first_qualifier_or_self(&self) -> ast::Path {
267         successors(Some(self.clone()), ast::Path::qualifier).last().unwrap()
268     }
269
270     pub fn first_segment(&self) -> Option<ast::PathSegment> {
271         self.first_qualifier_or_self().segment()
272     }
273
274     pub fn segments(&self) -> impl Iterator<Item = ast::PathSegment> + Clone {
275         successors(self.first_segment(), |p| {
276             p.parent_path().parent_path().and_then(|p| p.segment())
277         })
278     }
279
280     pub fn qualifiers(&self) -> impl Iterator<Item = ast::Path> + Clone {
281         successors(self.qualifier(), |p| p.qualifier())
282     }
283
284     pub fn top_path(&self) -> ast::Path {
285         let mut this = self.clone();
286         while let Some(path) = this.parent_path() {
287             this = path;
288         }
289         this
290     }
291 }
292
293 impl ast::Use {
294     pub fn is_simple_glob(&self) -> bool {
295         self.use_tree().map_or(false, |use_tree| {
296             use_tree.use_tree_list().is_none() && use_tree.star_token().is_some()
297         })
298     }
299 }
300
301 impl ast::UseTree {
302     pub fn is_simple_path(&self) -> bool {
303         self.use_tree_list().is_none() && self.star_token().is_none()
304     }
305 }
306
307 impl ast::UseTreeList {
308     pub fn parent_use_tree(&self) -> ast::UseTree {
309         self.syntax()
310             .parent()
311             .and_then(ast::UseTree::cast)
312             .expect("UseTreeLists are always nested in UseTrees")
313     }
314
315     pub fn has_inner_comment(&self) -> bool {
316         self.syntax()
317             .children_with_tokens()
318             .filter_map(|it| it.into_token())
319             .find_map(ast::Comment::cast)
320             .is_some()
321     }
322 }
323
324 impl ast::Impl {
325     pub fn self_ty(&self) -> Option<ast::Type> {
326         match self.target() {
327             (Some(t), None) | (_, Some(t)) => Some(t),
328             _ => None,
329         }
330     }
331
332     pub fn trait_(&self) -> Option<ast::Type> {
333         match self.target() {
334             (Some(t), Some(_)) => Some(t),
335             _ => None,
336         }
337     }
338
339     fn target(&self) -> (Option<ast::Type>, Option<ast::Type>) {
340         let mut types = support::children(self.syntax());
341         let first = types.next();
342         let second = types.next();
343         (first, second)
344     }
345
346     pub fn for_trait_name_ref(name_ref: &ast::NameRef) -> Option<ast::Impl> {
347         let this = name_ref.syntax().ancestors().find_map(ast::Impl::cast)?;
348         if this.trait_()?.syntax().text_range().start() == name_ref.syntax().text_range().start() {
349             Some(this)
350         } else {
351             None
352         }
353     }
354 }
355
356 #[derive(Debug, Clone, PartialEq, Eq)]
357 pub enum StructKind {
358     Record(ast::RecordFieldList),
359     Tuple(ast::TupleFieldList),
360     Unit,
361 }
362
363 impl StructKind {
364     fn from_node<N: AstNode>(node: &N) -> StructKind {
365         if let Some(nfdl) = support::child::<ast::RecordFieldList>(node.syntax()) {
366             StructKind::Record(nfdl)
367         } else if let Some(pfl) = support::child::<ast::TupleFieldList>(node.syntax()) {
368             StructKind::Tuple(pfl)
369         } else {
370             StructKind::Unit
371         }
372     }
373 }
374
375 impl ast::Struct {
376     pub fn kind(&self) -> StructKind {
377         StructKind::from_node(self)
378     }
379 }
380
381 impl ast::RecordExprField {
382     pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> {
383         let candidate = Self::for_name_ref(field_name)?;
384         if candidate.field_name().as_ref() == Some(field_name) {
385             Some(candidate)
386         } else {
387             None
388         }
389     }
390
391     pub fn for_name_ref(name_ref: &ast::NameRef) -> Option<ast::RecordExprField> {
392         let syn = name_ref.syntax();
393         syn.parent()
394             .and_then(ast::RecordExprField::cast)
395             .or_else(|| syn.ancestors().nth(4).and_then(ast::RecordExprField::cast))
396     }
397
398     /// Deals with field init shorthand
399     pub fn field_name(&self) -> Option<ast::NameRef> {
400         if let Some(name_ref) = self.name_ref() {
401             return Some(name_ref);
402         }
403         if let ast::Expr::PathExpr(expr) = self.expr()? {
404             let path = expr.path()?;
405             let segment = path.segment()?;
406             let name_ref = segment.name_ref()?;
407             if path.qualifier().is_none() {
408                 return Some(name_ref);
409             }
410         }
411         None
412     }
413 }
414
415 #[derive(Debug, Clone)]
416 pub enum NameLike {
417     NameRef(ast::NameRef),
418     Name(ast::Name),
419     Lifetime(ast::Lifetime),
420 }
421
422 impl NameLike {
423     pub fn as_name_ref(&self) -> Option<&ast::NameRef> {
424         match self {
425             NameLike::NameRef(name_ref) => Some(name_ref),
426             _ => None,
427         }
428     }
429     pub fn as_lifetime(&self) -> Option<&ast::Lifetime> {
430         match self {
431             NameLike::Lifetime(lifetime) => Some(lifetime),
432             _ => None,
433         }
434     }
435     pub fn text(&self) -> TokenText<'_> {
436         match self {
437             NameLike::NameRef(name_ref) => name_ref.text(),
438             NameLike::Name(name) => name.text(),
439             NameLike::Lifetime(lifetime) => lifetime.text(),
440         }
441     }
442 }
443
444 impl ast::AstNode for NameLike {
445     fn can_cast(kind: SyntaxKind) -> bool {
446         matches!(kind, SyntaxKind::NAME | SyntaxKind::NAME_REF | SyntaxKind::LIFETIME)
447     }
448     fn cast(syntax: SyntaxNode) -> Option<Self> {
449         let res = match syntax.kind() {
450             SyntaxKind::NAME => NameLike::Name(ast::Name { syntax }),
451             SyntaxKind::NAME_REF => NameLike::NameRef(ast::NameRef { syntax }),
452             SyntaxKind::LIFETIME => NameLike::Lifetime(ast::Lifetime { syntax }),
453             _ => return None,
454         };
455         Some(res)
456     }
457     fn syntax(&self) -> &SyntaxNode {
458         match self {
459             NameLike::NameRef(it) => it.syntax(),
460             NameLike::Name(it) => it.syntax(),
461             NameLike::Lifetime(it) => it.syntax(),
462         }
463     }
464 }
465
466 const _: () = {
467     use ast::{Lifetime, Name, NameRef};
468     stdx::impl_from!(NameRef, Name, Lifetime for NameLike);
469 };
470
471 #[derive(Debug, Clone, PartialEq)]
472 pub enum NameOrNameRef {
473     Name(ast::Name),
474     NameRef(ast::NameRef),
475 }
476
477 impl fmt::Display for NameOrNameRef {
478     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
479         match self {
480             NameOrNameRef::Name(it) => fmt::Display::fmt(it, f),
481             NameOrNameRef::NameRef(it) => fmt::Display::fmt(it, f),
482         }
483     }
484 }
485
486 impl NameOrNameRef {
487     pub fn text(&self) -> TokenText<'_> {
488         match self {
489             NameOrNameRef::Name(name) => name.text(),
490             NameOrNameRef::NameRef(name_ref) => name_ref.text(),
491         }
492     }
493 }
494
495 impl ast::RecordPatField {
496     pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> {
497         let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?;
498         match candidate.field_name()? {
499             NameOrNameRef::NameRef(name_ref) if name_ref == *field_name => Some(candidate),
500             _ => None,
501         }
502     }
503
504     pub fn for_field_name(field_name: &ast::Name) -> Option<ast::RecordPatField> {
505         let candidate =
506             field_name.syntax().ancestors().nth(2).and_then(ast::RecordPatField::cast)?;
507         match candidate.field_name()? {
508             NameOrNameRef::Name(name) if name == *field_name => Some(candidate),
509             _ => None,
510         }
511     }
512
513     pub fn parent_record_pat(&self) -> ast::RecordPat {
514         self.syntax().ancestors().find_map(ast::RecordPat::cast).unwrap()
515     }
516
517     /// Deals with field init shorthand
518     pub fn field_name(&self) -> Option<NameOrNameRef> {
519         if let Some(name_ref) = self.name_ref() {
520             return Some(NameOrNameRef::NameRef(name_ref));
521         }
522         match self.pat() {
523             Some(ast::Pat::IdentPat(pat)) => {
524                 let name = pat.name()?;
525                 Some(NameOrNameRef::Name(name))
526             }
527             Some(ast::Pat::BoxPat(pat)) => match pat.pat() {
528                 Some(ast::Pat::IdentPat(pat)) => {
529                     let name = pat.name()?;
530                     Some(NameOrNameRef::Name(name))
531                 }
532                 _ => None,
533             },
534             _ => None,
535         }
536     }
537 }
538
539 impl ast::Variant {
540     pub fn parent_enum(&self) -> ast::Enum {
541         self.syntax()
542             .parent()
543             .and_then(|it| it.parent())
544             .and_then(ast::Enum::cast)
545             .expect("EnumVariants are always nested in Enums")
546     }
547     pub fn kind(&self) -> StructKind {
548         StructKind::from_node(self)
549     }
550 }
551
552 impl ast::Item {
553     pub fn generic_param_list(&self) -> Option<ast::GenericParamList> {
554         ast::AnyHasGenericParams::cast(self.syntax().clone())?.generic_param_list()
555     }
556 }
557
558 #[derive(Debug, Clone, PartialEq, Eq)]
559 pub enum FieldKind {
560     Name(ast::NameRef),
561     Index(SyntaxToken),
562 }
563
564 impl ast::FieldExpr {
565     pub fn index_token(&self) -> Option<SyntaxToken> {
566         self.syntax
567             .children_with_tokens()
568             // FIXME: Accepting floats here to reject them in validation later
569             .find(|c| c.kind() == SyntaxKind::INT_NUMBER || c.kind() == SyntaxKind::FLOAT_NUMBER)
570             .as_ref()
571             .and_then(SyntaxElement::as_token)
572             .cloned()
573     }
574
575     pub fn field_access(&self) -> Option<FieldKind> {
576         match self.name_ref() {
577             Some(nr) => Some(FieldKind::Name(nr)),
578             None => self.index_token().map(FieldKind::Index),
579         }
580     }
581 }
582
583 pub struct SlicePatComponents {
584     pub prefix: Vec<ast::Pat>,
585     pub slice: Option<ast::Pat>,
586     pub suffix: Vec<ast::Pat>,
587 }
588
589 impl ast::SlicePat {
590     pub fn components(&self) -> SlicePatComponents {
591         let mut args = self.pats().peekable();
592         let prefix = args
593             .peeking_take_while(|p| match p {
594                 ast::Pat::RestPat(_) => false,
595                 ast::Pat::IdentPat(bp) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))),
596                 ast::Pat::RefPat(rp) => match rp.pat() {
597                     Some(ast::Pat::RestPat(_)) => false,
598                     Some(ast::Pat::IdentPat(bp)) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))),
599                     _ => true,
600                 },
601                 _ => true,
602             })
603             .collect();
604         let slice = args.next();
605         let suffix = args.collect();
606
607         SlicePatComponents { prefix, slice, suffix }
608     }
609 }
610
611 impl ast::IdentPat {
612     pub fn is_simple_ident(&self) -> bool {
613         self.at_token().is_none()
614             && self.mut_token().is_none()
615             && self.ref_token().is_none()
616             && self.pat().is_none()
617     }
618 }
619
620 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
621 pub enum SelfParamKind {
622     /// self
623     Owned,
624     /// &self
625     Ref,
626     /// &mut self
627     MutRef,
628 }
629
630 impl ast::SelfParam {
631     pub fn kind(&self) -> SelfParamKind {
632         if self.amp_token().is_some() {
633             if self.mut_token().is_some() {
634                 SelfParamKind::MutRef
635             } else {
636                 SelfParamKind::Ref
637             }
638         } else {
639             SelfParamKind::Owned
640         }
641     }
642 }
643
644 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
645 pub enum TypeBoundKind {
646     /// Trait
647     PathType(ast::PathType),
648     /// for<'a> ...
649     ForType(ast::ForType),
650     /// 'a
651     Lifetime(ast::Lifetime),
652 }
653
654 impl ast::TypeBound {
655     pub fn kind(&self) -> TypeBoundKind {
656         if let Some(path_type) = support::children(self.syntax()).next() {
657             TypeBoundKind::PathType(path_type)
658         } else if let Some(for_type) = support::children(self.syntax()).next() {
659             TypeBoundKind::ForType(for_type)
660         } else if let Some(lifetime) = self.lifetime() {
661             TypeBoundKind::Lifetime(lifetime)
662         } else {
663             unreachable!()
664         }
665     }
666 }
667
668 #[derive(Debug, Clone)]
669 pub enum TypeOrConstParam {
670     Type(ast::TypeParam),
671     Const(ast::ConstParam),
672 }
673
674 impl TypeOrConstParam {
675     pub fn name(&self) -> Option<ast::Name> {
676         match self {
677             TypeOrConstParam::Type(x) => x.name(),
678             TypeOrConstParam::Const(x) => x.name(),
679         }
680     }
681 }
682
683 pub enum VisibilityKind {
684     In(ast::Path),
685     PubCrate,
686     PubSuper,
687     PubSelf,
688     Pub,
689 }
690
691 impl ast::Visibility {
692     pub fn kind(&self) -> VisibilityKind {
693         match self.path() {
694             Some(path) => {
695                 if let Some(segment) =
696                     path.as_single_segment().filter(|it| it.coloncolon_token().is_none())
697                 {
698                     if segment.crate_token().is_some() {
699                         return VisibilityKind::PubCrate;
700                     } else if segment.super_token().is_some() {
701                         return VisibilityKind::PubSuper;
702                     } else if segment.self_token().is_some() {
703                         return VisibilityKind::PubSelf;
704                     }
705                 }
706                 VisibilityKind::In(path)
707             }
708             None => VisibilityKind::Pub,
709         }
710     }
711 }
712
713 impl ast::LifetimeParam {
714     pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> {
715         self.syntax()
716             .children_with_tokens()
717             .filter_map(|it| it.into_token())
718             .skip_while(|x| x.kind() != T![:])
719             .filter(|it| it.kind() == T![lifetime_ident])
720     }
721 }
722
723 impl ast::Module {
724     /// Returns the parent ast::Module, this is different than the semantic parent in that this only
725     /// considers parent declarations in the AST
726     pub fn parent(&self) -> Option<ast::Module> {
727         self.syntax().ancestors().nth(2).and_then(ast::Module::cast)
728     }
729 }
730
731 impl ast::RangePat {
732     pub fn start(&self) -> Option<ast::Pat> {
733         self.syntax()
734             .children_with_tokens()
735             .take_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
736             .filter_map(|it| it.into_node())
737             .find_map(ast::Pat::cast)
738     }
739
740     pub fn end(&self) -> Option<ast::Pat> {
741         self.syntax()
742             .children_with_tokens()
743             .skip_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
744             .filter_map(|it| it.into_node())
745             .find_map(ast::Pat::cast)
746     }
747 }
748
749 impl ast::TokenTree {
750     pub fn token_trees_and_tokens(
751         &self,
752     ) -> impl Iterator<Item = NodeOrToken<ast::TokenTree, SyntaxToken>> {
753         self.syntax().children_with_tokens().filter_map(|not| match not {
754             NodeOrToken::Node(node) => ast::TokenTree::cast(node).map(NodeOrToken::Node),
755             NodeOrToken::Token(t) => Some(NodeOrToken::Token(t)),
756         })
757     }
758
759     pub fn left_delimiter_token(&self) -> Option<SyntaxToken> {
760         self.syntax()
761             .first_child_or_token()?
762             .into_token()
763             .filter(|it| matches!(it.kind(), T!['{'] | T!['('] | T!['[']))
764     }
765
766     pub fn right_delimiter_token(&self) -> Option<SyntaxToken> {
767         self.syntax()
768             .last_child_or_token()?
769             .into_token()
770             .filter(|it| matches!(it.kind(), T!['}'] | T![')'] | T![']']))
771     }
772
773     pub fn parent_meta(&self) -> Option<ast::Meta> {
774         self.syntax().parent().and_then(ast::Meta::cast)
775     }
776 }
777
778 impl ast::Meta {
779     pub fn parent_attr(&self) -> Option<ast::Attr> {
780         self.syntax().parent().and_then(ast::Attr::cast)
781     }
782 }
783
784 impl ast::GenericArgList {
785     pub fn lifetime_args(&self) -> impl Iterator<Item = ast::LifetimeArg> {
786         self.generic_args().filter_map(|arg| match arg {
787             ast::GenericArg::LifetimeArg(it) => Some(it),
788             _ => None,
789         })
790     }
791 }
792
793 impl ast::GenericParamList {
794     pub fn lifetime_params(&self) -> impl Iterator<Item = ast::LifetimeParam> {
795         self.generic_params().filter_map(|param| match param {
796             ast::GenericParam::LifetimeParam(it) => Some(it),
797             ast::GenericParam::TypeParam(_) | ast::GenericParam::ConstParam(_) => None,
798         })
799     }
800     pub fn type_or_const_params(&self) -> impl Iterator<Item = ast::TypeOrConstParam> {
801         self.generic_params().filter_map(|param| match param {
802             ast::GenericParam::TypeParam(it) => Some(ast::TypeOrConstParam::Type(it)),
803             ast::GenericParam::LifetimeParam(_) => None,
804             ast::GenericParam::ConstParam(it) => Some(ast::TypeOrConstParam::Const(it)),
805         })
806     }
807 }
808
809 impl ast::ForExpr {
810     pub fn iterable(&self) -> Option<ast::Expr> {
811         // If the iterable is a BlockExpr, check if the body is missing.
812         // If it is assume the iterable is the expression that is missing instead.
813         let mut exprs = support::children(self.syntax());
814         let first = exprs.next();
815         match first {
816             Some(ast::Expr::BlockExpr(_)) => exprs.next().and(first),
817             first => first,
818         }
819     }
820 }
821
822 impl ast::HasLoopBody for ast::ForExpr {
823     fn loop_body(&self) -> Option<ast::BlockExpr> {
824         let mut exprs = support::children(self.syntax());
825         let first = exprs.next();
826         let second = exprs.next();
827         second.or(first)
828     }
829 }
830
831 impl ast::WhileExpr {
832     pub fn condition(&self) -> Option<ast::Expr> {
833         // If the condition is a BlockExpr, check if the body is missing.
834         // If it is assume the condition is the expression that is missing instead.
835         let mut exprs = support::children(self.syntax());
836         let first = exprs.next();
837         match first {
838             Some(ast::Expr::BlockExpr(_)) => exprs.next().and(first),
839             first => first,
840         }
841     }
842 }
843
844 impl ast::HasLoopBody for ast::WhileExpr {
845     fn loop_body(&self) -> Option<ast::BlockExpr> {
846         let mut exprs = support::children(self.syntax());
847         let first = exprs.next();
848         let second = exprs.next();
849         second.or(first)
850     }
851 }
852
853 impl ast::HasAttrs for ast::AnyHasDocComments {}
854
855 impl From<ast::Adt> for ast::Item {
856     fn from(it: ast::Adt) -> Self {
857         match it {
858             ast::Adt::Enum(it) => ast::Item::Enum(it),
859             ast::Adt::Struct(it) => ast::Item::Struct(it),
860             ast::Adt::Union(it) => ast::Item::Union(it),
861         }
862     }
863 }
864
865 impl ast::IfExpr {
866     pub fn condition(&self) -> Option<ast::Expr> {
867         support::child(&self.syntax)
868     }
869 }
870
871 impl ast::MatchGuard {
872     pub fn condition(&self) -> Option<ast::Expr> {
873         support::child(&self.syntax)
874     }
875 }
876
877 impl From<ast::Item> for ast::AnyHasAttrs {
878     fn from(node: ast::Item) -> Self {
879         Self::new(node)
880     }
881 }
882
883 impl From<ast::AssocItem> for ast::AnyHasAttrs {
884     fn from(node: ast::AssocItem) -> Self {
885         Self::new(node)
886     }
887 }
888
889 impl From<ast::Variant> for ast::AnyHasAttrs {
890     fn from(node: ast::Variant) -> Self {
891         Self::new(node)
892     }
893 }
894
895 impl From<ast::RecordField> for ast::AnyHasAttrs {
896     fn from(node: ast::RecordField) -> Self {
897         Self::new(node)
898     }
899 }
900
901 impl From<ast::TupleField> for ast::AnyHasAttrs {
902     fn from(node: ast::TupleField) -> Self {
903         Self::new(node)
904     }
905 }