Separate modules and files listing of reformatting
As suggested in #141 Closes #156
This commit is contained in:
parent
bc43b81200
commit
0e10329dc7
@ -216,10 +216,6 @@ fn write_system_newlines<T>(mut writer: T,
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn is_changed(&self, filename: &str) -> bool {
|
||||
self.file_map.get(filename).expect("Unknown filename").len != 0
|
||||
}
|
||||
}
|
||||
|
||||
// Iterates over each file in the ChangSet. Yields the filename and the changed
|
||||
|
@ -37,7 +37,6 @@
|
||||
use syntax::ast;
|
||||
use syntax::codemap::CodeMap;
|
||||
use syntax::diagnostics;
|
||||
use syntax::visit;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::collections::HashMap;
|
||||
@ -64,6 +63,7 @@
|
||||
mod rewrite;
|
||||
mod string;
|
||||
mod comment;
|
||||
mod modules;
|
||||
|
||||
const MIN_STRING: usize = 10;
|
||||
// When we get scoped annotations, we should have rustfmt::skip.
|
||||
@ -198,7 +198,9 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
// Formatting which depends on the AST.
|
||||
fn fmt_ast<'a>(krate: &ast::Crate, codemap: &'a CodeMap, config: &'a Config) -> ChangeSet<'a> {
|
||||
let mut visitor = FmtVisitor::from_codemap(codemap, config);
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
for (path, module) in modules::list_modules(krate, codemap) {
|
||||
visitor.format_separate_mod(module, path.to_str().unwrap());
|
||||
}
|
||||
visitor.changes
|
||||
}
|
||||
|
||||
|
73
src/modules.rs
Normal file
73
src/modules.rs
Normal file
@ -0,0 +1,73 @@
|
||||
// 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 <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 utils;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::parse::{parser, token};
|
||||
|
||||
|
||||
/// 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<PathBuf, &'a ast::Mod> {
|
||||
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);
|
||||
result.insert(root_filename, &krate.module);
|
||||
result
|
||||
}
|
||||
|
||||
/// Recursively list all external modules included in a module.
|
||||
fn list_submodules<'a>(module: &'a ast::Mod,
|
||||
search_dir: &Path,
|
||||
codemap: &codemap::CodeMap,
|
||||
result: &mut HashMap<PathBuf, &'a ast::Mod>) {
|
||||
debug!("list_submodules: search_dir: {:?}", search_dir);
|
||||
for item in module.items.iter() {
|
||||
if let ast::ItemMod(ref sub_mod) = item.node {
|
||||
if !utils::contains_skip(&item.attrs) {
|
||||
let is_internal = codemap.span_to_filename(item.span) ==
|
||||
codemap.span_to_filename(sub_mod.inner);
|
||||
let dir_path = if is_internal {
|
||||
let dir: &str = &token::get_ident(item.ident);
|
||||
search_dir.join(dir)
|
||||
} else {
|
||||
let mod_path = module_file(item.ident, &item.attrs, search_dir, codemap);
|
||||
let dir_path = mod_path.parent().unwrap().to_owned();
|
||||
result.insert(mod_path, sub_mod);
|
||||
dir_path
|
||||
};
|
||||
list_submodules(sub_mod, &dir_path, codemap, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the file corresponding to an external mod
|
||||
fn module_file(id: ast::Ident,
|
||||
attrs: &[ast::Attribute],
|
||||
dir_path: &Path,
|
||||
codemap: &codemap::CodeMap)
|
||||
-> PathBuf {
|
||||
if let Some(path) = parser::Parser::submod_path_from_attr(attrs, &dir_path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
match parser::Parser::default_submod_path(id, &dir_path, codemap).result {
|
||||
Ok(parser::ModulePathSuccess { path, .. }) => path,
|
||||
Err(_) => panic!("Couldn't find module {}", token::get_ident(id))
|
||||
}
|
||||
}
|
@ -11,8 +11,6 @@
|
||||
use syntax::ast;
|
||||
use syntax::codemap::{self, CodeMap, Span, BytePos};
|
||||
use syntax::visit;
|
||||
use syntax::parse::parser;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use utils;
|
||||
use config::Config;
|
||||
@ -197,7 +195,7 @@ fn visit_item(&mut self, item: &'v ast::Item) {
|
||||
}
|
||||
ast::Item_::ItemMod(ref module) => {
|
||||
self.format_missing_with_indent(item.span.lo);
|
||||
self.format_mod(module, item.span, item.ident, &item.attrs);
|
||||
self.format_mod(module, item.span, item.ident);
|
||||
}
|
||||
_ => {
|
||||
visit::walk_item(self, item);
|
||||
@ -237,12 +235,6 @@ fn visit_impl_item(&mut self, ii: &'v ast::ImplItem) {
|
||||
fn visit_mac(&mut self, mac: &'v ast::Mac) {
|
||||
visit::walk_mac(self, mac)
|
||||
}
|
||||
|
||||
fn visit_mod(&mut self, m: &'v ast::Mod, s: Span, _: ast::NodeId) {
|
||||
// This is only called for the root module
|
||||
let filename = self.codemap.span_to_filename(s);
|
||||
self.format_separate_mod(m, &filename);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FmtVisitor<'a> {
|
||||
@ -322,7 +314,7 @@ pub fn rewrite_attrs(&self, attrs: &[ast::Attribute], indent: usize) -> String {
|
||||
result
|
||||
}
|
||||
|
||||
fn format_mod(&mut self, m: &ast::Mod, s: Span, ident: ast::Ident, attrs: &[ast::Attribute]) {
|
||||
fn format_mod(&mut self, m: &ast::Mod, s: Span, ident: ast::Ident) {
|
||||
debug!("FmtVisitor::format_mod: ident: {:?}, span: {:?}", ident, s);
|
||||
|
||||
// Decide whether this is an inline mod or an external mod.
|
||||
@ -337,49 +329,15 @@ fn format_mod(&mut self, m: &ast::Mod, s: Span, ident: ast::Ident, attrs: &[ast:
|
||||
visit::walk_mod(self, m);
|
||||
debug!("... last_pos after: {:?}", self.last_pos);
|
||||
self.block_indent -= self.config.tab_spaces;
|
||||
} else {
|
||||
debug!("FmtVisitor::format_mod: external mod");
|
||||
let file_path = self.module_file(ident, attrs, local_file_name);
|
||||
let filename = file_path.to_str().unwrap();
|
||||
if self.changes.is_changed(filename) {
|
||||
// The file has already been reformatted, do nothing
|
||||
} else {
|
||||
self.format_separate_mod(m, filename);
|
||||
}
|
||||
}
|
||||
|
||||
debug!("FmtVisitor::format_mod: exit");
|
||||
}
|
||||
|
||||
/// Find the file corresponding to an external mod
|
||||
fn module_file(&self, id: ast::Ident, attrs: &[ast::Attribute], filename: String) -> PathBuf {
|
||||
let dir_path = {
|
||||
let mut path = PathBuf::from(&filename);
|
||||
path.pop();
|
||||
path
|
||||
};
|
||||
|
||||
if let Some(path) = parser::Parser::submod_path_from_attr(attrs, &dir_path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
match parser::Parser::default_submod_path(id, &dir_path, &self.codemap).result {
|
||||
Ok(parser::ModulePathSuccess { path, .. }) => path,
|
||||
_ => panic!("Couldn't find module {}", id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Format the content of a module into a separate file
|
||||
fn format_separate_mod(&mut self, m: &ast::Mod, filename: &str) {
|
||||
let last_pos = self.last_pos;
|
||||
let block_indent = self.block_indent;
|
||||
pub fn format_separate_mod(&mut self, m: &ast::Mod, filename: &str) {
|
||||
let filemap = self.codemap.get_filemap(filename);
|
||||
self.last_pos = filemap.start_pos;
|
||||
self.block_indent = 0;
|
||||
visit::walk_mod(self, m);
|
||||
self.format_missing(filemap.end_pos);
|
||||
self.last_pos = last_pos;
|
||||
self.block_indent = block_indent;
|
||||
}
|
||||
|
||||
fn format_import(&mut self, vis: ast::Visibility, vp: &ast::ViewPath, span: Span) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
mod mymod1 {
|
||||
use mod2a::{Foo,Bar};
|
||||
mod mod3a;
|
||||
}
|
||||
|
||||
#[path="mod2c.rs"]
|
||||
|
2
tests/source/nestedmod/mymod1/mod3a.rs
Normal file
2
tests/source/nestedmod/mymod1/mod3a.rs
Normal file
@ -0,0 +1,2 @@
|
||||
// Another mod
|
||||
fn a( ) { }
|
@ -4,6 +4,7 @@
|
||||
|
||||
mod mymod1 {
|
||||
use mod2a::{Foo, Bar};
|
||||
mod mod3a;
|
||||
}
|
||||
|
||||
#[path="mod2c.rs"]
|
||||
|
3
tests/target/nestedmod/mymod1/mod3a.rs
Normal file
3
tests/target/nestedmod/mymod1/mod3a.rs
Normal file
@ -0,0 +1,3 @@
|
||||
// Another mod
|
||||
fn a() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user