rustfmt wire_format_derive and poll_token_derive

BUG=None
TEST=cargo test

Change-Id: I62f00a71ed3693352de648bb8ee576335b32019f
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1273688
Reviewed-by: Zach Reizner <zachr@chromium.org>
This commit is contained in:
Daniel Verkamp 2018-10-10 09:59:55 -07:00 committed by chrome-bot
parent f5d565d693
commit 310b308166
3 changed files with 174 additions and 159 deletions

View file

@ -8,8 +8,8 @@
#![recursion_limit = "256"]
extern crate proc_macro2;
extern crate proc_macro;
extern crate proc_macro2;
#[macro_use]
extern crate quote;
@ -20,8 +20,8 @@ extern crate syn;
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::Tokens;
use syn::{Data, DeriveInput, Fields, Ident};
use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Fields, Ident};
/// The function that derives the actual implementation.
#[proc_macro_derive(P9WireFormat)]

View file

@ -207,7 +207,6 @@ impl ParseState {
Tokenized::Enum => States::Ident,
Tokenized::Visiblity => States::Start,
_ => panic!("derives for enum types only"),
};
}
@ -237,9 +236,9 @@ impl ParseState {
self.current_state = match tok {
Tokenized::Ident(ident) => {
let mut variant = Some(EnumVariant {
name: ident,
data: None,
});
name: ident,
data: None,
});
mem::swap(&mut variant, &mut self.current_variant);
if let Some(variant) = variant {
self.model.variants.push(variant);
@ -247,14 +246,11 @@ impl ParseState {
States::VariantIdent
}
Tokenized::IdentAndType(ident, type_) => {
let variant_data = EnumVariantData {
type_: type_,
name: None,
};
let variant_data = EnumVariantData { type_, name: None };
let mut variant = Some(EnumVariant {
name: ident,
data: Some(variant_data),
});
name: ident,
data: Some(variant_data),
});
mem::swap(&mut variant, &mut self.current_variant);
if let Some(variant) = variant {
self.model.variants.push(variant);
@ -278,12 +274,14 @@ impl ParseState {
let variant = self.current_variant.as_mut().unwrap();
self.current_state = match tok {
Tokenized::FieldIdent(ident) => {
assert!(variant.data.is_none(),
"enum variant can only have one field");
assert!(
variant.data.is_none(),
"enum variant can only have one field"
);
variant.data = Some(EnumVariantData {
type_: "".to_owned(),
name: Some(ident),
});
type_: "".to_owned(),
name: Some(ident),
});
States::VariantDataType
}
Tokenized::CloseBrace => States::VariantIdent,
@ -339,9 +337,10 @@ impl EnumModel {
// The capture string is for everything between the variant identifier and the `=>` in
// the match arm: the variant's data capture.
let capture = match variant.data.as_ref() {
Some(&EnumVariantData { name: Some(ref name), .. }) => {
format!("{{ {}: data }}", name)
}
Some(&EnumVariantData {
name: Some(ref name),
..
}) => format!("{{ {}: data }}", name),
Some(&EnumVariantData { .. }) => "(data)".to_owned(),
None => "".to_owned(),
};
@ -355,14 +354,11 @@ impl EnumModel {
};
// Assembly of the match arm.
write!(match_statement,
"{}::{}{} => {}{},\n",
self.name,
variant.name,
capture,
index,
modifer)
.unwrap();
write!(
match_statement,
"{}::{}{} => {}{},\n",
self.name, variant.name, capture, index, modifer
).unwrap();
}
match_statement.push_str("}");
match_statement
@ -382,24 +378,22 @@ impl EnumModel {
// data, which includes both variant index and data bits.
let data = match variant.data.as_ref() {
Some(&EnumVariantData {
name: Some(ref name),
ref type_,
}) => format!("{{ {}: (data >> {}) as {} }}", name, variant_bits, type_),
name: Some(ref name),
ref type_,
}) => format!("{{ {}: (data >> {}) as {} }}", name, variant_bits, type_),
Some(&EnumVariantData {
name: None,
ref type_,
}) => format!("((data >> {}) as {})", variant_bits, type_),
name: None,
ref type_,
}) => format!("((data >> {}) as {})", variant_bits, type_),
None => "".to_owned(),
};
// Assembly of the match arm.
write!(match_statement,
"{} => {}::{}{},\n",
index,
self.name,
variant.name,
data)
.unwrap();
write!(
match_statement,
"{} => {}::{}{},\n",
index, self.name, variant.name, data
).unwrap();
}
match_statement.push_str("_ => unreachable!()\n}");
match_statement
@ -419,9 +413,11 @@ fn poll_token_inner(src: &str) -> String {
state.handle_token(tok);
}
assert_eq!(state.current_state,
States::End,
"unexpected end after parsing source enum");
assert_eq!(
state.current_state,
States::End,
"unexpected end after parsing source enum"
);
// Given our basic model of a user given enum that is suitable as a token, we generate the
// implementation. The implementation is NOT always well formed, such as when a variant's data
@ -429,7 +425,8 @@ fn poll_token_inner(src: &str) -> String {
// would be difficult to detect every kind of error. Importantly, every implementation that we
// generate here and goes on to compile succesfully is sound.
let model = state.model;
format!("impl PollToken for {} {{
format!(
"impl PollToken for {} {{
fn as_raw_token(&self) -> u64 {{
{}
}}
@ -438,9 +435,10 @@ fn poll_token_inner(src: &str) -> String {
{}
}}
}}",
model.name,
model.generate_as_raw_token(),
model.generate_from_raw_token())
model.name,
model.generate_as_raw_token(),
model.generate_from_raw_token()
)
}
/// Implements the PollToken trait for a given `enum`.

View file

@ -21,27 +21,34 @@ mod tokenized {
#[test]
fn ident() {
assert_eq!(Tokenized::from_str("Important"),
Ident("Important".to_owned()));
assert_eq!(
Tokenized::from_str("Important"),
Ident("Important".to_owned())
);
assert_eq!(Tokenized::from_str("hello,"), Ident("hello".to_owned()));
assert_eq!(Tokenized::from_str("world2"), Ident("world2".to_owned()));
assert_eq!(Tokenized::from_str("A,"), Ident("A".to_owned()));
}
#[test]
fn field_ident() {
assert_eq!(Tokenized::from_str("index:"),
FieldIdent("index".to_owned()));
assert_eq!(
Tokenized::from_str("index:"),
FieldIdent("index".to_owned())
);
assert_eq!(Tokenized::from_str("a:"), FieldIdent("a".to_owned()));
}
#[test]
fn ident_and_type() {
assert_eq!(Tokenized::from_str("a(u32)"),
IdentAndType("a".to_owned(), "u32".to_owned()));
assert_eq!(Tokenized::from_str("Socket(usize),"),
IdentAndType("Socket".to_owned(), "usize".to_owned()));
assert_eq!(
Tokenized::from_str("a(u32)"),
IdentAndType("a".to_owned(), "u32".to_owned())
);
assert_eq!(
Tokenized::from_str("Socket(usize),"),
IdentAndType("Socket".to_owned(), "usize".to_owned())
);
}
#[test]
@ -63,27 +70,31 @@ mod tokenized {
}
mod parse_state {
use {Tokenized, States, ParseState, EnumModel, EnumVariant, EnumVariantData};
use Tokenized::*;
use {EnumModel, EnumVariant, EnumVariantData, ParseState, States, Tokenized};
fn parse_tokens(tokens: &[Tokenized]) -> EnumModel {
let mut state = ParseState::new();
for token in tokens {
state.handle_token(token.clone());
}
assert_eq!(state.current_state,
States::End,
"unexpected end after parsing source enum");
assert_eq!(
state.current_state,
States::End,
"unexpected end after parsing source enum"
);
state.model
}
#[test]
fn empty_struct() {
let model = parse_tokens(&[Visiblity,
Enum,
Ident("Blarg".to_owned()),
OpenBrace,
CloseBrace]);
let model = parse_tokens(&[
Visiblity,
Enum,
Ident("Blarg".to_owned()),
OpenBrace,
CloseBrace,
]);
let expected = EnumModel {
name: "Blarg".to_string(),
variants: Vec::new(),
@ -94,94 +105,106 @@ mod parse_state {
#[test]
#[should_panic]
fn invalid_token() {
parse_tokens(&[Visiblity,
Enum,
Ident("Blarg".to_owned()),
OpenBrace,
CloseBrace,
CloseBrace]);
parse_tokens(&[
Visiblity,
Enum,
Ident("Blarg".to_owned()),
OpenBrace,
CloseBrace,
CloseBrace,
]);
}
#[test]
fn only_unit_variants() {
let model = parse_tokens(&[Enum,
Ident("Foo".to_owned()),
OpenBrace,
Ident("A".to_owned()),
Ident("B".to_owned()),
Ident("C".to_owned()),
CloseBrace]);
let model = parse_tokens(&[
Enum,
Ident("Foo".to_owned()),
OpenBrace,
Ident("A".to_owned()),
Ident("B".to_owned()),
Ident("C".to_owned()),
CloseBrace,
]);
let expected = EnumModel {
name: "Foo".to_string(),
variants: vec![EnumVariant {
name: "A".to_owned(),
data: None,
},
EnumVariant {
name: "B".to_owned(),
data: None,
},
EnumVariant {
name: "C".to_owned(),
data: None,
}],
variants: vec![
EnumVariant {
name: "A".to_owned(),
data: None,
},
EnumVariant {
name: "B".to_owned(),
data: None,
},
EnumVariant {
name: "C".to_owned(),
data: None,
},
],
};
assert_eq!(model, expected);
}
#[test]
fn unnamed_data() {
let model = parse_tokens(&[Enum,
Ident("Foo".to_owned()),
OpenBrace,
IdentAndType("A".to_owned(), "u32".to_owned()),
Ident("B".to_owned()),
IdentAndType("C".to_owned(), "usize".to_owned()),
CloseBrace]);
let model = parse_tokens(&[
Enum,
Ident("Foo".to_owned()),
OpenBrace,
IdentAndType("A".to_owned(), "u32".to_owned()),
Ident("B".to_owned()),
IdentAndType("C".to_owned(), "usize".to_owned()),
CloseBrace,
]);
let expected = EnumModel {
name: "Foo".to_string(),
variants: vec![EnumVariant {
name: "A".to_owned(),
data: Some(EnumVariantData {
name: None,
type_: "u32".to_owned(),
}),
},
EnumVariant {
name: "B".to_owned(),
data: None,
},
EnumVariant {
name: "C".to_owned(),
data: Some(EnumVariantData {
name: None,
type_: "usize".to_owned(),
}),
}],
variants: vec![
EnumVariant {
name: "A".to_owned(),
data: Some(EnumVariantData {
name: None,
type_: "u32".to_owned(),
}),
},
EnumVariant {
name: "B".to_owned(),
data: None,
},
EnumVariant {
name: "C".to_owned(),
data: Some(EnumVariantData {
name: None,
type_: "usize".to_owned(),
}),
},
],
};
assert_eq!(model, expected);
}
#[test]
fn named_data() {
let model = parse_tokens(&[Enum,
Ident("Foo".to_owned()),
OpenBrace,
Ident("A".to_owned()),
OpenBrace,
FieldIdent("index".to_owned()),
Ident("u16".to_owned()),
CloseBrace,
CloseBrace]);
let model = parse_tokens(&[
Enum,
Ident("Foo".to_owned()),
OpenBrace,
Ident("A".to_owned()),
OpenBrace,
FieldIdent("index".to_owned()),
Ident("u16".to_owned()),
CloseBrace,
CloseBrace,
]);
let expected = EnumModel {
name: "Foo".to_string(),
variants: vec![EnumVariant {
name: "A".to_owned(),
data: Some(EnumVariantData {
name: Some("index".to_owned()),
type_: "u16".to_owned(),
}),
}],
name: "A".to_owned(),
data: Some(EnumVariantData {
name: Some("index".to_owned()),
type_: "u16".to_owned(),
}),
}],
};
assert_eq!(model, expected);
}
@ -195,40 +218,34 @@ mod enum_model {
let mut model = EnumModel {
name: "Baz".to_string(),
variants: vec![EnumVariant {
name: "A".to_owned(),
data: None,
}],
name: "A".to_owned(),
data: None,
}],
};
assert_eq!(model.variant_bits(), 0);
model.variants.append(
&mut vec![
EnumVariant {
name: "B".to_owned(),
data: None,
},
EnumVariant {
name: "C".to_owned(),
data: None,
}
]
);
model.variants.append(&mut vec![
EnumVariant {
name: "B".to_owned(),
data: None,
},
EnumVariant {
name: "C".to_owned(),
data: None,
},
]);
assert_eq!(model.variant_bits(), 2);
for _ in 0..1021 {
model
.variants
.push(EnumVariant {
name: "Dynamic".to_owned(),
data: None,
});
model.variants.push(EnumVariant {
name: "Dynamic".to_owned(),
data: None,
});
}
assert_eq!(model.variant_bits(), 10);
model
.variants
.push(EnumVariant {
name: "OneMore".to_owned(),
data: None,
});
model.variants.push(EnumVariant {
name: "OneMore".to_owned(),
data: None,
});
assert_eq!(model.variant_bits(), 11);
}
}