Skip to content

Implement Rewrite trait for syntax::ast::Attribute #1634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 77 additions & 10 deletions src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use comment::rewrite_comment;
use macros::{rewrite_macro, MacroPosition};
use items::{rewrite_static, rewrite_associated_type, rewrite_associated_impl_type,
rewrite_type_alias, format_impl, format_trait};
use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorTactic};

fn is_use_item(item: &ast::Item) -> bool {
match item.node {
Expand Down Expand Up @@ -637,6 +638,81 @@ impl<'a> FmtVisitor<'a> {
}
}

impl Rewrite for ast::NestedMetaItem {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
match self.node {
ast::NestedMetaItemKind::MetaItem(ref meta_item) => meta_item.rewrite(context, shape),
ast::NestedMetaItemKind::Literal(..) => Some(context.snippet(self.span)),
}
}
}

impl Rewrite for ast::MetaItem {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
Some(match self.node {
ast::MetaItemKind::Word => String::from(&*self.name.as_str()),
ast::MetaItemKind::List(ref list) => {
let name = self.name.as_str();
// 3 = `#[` and `(`, 2 = `]` and `)`
let item_shape = try_opt!(shape
.shrink_left(name.len() + 3)
.and_then(|s| s.sub_width(2)));
let items = itemize_list(context.codemap,
list.iter(),
")",
|nested_meta_item| nested_meta_item.span.lo,
|nested_meta_item| nested_meta_item.span.hi,
|nested_meta_item| {
nested_meta_item.rewrite(context, item_shape)
},
self.span.lo,
self.span.hi);
let item_vec = items.collect::<Vec<_>>();
let fmt = ListFormatting {
tactic: DefinitiveListTactic::Mixed,
separator: ",",
trailing_separator: SeparatorTactic::Never,
shape: item_shape,
ends_with_newline: false,
config: context.config,
};
format!("{}({})", name, try_opt!(write_list(&item_vec, &fmt)))
}
ast::MetaItemKind::NameValue(ref literal) => {
let name = self.name.as_str();
let value = context.snippet(literal.span);
if &*name == "doc" && value.starts_with("///") {
let doc_shape = Shape {
width: cmp::min(shape.width, context.config.comment_width())
.checked_sub(shape.indent.width())
.unwrap_or(0),
..shape
};
format!("{}",
try_opt!(rewrite_comment(&value,
false,
doc_shape,
context.config)))
} else {
format!("{} = {}", name, value)
}
}
})
}
}

impl Rewrite for ast::Attribute {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
self.value
.rewrite(context, shape)
.map(|rw| if rw.starts_with("///") {
rw
} else {
format!("#[{}]", rw)
})
}
}

impl<'a> Rewrite for [ast::Attribute] {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
let mut result = String::new();
Expand All @@ -646,7 +722,7 @@ impl<'a> Rewrite for [ast::Attribute] {
let indent = shape.indent.to_string(context.config);

for (i, a) in self.iter().enumerate() {
let mut a_str = context.snippet(a.span);
let a_str = try_opt!(a.rewrite(context, shape));

// Write comments and blank lines between attributes.
if i > 0 {
Expand All @@ -673,15 +749,6 @@ impl<'a> Rewrite for [ast::Attribute] {
result.push_str(&indent);
}

if a_str.starts_with("//") {
a_str = try_opt!(rewrite_comment(&a_str,
false,
Shape::legacy(context.config.comment_width() -
shape.indent.width(),
shape.indent),
context.config));
}

// Write the attribute itself.
result.push_str(&a_str);

Expand Down
10 changes: 10 additions & 0 deletions tests/source/attrib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,14 @@ impl Bar {
/// Blah blah bing.
fn f4(self) -> Cat {
}

// We want spaces around `=`
#[cfg(feature="nightly")]
fn f5(self) -> Monkey {}
}

// #984
struct Foo {
# [ derive ( Clone , PartialEq , Debug , Deserialize , Serialize ) ]
foo: usize,
}
11 changes: 11 additions & 0 deletions tests/source/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,14 @@ pub enum Bencoding<'i> {
// TODO make Dict "structlike" AKA name the two values.
Dict(&'i [u8], BTreeMap<&'i [u8], Bencoding<'i>>),
}

// #1261
pub enum CoreResourceMsg {
SetCookieForUrl(
ServoUrl,
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
Cookie,
CookieSource
),
}
15 changes: 15 additions & 0 deletions tests/source/struct-field-attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,18 @@ fn do_something() -> Foo {
fn main() {
do_something();
}

// #1462
struct Foo {
foo: usize,
#[cfg(feature="include-bar")]
bar: usize,
}

fn new_foo() -> Foo {
Foo {
foo: 0,
#[cfg(feature="include-bar")]
bar: 0,
}
}
10 changes: 10 additions & 0 deletions tests/target/attrib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,14 @@ impl Bar {
// tooooooooooooooooooooooooooooooo loooooooooooong.
/// Blah blah bing.
fn f4(self) -> Cat {}

// We want spaces around `=`
#[cfg(feature = "nightly")]
fn f5(self) -> Monkey {}
}

// #984
struct Foo {
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
foo: usize,
}
9 changes: 9 additions & 0 deletions tests/target/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,12 @@ pub enum Bencoding<'i> {
// TODO make Dict "structlike" AKA name the two values.
Dict(&'i [u8], BTreeMap<&'i [u8], Bencoding<'i>>),
}

// #1261
pub enum CoreResourceMsg {
SetCookieForUrl(ServoUrl,
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
Cookie,
CookieSource),
}
2 changes: 1 addition & 1 deletion tests/target/nestedmod/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod mymod1 {
mod mod3a;
}

#[path="mod2c.rs"]
#[path = "mod2c.rs"]
mod mymod2;

mod submod2;
2 changes: 1 addition & 1 deletion tests/target/nestedmod/mod2b.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

#[path="mod2a.rs"]
#[path = "mod2a.rs"]
mod c;
15 changes: 15 additions & 0 deletions tests/target/struct-field-attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,18 @@ fn do_something() -> Foo {
fn main() {
do_something();
}

// #1462
struct Foo {
foo: usize,
#[cfg(feature = "include-bar")]
bar: usize,
}

fn new_foo() -> Foo {
Foo {
foo: 0,
#[cfg(feature = "include-bar")]
bar: 0,
}
}