]> git.lizzy.rs Git - rust.git/blobdiff - src/visitor.rs
Remove BlockIndentStyle::Inherit
[rust.git] / src / visitor.rs
index 237866ed9ece5452a4fc927502a21b3db8d19745..2700287608de6f1944a3648c4f0fcdd5367fb476 100644 (file)
 
 use strings::string_buffer::StringBuffer;
 
-use Indent;
+use {Indent, Shape};
 use utils;
 use codemap::{LineRangeUtils, SpanUtils};
 use config::Config;
 use rewrite::{Rewrite, RewriteContext};
 use comment::rewrite_comment;
-use macros::rewrite_macro;
-use items::{rewrite_static, rewrite_associated_type, rewrite_type_alias, format_impl, format_trait};
+use macros::{rewrite_macro, MacroPosition};
+use items::{rewrite_static, rewrite_associated_type, rewrite_associated_impl_type,
+            rewrite_type_alias, format_impl, format_trait};
 
 fn is_use_item(item: &ast::Item) -> bool {
     match item.node {
@@ -52,28 +53,22 @@ fn visit_stmt(&mut self, stmt: &ast::Stmt) {
         }
 
         match stmt.node {
-            ast::StmtKind::Decl(ref decl, _) => {
-                if let ast::DeclKind::Item(ref item) = decl.node {
-                    self.visit_item(item);
-                } else {
-                    let rewrite = stmt.rewrite(&self.get_context(),
-                                               self.config.max_width - self.block_indent.width(),
-                                               self.block_indent);
-
-                    self.push_rewrite(stmt.span, rewrite);
-                }
+            ast::StmtKind::Item(ref item) => {
+                self.visit_item(item);
             }
+            ast::StmtKind::Local(..) |
             ast::StmtKind::Expr(..) |
             ast::StmtKind::Semi(..) => {
                 let rewrite = stmt.rewrite(&self.get_context(),
-                                           self.config.max_width - self.block_indent.width(),
-                                           self.block_indent);
-
+                                           Shape::legacy(self.config.max_width -
+                                                         self.block_indent.width(),
+                                                         self.block_indent));
                 self.push_rewrite(stmt.span, rewrite);
             }
-            ast::StmtKind::Mac(ref mac, _macro_style, _) => {
-                self.format_missing_with_indent(source!(self, stmt.span).lo);
-                self.visit_mac(mac, None);
+            ast::StmtKind::Mac(ref mac) => {
+                let (ref mac, _macro_style, _) = **mac;
+                self.visit_mac(mac, None, MacroPosition::Statement);
+                self.format_missing(stmt.span.hi);
             }
         }
     }
@@ -96,18 +91,11 @@ pub fn visit_block(&mut self, b: &ast::Block) {
             self.visit_stmt(stmt)
         }
 
-        if let Some(ref e) = b.expr {
-            self.format_missing_with_indent(source!(self, e.span).lo);
-            let rewrite = e.rewrite(&self.get_context(),
-                         self.config.max_width - self.block_indent.width(),
-                         self.block_indent)
-                .unwrap_or_else(|| self.snippet(e.span));
-
-            self.buffer.push_str(&rewrite);
-            self.last_pos = source!(self, e.span).hi;
-
-            if utils::semicolon_for_expr(e) {
-                self.buffer.push_str(";");
+        if !b.stmts.is_empty() {
+            if let Some(expr) = utils::stmt_expr(&b.stmts[b.stmts.len() - 1]) {
+                if utils::semicolon_for_expr(expr) {
+                    self.buffer.push_str(";");
+                }
             }
         }
 
@@ -138,39 +126,41 @@ fn close_block(&mut self) {
     fn visit_fn(&mut self,
                 fk: visit::FnKind,
                 fd: &ast::FnDecl,
-                b: &ast::Block,
                 s: Span,
                 _: ast::NodeId,
                 defaultness: ast::Defaultness) {
         let indent = self.block_indent;
+        let block;
         let rewrite = match fk {
-            visit::FnKind::ItemFn(ident, generics, unsafety, constness, abi, vis) => {
+            visit::FnKind::ItemFn(ident, generics, unsafety, constness, abi, vis, b) => {
+                block = b;
                 self.rewrite_fn(indent,
                                 ident,
                                 fd,
                                 generics,
                                 unsafety,
-                                constness,
+                                constness.node,
                                 defaultness,
                                 abi,
                                 vis,
                                 codemap::mk_sp(s.lo, b.span.lo),
-                                b)
+                                &b)
             }
-            visit::FnKind::Method(ident, sig, vis) => {
+            visit::FnKind::Method(ident, sig, vis, b) => {
+                block = b;
                 self.rewrite_fn(indent,
                                 ident,
                                 fd,
                                 &sig.generics,
                                 sig.unsafety,
-                                sig.constness,
+                                sig.constness.node,
                                 defaultness,
                                 sig.abi,
                                 vis.unwrap_or(&ast::Visibility::Inherited),
                                 codemap::mk_sp(s.lo, b.span.lo),
-                                b)
+                                &b)
             }
-            visit::FnKind::Closure => None,
+            visit::FnKind::Closure(_) => unreachable!(),
         };
 
         if let Some(fn_str) = rewrite {
@@ -178,22 +168,22 @@ fn visit_fn(&mut self,
             self.buffer.push_str(&fn_str);
             if let Some(c) = fn_str.chars().last() {
                 if c == '}' {
-                    self.last_pos = source!(self, b.span).hi;
+                    self.last_pos = source!(self, block.span).hi;
                     return;
                 }
             }
         } else {
-            self.format_missing(source!(self, b.span).lo);
+            self.format_missing(source!(self, block.span).lo);
         }
 
-        self.last_pos = source!(self, b.span).lo;
-        self.visit_block(b)
+        self.last_pos = source!(self, block.span).lo;
+        self.visit_block(block)
     }
 
     pub fn visit_item(&mut self, item: &ast::Item) {
         // 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 seperate file and there might be attributes in both files, but
+        // in a separate file and there might be attributes in both files, but
         // the AST lumps them all together.
         match item.node {
             ast::ItemKind::Mod(ref m) => {
@@ -275,12 +265,10 @@ pub fn visit_item(&mut self, item: &ast::Item) {
                                            item.span,
                                            indent,
                                            None)
-                        .map(|s| {
-                            match *def {
-                                ast::VariantData::Tuple(..) => s + ";",
-                                _ => s,
-                            }
-                        })
+                            .map(|s| match *def {
+                                     ast::VariantData::Tuple(..) => s + ";",
+                                     _ => s,
+                                 })
                 };
                 self.push_rewrite(item.span, rewrite);
             }
@@ -294,8 +282,7 @@ pub fn visit_item(&mut self, item: &ast::Item) {
                 self.format_mod(module, &item.vis, item.span, item.ident);
             }
             ast::ItemKind::Mac(ref mac) => {
-                self.format_missing_with_indent(source!(self, item.span).lo);
-                self.visit_mac(mac, Some(item.ident));
+                self.visit_mac(mac, Some(item.ident), MacroPosition::Item);
             }
             ast::ItemKind::ForeignMod(ref foreign_mod) => {
                 self.format_missing_with_indent(source!(self, item.span).lo);
@@ -308,6 +295,7 @@ pub fn visit_item(&mut self, item: &ast::Item) {
                                              ty,
                                              mutability,
                                              Some(expr),
+                                             self.block_indent,
                                              &self.get_context());
                 self.push_rewrite(item.span, rewrite);
             }
@@ -318,6 +306,7 @@ pub fn visit_item(&mut self, item: &ast::Item) {
                                              ty,
                                              ast::Mutability::Immutable,
                                              Some(expr),
+                                             self.block_indent,
                                              &self.get_context());
                 self.push_rewrite(item.span, rewrite);
             }
@@ -330,9 +319,9 @@ pub fn visit_item(&mut self, item: &ast::Item) {
                                                     unsafety,
                                                     constness,
                                                     abi,
-                                                    &item.vis),
+                                                    &item.vis,
+                                                    body),
                               decl,
-                              body,
                               item.span,
                               item.id,
                               ast::Defaultness::Final)
@@ -347,11 +336,15 @@ pub fn visit_item(&mut self, item: &ast::Item) {
                                                  item.span);
                 self.push_rewrite(item.span, rewrite);
             }
+            ast::ItemKind::Union(..) => {
+                // FIXME(#1157): format union definitions.
+            }
         }
     }
 
     pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
         if self.visit_attrs(&ti.attrs) {
+            self.push_rewrite(ti.span, None);
             return;
         }
 
@@ -363,6 +356,7 @@ pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
                                              ty,
                                              ast::Mutability::Immutable,
                                              expr_opt.as_ref(),
+                                             self.block_indent,
                                              &self.get_context());
                 self.push_rewrite(ti.span, rewrite);
             }
@@ -372,9 +366,8 @@ pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
                 self.push_rewrite(ti.span, rewrite);
             }
             ast::TraitItemKind::Method(ref sig, Some(ref body)) => {
-                self.visit_fn(visit::FnKind::Method(ti.ident, sig, None),
+                self.visit_fn(visit::FnKind::Method(ti.ident, sig, None, body),
                               &sig.decl,
-                              body,
                               ti.span,
                               ti.id,
                               ast::Defaultness::Final);
@@ -387,19 +380,22 @@ pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
                                                       self.block_indent);
                 self.push_rewrite(ti.span, rewrite);
             }
+            ast::TraitItemKind::Macro(..) => {
+                // FIXME(#1158) Macros in trait item position
+            }
         }
     }
 
     pub fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
         if self.visit_attrs(&ii.attrs) {
+            self.push_rewrite(ii.span, None);
             return;
         }
 
         match ii.node {
             ast::ImplItemKind::Method(ref sig, ref body) => {
-                self.visit_fn(visit::FnKind::Method(ii.ident, sig, Some(&ii.vis)),
+                self.visit_fn(visit::FnKind::Method(ii.ident, sig, Some(&ii.vis), body),
                               &sig.decl,
-                              body,
                               ii.span,
                               ii.id,
                               ii.defaultness);
@@ -411,33 +407,34 @@ pub fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
                                              ty,
                                              ast::Mutability::Immutable,
                                              Some(expr),
+                                             self.block_indent,
                                              &self.get_context());
                 self.push_rewrite(ii.span, rewrite);
             }
             ast::ImplItemKind::Type(ref ty) => {
-                let rewrite = rewrite_associated_type(ii.ident,
-                                                      Some(ty),
-                                                      None,
-                                                      &self.get_context(),
-                                                      self.block_indent);
+                let rewrite = rewrite_associated_impl_type(ii.ident,
+                                                           ii.defaultness,
+                                                           Some(ty),
+                                                           None,
+                                                           &self.get_context(),
+                                                           self.block_indent);
                 self.push_rewrite(ii.span, rewrite);
             }
             ast::ImplItemKind::Macro(ref mac) => {
-                self.format_missing_with_indent(source!(self, ii.span).lo);
-                self.visit_mac(mac, Some(ii.ident));
+                self.visit_mac(mac, Some(ii.ident), MacroPosition::Item);
             }
         }
     }
 
-    fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>) {
+    fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>, pos: MacroPosition) {
         // 1 = ;
         let width = self.config.max_width - self.block_indent.width() - 1;
-        let rewrite = rewrite_macro(mac, ident, &self.get_context(), width, self.block_indent);
-
-        if let Some(res) = rewrite {
-            self.buffer.push_str(&res);
-            self.last_pos = source!(self, mac.span).hi;
-        }
+        let rewrite = rewrite_macro(mac,
+                                    ident,
+                                    &self.get_context(),
+                                    Shape::legacy(width, self.block_indent),
+                                    pos);
+        self.push_rewrite(mac.span, rewrite);
     }
 
     fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
@@ -480,7 +477,7 @@ pub fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
         }
 
         let outers: Vec<_> = attrs.iter()
-            .filter(|a| a.node.style == ast::AttrStyle::Outer)
+            .filter(|a| a.style == ast::AttrStyle::Outer)
             .cloned()
             .collect();
         if outers.is_empty() {
@@ -491,8 +488,9 @@ pub fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
         self.format_missing_with_indent(source!(self, first.span).lo);
 
         let rewrite = outers.rewrite(&self.get_context(),
-                     self.config.max_width - self.block_indent.width(),
-                     self.block_indent)
+                                     Shape::legacy(self.config.max_width -
+                                                   self.block_indent.width(),
+                                                   self.block_indent))
             .unwrap();
         self.buffer.push_str(&rewrite);
         let last = outers.last().unwrap();
@@ -525,7 +523,9 @@ fn walk_mod_items(&mut self, m: &ast::Mod) {
     fn format_mod(&mut self, m: &ast::Mod, vis: &ast::Visibility, s: Span, ident: ast::Ident) {
         // Decide whether this is an inline mod or an external mod.
         let local_file_name = self.codemap.span_to_filename(s);
-        let is_internal = local_file_name == self.codemap.span_to_filename(source!(self, m.inner));
+        let inner_span = source!(self, m.inner);
+        let is_internal = !(inner_span.lo.0 == 0 && inner_span.hi.0 == 0) &&
+                          local_file_name == self.codemap.span_to_filename(inner_span);
 
         self.buffer.push_str(&*utils::format_visibility(vis));
         self.buffer.push_str("mod ");
@@ -555,7 +555,7 @@ fn format_mod(&mut self, m: &ast::Mod, vis: &ast::Visibility, s: Span, ident: as
     }
 
     pub fn format_separate_mod(&mut self, m: &ast::Mod) {
-        let filemap = self.codemap.lookup_char_pos(source!(self, m.inner).lo).file;
+        let filemap = self.codemap.lookup_char_pos(m.inner.lo).file;
         self.last_pos = filemap.start_pos;
         self.block_indent = Indent::empty();
         self.walk_mod_items(m);
@@ -567,18 +567,17 @@ pub fn get_context(&self) -> RewriteContext {
             parse_session: self.parse_session,
             codemap: self.codemap,
             config: self.config,
-            block_indent: self.block_indent,
         }
     }
 }
 
 impl<'a> Rewrite for [ast::Attribute] {
-    fn rewrite(&self, context: &RewriteContext, _: usize, offset: Indent) -> Option<String> {
+    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
         let mut result = String::new();
         if self.is_empty() {
             return Some(result);
         }
-        let indent = offset.to_string(context.config);
+        let indent = shape.indent.to_string(context.config);
 
         for (i, a) in self.iter().enumerate() {
             let mut a_str = context.snippet(a.span);
@@ -594,9 +593,10 @@ fn rewrite(&self, context: &RewriteContext, _: usize, offset: Indent) -> Option<
                 if !comment.is_empty() {
                     let comment = try_opt!(rewrite_comment(comment,
                                                            false,
-                                                           context.config.ideal_width -
-                                                           offset.width(),
-                                                           offset,
+                                                           Shape::legacy(context.config
+                                                                             .comment_width -
+                                                                         shape.indent.width(),
+                                                                         shape.indent),
                                                            context.config));
                     result.push_str(&indent);
                     result.push_str(&comment);
@@ -610,8 +610,9 @@ fn rewrite(&self, context: &RewriteContext, _: usize, offset: Indent) -> Option<
             if a_str.starts_with("//") {
                 a_str = try_opt!(rewrite_comment(&a_str,
                                                  false,
-                                                 context.config.ideal_width - offset.width(),
-                                                 offset,
+                                                 Shape::legacy(context.config.comment_width -
+                                                               shape.indent.width(),
+                                                               shape.indent),
                                                  context.config));
             }