]> git.lizzy.rs Git - rust.git/commitdiff
Merge pull request #207 from cassiersg/find-comments
authorcassiersg <cassiersg@users.noreply.github.com>
Fri, 28 Aug 2015 12:34:25 +0000 (14:34 +0200)
committercassiersg <cassiersg@users.noreply.github.com>
Fri, 28 Aug 2015 12:34:25 +0000 (14:34 +0200)
Add a generic tool for searching comments in code

src/expr.rs
src/items.rs
src/rewrite.rs
src/visitor.rs
tests/source/attrib.rs [new file with mode: 0644]
tests/source/struct_lits.rs
tests/target/attrib.rs
tests/target/struct_lits.rs

index cbcecc4cdcf9f4de591afe627661f50815111276..e1778dc8a30745b927273ca27c0f7bb1023e52e9 100644 (file)
@@ -31,7 +31,7 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Opti
                     ast::Lit_::LitStr(ref is, ast::StrStyle::CookedStr) => {
                         rewrite_string_lit(context, &is, l.span, width, offset)
                     }
-                    _ => context.codemap.span_to_snippet(self.span).ok(),
+                    _ => Some(context.snippet(self.span)),
                 }
             }
             ast::Expr_::ExprCall(ref callee, ref args) => {
@@ -137,7 +137,7 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Opti
             _ => {
                 // We do not format these expressions yet, but they should still
                 // satisfy our width restrictions.
-                let snippet = context.codemap.span_to_snippet(self.span).unwrap();
+                let snippet = context.snippet(self.span);
 
                 {
                     let mut lines = snippet.lines();
@@ -243,7 +243,7 @@ fn rewrite_closure(capture: ast::CaptureClause,
 
 impl Rewrite for ast::Block {
     fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Option<String> {
-        let user_str = context.codemap.span_to_snippet(self.span).unwrap();
+        let user_str = context.snippet(self.span);
         if user_str == "{}" && width >= 2 {
             return Some(user_str);
         }
@@ -254,7 +254,7 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Opti
         let prefix = match self.rules {
             ast::BlockCheckMode::PushUnsafeBlock(..) |
             ast::BlockCheckMode::UnsafeBlock(..) => {
-                let snippet = try_opt!(context.codemap.span_to_snippet(self.span).ok());
+                let snippet = context.snippet(self.span);
                 let open_pos = try_opt!(snippet.find_uncommented("{"));
                 visitor.last_pos = self.span.lo + BytePos(open_pos as u32);
 
@@ -289,7 +289,7 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Opti
 // FIXME(#18): implement pattern formatting
 impl Rewrite for ast::Pat {
     fn rewrite(&self, context: &RewriteContext, _: usize, _: usize) -> Option<String> {
-        context.codemap.span_to_snippet(self.span).ok()
+        Some(context.snippet(self.span))
     }
 }
 
@@ -546,11 +546,9 @@ fn rewrite_match(context: &RewriteContext,
     for (i, arm) in arms.iter().enumerate() {
         // Make sure we get the stuff between arms.
         let missed_str = if i == 0 {
-            context.codemap.span_to_snippet(mk_sp(open_brace_pos + BytePos(1),
-                                                  arm_start_pos(arm))).unwrap()
+            context.snippet(mk_sp(open_brace_pos + BytePos(1), arm_start_pos(arm)))
         } else {
-            context.codemap.span_to_snippet(mk_sp(arm_end_pos(&arms[i-1]),
-                                                  arm_start_pos(arm))).unwrap()
+            context.snippet(mk_sp(arm_end_pos(&arms[i-1]), arm_start_pos(arm)))
         };
         let missed_str = match missed_str.find_uncommented(",") {
             Some(n) => &missed_str[n+1..],
@@ -581,8 +579,7 @@ fn rewrite_match(context: &RewriteContext,
             result.push_str(arm_str);
         } else {
             // We couldn't format the arm, just reproduce the source.
-            let snippet = context.codemap.span_to_snippet(mk_sp(arm_start_pos(arm),
-                                                                arm_end_pos(arm))).unwrap();
+            let snippet = context.snippet(mk_sp(arm_start_pos(arm), arm_end_pos(arm)));
             result.push_str(&snippet);
         }
     }
@@ -625,8 +622,7 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Opti
             attr_visitor.last_pos = attrs[0].span.lo;
             if attr_visitor.visit_attrs(attrs) {
                 // Attributes included a skip instruction.
-                let snippet = context.codemap.span_to_snippet(mk_sp(attrs[0].span.lo,
-                                                                    body.span.hi)).unwrap();
+                let snippet = context.snippet(mk_sp(attrs[0].span.lo, body.span.hi));
                 return Some(snippet);
             }
             attr_visitor.format_missing(pats[0].span.lo);
@@ -651,7 +647,7 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Opti
             // If the patterns were previously stacked, keep them stacked.
             // FIXME should be an option.
             let pat_span = mk_sp(pats[0].span.lo, pats[pats.len() - 1].span.hi);
-            let pat_str = context.codemap.span_to_snippet(pat_span).unwrap();
+            let pat_str = context.snippet(pat_span);
             vertical = pat_str.find('\n').is_some();
         }
 
@@ -830,7 +826,7 @@ fn rewrite_string_lit(context: &RewriteContext,
     let l_loc = context.codemap.lookup_char_pos(span.lo);
     let r_loc = context.codemap.lookup_char_pos(span.hi);
     if l_loc.line == r_loc.line && r_loc.col.to_usize() <= context.config.max_width {
-        return context.codemap.span_to_snippet(span).ok();
+        return Some(context.snippet(span));
     }
     let fmt = StringFormat {
         opener: "\"",
@@ -879,7 +875,7 @@ fn rewrite_call(context: &RewriteContext,
                              // Take old span when rewrite fails.
                              |item| {
                                  item.rewrite(inner_context, remaining_width, offset)
-                                     .unwrap_or(context.codemap.span_to_snippet(item.span).unwrap())
+                                     .unwrap_or(context.snippet(item.span))
                              },
                              callee.span.hi + BytePos(1),
                              span.hi);
@@ -962,8 +958,14 @@ enum StructLitField<'a> {
                              |item| {
                                  match *item {
                                      StructLitField::Regular(ref field) => field.span.lo,
-                                     // 2 = ..
-                                     StructLitField::Base(ref expr) => expr.span.lo - BytePos(2),
+                                     StructLitField::Base(ref expr) => {
+                                         let last_field_hi =
+                                             fields.last().map_or(span.lo, |field| field.span.hi);
+                                         let snippet =
+                                             context.snippet(mk_sp(last_field_hi, expr.span.lo));
+                                         let pos = snippet.find_uncommented("..").unwrap();
+                                         last_field_hi + BytePos(pos as u32)
+                                     }
                                  }
                              },
                              |item| {
@@ -976,15 +978,13 @@ enum StructLitField<'a> {
                                  match *item {
                                      StructLitField::Regular(ref field) => {
                                          rewrite_field(inner_context, &field, h_budget, indent)
-                                            .unwrap_or(context.codemap.span_to_snippet(field.span)
-                                                                      .unwrap())
+                                            .unwrap_or(context.snippet(field.span))
                                      }
                                      StructLitField::Base(ref expr) => {
                                          // 2 = ..
                                          expr.rewrite(inner_context, h_budget - 2, indent + 2)
                                              .map(|s| format!("..{}", s))
-                                             .unwrap_or(context.codemap.span_to_snippet(expr.span)
-                                                                       .unwrap())
+                                             .unwrap_or(context.snippet(expr.span))
                                      }
                                  }
                              },
@@ -1052,7 +1052,7 @@ fn rewrite_tuple_lit(context: &RewriteContext,
                              |item| {
                                  let inner_width = context.config.max_width - indent - 1;
                                  item.rewrite(context, inner_width, indent)
-                                     .unwrap_or(context.codemap.span_to_snippet(item.span).unwrap())
+                                     .unwrap_or(context.snippet(item.span))
                              },
                              span.lo + BytePos(1), // Remove parens
                              span.hi - BytePos(1));
@@ -1071,7 +1071,7 @@ fn rewrite_binary_op(context: &RewriteContext,
                      -> Option<String> {
     // FIXME: format comments between operands and operator
 
-    let operator_str = context.codemap.span_to_snippet(op.span).unwrap();
+    let operator_str = context.snippet(op.span);
 
     // Get "full width" rhs and see if it fits on the current line. This
     // usually works fairly well since it tends to place operands of
@@ -1149,7 +1149,7 @@ fn rewrite_assignment(context: &RewriteContext,
                       offset: usize)
                       -> Option<String> {
     let operator_str = match op {
-        Some(op) => context.codemap.span_to_snippet(op.span).unwrap(),
+        Some(op) => context.snippet(op.span),
         None => "=".to_owned(),
     };
 
index 1501a904fdf034e2f745d07007afe42e8ec9c8d7..bcc851a5b3503a06442fa71bbc8927ce85620d62 100644 (file)
@@ -17,7 +17,6 @@
 use expr::rewrite_assign_rhs;
 use comment::FindUncommented;
 use visitor::FmtVisitor;
-
 use rewrite::Rewrite;
 use config::Config;
 
@@ -699,7 +698,11 @@ fn format_field(&self, field: &ast::StructField) -> String {
         let typ = pprust::ty_to_string(&field.node.ty);
 
         let indent = self.block_indent + self.config.tab_spaces;
-        let mut attr_str = self.rewrite_attrs(&field.node.attrs, indent);
+        let mut attr_str = field.node.attrs
+                                     .rewrite(&self.get_context(),
+                                              self.config.max_width - indent,
+                                              indent)
+                                     .unwrap();
         if !attr_str.is_empty() {
             attr_str.push('\n');
             attr_str.push_str(&make_indent(indent));
index d30d81a4885c3336d44edc7ef87fc8cbd7fb230d..5f1549846b55a65a1e2452e303d342dcb694ac39 100644 (file)
@@ -10,7 +10,7 @@
 
 // A generic trait to abstract the rewriting of an element (of the AST).
 
-use syntax::codemap::CodeMap;
+use syntax::codemap::{CodeMap, Span};
 
 use config::Config;
 
@@ -39,4 +39,8 @@ pub fn nested_context(&self) -> RewriteContext<'a> {
             block_indent: self.block_indent + self.config.tab_spaces,
         }
     }
+
+    pub fn snippet(&self, span: Span) -> String {
+        self.codemap.span_to_snippet(span).unwrap()
+    }
 }
index 20909391f09b3b314f2a7f4dcdc01defe942c46c..b773a20fe6fd14b6639cb7b08d782652a76240e5 100644 (file)
@@ -17,6 +17,7 @@
 use utils;
 use config::Config;
 use rewrite::{Rewrite, RewriteContext};
+use comment::rewrite_comment;
 
 pub struct FmtVisitor<'a> {
     pub codemap: &'a CodeMap,
@@ -293,7 +294,10 @@ pub fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
         if utils::contains_skip(attrs) {
             true
         } else {
-            let rewrite = self.rewrite_attrs(attrs, self.block_indent);
+            let rewrite = attrs.rewrite(&self.get_context(),
+                                        self.config.max_width - self.block_indent,
+                                        self.block_indent)
+                               .unwrap();
             self.buffer.push_str(&rewrite);
             let last = attrs.last().unwrap();
             self.last_pos = last.span.hi;
@@ -301,40 +305,6 @@ pub fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
         }
     }
 
-    pub fn rewrite_attrs(&self, attrs: &[ast::Attribute], indent: usize) -> String {
-        let mut result = String::new();
-        let indent = utils::make_indent(indent);
-
-        for (i, a) in attrs.iter().enumerate() {
-            let a_str = self.snippet(a.span);
-
-            if i > 0 {
-                let comment = self.snippet(codemap::mk_sp(attrs[i-1].span.hi, a.span.lo));
-                // This particular horror show is to preserve line breaks in between doc
-                // comments. An alternative would be to force such line breaks to start
-                // with the usual doc comment token.
-                let multi_line = a_str.starts_with("//") && comment.matches('\n').count() > 1;
-                let comment = comment.trim();
-                if !comment.is_empty() {
-                    result.push_str(&indent);
-                    result.push_str(comment);
-                    result.push('\n');
-                } else if multi_line {
-                    result.push('\n');
-                }
-                result.push_str(&indent);
-            }
-
-            result.push_str(&a_str);
-
-            if i < attrs.len() - 1 {
-                result.push('\n');
-            }
-        }
-
-        result
-    }
-
     fn format_mod(&mut self, m: &ast::Mod, s: Span, ident: ast::Ident) {
         debug!("FmtVisitor::format_mod: ident: {:?}, span: {:?}", ident, s);
 
@@ -402,3 +372,46 @@ pub fn get_context(&self) -> RewriteContext {
         }
     }
 }
+
+impl<'a> Rewrite for [ast::Attribute] {
+    fn rewrite(&self, context: &RewriteContext, _: usize, offset: usize) -> Option<String> {
+        let mut result = String::new();
+        if self.is_empty() {
+            return Some(result);
+        }
+        let indent = utils::make_indent(offset);
+
+        for (i, a) in self.iter().enumerate() {
+            let a_str = context.snippet(a.span);
+
+            if i > 0 {
+                let comment = context.snippet(codemap::mk_sp(self[i-1].span.hi, a.span.lo));
+                // This particular horror show is to preserve line breaks in between doc
+                // comments. An alternative would be to force such line breaks to start
+                // with the usual doc comment token.
+                let multi_line = a_str.starts_with("//") && comment.matches('\n').count() > 1;
+                let comment = comment.trim();
+                if !comment.is_empty() {
+                    let comment = rewrite_comment(comment,
+                                                  false,
+                                                  context.config.max_width - offset,
+                                                  offset);
+                    result.push_str(&indent);
+                    result.push_str(&comment);
+                    result.push('\n');
+                } else if multi_line {
+                    result.push('\n');
+                }
+                result.push_str(&indent);
+            }
+
+            result.push_str(&a_str);
+
+            if i < self.len() - 1 {
+                result.push('\n');
+            }
+        }
+
+        Some(result)
+    }
+}
diff --git a/tests/source/attrib.rs b/tests/source/attrib.rs
new file mode 100644 (file)
index 0000000..ac44a65
--- /dev/null
@@ -0,0 +1,43 @@
+// Test attributes and doc comments are preserved.
+
+/// Blah blah blah.
+/// Blah blah blah.
+/// Blah blah blah.
+/// Blah blah blah.
+
+/// Blah blah blah.
+impl Bar {
+    /// Blah blah blooo.
+    /// Blah blah blooo.
+    /// Blah blah blooo.
+    /// Blah blah blooo.
+    #[an_attribute]
+    fn foo(&mut self) -> isize {
+    }
+
+    /// Blah blah bing.
+    /// Blah blah bing.
+    /// Blah blah bing.
+
+
+    /// Blah blah bing.
+    /// Blah blah bing.
+    /// Blah blah bing.
+    pub fn f2(self) {
+        (foo, bar)
+    }
+
+    #[another_attribute]
+    fn f3(self) -> Dog {
+    }
+
+    /// Blah blah bing.
+
+    #[attrib1]
+    /// Blah blah bing.
+    #[attrib2]
+    // Another comment that needs rewrite because it's tooooooooooooooooooooooooooooooo loooooooooooong.
+    /// Blah blah bing.
+    fn f4(self) -> Cat {
+    }
+}
index 225d3a1698506bef96754667d0d3e5279c8e45a5..1caf20e99a5d103039590b7f2ee7f72489ea5735 100644 (file)
@@ -53,3 +53,11 @@ fn issue177() {
     struct Foo<T> { memb: T }
     let foo = Foo::<i64> { memb: 10 };
 }
+
+fn issue201() {
+    let s = S{a:0, ..  b};
+}
+
+fn issue201_2() {
+    let s = S{a: S2{    .. c}, ..  b};
+}
index ee7da10081e2b49f8028dbc6f9e7d6bee0ca8566..62657ad3b5d1d928667cfdcaebb92492c67e3b52 100644 (file)
@@ -29,4 +29,14 @@ pub fn f2(self) {
     #[another_attribute]
     fn f3(self) -> Dog {
     }
+
+    /// Blah blah bing.
+    #[attrib1]
+    /// Blah blah bing.
+    #[attrib2]
+    // Another comment that needs rewrite because it's tooooooooooooooooooooooooooooooo
+    // loooooooooooong.
+    /// Blah blah bing.
+    fn f4(self) -> Cat {
+    }
 }
index cc2887fc51ff360184bb7b1c0675d296cea330a2..6dd4180a7088b2a7fcb1e98c861f2c1afa0d5a80 100644 (file)
@@ -71,3 +71,11 @@ struct Foo<T> {
     }
     let foo = Foo::<i64> { memb: 10 };
 }
+
+fn issue201() {
+    let s = S { a: 0, ..b };
+}
+
+fn issue201_2() {
+    let s = S { a: S2 { ..c }, ..b };
+}