Merge pull request #1983 from topecongiro/cleanup

Refactoring: clean up source code
This commit is contained in:
Nick Cameron 2017-09-19 17:08:17 +12:00 committed by GitHub
commit c6b3cf9828
25 changed files with 627 additions and 615 deletions

View File

@ -76,7 +76,7 @@
/// .qux
/// ```
use Shape;
use shape::Shape;
use config::IndentStyle;
use expr::rewrite_call;
use macros::convert_try_mac;

View File

@ -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() {

View File

@ -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 {

View File

@ -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;

View File

@ -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};

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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())

View File

@ -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!"];

View File

@ -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;

View File

@ -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,
))
}
}
}
}

View File

@ -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
View 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
View 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(),
}
}
}

View File

@ -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,
};

View File

@ -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)
}
}

View File

@ -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";

View File

@ -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 {

View File

@ -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 {

View File

@ -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());
}

View File

@ -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() => {

View File

@ -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(),
);
}

View File

@ -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>),
}

View File

@ -307,9 +307,7 @@ fn combine_block() {
};
match x {
y => func(
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
),
y => func(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
_ => func(
x,
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy,

View File

@ -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";