From 5b5927996f9c78e16d75235d5953d072757c8bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Cassiers?= Date: Sat, 1 Aug 2015 15:02:59 +0200 Subject: [PATCH] Kill ChangeSet and replace remaining part by FileMap Also fix style issues Cargo update to get fixes of strings.rs (was cause of a misformatted function call). --- Cargo.lock | 22 +++--- src/changes.rs | 170 -------------------------------------------- src/filemap.rs | 113 +++++++++++++++++++++++++++++ src/lib.rs | 30 ++++---- src/missed_spans.rs | 4 +- src/modules.rs | 6 +- 6 files changed, 144 insertions(+), 201 deletions(-) delete mode 100644 src/changes.rs create mode 100644 src/filemap.rs diff --git a/Cargo.lock b/Cargo.lock index 97593cfad4c..82dbafd47d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,16 +2,16 @@ name = "rustfmt" version = "0.0.1" dependencies = [ - "diff 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "diff 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "strings 0.0.1 (git+https://github.com/nrc/strings.rs.git)", - "toml 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "aho-corasick" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -19,7 +19,7 @@ dependencies = [ [[package]] name = "diff" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -37,17 +37,17 @@ dependencies = [ [[package]] name = "regex" -version = "0.1.38" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.1.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -58,11 +58,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "strings" version = "0.0.1" -source = "git+https://github.com/nrc/strings.rs.git#b7f37c4545b7dba24fb28161cd9c405fae978be4" +source = "git+https://github.com/nrc/strings.rs.git#6d748148fbe3bf2d9e5ac2ede65ac503d7491a4f" [[package]] name = "toml" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/changes.rs b/src/changes.rs deleted file mode 100644 index ab758f71d95..00000000000 --- a/src/changes.rs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2015 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -// TODO -// print to files -// tests - -use strings::string_buffer::StringBuffer; -use std::collections::HashMap; -use std::fmt; -use std::fs::File; -use std::io::{Write, stdout}; -use WriteMode; -use NewlineStyle; -use config::Config; - -// This is basically a wrapper around a bunch of Ropes which makes it convenient -// to work with libsyntax. It is badly named. -pub struct ChangeSet { - pub file_map: HashMap, -} - -impl ChangeSet { - // Create a new ChangeSet for a given libsyntax CodeMap. - pub fn new() -> ChangeSet { - ChangeSet { file_map: HashMap::new() } - } - - // Fetch a mutable reference to the output buffer for the given file name. - // Panics on unknown files. - pub fn get_mut(&mut self, file_name: &str) -> &mut StringBuffer { - self.file_map.get_mut(file_name).unwrap() - } - - // Return an iterator over the entire changed text. - pub fn text<'c>(&'c self) -> FileIterator<'c> { - FileIterator { change_set: self, keys: self.file_map.keys().collect(), cur_key: 0 } - } - - // Append a newline to the end of each file. - pub fn append_newlines(&mut self) { - for (_, s) in self.file_map.iter_mut() { - s.push_str("\n"); - } - } - - pub fn write_all_files(&self, - mode: WriteMode, - config: &Config) - -> Result<(HashMap), ::std::io::Error> { - let mut result = HashMap::new(); - for filename in self.file_map.keys() { - let one_result = try!(self.write_file(filename, mode, config)); - if let Some(r) = one_result { - result.insert(filename.clone(), r); - } - } - - Ok(result) - } - - pub fn write_file(&self, - filename: &str, - mode: WriteMode, - config: &Config) - -> Result, ::std::io::Error> { - let text = &self.file_map[filename]; - - // prints all newlines either as `\n` or as `\r\n` - fn write_system_newlines(mut writer: T, - text: &StringBuffer, - config: &Config) - -> Result<(), ::std::io::Error> - where T: Write - { - match config.newline_style { - NewlineStyle::Unix => write!(writer, "{}", text), - NewlineStyle::Windows => { - for (c, _) in text.chars() { - match c { - '\n' => try!(write!(writer, "\r\n")), - '\r' => continue, - c => try!(write!(writer, "{}", c)), - } - } - Ok(()) - }, - } - } - - match mode { - WriteMode::Overwrite => { - // Do a little dance to make writing safer - write to a temp file - // rename the original to a .bk, then rename the temp file to the - // original. - let tmp_name = filename.to_owned() + ".tmp"; - let bk_name = filename.to_owned() + ".bk"; - { - // Write text to temp file - let tmp_file = try!(File::create(&tmp_name)); - try!(write_system_newlines(tmp_file, text, config)); - } - - try!(::std::fs::rename(filename, bk_name)); - try!(::std::fs::rename(tmp_name, filename)); - } - WriteMode::NewFile(extn) => { - let filename = filename.to_owned() + "." + extn; - let file = try!(File::create(&filename)); - try!(write_system_newlines(file, text, config)); - } - WriteMode::Display => { - println!("{}:\n", filename); - let stdout = stdout(); - let stdout_lock = stdout.lock(); - try!(write_system_newlines(stdout_lock, text, config)); - } - WriteMode::Return(_) => { - // io::Write is not implemented for String, working around with Vec - let mut v = Vec::new(); - try!(write_system_newlines(&mut v, text, config)); - // won't panic, we are writing correct utf8 - return Ok(Some(String::from_utf8(v).unwrap())); - } - } - - Ok(None) - } -} - -// Iterates over each file in the ChangSet. Yields the filename and the changed -// text for that file. -pub struct FileIterator<'c> { - change_set: &'c ChangeSet, - keys: Vec<&'c String>, - cur_key: usize, -} - -impl<'c> Iterator for FileIterator<'c> { - type Item = (&'c str, &'c StringBuffer); - - fn next(&mut self) -> Option<(&'c str, &'c StringBuffer)> { - if self.cur_key >= self.keys.len() { - return None; - } - - let key = self.keys[self.cur_key]; - self.cur_key += 1; - return Some((&key, &self.change_set.file_map[&*key])) - } -} - -impl fmt::Display for ChangeSet { - // Prints the entire changed text. - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - for (f, r) in self.text() { - try!(write!(fmt, "{}:\n", f)); - try!(write!(fmt, "{}\n\n", r)); - } - Ok(()) - } -} diff --git a/src/filemap.rs b/src/filemap.rs new file mode 100644 index 00000000000..750bea9b862 --- /dev/null +++ b/src/filemap.rs @@ -0,0 +1,113 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +// TODO tests + +use strings::string_buffer::StringBuffer; +use std::collections::HashMap; +use std::fs::File; +use std::io::{Write, stdout}; +use WriteMode; +use NewlineStyle; +use config::Config; + +// A map of the files of a crate, with their new content +pub type FileMap = HashMap; + +// Append a newline to the end of each file. +pub fn append_newlines(file_map: &mut FileMap) { + for (_, s) in file_map.iter_mut() { + s.push_str("\n"); + } +} + +pub fn write_all_files(file_map: &FileMap, + mode: WriteMode, + config: &Config) + -> Result<(HashMap), ::std::io::Error> { + let mut result = HashMap::new(); + for filename in file_map.keys() { + let one_result = try!(write_file(file_map, filename, mode, config)); + if let Some(r) = one_result { + result.insert(filename.clone(), r); + } + } + + Ok(result) +} + +fn write_file(file_map: &FileMap, + filename: &str, + mode: WriteMode, + config: &Config) + -> Result, ::std::io::Error> { + let text = &file_map[filename]; + + // prints all newlines either as `\n` or as `\r\n` + fn write_system_newlines(mut writer: T, + text: &StringBuffer, + config: &Config) + -> Result<(), ::std::io::Error> + where T: Write + { + match config.newline_style { + NewlineStyle::Unix => write!(writer, "{}", text), + NewlineStyle::Windows => { + for (c, _) in text.chars() { + match c { + '\n' => try!(write!(writer, "\r\n")), + '\r' => continue, + c => try!(write!(writer, "{}", c)), + } + } + Ok(()) + }, + } + } + + match mode { + WriteMode::Overwrite => { + // Do a little dance to make writing safer - write to a temp file + // rename the original to a .bk, then rename the temp file to the + // original. + let tmp_name = filename.to_owned() + ".tmp"; + let bk_name = filename.to_owned() + ".bk"; + { + // Write text to temp file + let tmp_file = try!(File::create(&tmp_name)); + try!(write_system_newlines(tmp_file, text, config)); + } + + try!(::std::fs::rename(filename, bk_name)); + try!(::std::fs::rename(tmp_name, filename)); + } + WriteMode::NewFile(extn) => { + let filename = filename.to_owned() + "." + extn; + let file = try!(File::create(&filename)); + try!(write_system_newlines(file, text, config)); + } + WriteMode::Display => { + println!("{}:\n", filename); + let stdout = stdout(); + let stdout_lock = stdout.lock(); + try!(write_system_newlines(stdout_lock, text, config)); + } + WriteMode::Return(_) => { + // io::Write is not implemented for String, working around with Vec + let mut v = Vec::new(); + try!(write_system_newlines(&mut v, text, config)); + // won't panic, we are writing correct utf8 + return Ok(Some(String::from_utf8(v).unwrap())); + } + } + + Ok(None) +} diff --git a/src/lib.rs b/src/lib.rs index f25e323504e..c0aff9a05b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,14 +44,14 @@ use std::fmt; use std::mem::swap; use issues::{BadIssueSeeker, Issue}; -use changes::ChangeSet; +use filemap::FileMap; use visitor::FmtVisitor; use config::Config; #[macro_use] mod utils; pub mod config; -mod changes; +mod filemap; mod visitor; mod items; mod missed_spans; @@ -196,26 +196,26 @@ impl fmt::Display for FormatReport { } // Formatting which depends on the AST. -fn fmt_ast(krate: &ast::Crate, codemap: &CodeMap, config: &Config) -> ChangeSet { - let mut changes = ChangeSet::new(); - for (path, module) in modules::list_modules(krate, codemap) { +fn fmt_ast(krate: &ast::Crate, codemap: &CodeMap, config: &Config) -> FileMap { + let mut file_map = FileMap::new(); + for (path, module) in modules::list_files(krate, codemap) { let path = path.to_str().unwrap(); let mut visitor = FmtVisitor::from_codemap(codemap, config); visitor.format_separate_mod(module, path); - changes.file_map.insert(path.to_owned(), visitor.buffer); + file_map.insert(path.to_owned(), visitor.buffer); } - changes + file_map } // Formatting done on a char by char or line by line basis. // TODO warn on bad license // TODO other stuff for parity with make tidy -fn fmt_lines(changes: &mut ChangeSet, config: &Config) -> FormatReport { +fn fmt_lines(file_map: &mut FileMap, config: &Config) -> FormatReport { let mut truncate_todo = Vec::new(); let mut report = FormatReport { file_error_map: HashMap::new() }; - // Iterate over the chars in the change set. - for (f, text) in changes.text() { + // Iterate over the chars in the file map. + for (f, text) in file_map.iter() { let mut trims = vec![]; let mut last_wspace: Option = None; let mut line_len = 0; @@ -283,7 +283,7 @@ fn fmt_lines(changes: &mut ChangeSet, config: &Config) -> FormatReport { } for (f, l) in truncate_todo { - changes.get_mut(&f).truncate(l); + file_map.get_mut(&f).unwrap().truncate(l); } report @@ -317,13 +317,13 @@ impl<'a> CompilerCalls<'a> for RustFmtCalls { control.after_parse.callback = Box::new(move |state| { let krate = state.krate.unwrap(); let codemap = state.session.codemap(); - let mut changes = fmt_ast(krate, codemap, &*config); + 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. - changes.append_newlines(); - println!("{}", fmt_lines(&mut changes, &*config)); + filemap::append_newlines(&mut file_map); + println!("{}", fmt_lines(&mut file_map, &*config)); - let result = changes.write_all_files(write_mode, &*config); + let result = filemap::write_all_files(&file_map, write_mode, &*config); match result { Err(msg) => println!("Error writing files: {}", msg), diff --git a/src/missed_spans.rs b/src/missed_spans.rs index 2f1a014a6e8..64025550410 100644 --- a/src/missed_spans.rs +++ b/src/missed_spans.rs @@ -57,8 +57,8 @@ impl<'a> FmtVisitor<'a> { let snippet = self.snippet(span); self.write_snippet(&snippet, - true, - &process_last_snippet); + true, + &process_last_snippet); } fn write_snippet(&mut self, diff --git a/src/modules.rs b/src/modules.rs index 6b3c223a4ff..2f40fd33a55 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -20,9 +20,9 @@ use syntax::parse::parser; /// List all the files containing modules of a crate. /// If a file is used twice in a crate, it appears only once. -pub fn list_modules<'a>(krate: &'a ast::Crate, - codemap: &codemap::CodeMap) - -> HashMap { +pub fn list_files<'a>(krate: &'a ast::Crate, + codemap: &codemap::CodeMap) + -> HashMap { let mut result = HashMap::new(); let root_filename: PathBuf = codemap.span_to_filename(krate.span).into(); list_submodules(&krate.module, root_filename.parent().unwrap(), codemap, &mut result);