mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-31 17:12:53 +00:00
Merge pull request #1983 from topecongiro/cleanup
Refactoring: clean up source code
This commit is contained in:
commit
c6b3cf9828
@ -76,7 +76,7 @@
|
||||
/// .qux
|
||||
/// ```
|
||||
|
||||
use Shape;
|
||||
use shape::Shape;
|
||||
use config::IndentStyle;
|
||||
use expr::rewrite_call;
|
||||
use macros::convert_try_mac;
|
||||
|
@ -14,9 +14,9 @@ use std::{self, iter};
|
||||
|
||||
use syntax::codemap::Span;
|
||||
|
||||
use {Indent, Shape};
|
||||
use config::Config;
|
||||
use rewrite::RewriteContext;
|
||||
use shape::{Indent, Shape};
|
||||
use string::{rewrite_string, StringFormat};
|
||||
use utils::{first_line_width, last_line_width};
|
||||
|
||||
@ -928,7 +928,7 @@ fn remove_comment_header(comment: &str) -> &str {
|
||||
mod test {
|
||||
use super::{contains_comment, rewrite_comment, CharClasses, CodeCharKind, CommentCodeSlices,
|
||||
FindUncommented, FullCodeCharKind};
|
||||
use {Indent, Shape};
|
||||
use shape::{Indent, Shape};
|
||||
|
||||
#[test]
|
||||
fn char_classes() {
|
||||
|
83
src/expr.rs
83
src/expr.rs
@ -17,7 +17,7 @@ use syntax::{ast, ptr};
|
||||
use syntax::codemap::{BytePos, CodeMap, Span};
|
||||
use syntax::parse::classify;
|
||||
|
||||
use {Indent, Shape, Spanned};
|
||||
use spanned::Spanned;
|
||||
use chains::rewrite_chain;
|
||||
use codemap::{LineRangeUtils, SpanUtils};
|
||||
use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
|
||||
@ -30,12 +30,13 @@ use lists::{definitive_tactic, itemize_list, shape_for_tactic, struct_lit_format
|
||||
use macros::{rewrite_macro, MacroArg, MacroPosition};
|
||||
use patterns::{can_be_overflowed_pat, TuplePatField};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::{Indent, Shape};
|
||||
use string::{rewrite_string, StringFormat};
|
||||
use types::{can_be_overflowed_type, rewrite_path, PathContext};
|
||||
use utils::{colon_spaces, contains_skip, extra_offset, first_line_width, inner_attributes,
|
||||
last_line_extendable, last_line_width, left_most_sub_expr, mk_sp, outer_attributes,
|
||||
paren_overhead, ptr_vec_to_ref_vec, semicolon_for_stmt, stmt_expr,
|
||||
trimmed_last_line_width, wrap_str};
|
||||
trimmed_last_line_width};
|
||||
use vertical::rewrite_with_alignment;
|
||||
use visitor::FmtVisitor;
|
||||
|
||||
@ -75,11 +76,7 @@ pub fn format_expr(
|
||||
ast::LitKind::Str(_, ast::StrStyle::Cooked) => {
|
||||
rewrite_string_lit(context, l.span, shape)
|
||||
}
|
||||
_ => wrap_str(
|
||||
context.snippet(expr.span),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
),
|
||||
_ => Some(context.snippet(expr.span)),
|
||||
},
|
||||
ast::ExprKind::Call(ref callee, ref args) => {
|
||||
let inner_span = mk_sp(callee.span.hi(), expr.span.hi());
|
||||
@ -152,11 +149,7 @@ pub fn format_expr(
|
||||
Some(ident) => format!(" {}", ident.node),
|
||||
None => String::new(),
|
||||
};
|
||||
wrap_str(
|
||||
format!("continue{}", id_str),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
)
|
||||
Some(format!("continue{}", id_str))
|
||||
}
|
||||
ast::ExprKind::Break(ref opt_ident, ref opt_expr) => {
|
||||
let id_str = match *opt_ident {
|
||||
@ -167,17 +160,13 @@ pub fn format_expr(
|
||||
if let Some(ref expr) = *opt_expr {
|
||||
rewrite_unary_prefix(context, &format!("break{} ", id_str), &**expr, shape)
|
||||
} else {
|
||||
wrap_str(
|
||||
format!("break{}", id_str),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
)
|
||||
Some(format!("break{}", id_str))
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Yield(ref opt_expr) => if let Some(ref expr) = *opt_expr {
|
||||
rewrite_unary_prefix(context, "yield ", &**expr, shape)
|
||||
} else {
|
||||
wrap_str("yield".to_string(), context.config.max_width(), shape)
|
||||
Some("yield".to_string())
|
||||
},
|
||||
ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) => {
|
||||
rewrite_closure(capture, fn_decl, body, expr.span, context, shape)
|
||||
@ -189,17 +178,10 @@ pub fn format_expr(
|
||||
ast::ExprKind::Mac(ref mac) => {
|
||||
// Failure to rewrite a marco should not imply failure to
|
||||
// rewrite the expression.
|
||||
rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| {
|
||||
wrap_str(
|
||||
context.snippet(expr.span),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
)
|
||||
})
|
||||
}
|
||||
ast::ExprKind::Ret(None) => {
|
||||
wrap_str("return".to_owned(), context.config.max_width(), shape)
|
||||
rewrite_macro(mac, None, context, shape, MacroPosition::Expression)
|
||||
.or_else(|| Some(context.snippet(expr.span)))
|
||||
}
|
||||
ast::ExprKind::Ret(None) => Some("return".to_owned()),
|
||||
ast::ExprKind::Ret(Some(ref expr)) => {
|
||||
rewrite_unary_prefix(context, "return ", &**expr, shape)
|
||||
}
|
||||
@ -301,16 +283,14 @@ pub fn format_expr(
|
||||
};
|
||||
rewrite_unary_suffix(context, &sp_delim, &*lhs, shape)
|
||||
}
|
||||
(None, None) => wrap_str(delim.into(), context.config.max_width(), shape),
|
||||
(None, None) => Some(delim.into()),
|
||||
}
|
||||
}
|
||||
// We do not format these expressions yet, but they should still
|
||||
// satisfy our width restrictions.
|
||||
ast::ExprKind::InPlace(..) | ast::ExprKind::InlineAsm(..) => wrap_str(
|
||||
context.snippet(expr.span),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
),
|
||||
ast::ExprKind::InPlace(..) | ast::ExprKind::InlineAsm(..) => {
|
||||
Some(context.snippet(expr.span))
|
||||
}
|
||||
ast::ExprKind::Catch(ref block) => {
|
||||
if let rw @ Some(_) = rewrite_single_line_block(context, "do catch ", block, shape) {
|
||||
rw
|
||||
@ -382,7 +362,11 @@ where
|
||||
.map(|first_line| first_line.ends_with('{'))
|
||||
.unwrap_or(false);
|
||||
if !rhs_result.contains('\n') || allow_same_line {
|
||||
return Some(format!("{}{}{}{}", lhs_result, infix, rhs_result, suffix));
|
||||
let one_line_width = last_line_width(&lhs_result) + infix.len()
|
||||
+ first_line_width(&rhs_result) + suffix.len();
|
||||
if one_line_width <= shape.width {
|
||||
return Some(format!("{}{}{}{}", lhs_result, infix, rhs_result, suffix));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2231,12 +2215,23 @@ where
|
||||
_ if args.len() >= 1 => {
|
||||
item_vec[args.len() - 1].item = args.last()
|
||||
.and_then(|last_arg| last_arg.rewrite(context, shape));
|
||||
tactic = definitive_tactic(
|
||||
&*item_vec,
|
||||
ListTactic::LimitedHorizontalVertical(args_max_width),
|
||||
Separator::Comma,
|
||||
one_line_width,
|
||||
);
|
||||
// Use horizontal layout for a function with a single argument as long as
|
||||
// everything fits in a single line.
|
||||
if args.len() == 1
|
||||
&& args_max_width != 0 // Vertical layout is forced.
|
||||
&& !item_vec[0].has_comment()
|
||||
&& !item_vec[0].inner_as_ref().contains('\n')
|
||||
&& ::lists::total_item_width(&item_vec[0]) <= one_line_width
|
||||
{
|
||||
tactic = DefinitiveListTactic::Horizontal;
|
||||
} else {
|
||||
tactic = definitive_tactic(
|
||||
&*item_vec,
|
||||
ListTactic::LimitedHorizontalVertical(args_max_width),
|
||||
Separator::Comma,
|
||||
one_line_width,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -2664,11 +2659,7 @@ pub fn rewrite_field(
|
||||
prefix_max_width: usize,
|
||||
) -> Option<String> {
|
||||
if contains_skip(&field.attrs) {
|
||||
return wrap_str(
|
||||
context.snippet(field.span()),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
);
|
||||
return Some(context.snippet(field.span()));
|
||||
}
|
||||
let name = &field.ident.node.to_string();
|
||||
if field.is_shorthand {
|
||||
|
@ -167,9 +167,7 @@ impl FileLines {
|
||||
}
|
||||
|
||||
/// `FileLines` files iterator.
|
||||
pub struct Files<'a>(
|
||||
Option<::std::collections::hash_map::Keys<'a, String, Vec<Range>>>,
|
||||
);
|
||||
pub struct Files<'a>(Option<::std::collections::hash_map::Keys<'a, String, Vec<Range>>>);
|
||||
|
||||
impl<'a> iter::Iterator for Files<'a> {
|
||||
type Item = &'a String;
|
||||
|
@ -13,13 +13,14 @@ use std::cmp::Ordering;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{BytePos, Span};
|
||||
|
||||
use {Shape, Spanned};
|
||||
use spanned::Spanned;
|
||||
use codemap::SpanUtils;
|
||||
use comment::combine_strs_with_missing_comments;
|
||||
use config::IndentStyle;
|
||||
use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
|
||||
ListItem, Separator, SeparatorPlace, SeparatorTactic};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::Shape;
|
||||
use types::{rewrite_path, PathContext};
|
||||
use utils::{format_visibility, mk_sp};
|
||||
use visitor::{rewrite_extern_crate, FmtVisitor};
|
||||
|
@ -16,7 +16,7 @@ use syntax::{abi, ast, ptr, symbol};
|
||||
use syntax::ast::ImplItem;
|
||||
use syntax::codemap::{BytePos, Span};
|
||||
|
||||
use {Indent, Shape, Spanned};
|
||||
use spanned::Spanned;
|
||||
use codemap::{LineRangeUtils, SpanUtils};
|
||||
use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
|
||||
recover_missing_comment_in_span, rewrite_missing_comment, FindUncommented};
|
||||
@ -26,12 +26,13 @@ use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs
|
||||
use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
|
||||
ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::{Indent, Shape};
|
||||
use types::join_bounds;
|
||||
use utils::{colon_spaces, contains_skip, end_typaram, first_line_width, format_abi,
|
||||
format_constness, format_defaultness, format_mutability, format_unsafety,
|
||||
format_visibility, is_attributes_extendable, last_line_contains_single_line_comment,
|
||||
last_line_used_width, last_line_width, mk_sp, semicolon_for_expr, stmt_expr,
|
||||
trim_newlines, trimmed_last_line_width, wrap_str};
|
||||
trim_newlines, trimmed_last_line_width};
|
||||
use vertical::rewrite_with_alignment;
|
||||
use visitor::FmtVisitor;
|
||||
|
||||
@ -1360,8 +1361,7 @@ pub fn rewrite_struct_field(
|
||||
lhs_max_width: usize,
|
||||
) -> Option<String> {
|
||||
if contains_skip(&field.attrs) {
|
||||
let span = context.snippet(mk_sp(field.attrs[0].span.lo(), field.span.hi()));
|
||||
return wrap_str(span, context.config.max_width(), shape);
|
||||
return Some(context.snippet(mk_sp(field.attrs[0].span.lo(), field.span.hi())));
|
||||
}
|
||||
|
||||
let type_annotation_spacing = type_annotation_spacing(context.config);
|
||||
|
511
src/lib.rs
511
src/lib.rs
@ -24,34 +24,33 @@ extern crate syntax;
|
||||
extern crate term;
|
||||
extern crate unicode_segmentation;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::io::{self, stdout, Write};
|
||||
use std::iter::repeat;
|
||||
use std::ops::{Add, Sub};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
|
||||
use errors::{DiagnosticBuilder, Handler};
|
||||
use errors::emitter::{ColorConfig, EmitterWriter};
|
||||
use macros::MacroArg;
|
||||
use strings::string_buffer::StringBuffer;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{CodeMap, FilePathMapping, Span};
|
||||
use syntax::codemap::{CodeMap, FilePathMapping};
|
||||
use syntax::parse::{self, ParseSess};
|
||||
|
||||
use checkstyle::{output_footer, output_header};
|
||||
use config::Config;
|
||||
use filemap::FileMap;
|
||||
use issues::{BadIssueSeeker, Issue};
|
||||
use utils::{isatty, mk_sp, outer_attributes};
|
||||
use utils::isatty;
|
||||
use visitor::FmtVisitor;
|
||||
|
||||
pub use self::summary::Summary;
|
||||
|
||||
#[macro_use]
|
||||
mod utils;
|
||||
mod shape;
|
||||
mod spanned;
|
||||
pub mod config;
|
||||
pub mod codemap;
|
||||
pub mod filemap;
|
||||
@ -76,423 +75,6 @@ mod patterns;
|
||||
mod summary;
|
||||
mod vertical;
|
||||
|
||||
/// Spanned returns a span including attributes, if available.
|
||||
pub trait Spanned {
|
||||
fn span(&self) -> Span;
|
||||
}
|
||||
|
||||
macro_rules! span_with_attrs_lo_hi {
|
||||
($this:ident, $lo:expr, $hi:expr) => {
|
||||
{
|
||||
let attrs = outer_attributes(&$this.attrs);
|
||||
if attrs.is_empty() {
|
||||
mk_sp($lo, $hi)
|
||||
} else {
|
||||
mk_sp(attrs[0].span.lo(), $hi)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! span_with_attrs {
|
||||
($this:ident) => {
|
||||
span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! implement_spanned {
|
||||
($this:ty) => {
|
||||
impl Spanned for $this {
|
||||
fn span(&self) -> Span {
|
||||
span_with_attrs!(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement `Spanned` for structs with `attrs` field.
|
||||
implement_spanned!(ast::Expr);
|
||||
implement_spanned!(ast::Field);
|
||||
implement_spanned!(ast::ForeignItem);
|
||||
implement_spanned!(ast::Item);
|
||||
implement_spanned!(ast::Local);
|
||||
|
||||
impl Spanned for ast::Stmt {
|
||||
fn span(&self) -> Span {
|
||||
match self.node {
|
||||
ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()),
|
||||
ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
|
||||
ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
|
||||
mk_sp(expr.span().lo(), self.span.hi())
|
||||
}
|
||||
ast::StmtKind::Mac(ref mac) => {
|
||||
let (_, _, ref attrs) = **mac;
|
||||
if attrs.is_empty() {
|
||||
self.span
|
||||
} else {
|
||||
mk_sp(attrs[0].span.lo(), self.span.hi())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::Pat {
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::Ty {
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::Arm {
|
||||
fn span(&self) -> Span {
|
||||
span_with_attrs_lo_hi!(self, self.pats[0].span.lo(), self.body.span.hi())
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::Arg {
|
||||
fn span(&self) -> Span {
|
||||
if items::is_named_arg(self) {
|
||||
utils::mk_sp(self.pat.span.lo(), self.ty.span.hi())
|
||||
} else {
|
||||
self.ty.span
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::StructField {
|
||||
fn span(&self) -> Span {
|
||||
span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::WherePredicate {
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
ast::WherePredicate::BoundPredicate(ref p) => p.span,
|
||||
ast::WherePredicate::RegionPredicate(ref p) => p.span,
|
||||
ast::WherePredicate::EqPredicate(ref p) => p.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::FunctionRetTy {
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
ast::FunctionRetTy::Default(span) => span,
|
||||
ast::FunctionRetTy::Ty(ref ty) => ty.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::TyParam {
|
||||
fn span(&self) -> Span {
|
||||
// Note that ty.span is the span for ty.ident, not the whole item.
|
||||
let lo = if self.attrs.is_empty() {
|
||||
self.span.lo()
|
||||
} else {
|
||||
self.attrs[0].span.lo()
|
||||
};
|
||||
if let Some(ref def) = self.default {
|
||||
return mk_sp(lo, def.span.hi());
|
||||
}
|
||||
if self.bounds.is_empty() {
|
||||
return mk_sp(lo, self.span.hi());
|
||||
}
|
||||
let hi = self.bounds[self.bounds.len() - 1].span().hi();
|
||||
mk_sp(lo, hi)
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::TyParamBound {
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
ast::TyParamBound::TraitTyParamBound(ref ptr, _) => ptr.span,
|
||||
ast::TyParamBound::RegionTyParamBound(ref l) => l.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::LifetimeDef {
|
||||
fn span(&self) -> Span {
|
||||
let hi = if self.bounds.is_empty() {
|
||||
self.lifetime.span.hi()
|
||||
} else {
|
||||
self.bounds[self.bounds.len() - 1].span.hi()
|
||||
};
|
||||
mk_sp(self.lifetime.span.lo(), hi)
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for MacroArg {
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
MacroArg::Expr(ref expr) => expr.span(),
|
||||
MacroArg::Ty(ref ty) => ty.span(),
|
||||
MacroArg::Pat(ref pat) => pat.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Indent {
|
||||
// Width of the block indent, in characters. Must be a multiple of
|
||||
// Config::tab_spaces.
|
||||
pub block_indent: usize,
|
||||
// Alignment in characters.
|
||||
pub alignment: usize,
|
||||
}
|
||||
|
||||
// INDENT_BUFFER.len() == 60
|
||||
const INDENT_BUFFER: &str = " ";
|
||||
const INDENT_BUFFER_LEN: usize = 60;
|
||||
|
||||
impl Indent {
|
||||
pub fn new(block_indent: usize, alignment: usize) -> Indent {
|
||||
Indent {
|
||||
block_indent: block_indent,
|
||||
alignment: alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_width(config: &Config, width: usize) -> Indent {
|
||||
if config.hard_tabs() {
|
||||
let tab_num = width / config.tab_spaces();
|
||||
let alignment = width % config.tab_spaces();
|
||||
Indent::new(config.tab_spaces() * tab_num, alignment)
|
||||
} else {
|
||||
Indent::new(width, 0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty() -> Indent {
|
||||
Indent::new(0, 0)
|
||||
}
|
||||
|
||||
pub fn block_only(&self) -> Indent {
|
||||
Indent {
|
||||
block_indent: self.block_indent,
|
||||
alignment: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_indent(mut self, config: &Config) -> Indent {
|
||||
self.block_indent += config.tab_spaces();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn block_unindent(mut self, config: &Config) -> Indent {
|
||||
if self.block_indent < config.tab_spaces() {
|
||||
Indent::new(self.block_indent, 0)
|
||||
} else {
|
||||
self.block_indent -= config.tab_spaces();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.block_indent + self.alignment
|
||||
}
|
||||
|
||||
pub fn to_string(&self, config: &Config) -> Cow<'static, str> {
|
||||
let (num_tabs, num_spaces) = if config.hard_tabs() {
|
||||
(self.block_indent / config.tab_spaces(), self.alignment)
|
||||
} else {
|
||||
(0, self.width())
|
||||
};
|
||||
let num_chars = num_tabs + num_spaces;
|
||||
if num_tabs == 0 && num_chars <= INDENT_BUFFER_LEN {
|
||||
Cow::from(&INDENT_BUFFER[..num_chars])
|
||||
} else {
|
||||
let mut indent = String::with_capacity(num_chars);
|
||||
for _ in 0..num_tabs {
|
||||
indent.push('\t')
|
||||
}
|
||||
for _ in 0..num_spaces {
|
||||
indent.push(' ')
|
||||
}
|
||||
Cow::from(indent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Indent {
|
||||
type Output = Indent;
|
||||
|
||||
fn add(self, rhs: Indent) -> Indent {
|
||||
Indent {
|
||||
block_indent: self.block_indent + rhs.block_indent,
|
||||
alignment: self.alignment + rhs.alignment,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Indent {
|
||||
type Output = Indent;
|
||||
|
||||
fn sub(self, rhs: Indent) -> Indent {
|
||||
Indent::new(
|
||||
self.block_indent - rhs.block_indent,
|
||||
self.alignment - rhs.alignment,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for Indent {
|
||||
type Output = Indent;
|
||||
|
||||
fn add(self, rhs: usize) -> Indent {
|
||||
Indent::new(self.block_indent, self.alignment + rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<usize> for Indent {
|
||||
type Output = Indent;
|
||||
|
||||
fn sub(self, rhs: usize) -> Indent {
|
||||
Indent::new(self.block_indent, self.alignment - rhs)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Shape {
|
||||
pub width: usize,
|
||||
// The current indentation of code.
|
||||
pub indent: Indent,
|
||||
// Indentation + any already emitted text on the first line of the current
|
||||
// statement.
|
||||
pub offset: usize,
|
||||
}
|
||||
|
||||
impl Shape {
|
||||
/// `indent` is the indentation of the first line. The next lines
|
||||
/// should begin with at least `indent` spaces (except backwards
|
||||
/// indentation). The first line should not begin with indentation.
|
||||
/// `width` is the maximum number of characters on the last line
|
||||
/// (excluding `indent`). The width of other lines is not limited by
|
||||
/// `width`.
|
||||
/// Note that in reality, we sometimes use width for lines other than the
|
||||
/// last (i.e., we are conservative).
|
||||
// .......*-------*
|
||||
// | |
|
||||
// | *-*
|
||||
// *-----|
|
||||
// |<------------>| max width
|
||||
// |<---->| indent
|
||||
// |<--->| width
|
||||
pub fn legacy(width: usize, indent: Indent) -> Shape {
|
||||
Shape {
|
||||
width: width,
|
||||
indent: indent,
|
||||
offset: indent.alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indented(indent: Indent, config: &Config) -> Shape {
|
||||
Shape {
|
||||
width: config.max_width().checked_sub(indent.width()).unwrap_or(0),
|
||||
indent: indent,
|
||||
offset: indent.alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_max_width(&self, config: &Config) -> Shape {
|
||||
Shape {
|
||||
width: config
|
||||
.max_width()
|
||||
.checked_sub(self.indent.width())
|
||||
.unwrap_or(0),
|
||||
..*self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn offset(width: usize, indent: Indent, offset: usize) -> Shape {
|
||||
Shape {
|
||||
width: width,
|
||||
indent: indent,
|
||||
offset: offset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visual_indent(&self, extra_width: usize) -> Shape {
|
||||
let alignment = self.offset + extra_width;
|
||||
Shape {
|
||||
width: self.width,
|
||||
indent: Indent::new(self.indent.block_indent, alignment),
|
||||
offset: alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_indent(&self, extra_width: usize) -> Shape {
|
||||
if self.indent.alignment == 0 {
|
||||
Shape {
|
||||
width: self.width,
|
||||
indent: Indent::new(self.indent.block_indent + extra_width, 0),
|
||||
offset: 0,
|
||||
}
|
||||
} else {
|
||||
Shape {
|
||||
width: self.width,
|
||||
indent: self.indent + extra_width,
|
||||
offset: self.indent.alignment + extra_width,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_left(&self, width: usize) -> Option<Shape> {
|
||||
self.block_indent(width).sub_width(width)
|
||||
}
|
||||
|
||||
pub fn add_offset(&self, extra_width: usize) -> Shape {
|
||||
Shape {
|
||||
offset: self.offset + extra_width,
|
||||
..*self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block(&self) -> Shape {
|
||||
Shape {
|
||||
indent: self.indent.block_only(),
|
||||
..*self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub_width(&self, width: usize) -> Option<Shape> {
|
||||
Some(Shape {
|
||||
width: try_opt!(self.width.checked_sub(width)),
|
||||
..*self
|
||||
})
|
||||
}
|
||||
|
||||
pub fn shrink_left(&self, width: usize) -> Option<Shape> {
|
||||
Some(Shape {
|
||||
width: try_opt!(self.width.checked_sub(width)),
|
||||
indent: self.indent + width,
|
||||
offset: self.offset + width,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn offset_left(&self, width: usize) -> Option<Shape> {
|
||||
self.add_offset(width).sub_width(width)
|
||||
}
|
||||
|
||||
pub fn used_width(&self) -> usize {
|
||||
self.indent.block_indent + self.offset
|
||||
}
|
||||
|
||||
pub fn rhs_overhead(&self, config: &Config) -> usize {
|
||||
config
|
||||
.max_width()
|
||||
.checked_sub(self.used_width() + self.width)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ErrorKind {
|
||||
// Line has exceeded character limit (found, maximum)
|
||||
LineOverflow(usize, usize),
|
||||
@ -1000,88 +582,3 @@ pub fn run(input: Input, config: &Config) -> Summary {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn indent_add_sub() {
|
||||
let indent = Indent::new(4, 8) + Indent::new(8, 12);
|
||||
assert_eq!(12, indent.block_indent);
|
||||
assert_eq!(20, indent.alignment);
|
||||
|
||||
let indent = indent - Indent::new(4, 4);
|
||||
assert_eq!(8, indent.block_indent);
|
||||
assert_eq!(16, indent.alignment);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indent_add_sub_alignment() {
|
||||
let indent = Indent::new(4, 8) + 4;
|
||||
assert_eq!(4, indent.block_indent);
|
||||
assert_eq!(12, indent.alignment);
|
||||
|
||||
let indent = indent - 4;
|
||||
assert_eq!(4, indent.block_indent);
|
||||
assert_eq!(8, indent.alignment);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indent_to_string_spaces() {
|
||||
let config = Config::default();
|
||||
let indent = Indent::new(4, 8);
|
||||
|
||||
// 12 spaces
|
||||
assert_eq!(" ", indent.to_string(&config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indent_to_string_hard_tabs() {
|
||||
let mut config = Config::default();
|
||||
config.set().hard_tabs(true);
|
||||
let indent = Indent::new(8, 4);
|
||||
|
||||
// 2 tabs + 4 spaces
|
||||
assert_eq!("\t\t ", indent.to_string(&config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_visual_indent() {
|
||||
let config = Config::default();
|
||||
let indent = Indent::new(4, 8);
|
||||
let shape = Shape::legacy(config.max_width(), indent);
|
||||
let shape = shape.visual_indent(20);
|
||||
|
||||
assert_eq!(config.max_width(), shape.width);
|
||||
assert_eq!(4, shape.indent.block_indent);
|
||||
assert_eq!(28, shape.indent.alignment);
|
||||
assert_eq!(28, shape.offset);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_block_indent_without_alignment() {
|
||||
let config = Config::default();
|
||||
let indent = Indent::new(4, 0);
|
||||
let shape = Shape::legacy(config.max_width(), indent);
|
||||
let shape = shape.block_indent(20);
|
||||
|
||||
assert_eq!(config.max_width(), shape.width);
|
||||
assert_eq!(24, shape.indent.block_indent);
|
||||
assert_eq!(0, shape.indent.alignment);
|
||||
assert_eq!(0, shape.offset);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_block_indent_with_alignment() {
|
||||
let config = Config::default();
|
||||
let indent = Indent::new(4, 8);
|
||||
let shape = Shape::legacy(config.max_width(), indent);
|
||||
let shape = shape.block_indent(20);
|
||||
|
||||
assert_eq!(config.max_width(), shape.width);
|
||||
assert_eq!(4, shape.indent.block_indent);
|
||||
assert_eq!(28, shape.indent.alignment);
|
||||
assert_eq!(28, shape.offset);
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,10 @@ use std::iter::Peekable;
|
||||
|
||||
use syntax::codemap::{BytePos, CodeMap};
|
||||
|
||||
use {Indent, Shape};
|
||||
use comment::{find_comment_end, rewrite_comment, FindUncommented};
|
||||
use config::{Config, IndentStyle};
|
||||
use rewrite::RewriteContext;
|
||||
use shape::{Indent, Shape};
|
||||
use utils::{first_line_width, last_line_width, mk_sp};
|
||||
|
||||
/// Formatting tactic for lists. This will be cast down to a
|
||||
@ -713,7 +713,7 @@ where
|
||||
.fold((0, 0), |acc, l| (acc.0 + 1, acc.1 + l))
|
||||
}
|
||||
|
||||
fn total_item_width(item: &ListItem) -> usize {
|
||||
pub fn total_item_width(item: &ListItem) -> usize {
|
||||
comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..]))
|
||||
+ comment_len(item.post_comment.as_ref().map(|x| &(*x)[..]))
|
||||
+ item.item.as_ref().map_or(0, |str| str.len())
|
||||
|
@ -28,11 +28,11 @@ use syntax::symbol;
|
||||
use syntax::tokenstream::TokenStream;
|
||||
use syntax::util::ThinVec;
|
||||
|
||||
use {Indent, Shape};
|
||||
use codemap::SpanUtils;
|
||||
use comment::{contains_comment, FindUncommented};
|
||||
use expr::{rewrite_array, rewrite_call_inner};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::{Indent, Shape};
|
||||
use utils::mk_sp;
|
||||
|
||||
const FORCED_BRACKET_MACROS: &'static [&'static str] = &["vec!"];
|
||||
|
@ -10,10 +10,11 @@
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use {Indent, Shape};
|
||||
use syntax::codemap::{BytePos, Pos, Span};
|
||||
|
||||
use comment::{rewrite_comment, CodeCharKind, CommentCodeSlices};
|
||||
use config::WriteMode;
|
||||
use syntax::codemap::{BytePos, Pos, Span};
|
||||
use shape::{Indent, Shape};
|
||||
use utils::mk_sp;
|
||||
use visitor::FmtVisitor;
|
||||
|
||||
|
@ -12,7 +12,7 @@ use syntax::ast::{self, BindingMode, FieldPat, Pat, PatKind, RangeEnd};
|
||||
use syntax::codemap::{self, BytePos, Span};
|
||||
use syntax::ptr;
|
||||
|
||||
use {Shape, Spanned};
|
||||
use spanned::Spanned;
|
||||
use codemap::SpanUtils;
|
||||
use comment::FindUncommented;
|
||||
use expr::{can_be_overflowed_expr, rewrite_call_inner, rewrite_pair, rewrite_unary_prefix,
|
||||
@ -20,8 +20,9 @@ use expr::{can_be_overflowed_expr, rewrite_call_inner, rewrite_pair, rewrite_una
|
||||
use lists::{itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
|
||||
struct_lit_tactic, write_list, DefinitiveListTactic, SeparatorPlace, SeparatorTactic};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::Shape;
|
||||
use types::{rewrite_path, PathContext};
|
||||
use utils::{format_mutability, mk_sp, wrap_str};
|
||||
use utils::{format_mutability, mk_sp};
|
||||
|
||||
impl Rewrite for Pat {
|
||||
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
@ -50,8 +51,7 @@ impl Rewrite for Pat {
|
||||
None => "".to_owned(),
|
||||
};
|
||||
|
||||
let result = format!("{}{}{}{}", prefix, mut_infix, id_str, sub_pat);
|
||||
wrap_str(result, context.config.max_width(), shape)
|
||||
Some(format!("{}{}{}{}", prefix, mut_infix, id_str, sub_pat))
|
||||
}
|
||||
PatKind::Wild => if 1 <= shape.width {
|
||||
Some("_".to_owned())
|
||||
@ -124,17 +124,13 @@ impl Rewrite for Pat {
|
||||
} else {
|
||||
format!("[{}]", pats.join(", "))
|
||||
};
|
||||
wrap_str(result, context.config.max_width(), shape)
|
||||
Some(result)
|
||||
}
|
||||
PatKind::Struct(ref path, ref fields, elipses) => {
|
||||
rewrite_struct_pat(path, fields, elipses, self.span, context, shape)
|
||||
}
|
||||
// FIXME(#819) format pattern macros.
|
||||
PatKind::Mac(..) => wrap_str(
|
||||
context.snippet(self.span),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
),
|
||||
PatKind::Mac(..) => Some(context.snippet(self.span)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -224,11 +220,21 @@ impl Rewrite for FieldPat {
|
||||
if self.is_shorthand {
|
||||
pat
|
||||
} else {
|
||||
wrap_str(
|
||||
format!("{}: {}", self.ident.to_string(), try_opt!(pat)),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
)
|
||||
let pat_str = try_opt!(pat);
|
||||
let id_str = self.ident.to_string();
|
||||
let one_line_width = id_str.len() + 2 + pat_str.len();
|
||||
if one_line_width <= shape.width {
|
||||
Some(format!("{}: {}", id_str, pat_str))
|
||||
} else {
|
||||
let nested_shape = shape.block_indent(context.config.tab_spaces());
|
||||
let pat_str = try_opt!(self.pat.rewrite(context, nested_shape));
|
||||
Some(format!(
|
||||
"{}:\n{}{}",
|
||||
id_str,
|
||||
nested_shape.indent.to_string(context.config),
|
||||
pat_str,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
use syntax::codemap::{CodeMap, Span};
|
||||
use syntax::parse::ParseSess;
|
||||
|
||||
use Shape;
|
||||
use config::{Config, IndentStyle};
|
||||
use shape::Shape;
|
||||
|
||||
pub trait Rewrite {
|
||||
/// Rewrite self into shape.
|
||||
|
344
src/shape.rs
Normal file
344
src/shape.rs
Normal file
@ -0,0 +1,344 @@
|
||||
// Copyright 2017 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 std::ops::{Add, Sub};
|
||||
|
||||
use Config;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Indent {
|
||||
// Width of the block indent, in characters. Must be a multiple of
|
||||
// Config::tab_spaces.
|
||||
pub block_indent: usize,
|
||||
// Alignment in characters.
|
||||
pub alignment: usize,
|
||||
}
|
||||
|
||||
impl Indent {
|
||||
pub fn new(block_indent: usize, alignment: usize) -> Indent {
|
||||
Indent {
|
||||
block_indent: block_indent,
|
||||
alignment: alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_width(config: &Config, width: usize) -> Indent {
|
||||
if config.hard_tabs() {
|
||||
let tab_num = width / config.tab_spaces();
|
||||
let alignment = width % config.tab_spaces();
|
||||
Indent::new(config.tab_spaces() * tab_num, alignment)
|
||||
} else {
|
||||
Indent::new(width, 0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty() -> Indent {
|
||||
Indent::new(0, 0)
|
||||
}
|
||||
|
||||
pub fn block_only(&self) -> Indent {
|
||||
Indent {
|
||||
block_indent: self.block_indent,
|
||||
alignment: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_indent(mut self, config: &Config) -> Indent {
|
||||
self.block_indent += config.tab_spaces();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn block_unindent(mut self, config: &Config) -> Indent {
|
||||
if self.block_indent < config.tab_spaces() {
|
||||
Indent::new(self.block_indent, 0)
|
||||
} else {
|
||||
self.block_indent -= config.tab_spaces();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.block_indent + self.alignment
|
||||
}
|
||||
|
||||
pub fn to_string(&self, config: &Config) -> String {
|
||||
let (num_tabs, num_spaces) = if config.hard_tabs() {
|
||||
(self.block_indent / config.tab_spaces(), self.alignment)
|
||||
} else {
|
||||
(0, self.width())
|
||||
};
|
||||
let num_chars = num_tabs + num_spaces;
|
||||
let mut indent = String::with_capacity(num_chars);
|
||||
for _ in 0..num_tabs {
|
||||
indent.push('\t')
|
||||
}
|
||||
for _ in 0..num_spaces {
|
||||
indent.push(' ')
|
||||
}
|
||||
indent
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Indent {
|
||||
type Output = Indent;
|
||||
|
||||
fn add(self, rhs: Indent) -> Indent {
|
||||
Indent {
|
||||
block_indent: self.block_indent + rhs.block_indent,
|
||||
alignment: self.alignment + rhs.alignment,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Indent {
|
||||
type Output = Indent;
|
||||
|
||||
fn sub(self, rhs: Indent) -> Indent {
|
||||
Indent::new(
|
||||
self.block_indent - rhs.block_indent,
|
||||
self.alignment - rhs.alignment,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for Indent {
|
||||
type Output = Indent;
|
||||
|
||||
fn add(self, rhs: usize) -> Indent {
|
||||
Indent::new(self.block_indent, self.alignment + rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<usize> for Indent {
|
||||
type Output = Indent;
|
||||
|
||||
fn sub(self, rhs: usize) -> Indent {
|
||||
Indent::new(self.block_indent, self.alignment - rhs)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Shape {
|
||||
pub width: usize,
|
||||
// The current indentation of code.
|
||||
pub indent: Indent,
|
||||
// Indentation + any already emitted text on the first line of the current
|
||||
// statement.
|
||||
pub offset: usize,
|
||||
}
|
||||
|
||||
impl Shape {
|
||||
/// `indent` is the indentation of the first line. The next lines
|
||||
/// should begin with at least `indent` spaces (except backwards
|
||||
/// indentation). The first line should not begin with indentation.
|
||||
/// `width` is the maximum number of characters on the last line
|
||||
/// (excluding `indent`). The width of other lines is not limited by
|
||||
/// `width`.
|
||||
/// Note that in reality, we sometimes use width for lines other than the
|
||||
/// last (i.e., we are conservative).
|
||||
// .......*-------*
|
||||
// | |
|
||||
// | *-*
|
||||
// *-----|
|
||||
// |<------------>| max width
|
||||
// |<---->| indent
|
||||
// |<--->| width
|
||||
pub fn legacy(width: usize, indent: Indent) -> Shape {
|
||||
Shape {
|
||||
width: width,
|
||||
indent: indent,
|
||||
offset: indent.alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indented(indent: Indent, config: &Config) -> Shape {
|
||||
Shape {
|
||||
width: config.max_width().checked_sub(indent.width()).unwrap_or(0),
|
||||
indent: indent,
|
||||
offset: indent.alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_max_width(&self, config: &Config) -> Shape {
|
||||
Shape {
|
||||
width: config
|
||||
.max_width()
|
||||
.checked_sub(self.indent.width())
|
||||
.unwrap_or(0),
|
||||
..*self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn offset(width: usize, indent: Indent, offset: usize) -> Shape {
|
||||
Shape {
|
||||
width: width,
|
||||
indent: indent,
|
||||
offset: offset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visual_indent(&self, extra_width: usize) -> Shape {
|
||||
let alignment = self.offset + extra_width;
|
||||
Shape {
|
||||
width: self.width,
|
||||
indent: Indent::new(self.indent.block_indent, alignment),
|
||||
offset: alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_indent(&self, extra_width: usize) -> Shape {
|
||||
if self.indent.alignment == 0 {
|
||||
Shape {
|
||||
width: self.width,
|
||||
indent: Indent::new(self.indent.block_indent + extra_width, 0),
|
||||
offset: 0,
|
||||
}
|
||||
} else {
|
||||
Shape {
|
||||
width: self.width,
|
||||
indent: self.indent + extra_width,
|
||||
offset: self.indent.alignment + extra_width,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_left(&self, width: usize) -> Option<Shape> {
|
||||
self.block_indent(width).sub_width(width)
|
||||
}
|
||||
|
||||
pub fn add_offset(&self, extra_width: usize) -> Shape {
|
||||
Shape {
|
||||
offset: self.offset + extra_width,
|
||||
..*self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block(&self) -> Shape {
|
||||
Shape {
|
||||
indent: self.indent.block_only(),
|
||||
..*self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub_width(&self, width: usize) -> Option<Shape> {
|
||||
Some(Shape {
|
||||
width: try_opt!(self.width.checked_sub(width)),
|
||||
..*self
|
||||
})
|
||||
}
|
||||
|
||||
pub fn shrink_left(&self, width: usize) -> Option<Shape> {
|
||||
Some(Shape {
|
||||
width: try_opt!(self.width.checked_sub(width)),
|
||||
indent: self.indent + width,
|
||||
offset: self.offset + width,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn offset_left(&self, width: usize) -> Option<Shape> {
|
||||
self.add_offset(width).sub_width(width)
|
||||
}
|
||||
|
||||
pub fn used_width(&self) -> usize {
|
||||
self.indent.block_indent + self.offset
|
||||
}
|
||||
|
||||
pub fn rhs_overhead(&self, config: &Config) -> usize {
|
||||
config
|
||||
.max_width()
|
||||
.checked_sub(self.used_width() + self.width)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn indent_add_sub() {
|
||||
let indent = Indent::new(4, 8) + Indent::new(8, 12);
|
||||
assert_eq!(12, indent.block_indent);
|
||||
assert_eq!(20, indent.alignment);
|
||||
|
||||
let indent = indent - Indent::new(4, 4);
|
||||
assert_eq!(8, indent.block_indent);
|
||||
assert_eq!(16, indent.alignment);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indent_add_sub_alignment() {
|
||||
let indent = Indent::new(4, 8) + 4;
|
||||
assert_eq!(4, indent.block_indent);
|
||||
assert_eq!(12, indent.alignment);
|
||||
|
||||
let indent = indent - 4;
|
||||
assert_eq!(4, indent.block_indent);
|
||||
assert_eq!(8, indent.alignment);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indent_to_string_spaces() {
|
||||
let config = Config::default();
|
||||
let indent = Indent::new(4, 8);
|
||||
|
||||
// 12 spaces
|
||||
assert_eq!(" ", indent.to_string(&config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indent_to_string_hard_tabs() {
|
||||
let mut config = Config::default();
|
||||
config.set().hard_tabs(true);
|
||||
let indent = Indent::new(8, 4);
|
||||
|
||||
// 2 tabs + 4 spaces
|
||||
assert_eq!("\t\t ", indent.to_string(&config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_visual_indent() {
|
||||
let config = Config::default();
|
||||
let indent = Indent::new(4, 8);
|
||||
let shape = Shape::legacy(config.max_width(), indent);
|
||||
let shape = shape.visual_indent(20);
|
||||
|
||||
assert_eq!(config.max_width(), shape.width);
|
||||
assert_eq!(4, shape.indent.block_indent);
|
||||
assert_eq!(28, shape.indent.alignment);
|
||||
assert_eq!(28, shape.offset);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_block_indent_without_alignment() {
|
||||
let config = Config::default();
|
||||
let indent = Indent::new(4, 0);
|
||||
let shape = Shape::legacy(config.max_width(), indent);
|
||||
let shape = shape.block_indent(20);
|
||||
|
||||
assert_eq!(config.max_width(), shape.width);
|
||||
assert_eq!(24, shape.indent.block_indent);
|
||||
assert_eq!(0, shape.indent.alignment);
|
||||
assert_eq!(0, shape.offset);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_block_indent_with_alignment() {
|
||||
let config = Config::default();
|
||||
let indent = Indent::new(4, 8);
|
||||
let shape = Shape::legacy(config.max_width(), indent);
|
||||
let shape = shape.block_indent(20);
|
||||
|
||||
assert_eq!(config.max_width(), shape.width);
|
||||
assert_eq!(4, shape.indent.block_indent);
|
||||
assert_eq!(28, shape.indent.alignment);
|
||||
assert_eq!(28, shape.offset);
|
||||
}
|
||||
}
|
178
src/spanned.rs
Normal file
178
src/spanned.rs
Normal file
@ -0,0 +1,178 @@
|
||||
// Copyright 2017 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 syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
use macros::MacroArg;
|
||||
use utils::{mk_sp, outer_attributes};
|
||||
|
||||
/// Spanned returns a span including attributes, if available.
|
||||
pub trait Spanned {
|
||||
fn span(&self) -> Span;
|
||||
}
|
||||
|
||||
macro_rules! span_with_attrs_lo_hi {
|
||||
($this:ident, $lo:expr, $hi:expr) => {
|
||||
{
|
||||
let attrs = outer_attributes(&$this.attrs);
|
||||
if attrs.is_empty() {
|
||||
mk_sp($lo, $hi)
|
||||
} else {
|
||||
mk_sp(attrs[0].span.lo(), $hi)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! span_with_attrs {
|
||||
($this:ident) => {
|
||||
span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! implement_spanned {
|
||||
($this:ty) => {
|
||||
impl Spanned for $this {
|
||||
fn span(&self) -> Span {
|
||||
span_with_attrs!(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement `Spanned` for structs with `attrs` field.
|
||||
implement_spanned!(ast::Expr);
|
||||
implement_spanned!(ast::Field);
|
||||
implement_spanned!(ast::ForeignItem);
|
||||
implement_spanned!(ast::Item);
|
||||
implement_spanned!(ast::Local);
|
||||
|
||||
impl Spanned for ast::Stmt {
|
||||
fn span(&self) -> Span {
|
||||
match self.node {
|
||||
ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()),
|
||||
ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
|
||||
ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
|
||||
mk_sp(expr.span().lo(), self.span.hi())
|
||||
}
|
||||
ast::StmtKind::Mac(ref mac) => {
|
||||
let (_, _, ref attrs) = **mac;
|
||||
if attrs.is_empty() {
|
||||
self.span
|
||||
} else {
|
||||
mk_sp(attrs[0].span.lo(), self.span.hi())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::Pat {
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::Ty {
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::Arm {
|
||||
fn span(&self) -> Span {
|
||||
span_with_attrs_lo_hi!(self, self.pats[0].span.lo(), self.body.span.hi())
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::Arg {
|
||||
fn span(&self) -> Span {
|
||||
if ::items::is_named_arg(self) {
|
||||
mk_sp(self.pat.span.lo(), self.ty.span.hi())
|
||||
} else {
|
||||
self.ty.span
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::StructField {
|
||||
fn span(&self) -> Span {
|
||||
span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::WherePredicate {
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
ast::WherePredicate::BoundPredicate(ref p) => p.span,
|
||||
ast::WherePredicate::RegionPredicate(ref p) => p.span,
|
||||
ast::WherePredicate::EqPredicate(ref p) => p.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::FunctionRetTy {
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
ast::FunctionRetTy::Default(span) => span,
|
||||
ast::FunctionRetTy::Ty(ref ty) => ty.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::TyParam {
|
||||
fn span(&self) -> Span {
|
||||
// Note that ty.span is the span for ty.ident, not the whole item.
|
||||
let lo = if self.attrs.is_empty() {
|
||||
self.span.lo()
|
||||
} else {
|
||||
self.attrs[0].span.lo()
|
||||
};
|
||||
if let Some(ref def) = self.default {
|
||||
return mk_sp(lo, def.span.hi());
|
||||
}
|
||||
if self.bounds.is_empty() {
|
||||
return mk_sp(lo, self.span.hi());
|
||||
}
|
||||
let hi = self.bounds[self.bounds.len() - 1].span().hi();
|
||||
mk_sp(lo, hi)
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::TyParamBound {
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
ast::TyParamBound::TraitTyParamBound(ref ptr, _) => ptr.span,
|
||||
ast::TyParamBound::RegionTyParamBound(ref l) => l.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for ast::LifetimeDef {
|
||||
fn span(&self) -> Span {
|
||||
let hi = if self.bounds.is_empty() {
|
||||
self.lifetime.span.hi()
|
||||
} else {
|
||||
self.bounds[self.bounds.len() - 1].span.hi()
|
||||
};
|
||||
mk_sp(self.lifetime.span.lo(), hi)
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for MacroArg {
|
||||
fn span(&self) -> Span {
|
||||
match *self {
|
||||
MacroArg::Expr(ref expr) => expr.span(),
|
||||
MacroArg::Ty(ref ty) => ty.span(),
|
||||
MacroArg::Pat(ref pat) => pat.span(),
|
||||
}
|
||||
}
|
||||
}
|
@ -13,8 +13,8 @@
|
||||
use regex::Regex;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use Shape;
|
||||
use config::Config;
|
||||
use shape::Shape;
|
||||
use utils::wrap_str;
|
||||
|
||||
const MIN_STRING: usize = 10;
|
||||
@ -128,6 +128,7 @@ pub fn rewrite_string<'a>(orig: &str, fmt: &StringFormat<'a>) -> Option<String>
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{rewrite_string, StringFormat};
|
||||
use shape::{Indent, Shape};
|
||||
|
||||
#[test]
|
||||
fn issue343() {
|
||||
@ -137,7 +138,7 @@ mod test {
|
||||
closer: "\"",
|
||||
line_start: " ",
|
||||
line_end: "\\",
|
||||
shape: ::Shape::legacy(2, ::Indent::empty()),
|
||||
shape: Shape::legacy(2, Indent::empty()),
|
||||
trim_end: false,
|
||||
config: &config,
|
||||
};
|
||||
|
19
src/types.rs
19
src/types.rs
@ -17,7 +17,7 @@ use syntax::codemap::{self, BytePos, Span};
|
||||
use syntax::print::pprust;
|
||||
use syntax::symbol::keywords;
|
||||
|
||||
use {Shape, Spanned};
|
||||
use spanned::Spanned;
|
||||
use codemap::SpanUtils;
|
||||
use config::{IndentStyle, Style, TypeDensity};
|
||||
use expr::{rewrite_pair, rewrite_tuple, rewrite_unary_prefix, wrap_args_with_parens};
|
||||
@ -25,7 +25,8 @@ use items::{format_generics_item_list, generics_shape_from_config};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator,
|
||||
SeparatorPlace, SeparatorTactic};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use utils::{colon_spaces, extra_offset, format_mutability, last_line_width, mk_sp, wrap_str};
|
||||
use shape::Shape;
|
||||
use utils::{colon_spaces, extra_offset, format_mutability, last_line_width, mk_sp};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum PathContext {
|
||||
@ -503,7 +504,7 @@ impl Rewrite for ast::WherePredicate {
|
||||
}
|
||||
};
|
||||
|
||||
wrap_str(result, context.config.max_width(), shape)
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
@ -541,7 +542,7 @@ where
|
||||
colon,
|
||||
join_bounds(context, try_opt!(shape.sub_width(overhead)), &appendix)
|
||||
);
|
||||
wrap_str(result, context.config.max_width(), shape)
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
@ -564,12 +565,8 @@ impl Rewrite for ast::TyParamBound {
|
||||
}
|
||||
|
||||
impl Rewrite for ast::Lifetime {
|
||||
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
wrap_str(
|
||||
pprust::lifetime_to_string(self),
|
||||
context.config.max_width(),
|
||||
shape,
|
||||
)
|
||||
fn rewrite(&self, _: &RewriteContext, _: Shape) -> Option<String> {
|
||||
Some(pprust::lifetime_to_string(self))
|
||||
}
|
||||
}
|
||||
|
||||
@ -611,7 +608,7 @@ impl Rewrite for ast::TyParam {
|
||||
result.push_str(&rewrite);
|
||||
}
|
||||
|
||||
wrap_str(result, context.config.max_width(), shape)
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ use syntax::ast::{self, Attribute, MetaItem, MetaItemKind, NestedMetaItem, Neste
|
||||
Path, Visibility};
|
||||
use syntax::codemap::{BytePos, Span, NO_EXPANSION};
|
||||
|
||||
use Shape;
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::Shape;
|
||||
|
||||
// When we get scoped annotations, we should have rustfmt::skip.
|
||||
const SKIP_ANNOTATION: &'static str = "rustfmt_skip";
|
||||
|
@ -15,7 +15,7 @@ use std::cmp;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{BytePos, Span};
|
||||
|
||||
use {Indent, Shape, Spanned};
|
||||
use spanned::Spanned;
|
||||
use codemap::SpanUtils;
|
||||
use comment::{combine_strs_with_missing_comments, contains_comment};
|
||||
use expr::rewrite_field;
|
||||
@ -23,6 +23,7 @@ use items::{rewrite_struct_field, rewrite_struct_field_prefix};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator,
|
||||
SeparatorPlace};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::{Indent, Shape};
|
||||
use utils::{contains_skip, is_attributes_extendable, mk_sp};
|
||||
|
||||
pub trait AlignedItem {
|
||||
|
@ -16,7 +16,7 @@ use syntax::attr::HasAttrs;
|
||||
use syntax::codemap::{self, BytePos, CodeMap, Pos, Span};
|
||||
use syntax::parse::ParseSess;
|
||||
|
||||
use {Indent, Shape, Spanned};
|
||||
use spanned::Spanned;
|
||||
use codemap::{LineRangeUtils, SpanUtils};
|
||||
use comment::{contains_comment, recover_missing_comment_in_span, CodeCharKind, CommentCodeSlices,
|
||||
FindUncommented};
|
||||
@ -30,6 +30,7 @@ use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, Sepa
|
||||
use macros::{rewrite_macro, MacroPosition};
|
||||
use regex::Regex;
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use shape::{Indent, Shape};
|
||||
use utils::{self, contains_skip, inner_attributes, mk_sp, ptr_vec_to_ref_vec};
|
||||
|
||||
fn is_use_item(item: &ast::Item) -> bool {
|
||||
|
@ -4,5 +4,5 @@
|
||||
// rustfmt should not add trailing comma when rewriting macro. See #1528.
|
||||
fn a() {
|
||||
panic!("this is a long string that goes past the maximum line length causing rustfmt to insert a comma here:");
|
||||
foo(oooptoptoptoptptooptoptoptoptptooptoptoptoptptoptoptoptoptpt());
|
||||
foo(a, oooptoptoptoptptooptoptoptoptptooptoptoptoptptoptoptoptoptpt());
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate regex;
|
||||
extern crate rustfmt_nightly as rustfmt;
|
||||
extern crate term;
|
||||
@ -201,7 +203,7 @@ where
|
||||
let mut reports = vec![];
|
||||
|
||||
for file_name in files.filter(|f| f.ends_with(".rs")) {
|
||||
println!("Testing '{}'...", file_name);
|
||||
debug!("Testing '{}'...", file_name);
|
||||
|
||||
match idempotent_check(file_name) {
|
||||
Ok(ref report) if report.has_warnings() => {
|
||||
|
@ -7,6 +7,7 @@ fn a() {
|
||||
"this is a long string that goes past the maximum line length causing rustfmt to insert a comma here:"
|
||||
);
|
||||
foo(
|
||||
a,
|
||||
oooptoptoptoptptooptoptoptoptptooptoptoptoptptoptoptoptoptpt(),
|
||||
);
|
||||
}
|
||||
|
@ -170,10 +170,6 @@ enum Loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
||||
|
||||
// #1046
|
||||
pub enum Entry<'a, K: 'a, V: 'a> {
|
||||
Vacant(
|
||||
#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>,
|
||||
),
|
||||
Occupied(
|
||||
#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>,
|
||||
),
|
||||
Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>),
|
||||
Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>),
|
||||
}
|
||||
|
@ -307,9 +307,7 @@ fn combine_block() {
|
||||
};
|
||||
|
||||
match x {
|
||||
y => func(
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
|
||||
),
|
||||
y => func(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
|
||||
_ => func(
|
||||
x,
|
||||
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,
|
||||
|
@ -25,9 +25,8 @@ formatting"#;
|
||||
|
||||
filename.replace(" ", "\\");
|
||||
|
||||
let xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = funktion(
|
||||
"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
|
||||
);
|
||||
let xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx =
|
||||
funktion("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
|
||||
|
||||
let unicode = "a̐éö̲\r\n";
|
||||
let unicode2 = "Löwe 老虎 Léopard";
|
||||
|
Loading…
Reference in New Issue
Block a user