use config::Config;
use filemap::FileMap;
use issues::{BadIssueSeeker, Issue};
-use utils::mk_sp;
+use utils::{mk_sp, outer_attributes};
use visitor::FmtVisitor;
pub use self::summary::Summary;
fn span(&self) -> Span;
}
+macro_rules! span_with_attrs_lo_hi {
+ ($this:ident, $lo:expr, $hi:expr) => {
+ {
+ let attrs = outer_attributes(&$this.attrs);
+ if attrs.is_empty() {
+ mk_sp($lo, $hi)
+ } else {
+ mk_sp(attrs[0].span.lo, $hi)
+ }
+ }
+ }
+}
+macro_rules! span_with_attrs {
+ ($this:ident) => {
+ span_with_attrs_lo_hi!($this, $this.span.lo, $this.span.hi)
+ }
+}
+
impl Spanned for ast::Expr {
fn span(&self) -> Span {
- if self.attrs.is_empty() {
- self.span
- } else {
- mk_sp(self.attrs[0].span.lo, self.span.hi)
- }
+ span_with_attrs!(self)
+ }
+}
+
+impl Spanned for ast::Item {
+ fn span(&self) -> Span {
+ span_with_attrs!(self)
}
}
impl Spanned for ast::Arm {
fn span(&self) -> Span {
- let hi = self.body.span.hi;
- if self.attrs.is_empty() {
- mk_sp(self.pats[0].span.lo, hi)
- } else {
- mk_sp(self.attrs[0].span.lo, hi)
- }
+ span_with_attrs_lo_hi!(self, self.pats[0].span.lo, self.body.span.hi)
}
}
impl Spanned for ast::StructField {
fn span(&self) -> Span {
- if self.attrs.is_empty() {
- mk_sp(self.span.lo, self.ty.span.hi)
- } else {
- // Include attributes and doc comments, if present
- mk_sp(self.attrs[0].span.lo, self.ty.span.hi)
- }
+ span_with_attrs_lo_hi!(self, self.span.lo, self.ty.span.hi)
}
}
impl Spanned for ast::Field {
fn span(&self) -> Span {
- let lo = if self.attrs.is_empty() {
- self.span.lo
- } else {
- self.attrs[0].span.lo
- };
- mk_sp(lo, self.span.hi)
+ span_with_attrs!(self)
}
}
}
}
+#[inline]
+pub fn filter_attributes(attrs: &[ast::Attribute], style: ast::AttrStyle) -> Vec<ast::Attribute> {
+ attrs
+ .iter()
+ .filter(|a| a.style == style)
+ .cloned()
+ .collect::<Vec<_>>()
+}
+
+#[inline]
+pub fn inner_attributes(attrs: &[ast::Attribute]) -> Vec<ast::Attribute> {
+ filter_attributes(attrs, ast::AttrStyle::Inner)
+}
+
+#[inline]
+pub fn outer_attributes(attrs: &[ast::Attribute]) -> Vec<ast::Attribute> {
+ filter_attributes(attrs, ast::AttrStyle::Outer)
+}
+
// The width of the first line in s.
#[inline]
pub fn first_line_width(s: &str) -> usize {
use syntax::codemap::{self, BytePos, CodeMap, Span};
use syntax::parse::ParseSess;
-use {Indent, Shape};
+use {Indent, Shape, Spanned};
use codemap::{LineRangeUtils, SpanUtils};
use comment::{contains_comment, FindUncommented};
use comment::rewrite_comment;
}
}
-fn item_bound(item: &ast::Item) -> Span {
- item.attrs.iter().map(|attr| attr.span).fold(
- item.span,
- |bound, span| {
- Span {
- lo: cmp::min(bound.lo, span.lo),
- hi: cmp::max(bound.hi, span.hi),
- ctxt: span.ctxt,
- }
- },
- )
-}
-
pub struct FmtVisitor<'a> {
pub parse_session: &'a ParseSess,
pub codemap: &'a CodeMap,
let span = if expr.attrs.is_empty() {
stmt.span
} else {
- mk_sp(expr.attrs[0].span.lo, stmt.span.hi)
+ mk_sp(expr.span().lo, stmt.span.hi)
};
self.push_rewrite(span, rewrite)
}
let span = if expr.attrs.is_empty() {
stmt.span
} else {
- mk_sp(expr.attrs[0].span.lo, stmt.span.hi)
+ mk_sp(expr.span().lo, stmt.span.hi)
};
self.push_rewrite(span, rewrite)
}
// next item for output.
if self.config.reorder_imports() && is_use_item(&*items_left[0]) {
let reorder_imports_in_group = self.config.reorder_imports_in_group();
- let mut last = self.codemap.lookup_line_range(item_bound(&items_left[0]));
+ let mut last = self.codemap.lookup_line_range(items_left[0].span());
let use_item_length = items_left
.iter()
.take_while(|ppi| {
is_use_item(&***ppi) && (!reorder_imports_in_group || {
- let current = self.codemap.lookup_line_range(item_bound(&ppi));
+ let current = self.codemap.lookup_line_range(ppi.span());
let in_same_group = current.lo < last.hi + 2;
last = current;
in_same_group