Skip to content

Commit 7da7764

Browse files
authored
Merge pull request #1864 from topecongiro/reorder-extern-crates
Reorder extern crates
2 parents 2c293bd + c28df85 commit 7da7764

File tree

9 files changed

+93
-44
lines changed

9 files changed

+93
-44
lines changed

src/bin/rustfmt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
#![cfg(not(test))]
1212

1313

14+
extern crate env_logger;
15+
extern crate getopts;
1416
extern crate log;
1517
extern crate rustfmt_nightly as rustfmt;
1618
extern crate toml;
17-
extern crate env_logger;
18-
extern crate getopts;
1919

2020
use std::{env, error};
2121
use std::fs::File;

src/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ create_config! {
558558
exceeds `chain_one_line_max`";
559559
imports_indent: IndentStyle, IndentStyle::Visual, "Indent of imports";
560560
imports_layout: ListTactic, ListTactic::Mixed, "Item layout inside a import block";
561+
reorder_extern_crates: bool, true, "Reorder extern crate statements alphabetically";
562+
reorder_extern_crates_in_group: bool, true, "Reorder extern crate statements in group";
561563
reorder_imports: bool, false, "Reorder import statements alphabetically";
562564
reorder_imports_in_group: bool, false, "Reorder import statements in group";
563565
reorder_imported_names: bool, true,

src/imports.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,14 @@ fn compare_view_paths(a: &ast::ViewPath_, b: &ast::ViewPath_) -> Ordering {
113113
}
114114
}
115115

116-
fn compare_use_items(a: &ast::Item, b: &ast::Item) -> Option<Ordering> {
116+
fn compare_use_items(context: &RewriteContext, a: &ast::Item, b: &ast::Item) -> Option<Ordering> {
117117
match (&a.node, &b.node) {
118118
(&ast::ItemKind::Use(ref a_vp), &ast::ItemKind::Use(ref b_vp)) => {
119119
Some(compare_view_paths(&a_vp.node, &b_vp.node))
120120
}
121+
(&ast::ItemKind::ExternCrate(..), &ast::ItemKind::ExternCrate(..)) => {
122+
Some(context.snippet(a.span).cmp(&context.snippet(b.span)))
123+
}
121124
_ => None,
122125
}
123126
}
@@ -214,7 +217,9 @@ impl<'a> FmtVisitor<'a> {
214217
.collect::<Vec<_>>();
215218
let pos_after_last_use_item = last_pos_of_prev_use_item;
216219
// Order the imports by view-path & other import path properties
217-
ordered_use_items.sort_by(|a, b| compare_use_items(a.0, b.0).unwrap());
220+
ordered_use_items.sort_by(|a, b| {
221+
compare_use_items(&self.get_context(), a.0, b.0).unwrap()
222+
});
218223
// First, output the span before the first import
219224
let prev_span_str = self.snippet(utils::mk_sp(self.last_pos, pos_before_first_use_item));
220225
// Look for purely trailing space at the start of the prefix snippet before a linefeed, or

src/lib.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,19 @@
1010

1111
#![feature(rustc_private)]
1212

13+
extern crate diff;
1314
#[macro_use]
1415
extern crate log;
15-
16+
extern crate regex;
17+
extern crate rustc_errors as errors;
1618
extern crate serde;
1719
#[macro_use]
1820
extern crate serde_derive;
1921
extern crate serde_json;
20-
21-
extern crate syntax;
22-
extern crate rustc_errors as errors;
23-
2422
extern crate strings;
25-
26-
extern crate unicode_segmentation;
27-
extern crate regex;
28-
extern crate diff;
23+
extern crate syntax;
2924
extern crate term;
25+
extern crate unicode_segmentation;
3026

3127
use std::collections::HashMap;
3228
use std::fmt;

src/visitor.rs

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ fn is_use_item(item: &ast::Item) -> bool {
3636
}
3737
}
3838

39+
fn is_extern_crate(item: &ast::Item) -> bool {
40+
match item.node {
41+
ast::ItemKind::ExternCrate(..) => true,
42+
_ => false,
43+
}
44+
}
45+
3946
pub struct FmtVisitor<'a> {
4047
pub parse_session: &'a ParseSess,
4148
pub codemap: &'a CodeMap,
@@ -627,40 +634,65 @@ impl<'a> FmtVisitor<'a> {
627634
false
628635
}
629636

637+
fn reorder_items<F>(
638+
&mut self,
639+
items_left: &[ptr::P<ast::Item>],
640+
is_item: &F,
641+
in_group: bool,
642+
) -> usize
643+
where
644+
F: Fn(&ast::Item) -> bool,
645+
{
646+
let mut last = self.codemap.lookup_line_range(items_left[0].span());
647+
let item_length = items_left
648+
.iter()
649+
.take_while(|ppi| {
650+
is_item(&***ppi) && (!in_group || {
651+
let current = self.codemap.lookup_line_range(ppi.span());
652+
let in_same_group = current.lo < last.hi + 2;
653+
last = current;
654+
in_same_group
655+
})
656+
})
657+
.count();
658+
let items = &items_left[..item_length];
659+
660+
let at_least_one_in_file_lines = items
661+
.iter()
662+
.any(|item| !out_of_file_lines_range!(self, item.span));
663+
664+
if at_least_one_in_file_lines {
665+
self.format_imports(items);
666+
} else {
667+
for item in items {
668+
self.push_rewrite(item.span, None);
669+
}
670+
}
671+
672+
item_length
673+
}
674+
630675
fn walk_mod_items(&mut self, m: &ast::Mod) {
631676
let mut items_left: &[ptr::P<ast::Item>] = &m.items;
632677
while !items_left.is_empty() {
633678
// If the next item is a `use` declaration, then extract it and any subsequent `use`s
634679
// to be potentially reordered within `format_imports`. Otherwise, just format the
635680
// next item for output.
636681
if self.config.reorder_imports() && is_use_item(&*items_left[0]) {
637-
let reorder_imports_in_group = self.config.reorder_imports_in_group();
638-
let mut last = self.codemap.lookup_line_range(items_left[0].span());
639-
let use_item_length = items_left
640-
.iter()
641-
.take_while(|ppi| {
642-
is_use_item(&***ppi) && (!reorder_imports_in_group || {
643-
let current = self.codemap.lookup_line_range(ppi.span());
644-
let in_same_group = current.lo < last.hi + 2;
645-
last = current;
646-
in_same_group
647-
})
648-
})
649-
.count();
650-
let (use_items, rest) = items_left.split_at(use_item_length);
651-
652-
let at_least_one_in_file_lines = use_items
653-
.iter()
654-
.any(|item| !out_of_file_lines_range!(self, item.span));
655-
656-
if at_least_one_in_file_lines {
657-
self.format_imports(use_items);
658-
} else {
659-
for item in use_items {
660-
self.push_rewrite(item.span, None);
661-
}
662-
}
663-
682+
let used_items_len = self.reorder_items(
683+
&items_left,
684+
&is_use_item,
685+
self.config.reorder_imports_in_group(),
686+
);
687+
let (_, rest) = items_left.split_at(used_items_len);
688+
items_left = rest;
689+
} else if self.config.reorder_extern_crates() && is_extern_crate(&*items_left[0]) {
690+
let used_items_len = self.reorder_items(
691+
&items_left,
692+
&is_extern_crate,
693+
self.config.reorder_extern_crates_in_group(),
694+
);
695+
let (_, rest) = items_left.split_at(used_items_len);
664696
items_left = rest;
665697
} else {
666698
// `unwrap()` is safe here because we know `items_left`

tests/source/extern.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
extern crate foo ;
44
extern crate foo as bar ;
55

6+
extern crate futures;
7+
extern crate dotenv;
8+
extern crate chrono;
9+
10+
extern crate foo;
11+
extern crate bar;
12+
613
extern "C" {
714
fn c_func(x: *mut *mut libc::c_void);
815

tests/system.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
extern crate rustfmt_nightly as rustfmt;
1211
extern crate diff;
1312
extern crate regex;
13+
extern crate rustfmt_nightly as rustfmt;
1414
extern crate term;
1515

1616
use std::collections::HashMap;

tests/target/attrib-extern-crate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// Attributes on extern crate.
22

3-
extern crate Foo;
43
#[Attr1]
54
extern crate Bar;
65
#[Attr2]
76
#[Attr2]
87
extern crate Baz;
8+
extern crate Foo;
99

1010
fn foo() {
11-
extern crate Foo;
1211
#[Attr1]
1312
extern crate Bar;
1413
#[Attr2]
1514
#[Attr2]
1615
extern crate Baz;
16+
extern crate Foo;
1717
}

tests/target/extern.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
// rustfmt-normalize_comments: true
22

3-
extern crate foo;
43
extern crate foo as bar;
4+
extern crate foo;
5+
6+
extern crate chrono;
7+
extern crate dotenv;
8+
extern crate futures;
9+
10+
extern crate bar;
11+
extern crate foo;
512

613
extern "C" {
714
fn c_func(x: *mut *mut libc::c_void);

0 commit comments

Comments
 (0)