]> git.lizzy.rs Git - rust.git/commitdiff
Refactor rewrite for ast::Block
authortopecongiro <seuchida@gmail.com>
Tue, 20 Jun 2017 12:34:19 +0000 (21:34 +0900)
committertopecongiro <seuchida@gmail.com>
Tue, 20 Jun 2017 13:35:16 +0000 (22:35 +0900)
src/expr.rs

index 2be7987d7c612e542b23e38298ed02721f9712a2..ebf9d5c1baac474947cb25f2718e81bc8f1584dd 100644 (file)
@@ -290,7 +290,9 @@ fn format_expr(
             )
         }
         ast::ExprKind::Catch(ref block) => {
-            if let rewrite @ Some(_) = try_one_line_block(context, shape, "do catch ", block) {
+            if let rewrite @ Some(_) =
+                rewrite_single_line_block(context, "do catch ", block, shape)
+            {
                 return rewrite;
             }
             // 9 = `do catch `
@@ -315,23 +317,6 @@ fn format_expr(
     }
 }
 
-fn try_one_line_block(
-    context: &RewriteContext,
-    shape: Shape,
-    prefix: &str,
-    block: &ast::Block,
-) -> Option<String> {
-    if is_simple_block(block, context.codemap) {
-        let expr_shape = Shape::legacy(shape.width - prefix.len(), shape.indent);
-        let expr_str = try_opt!(block.stmts[0].rewrite(context, expr_shape));
-        let result = format!("{}{{ {} }}", prefix, expr_str);
-        if result.len() <= shape.width && !result.contains('\n') {
-            return Some(result);
-        }
-    }
-    None
-}
-
 pub fn rewrite_pair<LHS, RHS>(
     lhs: &LHS,
     rhs: &RHS,
@@ -763,78 +748,124 @@ fn nop_block_collapse(block_str: Option<String>, budget: usize) -> Option<String
     })
 }
 
-impl Rewrite for ast::Block {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        // shape.width is used only for the single line case: either the empty block `{}`,
-        // or an unsafe expression `unsafe { e }`.
+fn rewrite_empty_block(
+    context: &RewriteContext,
+    block: &ast::Block,
+    shape: Shape,
+) -> Option<String> {
+    if block.stmts.is_empty() && !block_contains_comment(block, context.codemap) &&
+        shape.width >= 2
+    {
+        return Some("{}".to_owned());
+    }
 
-        if self.stmts.is_empty() && !block_contains_comment(self, context.codemap) &&
-            shape.width >= 2
+    // If a block contains only a single-line comment, then leave it on one line.
+    let user_str = context.snippet(block.span);
+    let user_str = user_str.trim();
+    if user_str.starts_with('{') && user_str.ends_with('}') {
+        let comment_str = user_str[1..user_str.len() - 1].trim();
+        if block.stmts.is_empty() && !comment_str.contains('\n') &&
+            !comment_str.starts_with("//") && comment_str.len() + 4 <= shape.width
         {
-            return Some("{}".to_owned());
+            return Some(format!("{{ {} }}", comment_str));
         }
+    }
 
-        // If a block contains only a single-line comment, then leave it on one line.
-        let user_str = context.snippet(self.span);
-        let user_str = user_str.trim();
-        if user_str.starts_with('{') && user_str.ends_with('}') {
-            let comment_str = user_str[1..user_str.len() - 1].trim();
-            if self.stmts.is_empty() && !comment_str.contains('\n') &&
-                !comment_str.starts_with("//") &&
-                comment_str.len() + 4 <= shape.width
-            {
-                return Some(format!("{{ {} }}", comment_str));
+    None
+}
+
+fn block_prefix(context: &RewriteContext, block: &ast::Block, shape: Shape) -> Option<String> {
+    Some(match block.rules {
+        ast::BlockCheckMode::Unsafe(..) => {
+            let snippet = context.snippet(block.span);
+            let open_pos = try_opt!(snippet.find_uncommented("{"));
+            // Extract comment between unsafe and block start.
+            let trimmed = &snippet[6..open_pos].trim();
+
+            if !trimmed.is_empty() {
+                // 9 = "unsafe  {".len(), 7 = "unsafe ".len()
+                let budget = try_opt!(shape.width.checked_sub(9));
+                format!(
+                    "unsafe {} ",
+                    try_opt!(rewrite_comment(
+                        trimmed,
+                        true,
+                        Shape::legacy(budget, shape.indent + 7),
+                        context.config,
+                    ))
+                )
+            } else {
+                "unsafe ".to_owned()
             }
         }
+        ast::BlockCheckMode::Default => String::new(),
+    })
+}
 
-        let mut visitor = FmtVisitor::from_codemap(context.parse_session, context.config);
-        visitor.block_indent = shape.indent;
-        visitor.is_if_else_block = context.is_if_else_block;
+fn rewrite_single_line_block(
+    context: &RewriteContext,
+    prefix: &str,
+    block: &ast::Block,
+    shape: Shape,
+) -> Option<String> {
+    if is_simple_block(block, context.codemap) {
+        let expr_shape = Shape::legacy(shape.width - prefix.len(), shape.indent);
+        let expr_str = try_opt!(block.stmts[0].rewrite(context, expr_shape));
+        let result = format!("{}{{ {} }}", prefix, expr_str);
+        if result.len() <= shape.width && !result.contains('\n') {
+            return Some(result);
+        }
+    }
+    None
+}
 
-        let prefix = match self.rules {
-            ast::BlockCheckMode::Unsafe(..) => {
-                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);
+fn rewrite_block_with_visitor(
+    context: &RewriteContext,
+    prefix: &str,
+    block: &ast::Block,
+    shape: Shape,
+) -> Option<String> {
+    if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
+        return rw;
+    }
 
-                // Extract comment between unsafe and block start.
-                let trimmed = &snippet[6..open_pos].trim();
+    let mut visitor = FmtVisitor::from_codemap(context.parse_session, context.config);
+    visitor.block_indent = shape.indent;
+    visitor.is_if_else_block = context.is_if_else_block;
+    match block.rules {
+        ast::BlockCheckMode::Unsafe(..) => {
+            let snippet = context.snippet(block.span);
+            let open_pos = try_opt!(snippet.find_uncommented("{"));
+            visitor.last_pos = block.span.lo + BytePos(open_pos as u32)
+        }
+        ast::BlockCheckMode::Default => visitor.last_pos = block.span.lo,
+    }
 
-                let prefix = if !trimmed.is_empty() {
-                    // 9 = "unsafe  {".len(), 7 = "unsafe ".len()
-                    let budget = try_opt!(shape.width.checked_sub(9));
-                    format!(
-                        "unsafe {} ",
-                        try_opt!(rewrite_comment(
-                            trimmed,
-                            true,
-                            Shape::legacy(budget, shape.indent + 7),
-                            context.config,
-                        ))
-                    )
-                } else {
-                    "unsafe ".to_owned()
-                };
-                if let result @ Some(_) = try_one_line_block(context, shape, &prefix, self) {
-                    return result;
-                }
-                prefix
-            }
-            ast::BlockCheckMode::Default => {
-                visitor.last_pos = self.span.lo;
-                String::new()
-            }
-        };
+    visitor.visit_block(block);
+    if visitor.failed && shape.indent.alignment != 0 {
+        block.rewrite(
+            context,
+            Shape::indented(shape.indent.block_only(), context.config),
+        )
+    } else {
+        Some(format!("{}{}", prefix, visitor.buffer))
+    }
+}
 
-        visitor.visit_block(self);
-        if visitor.failed && shape.indent.alignment != 0 {
-            self.rewrite(
-                context,
-                Shape::indented(shape.indent.block_only(), context.config),
-            )
-        } else {
-            Some(format!("{}{}", prefix, visitor.buffer))
+impl Rewrite for ast::Block {
+    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
+        // shape.width is used only for the single line case: either the empty block `{}`,
+        // or an unsafe expression `unsafe { e }`.
+        if let rw @ Some(_) = rewrite_empty_block(context, self, shape) {
+            return rw;
         }
+
+        let prefix = try_opt!(block_prefix(context, self, shape));
+        if let rw @ Some(_) = rewrite_single_line_block(context, &prefix, self, shape) {
+            return rw;
+        }
+
+        rewrite_block_with_visitor(context, &prefix, self, shape)
     }
 }