1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use syntax::codemap::Span;
15 use utils::{mk_sp, outer_attributes};
17 /// Spanned returns a span including attributes, if available.
19 fn span(&self) -> Span;
22 macro_rules! span_with_attrs_lo_hi {
23 ($this:ident, $lo:expr, $hi:expr) => {{
24 let attrs = outer_attributes(&$this.attrs);
28 mk_sp(attrs[0].span.lo(), $hi)
33 macro_rules! span_with_attrs {
35 span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
39 macro_rules! implement_spanned {
41 impl Spanned for $this {
42 fn span(&self) -> Span {
43 span_with_attrs!(self)
49 // Implement `Spanned` for structs with `attrs` field.
50 implement_spanned!(ast::Expr);
51 implement_spanned!(ast::Field);
52 implement_spanned!(ast::ForeignItem);
53 implement_spanned!(ast::Item);
54 implement_spanned!(ast::Local);
55 implement_spanned!(ast::TraitItem);
56 implement_spanned!(ast::ImplItem);
58 impl Spanned for ast::Stmt {
59 fn span(&self) -> Span {
61 ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()),
62 ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
63 ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
64 mk_sp(expr.span().lo(), self.span.hi())
66 ast::StmtKind::Mac(ref mac) => {
67 let (_, _, ref attrs) = **mac;
71 mk_sp(attrs[0].span.lo(), self.span.hi())
78 impl Spanned for ast::Pat {
79 fn span(&self) -> Span {
84 impl Spanned for ast::Ty {
85 fn span(&self) -> Span {
90 impl Spanned for ast::Arm {
91 fn span(&self) -> Span {
92 let lo = if self.attrs.is_empty() {
93 self.pats[0].span.lo()
95 self.attrs[0].span.lo()
97 span_with_attrs_lo_hi!(self, lo, self.body.span.hi())
101 impl Spanned for ast::Arg {
102 fn span(&self) -> Span {
103 if ::items::is_named_arg(self) {
104 mk_sp(self.pat.span.lo(), self.ty.span.hi())
111 impl Spanned for ast::GenericParam {
112 fn span(&self) -> Span {
114 ast::GenericParam::Lifetime(ref lifetime_def) => lifetime_def.span(),
115 ast::GenericParam::Type(ref ty) => ty.span(),
120 impl Spanned for ast::StructField {
121 fn span(&self) -> Span {
122 span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
126 impl Spanned for ast::WherePredicate {
127 fn span(&self) -> Span {
129 ast::WherePredicate::BoundPredicate(ref p) => p.span,
130 ast::WherePredicate::RegionPredicate(ref p) => p.span,
131 ast::WherePredicate::EqPredicate(ref p) => p.span,
136 impl Spanned for ast::FunctionRetTy {
137 fn span(&self) -> Span {
139 ast::FunctionRetTy::Default(span) => span,
140 ast::FunctionRetTy::Ty(ref ty) => ty.span,
145 impl Spanned for ast::TyParam {
146 fn span(&self) -> Span {
147 // Note that ty.span is the span for ty.ident, not the whole item.
148 let lo = if self.attrs.is_empty() {
151 self.attrs[0].span.lo()
153 if let Some(ref def) = self.default {
154 return mk_sp(lo, def.span.hi());
156 if self.bounds.is_empty() {
157 return mk_sp(lo, self.ident.span.hi());
159 let hi = self.bounds[self.bounds.len() - 1].span().hi();
164 impl Spanned for ast::TyParamBound {
165 fn span(&self) -> Span {
167 ast::TyParamBound::TraitTyParamBound(ref ptr, _) => ptr.span,
168 ast::TyParamBound::RegionTyParamBound(ref l) => l.ident.span,
173 impl Spanned for ast::LifetimeDef {
174 fn span(&self) -> Span {
175 let hi = if self.bounds.is_empty() {
176 self.lifetime.ident.span.hi()
178 self.bounds[self.bounds.len() - 1].ident.span.hi()
180 mk_sp(self.lifetime.ident.span.lo(), hi)
184 impl Spanned for MacroArg {
185 fn span(&self) -> Span {
187 MacroArg::Expr(ref expr) => expr.span(),
188 MacroArg::Ty(ref ty) => ty.span(),
189 MacroArg::Pat(ref pat) => pat.span(),
190 MacroArg::Item(ref item) => item.span(),