Format structs
This commit is contained in:
parent
c3856880f6
commit
e7adf64155
@ -24,8 +24,8 @@ fn main() {
|
||||
let mut def_config = String::new();
|
||||
def_config_file.read_to_string(&mut def_config).unwrap();
|
||||
|
||||
//run(args, WriteMode::Display, &def_config);
|
||||
run(args, WriteMode::Overwrite, &def_config);
|
||||
run(args, WriteMode::Display, &def_config);
|
||||
//run(args, WriteMode::Overwrite, &def_config);
|
||||
|
||||
std::env::set_exit_status(0);
|
||||
|
||||
|
@ -23,7 +23,6 @@ pub struct Config {
|
||||
|
||||
impl Config {
|
||||
fn from_toml(toml: &str) -> Config {
|
||||
println!("About to parse: {}", toml);
|
||||
let parsed = toml.parse().unwrap();
|
||||
toml::decode(parsed).unwrap()
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Formatting top-level items - functions, structs, enums, traits, impls.
|
||||
|
||||
use {ReturnIndent, BraceStyle};
|
||||
use utils::make_indent;
|
||||
use lists::{write_list, ListFormatting, SeparatorTactic, ListTactic};
|
||||
@ -123,7 +125,7 @@ impl<'a> FmtVisitor<'a> {
|
||||
let generics_indent = indent + result.len();
|
||||
result.push_str(&self.rewrite_generics(generics,
|
||||
generics_indent,
|
||||
span_for_return(&fd.output)));
|
||||
span_for_return(&fd.output).lo));
|
||||
|
||||
let ret_str = self.rewrite_return(&fd.output);
|
||||
|
||||
@ -388,7 +390,125 @@ impl<'a> FmtVisitor<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn rewrite_generics(&self, generics: &ast::Generics, indent: usize, ret_span: Span) -> String {
|
||||
pub fn visit_struct(&mut self,
|
||||
ident: ast::Ident,
|
||||
vis: ast::Visibility,
|
||||
struct_def: &ast::StructDef,
|
||||
generics: &ast::Generics,
|
||||
span: Span)
|
||||
{
|
||||
let header_str = self.struct_header(ident, vis);
|
||||
self.changes.push_str_span(span, &header_str);
|
||||
|
||||
if struct_def.fields.len() == 0 {
|
||||
assert!(generics.where_clause.predicates.len() == 0,
|
||||
"No-field struct with where clause?");
|
||||
assert!(generics.lifetimes.len() == 0, "No-field struct with generics?");
|
||||
assert!(generics.ty_params.len() == 0, "No-field struct with generics?");
|
||||
|
||||
self.changes.push_str_span(span, ";");
|
||||
return;
|
||||
}
|
||||
|
||||
let mut generics_buf = String::new();
|
||||
let generics_str = self.rewrite_generics(generics, self.block_indent, struct_def.fields[0].span.lo);
|
||||
generics_buf.push_str(&generics_str);
|
||||
|
||||
if generics.where_clause.predicates.len() > 0 {
|
||||
generics_buf.push_str(&self.rewrite_where_clause(&generics.where_clause,
|
||||
self.block_indent,
|
||||
struct_def.fields[0].span.lo));
|
||||
generics_buf.push_str(&make_indent(self.block_indent));
|
||||
generics_buf.push_str("\n{");
|
||||
|
||||
} else {
|
||||
generics_buf.push_str(" {");
|
||||
}
|
||||
self.changes.push_str_span(span, &generics_buf);
|
||||
|
||||
let struct_snippet = self.snippet(span);
|
||||
// FIXME this will give incorrect results if there is a { in a commet.
|
||||
self.last_pos = span.lo + BytePos(struct_snippet.find('{').unwrap() as u32 + 1);
|
||||
|
||||
self.block_indent += config!(tab_spaces);
|
||||
for f in &struct_def.fields {
|
||||
self.visit_field(f, span.lo, &struct_snippet);
|
||||
}
|
||||
self.block_indent -= config!(tab_spaces);
|
||||
|
||||
self.format_missing_with_indent(span.lo + BytePos(struct_snippet.rfind('}').unwrap() as u32));
|
||||
self.changes.push_str_span(span, "}");
|
||||
}
|
||||
|
||||
fn struct_header(&self,
|
||||
ident: ast::Ident,
|
||||
vis: ast::Visibility)
|
||||
-> String
|
||||
{
|
||||
let vis = if vis == ast::Visibility::Public {
|
||||
"pub "
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
format!("{}struct {}", vis, &token::get_ident(ident))
|
||||
}
|
||||
|
||||
// Field of a struct
|
||||
fn visit_field(&mut self,
|
||||
field: &ast::StructField,
|
||||
// These two args are for missing spans hacks.
|
||||
struct_start: BytePos,
|
||||
struct_snippet: &str)
|
||||
{
|
||||
if self.visit_attrs(&field.node.attrs) {
|
||||
return;
|
||||
}
|
||||
self.format_missing_with_indent(field.span.lo);
|
||||
|
||||
let name = match field.node.kind {
|
||||
ast::StructFieldKind::NamedField(ident, _) => Some(token::get_ident(ident)),
|
||||
ast::StructFieldKind::UnnamedField(_) => None,
|
||||
};
|
||||
let vis = match field.node.kind {
|
||||
ast::StructFieldKind::NamedField(_, vis) |
|
||||
ast::StructFieldKind::UnnamedField(vis) => if vis == ast::Visibility::Public {
|
||||
"pub "
|
||||
} else {
|
||||
""
|
||||
}
|
||||
};
|
||||
let typ = pprust::ty_to_string(&field.node.ty);
|
||||
|
||||
let field_str = match name {
|
||||
Some(name) => {
|
||||
let budget = config!(ideal_width) - self.block_indent;
|
||||
if self.block_indent + vis.len() + name.len() + typ.len() + 3 > budget {
|
||||
format!("{}{}:\n{}{},",
|
||||
vis,
|
||||
name,
|
||||
&make_indent(self.block_indent + config!(tab_spaces)),
|
||||
typ)
|
||||
} else {
|
||||
format!("{}{}: {},", vis, name, typ)
|
||||
}
|
||||
}
|
||||
None => format!("{}{},", vis, typ),
|
||||
};
|
||||
self.changes.push_str_span(field.span, &field_str);
|
||||
|
||||
// This hack makes sure we only add comments etc. after the comma, and
|
||||
// makes sure we don't repeat any commas.
|
||||
let hi = field.span.hi;
|
||||
// FIXME a comma in a comment will break this hack.
|
||||
let comma_pos = match struct_snippet[(hi.0 - struct_start.0) as usize..].find(',') {
|
||||
Some(i) => i,
|
||||
None => 0,
|
||||
};
|
||||
self.last_pos = hi + BytePos(comma_pos as u32 + 1);
|
||||
}
|
||||
|
||||
fn rewrite_generics(&self, generics: &ast::Generics, indent: usize, span_end: BytePos) -> String {
|
||||
// FIXME convert bounds to where clauses where they get too big or if
|
||||
// there is a where clause at all.
|
||||
let mut result = String::new();
|
||||
@ -422,7 +542,7 @@ impl<'a> FmtVisitor<'a> {
|
||||
">",
|
||||
|sp| sp.lo,
|
||||
|sp| sp.hi,
|
||||
ret_span.lo);
|
||||
span_end);
|
||||
|
||||
// If there are // comments, keep them multi-line.
|
||||
let mut list_tactic = ListTactic::HorizontalVertical;
|
@ -50,7 +50,7 @@ use visitor::FmtVisitor;
|
||||
mod config;
|
||||
mod changes;
|
||||
mod visitor;
|
||||
mod functions;
|
||||
mod items;
|
||||
mod missed_spans;
|
||||
mod lists;
|
||||
mod utils;
|
||||
|
@ -180,6 +180,15 @@ impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> {
|
||||
self.changes.push_str_span(item.span, &new_str);
|
||||
self.last_pos = item.span.hi;
|
||||
}
|
||||
ast::Item_::ItemStruct(ref def, ref generics) => {
|
||||
self.format_missing_with_indent(item.span.lo);
|
||||
self.visit_struct(item.ident,
|
||||
item.vis,
|
||||
def,
|
||||
generics,
|
||||
item.span);
|
||||
self.last_pos = item.span.hi;
|
||||
}
|
||||
_ => {
|
||||
visit::walk_item(self, item);
|
||||
}
|
||||
@ -252,7 +261,7 @@ impl<'a> FmtVisitor<'a> {
|
||||
}
|
||||
|
||||
// Returns true if we should skip the following item.
|
||||
fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
|
||||
pub fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
|
||||
if attrs.len() == 0 {
|
||||
return false;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ fn idempotent_tests() {
|
||||
|
||||
// Compare output to input.
|
||||
fn print_mismatches(result: HashMap<String, String>) {
|
||||
for (file_name, fmt_text) in result {
|
||||
for (_, fmt_text) in result {
|
||||
println!("{}", fmt_text);
|
||||
}
|
||||
}
|
||||
|
37
tests/idem/structs.rs
Normal file
37
tests/idem/structs.rs
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
/// A Doc comment
|
||||
#[AnAttribute]
|
||||
pub struct Foo {
|
||||
#[rustfmt_skip]
|
||||
f : SomeType, // Comment beside a field
|
||||
f: SomeType, // Comment beside a field
|
||||
// Comment on a field
|
||||
#[AnAttribute]
|
||||
g: SomeOtherType,
|
||||
/// A doc comment on a field
|
||||
h: AThirdType,
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
// With a where clause and generics.
|
||||
pub struct Foo<'a, Y: Baz>
|
||||
where X: Whatever
|
||||
{
|
||||
f: SomeType, // Comment beside a field
|
||||
}
|
||||
|
||||
struct Baz {
|
||||
a: A, // Comment A
|
||||
b: B, // Comment B
|
||||
c: C, // Comment C
|
||||
}
|
||||
|
||||
struct Baz {
|
||||
// Comment A
|
||||
a: A,
|
||||
// Comment B
|
||||
b: B,
|
||||
// Comment C
|
||||
c: C,
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user