]> git.lizzy.rs Git - rust.git/blobdiff - src/reorder.rs
rewrite_string: retain blank lines that are trailing
[rust.git] / src / reorder.rs
index e4065146cc6881bfb5e0c08722168ea9f12608fc..f990e68656590a601c07d82a0db0cbea6237b641 100644 (file)
 //! order. Trait items are reordered in pre-determined order (associated types
 //! and constants comes before methods).
 
-// TODO(#2455): Reorder trait items.
+// FIXME(#2455): Reorder trait items.
 
-use config::{lists::*, Config};
-use syntax::{ast, attr, codemap::Span};
+use config::Config;
+use syntax::{ast, attr, source_map::Span};
 
 use attr::filter_inline_attrs;
-use codemap::LineRangeUtils;
 use comment::combine_strs_with_missing_comments;
-use imports::UseTree;
+use imports::{merge_use_trees, UseTree};
 use items::{is_mod_decl, rewrite_extern_crate, rewrite_mod};
 use lists::{itemize_list, write_list, ListFormatting, ListItem};
 use rewrite::{Rewrite, RewriteContext};
 use shape::Shape;
+use source_map::LineRangeUtils;
 use spanned::Spanned;
 use utils::mk_sp;
 use visitor::FmtVisitor;
@@ -69,17 +69,7 @@ fn wrap_reorderable_items(
     list_items: &[ListItem],
     shape: Shape,
 ) -> Option<String> {
-    let fmt = ListFormatting {
-        tactic: DefinitiveListTactic::Vertical,
-        separator: "",
-        trailing_separator: SeparatorTactic::Never,
-        separator_place: SeparatorPlace::Back,
-        shape,
-        ends_with_newline: true,
-        preserve_newline: false,
-        config: context.config,
-    };
-
+    let fmt = ListFormatting::new(shape, context.config).separator("");
     write_list(list_items, &fmt)
 }
 
@@ -99,7 +89,7 @@ fn rewrite_reorderable_item(
 
     let item_str = match item.node {
         ast::ItemKind::ExternCrate(..) => rewrite_extern_crate(context, item)?,
-        ast::ItemKind::Mod(..) => rewrite_mod(item),
+        ast::ItemKind::Mod(..) => rewrite_mod(context, item),
         _ => return None,
     };
 
@@ -117,29 +107,41 @@ fn rewrite_reorderable_items(
     match reorderable_items[0].node {
         // FIXME: Remove duplicated code.
         ast::ItemKind::Use(..) => {
-            let normalized_items: Vec<_> = reorderable_items
+            let mut normalized_items: Vec<_> = reorderable_items
                 .iter()
                 .filter_map(|item| UseTree::from_ast_with_normalization(context, item))
                 .collect();
-
-            // 4 = "use ", 1 = ";"
-            let nested_shape = shape.offset_left(4)?.sub_width(1)?;
+            let cloned = normalized_items.clone();
+            // Add comments before merging.
             let list_items = itemize_list(
                 context.snippet_provider,
-                normalized_items.iter(),
+                cloned.iter(),
                 "",
                 ";",
-                |item| item.span.lo(),
-                |item| item.span.hi(),
-                |item| item.rewrite_top_level(context, nested_shape),
+                |item| item.span().lo(),
+                |item| item.span().hi(),
+                |_item| Some("".to_owned()),
                 span.lo(),
                 span.hi(),
                 false,
             );
+            for (item, list_item) in normalized_items.iter_mut().zip(list_items) {
+                item.list_item = Some(list_item.clone());
+            }
+            if context.config.merge_imports() {
+                normalized_items = merge_use_trees(normalized_items);
+            }
+            normalized_items.sort();
 
-            let mut item_pair_vec: Vec<_> = list_items.zip(&normalized_items).collect();
-            item_pair_vec.sort_by(|a, b| a.1.cmp(b.1));
-            let item_vec: Vec<_> = item_pair_vec.into_iter().map(|pair| pair.0).collect();
+            // 4 = "use ", 1 = ";"
+            let nested_shape = shape.offset_left(4)?.sub_width(1)?;
+            let item_vec: Vec<_> = normalized_items
+                .into_iter()
+                .map(|use_tree| ListItem {
+                    item: use_tree.rewrite_top_level(context, nested_shape),
+                    ..use_tree.list_item.unwrap_or_else(ListItem::empty)
+                })
+                .collect();
 
             wrap_reorderable_items(context, &item_vec, nested_shape)
         }
@@ -182,7 +184,7 @@ enum ReorderableItemKind {
 }
 
 impl ReorderableItemKind {
-    pub fn from(item: &ast::Item) -> Self {
+    fn from(item: &ast::Item) -> Self {
         match item.node {
             _ if contains_macro_use_attr(item) => ReorderableItemKind::Other,
             ast::ItemKind::ExternCrate(..) => ReorderableItemKind::ExternCrate,
@@ -192,12 +194,12 @@ pub fn from(item: &ast::Item) -> Self {
         }
     }
 
-    pub fn is_same_item_kind(&self, item: &ast::Item) -> bool {
-        ReorderableItemKind::from(item) == *self
+    fn is_same_item_kind(self, item: &ast::Item) -> bool {
+        ReorderableItemKind::from(item) == self
     }
 
-    pub fn is_reorderable(&self, config: &Config) -> bool {
-        match *self {
+    fn is_reorderable(self, config: &Config) -> bool {
+        match self {
             ReorderableItemKind::ExternCrate => config.reorder_imports(),
             ReorderableItemKind::Mod => config.reorder_modules(),
             ReorderableItemKind::Use => config.reorder_imports(),
@@ -205,11 +207,11 @@ pub fn is_reorderable(&self, config: &Config) -> bool {
         }
     }
 
-    pub fn in_group(&self) -> bool {
-        match *self {
-            ReorderableItemKind::ExternCrate => true,
-            ReorderableItemKind::Mod => true,
-            ReorderableItemKind::Use => true,
+    fn in_group(self) -> bool {
+        match self {
+            ReorderableItemKind::ExternCrate
+            | ReorderableItemKind::Mod
+            ReorderableItemKind::Use => true,
             ReorderableItemKind::Other => false,
         }
     }
@@ -225,16 +227,17 @@ fn walk_reorderable_items(
         item_kind: ReorderableItemKind,
         in_group: bool,
     ) -> usize {
-        let mut last = self.codemap.lookup_line_range(items[0].span());
+        let mut last = self.source_map.lookup_line_range(items[0].span());
         let item_length = items
             .iter()
             .take_while(|ppi| {
-                item_kind.is_same_item_kind(&***ppi) && (!in_group || {
-                    let current = self.codemap.lookup_line_range(ppi.span());
-                    let in_same_group = current.lo < last.hi + 2;
-                    last = current;
-                    in_same_group
-                })
+                item_kind.is_same_item_kind(&***ppi)
+                    && (!in_group || {
+                        let current = self.source_map.lookup_line_range(ppi.span());
+                        let in_same_group = current.lo < last.hi + 2;
+                        last = current;
+                        in_same_group
+                    })
             })
             .count();
         let items = &items[..item_length];