about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMarcus Klaas <mail@marcusklaas.nl>2015-10-17 15:56:53 +0200
committerMarcus Klaas <mail@marcusklaas.nl>2015-10-19 20:15:36 +0200
commitca023ba9b702ec9d453e917ffac54263ab4ef965 (patch)
treea260e038717129d88e1d3a008d9025bdc15fd11b /src
parent8a9bbd9d7cef43b0977dcce7f4f89886a7d288d7 (diff)
Format some patterns
Diffstat (limited to 'src')
-rw-r--r--src/expr.rs41
-rw-r--r--src/items.rs65
-rw-r--r--src/lib.rs25
-rw-r--r--src/patterns.rs95
-rw-r--r--src/types.rs28
5 files changed, 174 insertions, 80 deletions
diff --git a/src/expr.rs b/src/expr.rs
index 2deaed9609a..b69989aa761 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -12,7 +12,7 @@ use std::cmp::Ordering;
 use std::borrow::Borrow;
 use std::mem::swap;
 
-use Indent;
+use {Indent, Spanned};
 use rewrite::{Rewrite, RewriteContext};
 use lists::{write_list, itemize_list, ListFormatting, SeparatorTactic, ListTactic,
             DefinitiveListTactic, definitive_tactic, ListItem, format_fn_args};
@@ -76,7 +76,7 @@ impl Rewrite for ast::Expr {
                                    offset)
             }
             ast::Expr_::ExprTup(ref items) => {
-                rewrite_tuple_lit(context, items, self.span, width, offset)
+                rewrite_tuple(context, items, self.span, width, offset)
             }
             ast::Expr_::ExprWhile(ref cond, ref block, label) => {
                 Loop::new_while(None, cond, block, label).rewrite(context, width, offset)
@@ -479,13 +479,6 @@ impl Rewrite for ast::Block {
     }
 }
 
-// FIXME(#18): implement pattern formatting
-impl Rewrite for ast::Pat {
-    fn rewrite(&self, context: &RewriteContext, _: usize, _: Indent) -> Option<String> {
-        Some(context.snippet(self.span))
-    }
-}
-
 // Abstraction over for, while and loop expressions
 struct Loop<'a> {
     cond: Option<&'a ast::Expr>,
@@ -849,11 +842,7 @@ impl Rewrite for ast::Arm {
         // 5 = ` => {`
         let pat_budget = try_opt!(width.checked_sub(5));
         let pat_strs = try_opt!(pats.iter()
-                                    .map(|p| {
-                                        p.rewrite(context,
-                                                  pat_budget,
-                                                  offset.block_indent(context.config))
-                                    })
+                                    .map(|p| p.rewrite(context, pat_budget, offset))
                                     .collect::<Option<Vec<_>>>());
 
         let mut total_width = pat_strs.iter().fold(0, |a, p| a + p.len());
@@ -1187,7 +1176,9 @@ fn rewrite_call_inner<R>(context: &RewriteContext,
     // Replace the stub with the full overflowing last argument if the rewrite
     // succeeded and its first line fits with the other arguments.
     match (overflow_last, tactic, placeholder) {
-        (true, DefinitiveListTactic::Horizontal, placeholder @ Some(..)) => {
+        (true,
+         DefinitiveListTactic::Horizontal,
+         placeholder @ Some(..)) => {
             item_vec[arg_count - 1].item = placeholder;
         }
         (true, _, _) => {
@@ -1206,8 +1197,6 @@ fn rewrite_call_inner<R>(context: &RewriteContext,
         config: context.config,
     };
 
-    // format_fn_args(items, remaining_width, offset, context.config)
-
     let list_str = match write_list(&item_vec, &fmt) {
         Some(str) => str,
         None => return Err(Ordering::Less),
@@ -1382,12 +1371,14 @@ fn rewrite_field(context: &RewriteContext,
     expr.map(|s| format!("{}: {}", name, s))
 }
 
-fn rewrite_tuple_lit(context: &RewriteContext,
-                     items: &[ptr::P<ast::Expr>],
-                     span: Span,
-                     width: usize,
-                     offset: Indent)
-                     -> Option<String> {
+pub fn rewrite_tuple<'a, R>(context: &RewriteContext,
+                            items: &'a [ptr::P<R>],
+                            span: Span,
+                            width: usize,
+                            offset: Indent)
+                            -> Option<String>
+    where R: Rewrite + Spanned + 'a
+{
     debug!("rewrite_tuple_lit: width: {}, offset: {:?}", width, offset);
     let indent = offset + 1;
     // In case of length 1, need a trailing comma
@@ -1400,8 +1391,8 @@ fn rewrite_tuple_lit(context: &RewriteContext,
     let items = itemize_list(context.codemap,
                              items.iter(),
                              ")",
-                             |item| item.span.lo,
-                             |item| item.span.hi,
+                             |item| item.span().lo,
+                             |item| item.span().hi,
                              |item| {
                                  let inner_width = context.config.max_width - indent.width() - 1;
                                  item.rewrite(context, inner_width, indent)
diff --git a/src/items.rs b/src/items.rs
index 68715252ce9..6d486bbbe51 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -29,41 +29,16 @@ impl<'a> FmtVisitor<'a> {
     pub fn visit_let(&mut self, local: &ast::Local, span: Span) {
         self.format_missing_with_indent(span.lo);
 
-        // String that is placed within the assignment pattern and expression.
-        let infix = {
-            let mut infix = String::new();
-
-            if let Some(ref ty) = local.ty {
-                // 2 = ": ".len()
-                let offset = self.block_indent + 2;
-                let width = self.config.max_width - offset.width();
-                let rewrite = ty.rewrite(&self.get_context(), width, offset);
-
-                match rewrite {
-                    Some(result) => {
-                        infix.push_str(": ");
-                        infix.push_str(&result);
-                    }
-                    None => return,
-                }
-            }
-
-            if local.init.is_some() {
-                infix.push_str(" =");
-            }
-
-            infix
-        };
-
         // New scope so we drop the borrow of self (context) in time to mutably
         // borrow self to mutate its buffer.
         let result = {
             let context = self.get_context();
             let mut result = "let ".to_owned();
-            let pattern_offset = self.block_indent + result.len() + infix.len();
+            let pattern_offset = self.block_indent + result.len();
             // 1 = ;
-            let pattern_width = self.config.max_width.checked_sub(pattern_offset.width() + 1);
-            let pattern_width = match pattern_width {
+            let pattern_width = match self.config
+                                          .max_width
+                                          .checked_sub(pattern_offset.width() + 1) {
                 Some(width) => width,
                 None => return,
             };
@@ -73,6 +48,36 @@ impl<'a> FmtVisitor<'a> {
                 None => return,
             }
 
+            // String that is placed within the assignment pattern and expression.
+            let infix = {
+                let mut infix = String::new();
+
+                if let Some(ref ty) = local.ty {
+                    // 2 = ": ".len()
+                    // 1 = ;
+                    let offset = self.block_indent + result.len() + 2;
+                    let width = match self.config.max_width.checked_sub(offset.width() + 1) {
+                        Some(w) => w,
+                        None => return,
+                    };
+                    let rewrite = ty.rewrite(&self.get_context(), width, offset);
+
+                    match rewrite {
+                        Some(result) => {
+                            infix.push_str(": ");
+                            infix.push_str(&result);
+                        }
+                        None => return,
+                    }
+                }
+
+                if local.init.is_some() {
+                    infix.push_str(" =");
+                }
+
+                infix
+            };
+
             result.push_str(&infix);
 
             if let Some(ref ex) = local.init {
@@ -86,7 +91,7 @@ impl<'a> FmtVisitor<'a> {
                 let rhs = rewrite_assign_rhs(&context, result, ex, max_width, context.block_indent);
 
                 match rhs {
-                    Some(result) => result,
+                    Some(s) => s,
                     None => return,
                 }
             } else {
diff --git a/src/lib.rs b/src/lib.rs
index 1dfb05c88b6..03422a20c36 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -41,7 +41,7 @@ use rustc::session::config::Input;
 use rustc_driver::{driver, CompilerCalls, Compilation};
 
 use syntax::ast;
-use syntax::codemap::CodeMap;
+use syntax::codemap::{CodeMap, Span};
 use syntax::diagnostics;
 
 use std::ops::{Add, Sub};
@@ -76,11 +76,34 @@ mod modules;
 pub mod rustfmt_diff;
 mod chains;
 mod macros;
+mod patterns;
 
 const MIN_STRING: usize = 10;
 // When we get scoped annotations, we should have rustfmt::skip.
 const SKIP_ANNOTATION: &'static str = "rustfmt_skip";
 
+pub trait Spanned {
+    fn span(&self) -> Span;
+}
+
+impl Spanned for ast::Expr {
+    fn span(&self) -> Span {
+        self.span
+    }
+}
+
+impl Spanned for ast::Pat {
+    fn span(&self) -> Span {
+        self.span
+    }
+}
+
+impl Spanned for ast::Ty {
+    fn span(&self) -> Span {
+        self.span
+    }
+}
+
 #[derive(Copy, Clone, Debug)]
 pub struct Indent {
     // Width of the block indent, in characters. Must be a multiple of
diff --git a/src/patterns.rs b/src/patterns.rs
new file mode 100644
index 00000000000..2e90f719853
--- /dev/null
+++ b/src/patterns.rs
@@ -0,0 +1,95 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use Indent;
+use rewrite::{Rewrite, RewriteContext};
+use utils::{wrap_str, format_mutability, span_after};
+use lists::{format_item_list, itemize_list};
+use expr::{rewrite_unary_prefix, rewrite_pair, rewrite_tuple};
+use types::rewrite_path;
+
+use syntax::ast::{PatWildKind, BindingMode, Pat, Pat_};
+
+// FIXME(#18): implement pattern formatting.
+impl Rewrite for Pat {
+    fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
+        match self.node {
+            Pat_::PatBox(ref pat) => {
+                rewrite_unary_prefix(context, "box ", &**pat, width, offset)
+            }
+            Pat_::PatIdent(binding_mode, ident, None) => {
+                let (prefix, mutability) = match binding_mode {
+                    BindingMode::BindByRef(mutability) => ("ref ", mutability),
+                    BindingMode::BindByValue(mutability) => ("", mutability),
+                };
+                let mut_infix = format_mutability(mutability);
+                let result = format!("{}{}{}", prefix, mut_infix, ident.node);
+                wrap_str(result, context.config.max_width, width, offset)
+            }
+            Pat_::PatWild(kind) => {
+                let result = match kind {
+                    PatWildKind::PatWildSingle => "_",
+                    PatWildKind::PatWildMulti => "..",
+                };
+                if result.len() <= width {
+                    Some(result.to_owned())
+                } else {
+                    None
+                }
+            }
+            Pat_::PatQPath(ref q_self, ref path) => {
+                rewrite_path(context, Some(q_self), path, width, offset)
+            }
+            Pat_::PatRange(ref lhs, ref rhs) => {
+                rewrite_pair(&**lhs, &**rhs, "", "...", "", context, width, offset)
+            }
+            Pat_::PatRegion(ref pat, mutability) => {
+                let prefix = format!("&{}", format_mutability(mutability));
+                rewrite_unary_prefix(context, &prefix, &**pat, width, offset)
+            }
+            Pat_::PatTup(ref items) => {
+                rewrite_tuple(context, items, self.span, width, offset)
+            }
+            Pat_::PatEnum(ref path, Some(ref pat_vec)) => {
+                let path_str = try_opt!(::types::rewrite_path(context, None, path, width, offset));
+
+                if pat_vec.is_empty() {
+                    Some(path_str)
+                } else {
+                    let width = try_opt!(width.checked_sub(path_str.len()));
+                    let offset = offset + path_str.len();
+                    let items = itemize_list(context.codemap,
+                                             pat_vec.iter(),
+                                             ")",
+                                             |item| item.span.lo,
+                                             |item| item.span.hi,
+                                             |item| item.rewrite(context, width, offset),
+                                             span_after(self.span, "(", context.codemap),
+                                             self.span.hi);
+                    Some(format!("{}({})",
+                                 path_str,
+                                 try_opt!(format_item_list(items, width, offset, context.config))))
+                }
+            }
+            Pat_::PatLit(ref expr) => expr.rewrite(context, width, offset),
+            // FIXME(#8): format remaining pattern variants.
+            Pat_::PatIdent(_, _, Some(..)) |
+            Pat_::PatEnum(_, None) |
+            Pat_::PatStruct(..) |
+            Pat_::PatVec(..) |
+            Pat_::PatMac(..) => {
+                wrap_str(context.snippet(self.span),
+                         context.config.max_width,
+                         width,
+                         offset)
+            }
+        }
+    }
+}
diff --git a/src/types.rs b/src/types.rs
index 14c0c2669a9..d8170e2f917 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -13,10 +13,10 @@ use syntax::print::pprust;
 use syntax::codemap::{self, Span, BytePos, CodeMap};
 
 use Indent;
-use lists::{format_item_list, itemize_list, format_fn_args, list_helper, ListTactic};
+use lists::{format_item_list, itemize_list, format_fn_args};
 use rewrite::{Rewrite, RewriteContext};
 use utils::{extra_offset, span_after, format_mutability, wrap_str};
-use expr::{rewrite_unary_prefix, rewrite_pair};
+use expr::{rewrite_unary_prefix, rewrite_pair, rewrite_tuple};
 
 impl Rewrite for ast::Path {
     fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
@@ -491,28 +491,8 @@ impl Rewrite for ast::Ty {
                 let budget = try_opt!(width.checked_sub(2));
                 ty.rewrite(context, budget, offset + 1).map(|ty_str| format!("[{}]", ty_str))
             }
-            ast::TyTup(ref tup_ret) => {
-                if tup_ret.is_empty() {
-                    Some("()".to_owned())
-                } else if let [ref item] = &**tup_ret {
-                    let budget = try_opt!(width.checked_sub(3));
-                    let inner = try_opt!(item.rewrite(context, budget, offset + 1));
-                    let ret = format!("({},)", inner);
-                    wrap_str(ret, context.config.max_width, budget, offset + 1)
-                } else {
-                    let budget = try_opt!(width.checked_sub(2));
-                    let items = itemize_list(context.codemap,
-                                             tup_ret.iter(),
-                                             ")",
-                                             |item| item.span.lo,
-                                             |item| item.span.hi,
-                                             |item| item.rewrite(context, budget, offset + 1),
-                                             span_after(self.span, "(", context.codemap),
-                                             self.span.hi);
-
-                    list_helper(items, budget, offset + 1, context.config, ListTactic::Mixed)
-                        .map(|s| format!("({})", s))
-                }
+            ast::TyTup(ref items) => {
+                rewrite_tuple(context, items, self.span, width, offset)
             }
             ast::TyPolyTraitRef(ref trait_ref) => trait_ref.rewrite(context, width, offset),
             ast::TyPath(ref q_self, ref path) => {