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) => {
25 let attrs = outer_attributes(&$this.attrs);
29 mk_sp(attrs[0].span.lo(), $hi)
35 macro_rules! span_with_attrs {
37 span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
41 macro_rules! implement_spanned {
43 impl Spanned for $this {
44 fn span(&self) -> Span {
45 span_with_attrs!(self)
51 // Implement `Spanned` for structs with `attrs` field.
52 implement_spanned!(ast::Expr);
53 implement_spanned!(ast::Field);
54 implement_spanned!(ast::ForeignItem);
55 implement_spanned!(ast::Item);
56 implement_spanned!(ast::Local);
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 span_with_attrs_lo_hi!(self, self.pats[0].span.lo(), self.body.span.hi())
96 impl Spanned for ast::Arg {
97 fn span(&self) -> Span {
98 if ::items::is_named_arg(self) {
99 mk_sp(self.pat.span.lo(), self.ty.span.hi())
106 impl Spanned for ast::StructField {
107 fn span(&self) -> Span {
108 span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
112 impl Spanned for ast::WherePredicate {
113 fn span(&self) -> Span {
115 ast::WherePredicate::BoundPredicate(ref p) => p.span,
116 ast::WherePredicate::RegionPredicate(ref p) => p.span,
117 ast::WherePredicate::EqPredicate(ref p) => p.span,
122 impl Spanned for ast::FunctionRetTy {
123 fn span(&self) -> Span {
125 ast::FunctionRetTy::Default(span) => span,
126 ast::FunctionRetTy::Ty(ref ty) => ty.span,
131 impl Spanned for ast::TyParam {
132 fn span(&self) -> Span {
133 // Note that ty.span is the span for ty.ident, not the whole item.
134 let lo = if self.attrs.is_empty() {
137 self.attrs[0].span.lo()
139 if let Some(ref def) = self.default {
140 return mk_sp(lo, def.span.hi());
142 if self.bounds.is_empty() {
143 return mk_sp(lo, self.span.hi());
145 let hi = self.bounds[self.bounds.len() - 1].span().hi();
150 impl Spanned for ast::TyParamBound {
151 fn span(&self) -> Span {
153 ast::TyParamBound::TraitTyParamBound(ref ptr, _) => ptr.span,
154 ast::TyParamBound::RegionTyParamBound(ref l) => l.span,
159 impl Spanned for ast::LifetimeDef {
160 fn span(&self) -> Span {
161 let hi = if self.bounds.is_empty() {
162 self.lifetime.span.hi()
164 self.bounds[self.bounds.len() - 1].span.hi()
166 mk_sp(self.lifetime.span.lo(), hi)
170 impl Spanned for MacroArg {
171 fn span(&self) -> Span {
173 MacroArg::Expr(ref expr) => expr.span(),
174 MacroArg::Ty(ref ty) => ty.span(),
175 MacroArg::Pat(ref pat) => pat.span(),