Move Indent and Shape to shape.rs from lib.rs
This commit is contained in:
parent
8974f89381
commit
df7d2be562
@ -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() {
|
||||
|
@ -17,7 +17,7 @@ use syntax::{ast, ptr};
|
||||
use syntax::codemap::{BytePos, CodeMap, Span};
|
||||
use syntax::parse::classify;
|
||||
|
||||
use {Indent, Shape, Spanned};
|
||||
use Spanned;
|
||||
use chains::rewrite_chain;
|
||||
use codemap::{LineRangeUtils, SpanUtils};
|
||||
use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
|
||||
@ -30,6 +30,7 @@ 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,
|
||||
|
@ -13,13 +13,14 @@ use std::cmp::Ordering;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{BytePos, Span};
|
||||
|
||||
use {Shape, Spanned};
|
||||
use 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;
|
||||
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,6 +26,7 @@ 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,
|
||||
|
341
src/lib.rs
341
src/lib.rs
@ -29,7 +29,6 @@ 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;
|
||||
|
||||
@ -52,6 +51,7 @@ pub use self::summary::Summary;
|
||||
|
||||
#[macro_use]
|
||||
mod utils;
|
||||
mod shape;
|
||||
pub mod config;
|
||||
pub mod codemap;
|
||||
pub mod filemap;
|
||||
@ -239,260 +239,6 @@ impl Spanned for MacroArg {
|
||||
}
|
||||
}
|
||||
|
||||
#[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 +746,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
|
||||
|
@ -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;
|
||||
use codemap::SpanUtils;
|
||||
use comment::FindUncommented;
|
||||
use expr::{can_be_overflowed_expr, rewrite_call_inner, rewrite_pair, rewrite_unary_prefix,
|
||||
@ -20,6 +20,7 @@ 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};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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,
|
||||
};
|
||||
|
@ -17,7 +17,7 @@ use syntax::codemap::{self, BytePos, Span};
|
||||
use syntax::print::pprust;
|
||||
use syntax::symbol::keywords;
|
||||
|
||||
use {Shape, Spanned};
|
||||
use Spanned;
|
||||
use codemap::SpanUtils;
|
||||
use config::{IndentStyle, Style, TypeDensity};
|
||||
use expr::{rewrite_pair, rewrite_tuple, rewrite_unary_prefix, wrap_args_with_parens};
|
||||
@ -25,6 +25,7 @@ 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 shape::Shape;
|
||||
use utils::{colon_spaces, extra_offset, format_mutability, last_line_width, mk_sp, wrap_str};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
|
@ -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;
|
||||
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;
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user