]> git.lizzy.rs Git - rust.git/commitdiff
Use attribute span
authorsinkuu <sinkuu@sinkuu.xyz>
Fri, 11 Aug 2017 13:16:24 +0000 (22:16 +0900)
committersinkuu <sinkuu@sinkuu.xyz>
Sat, 12 Aug 2017 09:28:28 +0000 (18:28 +0900)
src/visitor.rs

index b455e569e435dd618f93fa35ea14e9f41958368e..8c911465722b7273a68c5542006790393fed33cc 100644 (file)
@@ -12,7 +12,8 @@
 
 use strings::string_buffer::StringBuffer;
 use syntax::{ast, ptr, visit};
-use syntax::codemap::{self, BytePos, CodeMap, Span};
+use syntax::attr::HasAttrs;
+use syntax::codemap::{self, BytePos, CodeMap, Pos, Span};
 use syntax::parse::ParseSess;
 
 use {Indent, Shape, Spanned};
@@ -132,22 +133,45 @@ pub fn visit_block(&mut self, b: &ast::Block, inner_attrs: Option<&[ast::Attribu
         self.buffer.push_str("{");
 
         if self.config.remove_blank_lines_at_start_or_end_of_block() {
-            if let Some(stmt) = b.stmts.first() {
-                let snippet = self.snippet(mk_sp(self.last_pos, stmt.span.lo));
-                let len = CommentCodeSlices::new(&snippet)
-                    .nth(0)
-                    .and_then(|(kind, _, s)| {
-                        if kind == CodeCharKind::Normal {
-                            // There may be inner attributes
-                            let s = &s[..s.len() -
-                                           s.trim_left_matches(&[' ', '\t', '\r', '\n'][..]).len()];
-                            s.rfind('\n')
+            if let Some(first_stmt) = b.stmts.first() {
+                let attr_lo = inner_attrs
+                    .and_then(|attrs| {
+                        attrs
+                            .iter()
+                            .filter(|a| a.style == ast::AttrStyle::Inner)
+                            .nth(0)
+                            .map(|attr| attr.span.lo)
+                    })
+                    .or_else(|| {
+                        // Attributes for an item in a statement position
+                        // do not belong to the statement. (rust-lang/rust#34459)
+                        if let ast::StmtKind::Item(ref item) = first_stmt.node {
+                            item.attrs.first()
                         } else {
-                            None
-                        }
+                            first_stmt.attrs().first()
+                        }.and_then(|attr| {
+                            // Some stmts can have embedded attributes.
+                            // e.g. `match { #![attr] ... }`
+                            let attr_lo = attr.span.lo;
+                            if attr_lo < first_stmt.span.lo {
+                                Some(attr_lo)
+                            } else {
+                                None
+                            }
+                        })
                     });
+
+                let snippet =
+                    self.snippet(mk_sp(self.last_pos, attr_lo.unwrap_or(first_stmt.span.lo)));
+                let len = CommentCodeSlices::new(&snippet).nth(0).and_then(
+                    |(kind, _, s)| if kind == CodeCharKind::Normal {
+                        s.rfind('\n')
+                    } else {
+                        None
+                    },
+                );
                 if let Some(len) = len {
-                    self.last_pos = self.last_pos + BytePos(len as u32);
+                    self.last_pos = self.last_pos + BytePos::from_usize(len);
                 }
             }
         }
@@ -186,7 +210,7 @@ pub fn visit_block(&mut self, b: &ast::Block, inner_attrs: Option<&[ast::Attribu
                         }
                     });
                 if let Some(len) = len {
-                    remove_len = BytePos(len as u32);
+                    remove_len = BytePos::from_usize(len);
                 }
             }
         }