Create rustfmt_core crate

This commit is contained in:
topecongiro 2018-02-07 22:48:05 +09:00
parent c9e250a1ab
commit 4af2aa3a9e
580 changed files with 97 additions and 230 deletions

33
rustfmt-core/Cargo.toml Normal file
View File

@ -0,0 +1,33 @@
[package]
name = "rustfmt-core"
version = "0.4.0"
authors = ["Nicholas Cameron <ncameron@mozilla.com>", "The Rustfmt developers"]
description = "A core library of rustfmt"
repository = "https://github.com/rust-lang-nursery/rustfmt"
readme = "README.md"
license = "Apache-2.0/MIT"
categories = ["development-tools"]
[lib]
doctest = false
[dependencies]
derive-new = "0.5"
diff = "0.1"
log = "0.3"
regex = "0.2"
rustc-ap-syntax = "29.0.0"
rustc-ap-rustc_errors = "29.0.0"
rustfmt-config = { path = "../rustfmt-config" }
term = "0.4"
unicode-segmentation = "1.0.0"
[dev-dependencies]
lazy_static = "1.0.0"
[target.'cfg(unix)'.dependencies]
libc = "0.2.11"
[target.'cfg(windows)'.dependencies]
kernel32-sys = "0.2.2"
winapi = "0.2.7"

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use config::lists::*;
use syntax::{ast, ptr};
use syntax::codemap::Span;
use syntax::parse::classify;
@ -15,8 +16,7 @@ use syntax::parse::classify;
use codemap::SpanUtils;
use expr::{block_contains_comment, is_simple_block, is_unsafe_block, rewrite_cond, ToExpr};
use items::{span_hi_for_arg, span_lo_for_arg};
use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
ListTactic, Separator, SeparatorPlace, SeparatorTactic};
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
use rewrite::{Rewrite, RewriteContext};
use shape::Shape;
use utils::{last_line_width, left_most_sub_expr, stmt_expr};

View File

@ -11,25 +11,11 @@
//! This module contains utilities that work with the `CodeMap` from `libsyntax` / `syntex_syntax`.
//! This includes extension traits and methods for looking up spans and line ranges for AST nodes.
use std::rc::Rc;
use syntax::codemap::{BytePos, CodeMap, FileMap, FileName, Span};
use config::file_lines::LineRange;
use syntax::codemap::{BytePos, CodeMap, Span};
use comment::FindUncommented;
/// A range of lines in a file, inclusive of both ends.
pub struct LineRange {
pub file: Rc<FileMap>,
pub lo: usize,
pub hi: usize,
}
impl LineRange {
pub fn file_name(&self) -> &FileName {
&self.file.name
}
}
pub trait SpanUtils {
fn span_after(&self, original: Span, needle: &str) -> BytePos;
fn span_after_last(&self, original: Span, needle: &str) -> BytePos;

View File

@ -12,6 +12,7 @@ use std::borrow::Cow;
use std::cmp::min;
use std::iter::repeat;
use config::lists::*;
use syntax::{ast, ptr};
use syntax::codemap::{BytePos, CodeMap, Span};
@ -22,8 +23,7 @@ use comment::{combine_strs_with_missing_comments, contains_comment, recover_comm
rewrite_comment, rewrite_missing_comment, FindUncommented};
use config::{Config, ControlBraceStyle, IndentStyle};
use lists::{definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting,
struct_lit_shape, struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting,
ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
struct_lit_shape, struct_lit_tactic, write_list, ListFormatting, ListItem, Separator};
use macros::{rewrite_macro, MacroArg, MacroPosition};
use patterns::{can_be_overflowed_pat, TuplePatField};
use rewrite::{Rewrite, RewriteContext};

View File

@ -19,10 +19,7 @@ use config::{Config, NewlineStyle, WriteMode};
use rustfmt_diff::{make_diff, print_diff, Mismatch};
use syntax::codemap::FileName;
// A map of the files of a crate, with their new content
pub type FileMap = Vec<FileRecord>;
pub type FileRecord = (FileName, String);
use FileRecord;
// Append a newline to the end of each file.
pub fn append_newline(s: &mut String) {

View File

@ -10,14 +10,14 @@
use std::cmp::Ordering;
use config::lists::*;
use syntax::ast;
use syntax::codemap::{BytePos, Span};
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 lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator};
use rewrite::{Rewrite, RewriteContext};
use shape::Shape;
use spanned::Spanned;

View File

@ -14,17 +14,15 @@
use std::fmt;
pub use config::ReportTactic;
use config::ReportTactic;
const TO_DO_CHARS: &[char] = &['t', 'o', 'd', 'o'];
const FIX_ME_CHARS: &[char] = &['f', 'i', 'x', 'm', 'e'];
// Enabled implementation detail is here because it is
// irrelevant outside the issues module
impl ReportTactic {
fn is_enabled(&self) -> bool {
*self != ReportTactic::Never
}
fn is_enabled(report_tactic: ReportTactic) -> bool {
report_tactic != ReportTactic::Never
}
#[derive(Clone, Copy)]
@ -128,7 +126,7 @@ impl BadIssueSeeker {
fn inspect_issue(&mut self, c: char, mut todo_idx: usize, mut fixme_idx: usize) -> Seeking {
if let Some(lower_case_c) = c.to_lowercase().next() {
if self.report_todo.is_enabled() && lower_case_c == TO_DO_CHARS[todo_idx] {
if is_enabled(self.report_todo) && lower_case_c == TO_DO_CHARS[todo_idx] {
todo_idx += 1;
if todo_idx == TO_DO_CHARS.len() {
return Seeking::Number {
@ -144,7 +142,7 @@ impl BadIssueSeeker {
};
}
fixme_idx = 0;
} else if self.report_fixme.is_enabled() && lower_case_c == FIX_ME_CHARS[fixme_idx] {
} else if is_enabled(self.report_fixme) && lower_case_c == FIX_ME_CHARS[fixme_idx] {
// Exploit the fact that the character sets of todo and fixme
// are disjoint by adding else.
fixme_idx += 1;

View File

@ -13,6 +13,7 @@
use std::borrow::Cow;
use std::cmp::min;
use config::lists::*;
use syntax::{abi, ast, ptr, symbol};
use syntax::ast::{CrateSugar, ImplItem};
use syntax::codemap::{BytePos, Span};
@ -24,8 +25,7 @@ use comment::{combine_strs_with_missing_comments, contains_comment, recover_comm
use config::{BraceStyle, Config, Density, IndentStyle};
use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
rewrite_call_inner, ExprType};
use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator};
use rewrite::{Rewrite, RewriteContext};
use shape::{Indent, Shape};
use spanned::Spanned;

View File

@ -19,10 +19,7 @@ extern crate diff;
extern crate log;
extern crate regex;
extern crate rustc_errors as errors;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate rustfmt_config as config;
extern crate syntax;
extern crate term;
extern crate unicode_segmentation;
@ -44,14 +41,13 @@ use syntax::parse::{self, ParseSess};
use checkstyle::{output_footer, output_header};
use comment::{CharClasses, FullCodeCharKind};
pub use config::Config;
use filemap::FileMap;
use issues::{BadIssueSeeker, Issue};
use shape::Indent;
use utils::use_colored_tty;
use visitor::{FmtVisitor, SnippetProvider};
pub use self::summary::Summary;
use config::Config;
use config::summary::Summary;
#[macro_use]
mod utils;
@ -60,9 +56,7 @@ mod checkstyle;
mod closures;
pub mod codemap;
mod comment;
pub mod config;
mod expr;
pub mod file_lines;
pub mod filemap;
mod imports;
mod issues;
@ -77,11 +71,15 @@ pub mod rustfmt_diff;
mod shape;
mod spanned;
mod string;
mod summary;
mod types;
mod vertical;
pub mod visitor;
// A map of the files of a crate, with their new content
pub type FileMap = Vec<FileRecord>;
pub type FileRecord = (FileName, String);
#[derive(Clone, Copy)]
pub enum ErrorKind {
// Line has exceeded character limit (found, maximum)

View File

@ -8,9 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Format list-like expressions and items.
use std::cmp;
use std::iter::Peekable;
use config::lists::*;
use syntax::codemap::{BytePos, CodeMap};
use comment::{find_comment_end, rewrite_comment, FindUncommented};
@ -19,44 +22,6 @@ use rewrite::RewriteContext;
use shape::{Indent, Shape};
use utils::{count_newlines, first_line_width, last_line_width, mk_sp, starts_with_newline};
/// Formatting tactic for lists. This will be cast down to a
/// `DefinitiveListTactic` depending on the number and length of the items and
/// their comments.
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum ListTactic {
// One item per row.
Vertical,
// All items on one row.
Horizontal,
// Try Horizontal layout, if that fails then vertical.
HorizontalVertical,
// HorizontalVertical with a soft limit of n characters.
LimitedHorizontalVertical(usize),
// Pack as many items as possible per row over (possibly) many rows.
Mixed,
}
impl_enum_serialize_and_deserialize!(ListTactic, Vertical, Horizontal, HorizontalVertical, Mixed);
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum SeparatorTactic {
Always,
Never,
Vertical,
}
impl_enum_serialize_and_deserialize!(SeparatorTactic, Always, Never, Vertical);
impl SeparatorTactic {
pub fn from_bool(b: bool) -> SeparatorTactic {
if b {
SeparatorTactic::Always
} else {
SeparatorTactic::Never
}
}
}
pub struct ListFormatting<'a> {
pub tactic: DefinitiveListTactic,
pub separator: &'a str,
@ -154,25 +119,6 @@ impl ListItem {
}
}
/// The definitive formatting tactic for lists.
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum DefinitiveListTactic {
Vertical,
Horizontal,
Mixed,
/// Special case tactic for `format!()`, `write!()` style macros.
SpecialMacro(usize),
}
impl DefinitiveListTactic {
pub fn ends_with_newline(&self, indent_style: IndentStyle) -> bool {
match indent_style {
IndentStyle::Block => *self != DefinitiveListTactic::Horizontal,
IndentStyle::Visual => false,
}
}
}
/// The type of separator for lists.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Separator {
@ -191,40 +137,6 @@ impl Separator {
}
}
/// Where to put separator.
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum SeparatorPlace {
Front,
Back,
}
impl_enum_serialize_and_deserialize!(SeparatorPlace, Front, Back);
impl SeparatorPlace {
pub fn is_front(&self) -> bool {
*self == SeparatorPlace::Front
}
pub fn is_back(&self) -> bool {
*self == SeparatorPlace::Back
}
pub fn from_tactic(
default: SeparatorPlace,
tactic: DefinitiveListTactic,
sep: &str,
) -> SeparatorPlace {
match tactic {
DefinitiveListTactic::Vertical => default,
_ => if sep == "," {
SeparatorPlace::Back
} else {
default
},
}
}
}
pub fn definitive_tactic<I, T>(
items: I,
tactic: ListTactic,

View File

@ -20,6 +20,8 @@
// and those with brackets will be formatted as array literals.
use std::collections::HashMap;
use config::lists::*;
use syntax::ast;
use syntax::codemap::{BytePos, Span};
use syntax::parse::new_parser_from_tts;
@ -33,8 +35,7 @@ use syntax::util::ThinVec;
use codemap::SpanUtils;
use comment::{contains_comment, remove_trailing_white_spaces, FindUncommented};
use expr::{rewrite_array, rewrite_call_inner};
use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorPlace,
SeparatorTactic};
use lists::{itemize_list, write_list, ListFormatting};
use rewrite::{Rewrite, RewriteContext};
use shape::{Indent, Shape};
use utils::{format_visibility, mk_sp};

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use config::lists::*;
use syntax::ast::{self, BindingMode, FieldPat, Pat, PatKind, RangeEnd, RangeSyntax};
use syntax::codemap::{self, BytePos, Span};
use syntax::ptr;
@ -17,7 +18,7 @@ use comment::FindUncommented;
use expr::{can_be_overflowed_expr, rewrite_call_inner, rewrite_pair, rewrite_unary_prefix,
wrap_struct_field, PairParts};
use lists::{itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
struct_lit_tactic, write_list, DefinitiveListTactic, SeparatorPlace, SeparatorTactic};
struct_lit_tactic, write_list};
use macros::{rewrite_macro, MacroPosition};
use rewrite::{Rewrite, RewriteContext};
use shape::Shape;

View File

@ -11,6 +11,7 @@
use std::iter::ExactSizeIterator;
use std::ops::Deref;
use config::lists::*;
use syntax::ast::{self, FunctionRetTy, Mutability};
use syntax::codemap::{self, BytePos, Span};
use syntax::print::pprust;
@ -20,8 +21,7 @@ use codemap::SpanUtils;
use config::{IndentStyle, TypeDensity};
use expr::{rewrite_pair, rewrite_tuple, rewrite_unary_prefix, wrap_args_with_parens, PairParts};
use items::{format_generics_item_list, generics_shape_from_config};
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator,
SeparatorPlace, SeparatorTactic};
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
use macros::{rewrite_macro, MacroPosition};
use rewrite::{Rewrite, RewriteContext};
use shape::Shape;

View File

@ -254,82 +254,6 @@ pub fn count_newlines(input: &str) -> usize {
input.chars().filter(|&c| c == '\n').count()
}
// Macro for deriving implementations of Serialize/Deserialize for enums
#[macro_export]
macro_rules! impl_enum_serialize_and_deserialize {
( $e:ident, $( $x:ident ),* ) => {
impl ::serde::ser::Serialize for $e {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: ::serde::ser::Serializer
{
use serde::ser::Error;
// We don't know whether the user of the macro has given us all options.
#[allow(unreachable_patterns)]
match *self {
$(
$e::$x => serializer.serialize_str(stringify!($x)),
)*
_ => {
Err(S::Error::custom(format!("Cannot serialize {:?}", self)))
}
}
}
}
impl<'de> ::serde::de::Deserialize<'de> for $e {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where D: ::serde::Deserializer<'de> {
use serde::de::{Error, Visitor};
use std::marker::PhantomData;
use std::fmt;
struct StringOnly<T>(PhantomData<T>);
impl<'de, T> Visitor<'de> for StringOnly<T>
where T: ::serde::Deserializer<'de> {
type Value = String;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("string")
}
fn visit_str<E>(self, value: &str) -> Result<String, E> {
Ok(String::from(value))
}
}
let s = d.deserialize_string(StringOnly::<D>(PhantomData))?;
$(
if stringify!($x).eq_ignore_ascii_case(&s) {
return Ok($e::$x);
}
)*
static ALLOWED: &'static[&str] = &[$(stringify!($x),)*];
Err(D::Error::unknown_variant(&s, ALLOWED))
}
}
impl ::std::str::FromStr for $e {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
$(
if stringify!($x).eq_ignore_ascii_case(s) {
return Ok($e::$x);
}
)*
Err("Bad variant")
}
}
impl ::config::ConfigType for $e {
fn doc_hint() -> String {
let mut variants = Vec::new();
$(
variants.push(stringify!($x));
)*
format!("[{}]", variants.join("|"))
}
}
};
}
macro_rules! msg {
($($arg:tt)*) => (
match writeln!(&mut ::std::io::stderr(), $($arg)* ) {

View File

@ -12,6 +12,7 @@
use std::cmp;
use config::lists::*;
use syntax::ast;
use syntax::codemap::{BytePos, Span};
@ -19,8 +20,7 @@ use codemap::SpanUtils;
use comment::{combine_strs_with_missing_comments, contains_comment};
use expr::rewrite_field;
use items::{rewrite_struct_field, rewrite_struct_field_prefix};
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator,
SeparatorPlace};
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
use rewrite::{Rewrite, RewriteContext};
use shape::{Indent, Shape};
use spanned::Spanned;

View File

@ -10,6 +10,7 @@
use std::cmp;
use config::lists::*;
use syntax::{ast, visit};
use syntax::attr::{self, HasAttrs};
use syntax::codemap::{self, BytePos, CodeMap, Pos, Span};
@ -23,8 +24,7 @@ use config::{BraceStyle, Config};
use expr::rewrite_literal;
use items::{format_impl, format_trait, format_trait_alias, rewrite_associated_impl_type,
rewrite_associated_type, rewrite_type_alias, FnSig, StaticParts, StructParts};
use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorPlace,
SeparatorTactic};
use lists::{itemize_list, write_list, ListFormatting};
use macros::{rewrite_macro, rewrite_macro_def, MacroPosition};
use regex::Regex;
use rewrite::{Rewrite, RewriteContext};

View File

@ -8,14 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(rustc_private)]
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate regex;
extern crate rustfmt_nightly as rustfmt;
extern crate rustfmt_config as config;
extern crate rustfmt_core as rustfmt;
extern crate term;
use std::collections::HashMap;
@ -26,8 +25,10 @@ use std::path::{Path, PathBuf};
use std::str::Chars;
use rustfmt::*;
use rustfmt::config::{Color, Config, ReportTactic};
use rustfmt::filemap::{write_system_newlines, FileMap};
use config::{Color, Config, ReportTactic};
use config::summary::Summary;
use config::file_lines::FileLines;
use rustfmt::filemap::write_system_newlines;
use rustfmt::rustfmt_diff::*;
const DIFF_CONTEXT_SIZE: usize = 3;
@ -186,10 +187,26 @@ fn idempotence_tests() {
// no warnings are emitted.
#[test]
fn self_tests() {
let mut files = get_test_files(Path::new("src/bin"), false);
files.append(&mut get_test_files(Path::new("tests"), false));
files.push(PathBuf::from("src/lib.rs"));
files.push(PathBuf::from("build.rs"));
let mut files = get_test_files(Path::new("tests"), false);
let bin_directories = vec![
"cargo-fmt",
"git-rustfmt",
"rustfmt-bin",
"rustfmt-format-diff",
];
for dir in bin_directories {
let mut path = PathBuf::from("..");
path.push(dir);
path.push("src/main.rs");
files.push(path);
}
let lib_directories = vec!["rustfmt-core", "rustfmt-config"];
for dir in lib_directories {
let mut path = PathBuf::from("..");
path.push(dir);
path.push("src/lib.rs");
files.push(path);
}
let (reports, count, fails) = check_files(files);
let mut warnings = 0;

Some files were not shown because too many files have changed in this diff Show More