Implement Rewrite trait for ast::ForeignItem

This commit is contained in:
topecongiro 2017-08-25 08:19:51 +09:00
parent 1a02c35f9b
commit 1f9e7c25c9
3 changed files with 77 additions and 58 deletions

View File

@ -185,64 +185,11 @@ pub fn format_foreign_mod(&mut self, fm: &ast::ForeignMod, span: Span) {
self.format_item(item);
}
fn format_foreign_item(&mut self, item: &ast::ForeignItem) {
self.format_missing_with_indent(item.span.lo);
// Drop semicolon or it will be interpreted as comment.
// FIXME: this may be a faulty span from libsyntax.
let span = mk_sp(item.span.lo, item.span.hi - BytePos(1));
match item.node {
ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => {
let indent = self.block_indent;
let rewrite = rewrite_fn_base(
&self.get_context(),
indent,
item.ident,
fn_decl,
generics,
ast::Unsafety::Normal,
ast::Constness::NotConst,
ast::Defaultness::Final,
// These are not actually rust functions,
// but we format them as such.
abi::Abi::Rust,
&item.vis,
span,
false,
false,
false,
);
match rewrite {
Some((new_fn, _)) => {
self.buffer.push_str(&new_fn);
self.buffer.push_str(";");
}
None => self.format_missing(item.span.hi),
}
}
ast::ForeignItemKind::Static(ref ty, is_mutable) => {
// FIXME(#21): we're dropping potential comments in between the
// function keywords here.
let vis = format_visibility(&item.vis);
let mut_str = if is_mutable { "mut " } else { "" };
let prefix = format!("{}static {}{}: ", vis, mut_str, item.ident);
let offset = self.block_indent + prefix.len();
// 1 = ;
let shape = Shape::indented(offset, self.config).sub_width(1).unwrap();
let rewrite = ty.rewrite(&self.get_context(), shape);
match rewrite {
Some(result) => {
self.buffer.push_str(&prefix);
self.buffer.push_str(&result);
self.buffer.push_str(";");
}
None => self.format_missing(item.span.hi),
}
}
}
let shape = Shape::indented(self.block_indent, self.config);
let rewrite = item.rewrite(&self.get_context(), shape);
self.push_rewrite(item.span(), rewrite);
self.last_pos = item.span.hi;
}
@ -2837,3 +2784,68 @@ fn format_generics(
Some(result)
}
impl Rewrite for ast::ForeignItem {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
let attrs_str = try_opt!(self.attrs.rewrite(context, shape));
// Drop semicolon or it will be interpreted as comment.
// FIXME: this may be a faulty span from libsyntax.
let span = mk_sp(self.span.lo, self.span.hi - BytePos(1));
let item_str = try_opt!(match self.node {
ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => {
rewrite_fn_base(
context,
shape.indent,
self.ident,
fn_decl,
generics,
ast::Unsafety::Normal,
ast::Constness::NotConst,
ast::Defaultness::Final,
// These are not actually rust functions,
// but we format them as such.
abi::Abi::Rust,
&self.vis,
span,
false,
false,
false,
).map(|(s, _)| format!("{};", s))
}
ast::ForeignItemKind::Static(ref ty, is_mutable) => {
// FIXME(#21): we're dropping potential comments in between the
// function keywords here.
let vis = format_visibility(&self.vis);
let mut_str = if is_mutable { "mut " } else { "" };
let prefix = format!("{}static {}{}:", vis, mut_str, self.ident);
// 1 = ;
let shape = try_opt!(shape.sub_width(1));
ty.rewrite(context, shape).map(|ty_str| {
// 1 = space between prefix and type.
let sep = if prefix.len() + ty_str.len() + 1 <= shape.width {
String::from(" ")
} else {
let nested_indent = shape.indent.block_indent(context.config);
format!("\n{}", nested_indent.to_string(context.config))
};
format!("{}{}{};", prefix, sep, ty_str)
})
}
});
let missing_span = if self.attrs.is_empty() {
mk_sp(self.span.lo, self.span.lo)
} else {
mk_sp(self.attrs[self.attrs.len() - 1].span.hi, self.span.lo)
};
combine_strs_with_missing_comments(
context,
&attrs_str,
&item_str,
missing_span,
shape,
false,
)
}
}

View File

@ -74,6 +74,7 @@
mod summary;
mod vertical;
/// Spanned returns a span including attributes, if available.
pub trait Spanned {
fn span(&self) -> Span;
}
@ -207,6 +208,12 @@ fn span(&self) -> Span {
}
}
impl Spanned for ast::ForeignItem {
fn span(&self) -> Span {
span_with_attrs!(self)
}
}
#[derive(Copy, Clone, Debug)]
pub struct Indent {
// Width of the block indent, in characters. Must be a multiple of

View File

@ -641,7 +641,7 @@ fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>, pos: MacroPos
self.push_rewrite(mac.span, rewrite);
}
fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
pub fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
self.format_missing_with_indent(source!(self, span).lo);
let result = rewrite.unwrap_or_else(|| self.snippet(span));
self.buffer.push_str(&result);