parent
08e6e74e69
commit
9cf8529e33
100
src/items.rs
100
src/items.rs
@ -12,7 +12,7 @@
|
||||
|
||||
use Indent;
|
||||
use utils::{format_mutability, format_visibility, contains_skip, span_after, end_typaram,
|
||||
wrap_str, last_line_width, semicolon_for_expr};
|
||||
wrap_str, last_line_width, semicolon_for_expr, format_unsafety, trim_newlines};
|
||||
use lists::{write_list, itemize_list, ListItem, ListFormatting, SeparatorTactic,
|
||||
DefinitiveListTactic, definitive_tactic, format_item_list};
|
||||
use expr::{is_empty_block, is_simple_block_stmt, rewrite_assign_rhs};
|
||||
@ -435,6 +435,104 @@ fn format_variant(&self, field: &ast::Variant) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_impl(context: &RewriteContext, item: &ast::Item, offset: Indent) -> Option<String> {
|
||||
if let ast::Item_::ItemImpl(unsafety,
|
||||
polarity,
|
||||
ref generics,
|
||||
ref trait_ref,
|
||||
ref self_ty,
|
||||
ref items) = item.node {
|
||||
let mut result = String::new();
|
||||
result.push_str(format_visibility(item.vis));
|
||||
result.push_str(format_unsafety(unsafety));
|
||||
result.push_str("impl");
|
||||
|
||||
let lo = span_after(item.span, "impl", context.codemap);
|
||||
let hi = match *trait_ref {
|
||||
Some(ref tr) => tr.path.span.lo,
|
||||
None => self_ty.span.lo,
|
||||
};
|
||||
let generics_str = try_opt!(rewrite_generics(context,
|
||||
generics,
|
||||
offset,
|
||||
offset + result.len(),
|
||||
mk_sp(lo, hi)));
|
||||
result.push_str(&generics_str);
|
||||
|
||||
// FIXME might need to linebreak in the impl header, here would be a
|
||||
// good place.
|
||||
result.push(' ');
|
||||
if polarity == ast::ImplPolarity::Negative {
|
||||
result.push_str("!");
|
||||
}
|
||||
if let &Some(ref trait_ref) = trait_ref {
|
||||
let budget = try_opt!(context.config.max_width.checked_sub(result.len()));
|
||||
let indent = offset + result.len();
|
||||
result.push_str(&*try_opt!(trait_ref.rewrite(context, budget, indent)));
|
||||
result.push_str(" for ");
|
||||
}
|
||||
|
||||
let budget = try_opt!(context.config.max_width.checked_sub(result.len()));
|
||||
let indent = offset + result.len();
|
||||
result.push_str(&*try_opt!(self_ty.rewrite(context, budget, indent)));
|
||||
|
||||
let where_clause_str = try_opt!(rewrite_where_clause(context,
|
||||
&generics.where_clause,
|
||||
context.config,
|
||||
context.block_indent,
|
||||
context.config.where_density,
|
||||
"{",
|
||||
None));
|
||||
if !where_clause_str.contains('\n') &&
|
||||
result.len() + where_clause_str.len() + offset.width() > context.config.max_width {
|
||||
result.push('\n');
|
||||
let width = context.block_indent.width() + context.config.tab_spaces - 1;
|
||||
let where_indent = Indent::new(0, width);
|
||||
result.push_str(&where_indent.to_string(context.config));
|
||||
}
|
||||
result.push_str(&where_clause_str);
|
||||
|
||||
match context.config.item_brace_style {
|
||||
BraceStyle::AlwaysNextLine => result.push('\n'),
|
||||
BraceStyle::PreferSameLine => result.push(' '),
|
||||
BraceStyle::SameLineWhere => {
|
||||
if where_clause_str.len() > 0 {
|
||||
result.push('\n')
|
||||
} else {
|
||||
result.push(' ')
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push('{');
|
||||
|
||||
if !items.is_empty() {
|
||||
result.push('\n');
|
||||
let indent_str = context.block_indent.to_string(context.config);
|
||||
result.push_str(&indent_str);
|
||||
|
||||
let mut visitor = FmtVisitor::from_codemap(context.parse_session, context.config, None);
|
||||
visitor.block_indent = context.block_indent.block_indent(context.config);
|
||||
|
||||
let snippet = context.snippet(item.span);
|
||||
let open_pos = try_opt!(snippet.find_uncommented("{")) + 1;
|
||||
visitor.last_pos = item.span.lo + BytePos(open_pos as u32);
|
||||
|
||||
for item in items {
|
||||
visitor.visit_impl_item(&item);
|
||||
}
|
||||
|
||||
result.push_str(trim_newlines(&visitor.buffer.to_string()));
|
||||
result.push('\n');
|
||||
result.push_str(&indent_str);
|
||||
}
|
||||
result.push('}');
|
||||
|
||||
Some(result)
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_struct(context: &RewriteContext,
|
||||
item_name: &str,
|
||||
ident: ast::Ident,
|
||||
|
16
src/types.rs
16
src/types.rs
@ -432,20 +432,22 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Opt
|
||||
// 6 is "for<> ".len()
|
||||
let extra_offset = lifetime_str.len() + 6;
|
||||
let max_path_width = try_opt!(width.checked_sub(extra_offset));
|
||||
let path_str = try_opt!(rewrite_path(context,
|
||||
false,
|
||||
None,
|
||||
&self.trait_ref.path,
|
||||
max_path_width,
|
||||
offset + extra_offset));
|
||||
let path_str = try_opt!(self.trait_ref
|
||||
.rewrite(context, max_path_width, offset + extra_offset));
|
||||
|
||||
Some(format!("for<{}> {}", lifetime_str, path_str))
|
||||
} else {
|
||||
rewrite_path(context, false, None, &self.trait_ref.path, width, offset)
|
||||
self.trait_ref.rewrite(context, width, offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Rewrite for ast::TraitRef {
|
||||
fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
|
||||
rewrite_path(context, false, None, &self.path, width, offset)
|
||||
}
|
||||
}
|
||||
|
||||
impl Rewrite for ast::Ty {
|
||||
fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
|
||||
match self.node {
|
||||
|
@ -142,6 +142,13 @@ pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn trim_newlines(input: &str) -> &str {
|
||||
let start = input.find(|c| c != '\n' && c != '\r').unwrap_or(0);
|
||||
let end = input.rfind(|c| c != '\n' && c != '\r').unwrap_or(0) + 1;
|
||||
&input[start..end]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_pointer_width="64")]
|
||||
// Based on the trick layed out at
|
||||
|
@ -21,7 +21,7 @@
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use comment::rewrite_comment;
|
||||
use macros::rewrite_macro;
|
||||
use items::rewrite_static;
|
||||
use items::{rewrite_static, format_impl};
|
||||
|
||||
pub struct FmtVisitor<'a> {
|
||||
pub parse_session: &'a ParseSess,
|
||||
@ -200,14 +200,12 @@ fn visit_item(&mut self, item: &ast::Item) {
|
||||
ast::Item_::ItemUse(ref vp) => {
|
||||
self.format_import(item.vis, vp, item.span);
|
||||
}
|
||||
// FIXME(#78): format impl definitions.
|
||||
ast::Item_::ItemImpl(_, _, _, _, _, ref impl_items) => {
|
||||
ast::Item_::ItemImpl(..) => {
|
||||
self.format_missing_with_indent(item.span.lo);
|
||||
self.block_indent = self.block_indent.block_indent(self.config);
|
||||
for item in impl_items {
|
||||
self.visit_impl_item(&item);
|
||||
if let Some(impl_str) = format_impl(&self.get_context(), item, self.block_indent) {
|
||||
self.buffer.push_str(&impl_str);
|
||||
self.last_pos = item.span.hi;
|
||||
}
|
||||
self.block_indent = self.block_indent.block_unindent(self.config);
|
||||
}
|
||||
// FIXME(#78): format traits.
|
||||
ast::Item_::ItemTrait(_, _, _, ref trait_items) => {
|
||||
@ -334,7 +332,7 @@ fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
|
||||
pub fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
|
||||
if self.visit_attrs(&ii.attrs) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user