diff --git a/src/expr.rs b/src/expr.rs index 68272f5af84..0d42582ff56 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -18,7 +18,7 @@ use syntax::parse::classify; use {Indent, Shape, Spanned}; use chains::rewrite_chain; -use codemap::SpanUtils; +use codemap::{LineRangeUtils, SpanUtils}; use comment::{contains_comment, recover_comment_removed, rewrite_comment, FindUncommented}; use config::{Config, ControlBraceStyle, IndentStyle, MultilineStyle, Style}; use items::{span_hi_for_arg, span_lo_for_arg}; @@ -111,9 +111,12 @@ pub fn format_expr( context: &RewriteContext, shape: Shape, ) -> Option { + skip_out_of_file_lines_range!(context, expr.span); + if contains_skip(&*expr.attrs) { return Some(context.snippet(expr.span())); } + let expr_rw = match expr.node { ast::ExprKind::Array(ref expr_vec) => rewrite_array( expr_vec.iter().map(|e| &**e), @@ -898,6 +901,8 @@ impl Rewrite for ast::Block { impl Rewrite for ast::Stmt { fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { + skip_out_of_file_lines_range!(context, self.span()); + let result = match self.node { ast::StmtKind::Local(ref local) => local.rewrite(context, shape), ast::StmtKind::Expr(ref ex) | ast::StmtKind::Semi(ref ex) => { diff --git a/src/items.rs b/src/items.rs index f21277e9e83..f4354549499 100644 --- a/src/items.rs +++ b/src/items.rs @@ -17,7 +17,7 @@ use syntax::ast::ImplItem; use syntax::codemap::{BytePos, Span}; use {Indent, Shape, Spanned}; -use codemap::SpanUtils; +use codemap::{LineRangeUtils, SpanUtils}; use comment::{contains_comment, recover_comment_removed, rewrite_comment, FindUncommented}; use config::{BraceStyle, Config, Density, IndentStyle, ReturnIndent, Style}; use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, @@ -50,6 +50,9 @@ impl Rewrite for ast::Local { shape.width, shape.indent ); + + skip_out_of_file_lines_range!(context, self.span); + let mut result = "let ".to_owned(); // 4 = "let ".len() diff --git a/src/utils.rs b/src/utils.rs index 56dde6c247a..9c1717e8638 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -323,6 +323,31 @@ pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span { } } +// Return true if the given span does not intersect with file lines. +macro_rules! out_of_file_lines_range { + ($self:ident, $span:expr) => { + !$self.config + .file_lines() + .intersects(&$self.codemap.lookup_line_range($span)) + } +} + +macro_rules! skip_out_of_file_lines_range { + ($self:ident, $span:expr) => { + if out_of_file_lines_range!($self, $span) { + return None; + } + } +} + +macro_rules! skip_out_of_file_lines_range_visitor { + ($self:ident, $span:expr) => { + if out_of_file_lines_range!($self, $span) { + return; + } + } +} + // Wraps string-like values in an Option. Returns Some when the string adheres // to the Rewrite constraints defined for the Rewrite trait and else otherwise. pub fn wrap_str>(s: S, max_width: usize, shape: Shape) -> Option { diff --git a/src/visitor.rs b/src/visitor.rs index cb94ea9a6dc..389c606c54b 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -67,14 +67,6 @@ impl<'a> FmtVisitor<'a> { self.codemap.lookup_char_pos(stmt.span.hi) ); - // FIXME(#434): Move this check to somewhere more central, eg Rewrite. - if !self.config - .file_lines() - .intersects(&self.codemap.lookup_line_range(stmt.span)) - { - return; - } - match stmt.node { ast::StmtKind::Item(ref item) => { self.visit_item(item); @@ -264,6 +256,8 @@ impl<'a> FmtVisitor<'a> { } pub fn visit_item(&mut self, item: &ast::Item) { + skip_out_of_file_lines_range_visitor!(self, item.span); + // This is where we bail out if there is a skip attribute. This is only // complex in the module case. It is complex because the module could be // in a separate file and there might be attributes in both files, but @@ -465,6 +459,8 @@ impl<'a> FmtVisitor<'a> { } pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) { + skip_out_of_file_lines_range_visitor!(self, ti.span); + if self.visit_attrs(&ti.attrs, ast::AttrStyle::Outer) { self.push_rewrite(ti.span, None); return; @@ -517,6 +513,8 @@ impl<'a> FmtVisitor<'a> { } pub fn visit_impl_item(&mut self, ii: &ast::ImplItem) { + skip_out_of_file_lines_range_visitor!(self, ii.span); + if self.visit_attrs(&ii.attrs, ast::AttrStyle::Outer) { self.push_rewrite(ii.span, None); return; @@ -565,6 +563,8 @@ impl<'a> FmtVisitor<'a> { } fn visit_mac(&mut self, mac: &ast::Mac, ident: Option, pos: MacroPosition) { + skip_out_of_file_lines_range_visitor!(self, mac.span); + // 1 = ; let shape = Shape::indented(self.block_indent, self.config) .sub_width(1) diff --git a/tests/source/file-lines-item.rs b/tests/source/file-lines-item.rs new file mode 100644 index 00000000000..41043d873ac --- /dev/null +++ b/tests/source/file-lines-item.rs @@ -0,0 +1,12 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-item.rs","range":[5,7]}] + +use foo::{c, b, a}; + +fn foo() { + bar ( ) ; +} + +impl Drop for Context { + fn drop(&mut self) { + } +} diff --git a/tests/target/file-lines-item.rs b/tests/target/file-lines-item.rs new file mode 100644 index 00000000000..b5561040ac6 --- /dev/null +++ b/tests/target/file-lines-item.rs @@ -0,0 +1,12 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-item.rs","range":[5,7]}] + +use foo::{c, b, a}; + +fn foo() { + bar(); +} + +impl Drop for Context { + fn drop(&mut self) { + } +}