diff options
| author | Marcus Klaas de Vries <mail@marcusklaas.nl> | 2015-10-23 22:57:43 +0200 |
|---|---|---|
| committer | Marcus Klaas de Vries <mail@marcusklaas.nl> | 2015-10-23 22:57:43 +0200 |
| commit | 02c118ae7207c2d5a48a2b1cf5f6a59dbbe1d314 (patch) | |
| tree | f73c9f7d9e06fe9026de8a729da7dfbc7a63e2e8 /src | |
| parent | 7e76fad1f55945c196b32e6629ebaecc4ebfda74 (diff) | |
| parent | 7fdfff6e58cd30548b1d02946364b746243cdc02 (diff) | |
Merge pull request #523 from alexcrichton/stable
Move to stable Rust
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/rustfmt.rs | 86 | ||||
| -rw-r--r-- | src/chains.rs | 12 | ||||
| -rw-r--r-- | src/comment.rs | 2 | ||||
| -rw-r--r-- | src/lib.rs | 84 | ||||
| -rw-r--r-- | src/macros.rs | 54 | ||||
| -rw-r--r-- | src/utils.rs | 3 |
6 files changed, 89 insertions, 152 deletions
diff --git a/src/bin/rustfmt.rs b/src/bin/rustfmt.rs index 01c292948df..6b3405aa936 100644 --- a/src/bin/rustfmt.rs +++ b/src/bin/rustfmt.rs @@ -7,30 +7,32 @@ // <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. -#![feature(path_ext)] -#![feature(rustc_private)] + #![cfg(not(test))] #[macro_use] extern crate log; extern crate rustfmt; extern crate toml; +extern crate env_logger; +extern crate getopts; use rustfmt::{WriteMode, run}; use rustfmt::config::Config; use std::env; -use std::fs::{File, PathExt}; +use std::fs::{self, File}; use std::io::{self, Read}; use std::path::PathBuf; -use std::str::FromStr; + +use getopts::Options; // Try to find a project file in the current directory and its parents. fn lookup_project_file() -> io::Result<PathBuf> { let mut current = try!(env::current_dir()); loop { let config_file = current.join("rustfmt.toml"); - if config_file.exists() { + if fs::metadata(&config_file).is_ok() { return Ok(config_file); } else { current = match current.parent() { @@ -52,7 +54,7 @@ fn lookup_and_read_project_file() -> io::Result<(PathBuf, String)> { } fn execute() -> i32 { - let (args, write_mode) = match determine_params(std::env::args()) { + let (file, write_mode) = match determine_params(std::env::args().skip(1)) { Some(params) => params, None => return 1, }; @@ -65,12 +67,14 @@ fn execute() -> i32 { Err(_) => Default::default(), }; - run(args, write_mode, &config); + run(&file, write_mode, &config); 0 } fn main() { use std::io::Write; + let _ = env_logger::init(); + let exit_code = execute(); // Make sure standard output is flushed before we exit std::io::stdout().flush().unwrap(); @@ -81,50 +85,52 @@ fn main() { std::process::exit(exit_code); } -fn print_usage<S: Into<String>>(reason: S) { - println!("{}\n\r usage: rustfmt [-h Help] [--write-mode=[replace|overwrite|display|diff]] \ - <file_name>", - reason.into()); +fn print_usage(opts: &Options, reason: &str) { + let reason = format!("{}\nusage: {} [options] <file>", + reason, + env::current_exe().unwrap().display()); + println!("{}", opts.usage(&reason)); Config::print_docs(); } -fn determine_params<I>(args: I) -> Option<(Vec<String>, WriteMode)> +fn determine_params<I>(args: I) -> Option<(PathBuf, WriteMode)> where I: Iterator<Item = String> { - let arg_prefix = "-"; - let write_mode_prefix = "--write-mode="; - let help_mode = "-h"; - let long_help_mode = "--help"; - let mut write_mode = WriteMode::Replace; - let mut rustc_args = Vec::new(); - - // The NewFile option currently isn't supported because it requires another - // parameter, but it can be added later. - for arg in args { - if arg.starts_with(write_mode_prefix) { - match FromStr::from_str(&arg[write_mode_prefix.len()..]) { - Ok(mode) => write_mode = mode, - Err(_) => { - print_usage("Unrecognized write mode"); + let mut opts = Options::new(); + opts.optflag("h", "help", "show this message"); + opts.optopt("", + "write-mode", + "mode to write in", + "[replace|overwrite|display|diff]"); + let matches = match opts.parse(args) { + Ok(m) => m, + Err(e) => { + print_usage(&opts, &e.to_string()); + return None; + } + }; + + if matches.opt_present("h") { + print_usage(&opts, ""); + } + + let write_mode = match matches.opt_str("write-mode") { + Some(mode) => { + match mode.parse() { + Ok(mode) => mode, + Err(..) => { + print_usage(&opts, "Unrecognized write mode"); return None; } } - } else if arg.starts_with(help_mode) || arg.starts_with(long_help_mode) { - print_usage(""); - return None; - } else if arg.starts_with(arg_prefix) { - print_usage("Invalid argument"); - return None; - } else { - // Pass everything else to rustc - rustc_args.push(arg); } - } + None => WriteMode::Replace, + }; - if rustc_args.len() < 2 { - print_usage("Please provide a file to be formatted"); + if matches.free.len() != 1 { + print_usage(&opts, "Please provide one file to format"); return None; } - Some((rustc_args, write_mode)) + Some((PathBuf::from(&matches.free[0]), write_mode)) } diff --git a/src/chains.rs b/src/chains.rs index 4b6824a9073..4716f545b3f 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -72,11 +72,9 @@ pub fn rewrite_chain(mut expr: &ast::Expr, .collect::<Option<Vec<_>>>()); // Total of all items excluding the last. - let almost_total = rewrites.split_last() - .unwrap() - .1 - .iter() - .fold(0, |a, b| a + first_line_width(b)) + + let almost_total = rewrites[..rewrites.len() - 1] + .iter() + .fold(0, |a, b| a + first_line_width(b)) + parent_rewrite.len(); let total_width = almost_total + first_line_width(rewrites.last().unwrap()); let veto_single_line = if context.config.take_source_hints && subexpr_list.len() > 1 { @@ -95,7 +93,9 @@ pub fn rewrite_chain(mut expr: &ast::Expr, match subexpr_list[0].node { ast::Expr_::ExprMethodCall(ref method_name, ref types, ref expressions) if context.config.chains_overflow_last => { - let (last, init) = rewrites.split_last_mut().unwrap(); + let len = rewrites.len(); + let (init, last) = rewrites.split_at_mut(len - 1); + let last = &mut last[0]; if init.iter().all(|s| !s.contains('\n')) && total_width <= width { let last_rewrite = width.checked_sub(almost_total) diff --git a/src/comment.rs b/src/comment.rs index 045d1cb5047..091b4293ad3 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -437,7 +437,7 @@ mod test { } #[test] - #[rustfmt_skip] + #[cfg_attr(rustfmt, rustfmt_skip)] fn format_comments() { let config = Default::default(); assert_eq!("/* test */", rewrite_comment(" //test", true, 100, Indent::new(0, 100), diff --git a/src/lib.rs b/src/lib.rs index 03422a20c36..51497e3b1c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,13 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(rustc_private)] -#![feature(custom_attribute)] -#![feature(slice_splits)] -#![feature(slice_patterns)] -#![feature(catch_panic)] -#![allow(unused_attributes)] - // TODO we're going to allocate a whole bunch of temp Strings, is it worth // keeping some scratch mem for this and running our own StrPool? // TODO for lint violations of names, emit a refactor script @@ -22,10 +15,7 @@ #[macro_use] extern crate log; -extern crate getopts; -extern crate rustc; -extern crate rustc_driver; -extern crate syntax; +extern crate syntex_syntax as syntax; extern crate rustc_serialize; extern crate strings; @@ -35,22 +25,15 @@ extern crate regex; extern crate diff; extern crate term; -use rustc::session::Session; -use rustc::session::config as rustc_config; -use rustc::session::config::Input; -use rustc_driver::{driver, CompilerCalls, Compilation}; - use syntax::ast; use syntax::codemap::{CodeMap, Span}; -use syntax::diagnostics; +use syntax::parse::{self, ParseSess}; use std::ops::{Add, Sub}; -use std::path::PathBuf; +use std::path::Path; use std::collections::HashMap; use std::fmt; use std::str::FromStr; -use std::rc::Rc; -use std::cell::RefCell; use issues::{BadIssueSeeker, Issue}; use filemap::FileMap; @@ -387,65 +370,24 @@ pub fn fmt_lines(file_map: &mut FileMap, config: &Config) -> FormatReport { report } -struct RustFmtCalls { - config: Rc<Config>, - result: Rc<RefCell<Option<FileMap>>>, -} - -impl<'a> CompilerCalls<'a> for RustFmtCalls { - fn no_input(&mut self, - _: &getopts::Matches, - _: &rustc_config::Options, - _: &Option<PathBuf>, - _: &Option<PathBuf>, - _: &diagnostics::registry::Registry) - -> Option<(Input, Option<PathBuf>)> { - panic!("No input supplied to RustFmt"); - } - - fn build_controller(&mut self, _: &Session) -> driver::CompileController<'a> { - let result = self.result.clone(); - let config = self.config.clone(); - - let mut control = driver::CompileController::basic(); - control.after_parse.stop = Compilation::Stop; - control.after_parse.callback = Box::new(move |state| { - let krate = state.krate.unwrap(); - let codemap = state.session.codemap(); - let mut file_map = fmt_ast(krate, codemap, &*config); - // For some reason, the codemap does not include terminating - // newlines so we must add one on for each file. This is sad. - filemap::append_newlines(&mut file_map); - - *result.borrow_mut() = Some(file_map); - }); - - control - } -} - -pub fn format(args: Vec<String>, config: &Config) -> FileMap { - let result = Rc::new(RefCell::new(None)); +pub fn format(file: &Path, config: &Config) -> FileMap { + let parse_session = ParseSess::new(); + let krate = parse::parse_crate_from_file(file, Vec::new(), &parse_session); + let mut file_map = fmt_ast(&krate, parse_session.codemap(), config); - { - let config = Rc::new(config.clone()); - let mut call_ctxt = RustFmtCalls { - config: config, - result: result.clone(), - }; - rustc_driver::run_compiler(&args, &mut call_ctxt); - } + // For some reason, the codemap does not include terminating + // newlines so we must add one on for each file. This is sad. + filemap::append_newlines(&mut file_map); - // Peel the union. - Rc::try_unwrap(result).ok().unwrap().into_inner().unwrap() + return file_map; } // args are the arguments passed on the command line, generally passed through // to the compiler. // write_mode determines what happens to the result of running rustfmt, see // WriteMode. -pub fn run(args: Vec<String>, write_mode: WriteMode, config: &Config) { - let mut result = format(args, config); +pub fn run(file: &Path, write_mode: WriteMode, config: &Config) { + let mut result = format(file, config); println!("{}", fmt_lines(&mut result, config)); diff --git a/src/macros.rs b/src/macros.rs index 9035b0c7d8b..bede00d6e9e 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -19,8 +19,6 @@ // List-like invocations with parentheses will be formatted as function calls, // and those with brackets will be formatted as array literals. -use std::thread; - use syntax::ast; use syntax::parse::token::{Eof, Comma, Token}; use syntax::parse::{ParseSess, tts_to_parser}; @@ -34,12 +32,6 @@ use utils::{wrap_str, span_after}; static FORCED_BRACKET_MACROS: &'static [&'static str] = &["vec!"]; -// We need to pass `TokenTree`s to our expression parsing thread, but they are -// not `Send`. We wrap them in a `Send` container to force our will. -// FIXME: this is a pretty terrible hack. Any other solution would be preferred. -struct ForceSend<T>(pub T); -unsafe impl<T> Send for ForceSend<T> {} - // FIXME: use the enum from libsyntax? #[derive(Clone, Copy)] enum MacroStyle { @@ -81,34 +73,28 @@ pub fn rewrite_macro(mac: &ast::Mac, }; } - let wrapped_tt_vec = ForceSend(mac.node.tts.clone()); - // Wrap expression parsing logic in a thread since the libsyntax parser - // panics on failure, which we do not want to propagate. - // The expression vector is wrapped in an Option inside a Result. - let expr_vec_result = thread::catch_panic(move || { - let parse_session = ParseSess::new(); - let mut parser = tts_to_parser(&parse_session, wrapped_tt_vec.0, vec![]); - let mut expr_vec = vec![]; - - loop { - expr_vec.push(parser.parse_expr()); - - match parser.token { - Token::Eof => break, - Token::Comma => (), - _ => panic!("Macro not list-like, skiping..."), - } - - let _ = parser.bump(); - - if parser.token == Token::Eof { - return None; - } + let parse_session = ParseSess::new(); + let mut parser = tts_to_parser(&parse_session, mac.node.tts.clone(), Vec::new()); + let mut expr_vec = Vec::new(); + + loop { + expr_vec.push(match parser.parse_expr_nopanic() { + Ok(expr) => expr, + Err(..) => return None, + }); + + match parser.token { + Token::Eof => break, + Token::Comma => (), + _ => return None, } - Some(expr_vec) - }); - let expr_vec = try_opt!(try_opt!(expr_vec_result.ok())); + let _ = parser.bump(); + + if parser.token == Token::Eof { + return None; + } + } match style { MacroStyle::Parens => { diff --git a/src/utils.rs b/src/utils.rs index 0fd749a5471..fea385532d0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -75,6 +75,9 @@ pub fn last_line_width(s: &str) -> usize { fn is_skip(meta_item: &MetaItem) -> bool { match meta_item.node { MetaItem_::MetaWord(ref s) => *s == SKIP_ANNOTATION, + MetaItem_::MetaList(ref s, ref l) => { + *s == "cfg_attr" && l.len() == 2 && is_skip(&l[1]) + } _ => false, } } |
