From 9273a724209849be96ded894f8eed5300b4daa1f Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sun, 4 Feb 2018 12:07:51 +0900 Subject: [PATCH 1/2] Add tests for reorder_extern_crates --- tests/source/configs/reorder_extern_crates/false.rs | 11 +++++++++++ tests/source/configs/reorder_extern_crates/true.rs | 11 +++++++++++ tests/target/configs/reorder_extern_crates/false.rs | 11 +++++++++++ tests/target/configs/reorder_extern_crates/true.rs | 11 +++++++++++ 4 files changed, 44 insertions(+) create mode 100644 tests/source/configs/reorder_extern_crates/false.rs create mode 100644 tests/source/configs/reorder_extern_crates/true.rs create mode 100644 tests/target/configs/reorder_extern_crates/false.rs create mode 100644 tests/target/configs/reorder_extern_crates/true.rs diff --git a/tests/source/configs/reorder_extern_crates/false.rs b/tests/source/configs/reorder_extern_crates/false.rs new file mode 100644 index 00000000000..6bef132e5c3 --- /dev/null +++ b/tests/source/configs/reorder_extern_crates/false.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_extern_crates: false + +extern crate foo; +extern crate bar; +extern crate foobar; + +#[macro_use] +extern crate nom; +extern crate regex; +#[macro_use] +extern crate log; diff --git a/tests/source/configs/reorder_extern_crates/true.rs b/tests/source/configs/reorder_extern_crates/true.rs new file mode 100644 index 00000000000..bdf00f57cda --- /dev/null +++ b/tests/source/configs/reorder_extern_crates/true.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_extern_crates: true + +extern crate foo; +extern crate bar; +extern crate foobar; + +#[macro_use] +extern crate nom; +extern crate regex; +#[macro_use] +extern crate log; diff --git a/tests/target/configs/reorder_extern_crates/false.rs b/tests/target/configs/reorder_extern_crates/false.rs new file mode 100644 index 00000000000..6bef132e5c3 --- /dev/null +++ b/tests/target/configs/reorder_extern_crates/false.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_extern_crates: false + +extern crate foo; +extern crate bar; +extern crate foobar; + +#[macro_use] +extern crate nom; +extern crate regex; +#[macro_use] +extern crate log; diff --git a/tests/target/configs/reorder_extern_crates/true.rs b/tests/target/configs/reorder_extern_crates/true.rs new file mode 100644 index 00000000000..86aba38b5d1 --- /dev/null +++ b/tests/target/configs/reorder_extern_crates/true.rs @@ -0,0 +1,11 @@ +// rustfmt-reorder_extern_crates: true + +extern crate bar; +extern crate foo; +extern crate foobar; + +#[macro_use] +extern crate nom; +extern crate regex; +#[macro_use] +extern crate log; From 3bb0a2a7495011868a52cdbb848f87e59bdc98d8 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sun, 4 Feb 2018 12:08:02 +0900 Subject: [PATCH 2/2] Do not reorder items with '#[macro_use]' Reordering items with `#[macro_use]` could change the semantic of source code. There could exist other attributes that requires special treatment. --- src/visitor.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/visitor.rs b/src/visitor.rs index 3157597697d..c28eed561a5 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -11,7 +11,7 @@ use std::cmp; use syntax::{ast, visit}; -use syntax::attr::HasAttrs; +use syntax::attr::{self, HasAttrs}; use syntax::codemap::{self, BytePos, CodeMap, Pos, Span}; use syntax::parse::ParseSess; @@ -49,11 +49,15 @@ fn is_mod_decl(item: &ast::Item) -> bool { } } +fn contains_macro_use_attr(attrs: &[ast::Attribute], span: Span) -> bool { + attr::contains_name(&filter_inline_attrs(attrs, span), "macro_use") +} + /// Returns true for `mod foo;` without any inline attributes. /// We cannot reorder modules with attributes because doing so can break the code. /// e.g. `#[macro_use]`. fn is_mod_decl_without_attr(item: &ast::Item) -> bool { - is_mod_decl(item) && filter_inline_attrs(&item.attrs, item.span()).is_empty() + is_mod_decl(item) && !contains_macro_use_attr(&item.attrs, item.span()) } fn is_use_item(item: &ast::Item) -> bool { @@ -63,6 +67,10 @@ fn is_use_item(item: &ast::Item) -> bool { } } +fn is_use_item_without_attr(item: &ast::Item) -> bool { + is_use_item(item) && !contains_macro_use_attr(&item.attrs, item.span()) +} + fn is_extern_crate(item: &ast::Item) -> bool { match item.node { ast::ItemKind::ExternCrate(..) => true, @@ -70,6 +78,10 @@ fn is_extern_crate(item: &ast::Item) -> bool { } } +fn is_extern_crate_without_attr(item: &ast::Item) -> bool { + is_extern_crate(item) && !contains_macro_use_attr(&item.attrs, item.span()) +} + /// Creates a string slice corresponding to the specified span. pub struct SnippetProvider<'a> { /// A pointer to the content of the file we are formatting. @@ -676,11 +688,15 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // subsequent items that have the same item kind to be reordered within // `format_imports`. Otherwise, just format the next item for output. { - try_reorder_items_with!(reorder_imports, reorder_imports_in_group, is_use_item); + try_reorder_items_with!( + reorder_imports, + reorder_imports_in_group, + is_use_item_without_attr + ); try_reorder_items_with!( reorder_extern_crates, reorder_extern_crates_in_group, - is_extern_crate + is_extern_crate_without_attr ); try_reorder_items_with!(reorder_modules, reorder_modules, is_mod_decl_without_attr); }