]> git.lizzy.rs Git - rust.git/blob - src/spanned.rs
Update rustc-ap-* crates to 606.0.0 (#3835)
[rust.git] / src / spanned.rs
1 use std::cmp::max;
2
3 use syntax::{
4     ast, ptr,
5     source_map::{self, Span},
6 };
7
8 use crate::macros::MacroArg;
9 use crate::utils::{mk_sp, outer_attributes};
10
11 /// Spanned returns a span including attributes, if available.
12 pub(crate) trait Spanned {
13     fn span(&self) -> Span;
14 }
15
16 impl<T: Spanned> Spanned for ptr::P<T> {
17     fn span(&self) -> Span {
18         (**self).span()
19     }
20 }
21
22 impl<T> Spanned for source_map::Spanned<T> {
23     fn span(&self) -> Span {
24         self.span
25     }
26 }
27
28 macro_rules! span_with_attrs_lo_hi {
29     ($this:ident, $lo:expr, $hi:expr) => {{
30         let attrs = outer_attributes(&$this.attrs);
31         if attrs.is_empty() {
32             mk_sp($lo, $hi)
33         } else {
34             mk_sp(attrs[0].span.lo(), $hi)
35         }
36     }};
37 }
38
39 macro_rules! span_with_attrs {
40     ($this:ident) => {
41         span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
42     };
43 }
44
45 macro_rules! implement_spanned {
46     ($this:ty) => {
47         impl Spanned for $this {
48             fn span(&self) -> Span {
49                 span_with_attrs!(self)
50             }
51         }
52     };
53 }
54
55 // Implement `Spanned` for structs with `attrs` field.
56 implement_spanned!(ast::Expr);
57 implement_spanned!(ast::Field);
58 implement_spanned!(ast::ForeignItem);
59 implement_spanned!(ast::Item);
60 implement_spanned!(ast::Local);
61 implement_spanned!(ast::TraitItem);
62 implement_spanned!(ast::ImplItem);
63
64 impl Spanned for ast::Stmt {
65     fn span(&self) -> Span {
66         match self.kind {
67             ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()),
68             ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
69             ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
70                 mk_sp(expr.span().lo(), self.span.hi())
71             }
72             ast::StmtKind::Mac(ref mac) => {
73                 let (_, _, ref attrs) = **mac;
74                 if attrs.is_empty() {
75                     self.span
76                 } else {
77                     mk_sp(attrs[0].span.lo(), self.span.hi())
78                 }
79             }
80         }
81     }
82 }
83
84 impl Spanned for ast::Pat {
85     fn span(&self) -> Span {
86         self.span
87     }
88 }
89
90 impl Spanned for ast::Ty {
91     fn span(&self) -> Span {
92         self.span
93     }
94 }
95
96 impl Spanned for ast::Arm {
97     fn span(&self) -> Span {
98         let lo = if self.attrs.is_empty() {
99             self.pat.span.lo()
100         } else {
101             self.attrs[0].span.lo()
102         };
103         span_with_attrs_lo_hi!(self, lo, self.body.span.hi())
104     }
105 }
106
107 impl Spanned for ast::Param {
108     fn span(&self) -> Span {
109         if crate::items::is_named_param(self) {
110             mk_sp(self.pat.span.lo(), self.ty.span.hi())
111         } else {
112             self.ty.span
113         }
114     }
115 }
116
117 impl Spanned for ast::GenericParam {
118     fn span(&self) -> Span {
119         let lo = if self.attrs.is_empty() {
120             self.ident.span.lo()
121         } else {
122             self.attrs[0].span.lo()
123         };
124         let hi = if self.bounds.is_empty() {
125             self.ident.span.hi()
126         } else {
127             self.bounds.last().unwrap().span().hi()
128         };
129         let ty_hi = if let ast::GenericParamKind::Type {
130             default: Some(ref ty),
131         } = self.kind
132         {
133             ty.span().hi()
134         } else {
135             hi
136         };
137         mk_sp(lo, max(hi, ty_hi))
138     }
139 }
140
141 impl Spanned for ast::StructField {
142     fn span(&self) -> Span {
143         span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
144     }
145 }
146
147 impl Spanned for ast::WherePredicate {
148     fn span(&self) -> Span {
149         match *self {
150             ast::WherePredicate::BoundPredicate(ref p) => p.span,
151             ast::WherePredicate::RegionPredicate(ref p) => p.span,
152             ast::WherePredicate::EqPredicate(ref p) => p.span,
153         }
154     }
155 }
156
157 impl Spanned for ast::FunctionRetTy {
158     fn span(&self) -> Span {
159         match *self {
160             ast::FunctionRetTy::Default(span) => span,
161             ast::FunctionRetTy::Ty(ref ty) => ty.span,
162         }
163     }
164 }
165
166 impl Spanned for ast::GenericArg {
167     fn span(&self) -> Span {
168         match *self {
169             ast::GenericArg::Lifetime(ref lt) => lt.ident.span,
170             ast::GenericArg::Type(ref ty) => ty.span(),
171             ast::GenericArg::Const(ref _const) => _const.value.span(),
172         }
173     }
174 }
175
176 impl Spanned for ast::GenericBound {
177     fn span(&self) -> Span {
178         match *self {
179             ast::GenericBound::Trait(ref ptr, _) => ptr.span,
180             ast::GenericBound::Outlives(ref l) => l.ident.span,
181         }
182     }
183 }
184
185 impl Spanned for MacroArg {
186     fn span(&self) -> Span {
187         match *self {
188             MacroArg::Expr(ref expr) => expr.span(),
189             MacroArg::Ty(ref ty) => ty.span(),
190             MacroArg::Pat(ref pat) => pat.span(),
191             MacroArg::Item(ref item) => item.span(),
192             MacroArg::Keyword(_, span) => span,
193         }
194     }
195 }
196
197 impl Spanned for ast::NestedMetaItem {
198     fn span(&self) -> Span {
199         self.span()
200     }
201 }