@@ -36,6 +36,13 @@ fn is_use_item(item: &ast::Item) -> bool {
36
36
}
37
37
}
38
38
39
+ fn is_extern_crate ( item : & ast:: Item ) -> bool {
40
+ match item. node {
41
+ ast:: ItemKind :: ExternCrate ( ..) => true ,
42
+ _ => false ,
43
+ }
44
+ }
45
+
39
46
pub struct FmtVisitor < ' a > {
40
47
pub parse_session : & ' a ParseSess ,
41
48
pub codemap : & ' a CodeMap ,
@@ -627,40 +634,65 @@ impl<'a> FmtVisitor<'a> {
627
634
false
628
635
}
629
636
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
+
630
675
fn walk_mod_items ( & mut self , m : & ast:: Mod ) {
631
676
let mut items_left: & [ ptr:: P < ast:: Item > ] = & m. items ;
632
677
while !items_left. is_empty ( ) {
633
678
// If the next item is a `use` declaration, then extract it and any subsequent `use`s
634
679
// to be potentially reordered within `format_imports`. Otherwise, just format the
635
680
// next item for output.
636
681
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) ;
664
696
items_left = rest;
665
697
} else {
666
698
// `unwrap()` is safe here because we know `items_left`
0 commit comments