From 178a339fc3eb97480952a73e9409ba2e5d079f3d Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 15 Sep 2017 22:31:52 +0900 Subject: [PATCH] Reorder use items inside blocks --- src/imports.rs | 6 +++--- src/visitor.rs | 55 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/imports.rs b/src/imports.rs index 7cfe5d8b6b98..ecfd091a43d2 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -10,7 +10,7 @@ use std::cmp::Ordering; -use syntax::{ast, ptr}; +use syntax::ast; use syntax::codemap::{BytePos, Span}; use {Shape, Spanned}; @@ -216,7 +216,7 @@ fn rewrite_import( fn rewrite_imports( context: &RewriteContext, - use_items: &[ptr::P], + use_items: &[&ast::Item], shape: Shape, span: Span, ) -> Option { @@ -275,7 +275,7 @@ fn rewrite_imports( } impl<'a> FmtVisitor<'a> { - pub fn format_imports(&mut self, use_items: &[ptr::P]) { + pub fn format_imports(&mut self, use_items: &[&ast::Item]) { if use_items.is_empty() { return; } diff --git a/src/visitor.rs b/src/visitor.rs index 832883c2c3e4..46998bd78c4b 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -11,7 +11,7 @@ use std::cmp; use strings::string_buffer::StringBuffer; -use syntax::{ast, ptr, visit}; +use syntax::{ast, visit}; use syntax::attr::HasAttrs; use syntax::codemap::{self, BytePos, CodeMap, Pos, Span}; use syntax::parse::ParseSess; @@ -30,7 +30,7 @@ use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, Sepa use macros::{rewrite_macro, MacroPosition}; use regex::Regex; use rewrite::{Rewrite, RewriteContext}; -use utils::{self, contains_skip, inner_attributes, mk_sp}; +use utils::{self, contains_skip, inner_attributes, mk_sp, ptr_vec_to_ref_vec}; fn is_use_item(item: &ast::Item) -> bool { match item.node { @@ -152,9 +152,7 @@ impl<'a> FmtVisitor<'a> { self.visit_attrs(attrs, ast::AttrStyle::Inner); } - for stmt in &b.stmts { - self.visit_stmt(stmt) - } + self.walk_block_stmts(b); if !b.stmts.is_empty() { if let Some(expr) = utils::stmt_expr(&b.stmts[b.stmts.len() - 1]) { @@ -641,12 +639,7 @@ impl<'a> FmtVisitor<'a> { false } - fn reorder_items( - &mut self, - items_left: &[ptr::P], - is_item: &F, - in_group: bool, - ) -> usize + fn reorder_items(&mut self, items_left: &[&ast::Item], is_item: &F, in_group: bool) -> usize where F: Fn(&ast::Item) -> bool, { @@ -679,8 +672,7 @@ impl<'a> FmtVisitor<'a> { item_length } - fn walk_mod_items(&mut self, m: &ast::Mod) { - let mut items_left: &[ptr::P] = &m.items; + fn walk_items(&mut self, mut items_left: &[&ast::Item]) { while !items_left.is_empty() { // If the next item is a `use` declaration, then extract it and any subsequent `use`s // to be potentially reordered within `format_imports`. Otherwise, just format the @@ -711,6 +703,43 @@ impl<'a> FmtVisitor<'a> { } } + fn walk_mod_items(&mut self, m: &ast::Mod) { + self.walk_items(&ptr_vec_to_ref_vec(&m.items)); + } + + fn walk_stmts(&mut self, stmts: &[ast::Stmt]) { + fn to_stmt_item(stmt: &ast::Stmt) -> Option<&ast::Item> { + match stmt.node { + ast::StmtKind::Item(ref item) => Some(&**item), + _ => None, + } + } + + if stmts.is_empty() { + return; + } + + // Extract leading `use ...;`. + let items: Vec<_> = stmts + .iter() + .take_while(|stmt| to_stmt_item(stmt).is_some()) + .filter_map(|stmt| to_stmt_item(stmt)) + .take_while(|item| is_use_item(item)) + .collect(); + + if items.is_empty() { + self.visit_stmt(&stmts[0]); + self.walk_stmts(&stmts[1..]); + } else { + self.walk_items(&items); + self.walk_stmts(&stmts[items.len()..]); + } + } + + fn walk_block_stmts(&mut self, b: &ast::Block) { + self.walk_stmts(&b.stmts) + } + fn format_mod( &mut self, m: &ast::Mod,