use strings::string_buffer::StringBuffer;
-use Indent;
+use {Indent, Shape};
use utils;
use codemap::{LineRangeUtils, SpanUtils};
use config::Config;
use rewrite::{Rewrite, RewriteContext};
use comment::rewrite_comment;
-use macros::rewrite_macro;
-use items::{rewrite_static, rewrite_associated_type, rewrite_type_alias, format_impl, format_trait};
+use macros::{rewrite_macro, MacroPosition};
+use items::{rewrite_static, rewrite_associated_type, rewrite_associated_impl_type,
+ rewrite_type_alias, format_impl, format_trait};
fn is_use_item(item: &ast::Item) -> bool {
match item.node {
}
match stmt.node {
- ast::StmtKind::Decl(ref decl, _) => {
- if let ast::DeclKind::Item(ref item) = decl.node {
- self.visit_item(item);
- } else {
- let rewrite = stmt.rewrite(&self.get_context(),
- self.config.max_width - self.block_indent.width(),
- self.block_indent);
-
- self.push_rewrite(stmt.span, rewrite);
- }
+ ast::StmtKind::Item(ref item) => {
+ self.visit_item(item);
}
+ ast::StmtKind::Local(..) |
ast::StmtKind::Expr(..) |
ast::StmtKind::Semi(..) => {
let rewrite = stmt.rewrite(&self.get_context(),
- self.config.max_width - self.block_indent.width(),
- self.block_indent);
-
+ Shape::legacy(self.config.max_width -
+ self.block_indent.width(),
+ self.block_indent));
self.push_rewrite(stmt.span, rewrite);
}
- ast::StmtKind::Mac(ref mac, _macro_style, _) => {
- self.format_missing_with_indent(source!(self, stmt.span).lo);
- self.visit_mac(mac, None);
+ ast::StmtKind::Mac(ref mac) => {
+ let (ref mac, _macro_style, _) = **mac;
+ self.visit_mac(mac, None, MacroPosition::Statement);
+ self.format_missing(stmt.span.hi);
}
}
}
self.visit_stmt(stmt)
}
- if let Some(ref e) = b.expr {
- self.format_missing_with_indent(source!(self, e.span).lo);
- let rewrite = e.rewrite(&self.get_context(),
- self.config.max_width - self.block_indent.width(),
- self.block_indent)
- .unwrap_or_else(|| self.snippet(e.span));
-
- self.buffer.push_str(&rewrite);
- self.last_pos = source!(self, e.span).hi;
-
- if utils::semicolon_for_expr(e) {
- self.buffer.push_str(";");
+ if !b.stmts.is_empty() {
+ if let Some(expr) = utils::stmt_expr(&b.stmts[b.stmts.len() - 1]) {
+ if utils::semicolon_for_expr(expr) {
+ self.buffer.push_str(";");
+ }
}
}
fn visit_fn(&mut self,
fk: visit::FnKind,
fd: &ast::FnDecl,
- b: &ast::Block,
s: Span,
_: ast::NodeId,
defaultness: ast::Defaultness) {
let indent = self.block_indent;
+ let block;
let rewrite = match fk {
- visit::FnKind::ItemFn(ident, generics, unsafety, constness, abi, vis) => {
+ visit::FnKind::ItemFn(ident, generics, unsafety, constness, abi, vis, b) => {
+ block = b;
self.rewrite_fn(indent,
ident,
fd,
generics,
unsafety,
- constness,
+ constness.node,
defaultness,
abi,
vis,
codemap::mk_sp(s.lo, b.span.lo),
- b)
+ &b)
}
- visit::FnKind::Method(ident, sig, vis) => {
+ visit::FnKind::Method(ident, sig, vis, b) => {
+ block = b;
self.rewrite_fn(indent,
ident,
fd,
&sig.generics,
sig.unsafety,
- sig.constness,
+ sig.constness.node,
defaultness,
sig.abi,
vis.unwrap_or(&ast::Visibility::Inherited),
codemap::mk_sp(s.lo, b.span.lo),
- b)
+ &b)
}
- visit::FnKind::Closure => None,
+ visit::FnKind::Closure(_) => unreachable!(),
};
if let Some(fn_str) = rewrite {
self.buffer.push_str(&fn_str);
if let Some(c) = fn_str.chars().last() {
if c == '}' {
- self.last_pos = source!(self, b.span).hi;
+ self.last_pos = source!(self, block.span).hi;
return;
}
}
} else {
- self.format_missing(source!(self, b.span).lo);
+ self.format_missing(source!(self, block.span).lo);
}
- self.last_pos = source!(self, b.span).lo;
- self.visit_block(b)
+ self.last_pos = source!(self, block.span).lo;
+ self.visit_block(block)
}
pub fn visit_item(&mut self, item: &ast::Item) {
// This is where we bail out if there is a skip attribute. This is only
// complex in the module case. It is complex because the module could be
- // in a seperate file and there might be attributes in both files, but
+ // in a separate file and there might be attributes in both files, but
// the AST lumps them all together.
match item.node {
ast::ItemKind::Mod(ref m) => {
item.span,
indent,
None)
- .map(|s| {
- match *def {
- ast::VariantData::Tuple(..) => s + ";",
- _ => s,
- }
- })
+ .map(|s| match *def {
+ ast::VariantData::Tuple(..) => s + ";",
+ _ => s,
+ })
};
self.push_rewrite(item.span, rewrite);
}
self.format_mod(module, &item.vis, item.span, item.ident);
}
ast::ItemKind::Mac(ref mac) => {
- self.format_missing_with_indent(source!(self, item.span).lo);
- self.visit_mac(mac, Some(item.ident));
+ self.visit_mac(mac, Some(item.ident), MacroPosition::Item);
}
ast::ItemKind::ForeignMod(ref foreign_mod) => {
self.format_missing_with_indent(source!(self, item.span).lo);
ty,
mutability,
Some(expr),
+ self.block_indent,
&self.get_context());
self.push_rewrite(item.span, rewrite);
}
ty,
ast::Mutability::Immutable,
Some(expr),
+ self.block_indent,
&self.get_context());
self.push_rewrite(item.span, rewrite);
}
unsafety,
constness,
abi,
- &item.vis),
+ &item.vis,
+ body),
decl,
- body,
item.span,
item.id,
ast::Defaultness::Final)
item.span);
self.push_rewrite(item.span, rewrite);
}
+ ast::ItemKind::Union(..) => {
+ // FIXME(#1157): format union definitions.
+ }
}
}
pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
if self.visit_attrs(&ti.attrs) {
+ self.push_rewrite(ti.span, None);
return;
}
ty,
ast::Mutability::Immutable,
expr_opt.as_ref(),
+ self.block_indent,
&self.get_context());
self.push_rewrite(ti.span, rewrite);
}
self.push_rewrite(ti.span, rewrite);
}
ast::TraitItemKind::Method(ref sig, Some(ref body)) => {
- self.visit_fn(visit::FnKind::Method(ti.ident, sig, None),
+ self.visit_fn(visit::FnKind::Method(ti.ident, sig, None, body),
&sig.decl,
- body,
ti.span,
ti.id,
ast::Defaultness::Final);
self.block_indent);
self.push_rewrite(ti.span, rewrite);
}
+ ast::TraitItemKind::Macro(..) => {
+ // FIXME(#1158) Macros in trait item position
+ }
}
}
pub fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
if self.visit_attrs(&ii.attrs) {
+ self.push_rewrite(ii.span, None);
return;
}
match ii.node {
ast::ImplItemKind::Method(ref sig, ref body) => {
- self.visit_fn(visit::FnKind::Method(ii.ident, sig, Some(&ii.vis)),
+ self.visit_fn(visit::FnKind::Method(ii.ident, sig, Some(&ii.vis), body),
&sig.decl,
- body,
ii.span,
ii.id,
ii.defaultness);
ty,
ast::Mutability::Immutable,
Some(expr),
+ self.block_indent,
&self.get_context());
self.push_rewrite(ii.span, rewrite);
}
ast::ImplItemKind::Type(ref ty) => {
- let rewrite = rewrite_associated_type(ii.ident,
- Some(ty),
- None,
- &self.get_context(),
- self.block_indent);
+ let rewrite = rewrite_associated_impl_type(ii.ident,
+ ii.defaultness,
+ Some(ty),
+ None,
+ &self.get_context(),
+ self.block_indent);
self.push_rewrite(ii.span, rewrite);
}
ast::ImplItemKind::Macro(ref mac) => {
- self.format_missing_with_indent(source!(self, ii.span).lo);
- self.visit_mac(mac, Some(ii.ident));
+ self.visit_mac(mac, Some(ii.ident), MacroPosition::Item);
}
}
}
- fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>) {
+ fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>, pos: MacroPosition) {
// 1 = ;
let width = self.config.max_width - self.block_indent.width() - 1;
- let rewrite = rewrite_macro(mac, ident, &self.get_context(), width, self.block_indent);
-
- if let Some(res) = rewrite {
- self.buffer.push_str(&res);
- self.last_pos = source!(self, mac.span).hi;
- }
+ let rewrite = rewrite_macro(mac,
+ ident,
+ &self.get_context(),
+ Shape::legacy(width, self.block_indent),
+ pos);
+ self.push_rewrite(mac.span, rewrite);
}
fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
}
let outers: Vec<_> = attrs.iter()
- .filter(|a| a.node.style == ast::AttrStyle::Outer)
+ .filter(|a| a.style == ast::AttrStyle::Outer)
.cloned()
.collect();
if outers.is_empty() {
self.format_missing_with_indent(source!(self, first.span).lo);
let rewrite = outers.rewrite(&self.get_context(),
- self.config.max_width - self.block_indent.width(),
- self.block_indent)
+ Shape::legacy(self.config.max_width -
+ self.block_indent.width(),
+ self.block_indent))
.unwrap();
self.buffer.push_str(&rewrite);
let last = outers.last().unwrap();
fn format_mod(&mut self, m: &ast::Mod, vis: &ast::Visibility, s: Span, ident: ast::Ident) {
// Decide whether this is an inline mod or an external mod.
let local_file_name = self.codemap.span_to_filename(s);
- let is_internal = local_file_name == self.codemap.span_to_filename(source!(self, m.inner));
+ let inner_span = source!(self, m.inner);
+ let is_internal = !(inner_span.lo.0 == 0 && inner_span.hi.0 == 0) &&
+ local_file_name == self.codemap.span_to_filename(inner_span);
self.buffer.push_str(&*utils::format_visibility(vis));
self.buffer.push_str("mod ");
}
pub fn format_separate_mod(&mut self, m: &ast::Mod) {
- let filemap = self.codemap.lookup_char_pos(source!(self, m.inner).lo).file;
+ let filemap = self.codemap.lookup_char_pos(m.inner.lo).file;
self.last_pos = filemap.start_pos;
self.block_indent = Indent::empty();
self.walk_mod_items(m);
parse_session: self.parse_session,
codemap: self.codemap,
config: self.config,
- block_indent: self.block_indent,
}
}
}
impl<'a> Rewrite for [ast::Attribute] {
- fn rewrite(&self, context: &RewriteContext, _: usize, offset: Indent) -> Option<String> {
+ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
let mut result = String::new();
if self.is_empty() {
return Some(result);
}
- let indent = offset.to_string(context.config);
+ let indent = shape.indent.to_string(context.config);
for (i, a) in self.iter().enumerate() {
let mut a_str = context.snippet(a.span);
if !comment.is_empty() {
let comment = try_opt!(rewrite_comment(comment,
false,
- context.config.ideal_width -
- offset.width(),
- offset,
+ Shape::legacy(context.config
+ .comment_width -
+ shape.indent.width(),
+ shape.indent),
context.config));
result.push_str(&indent);
result.push_str(&comment);
if a_str.starts_with("//") {
a_str = try_opt!(rewrite_comment(&a_str,
false,
- context.config.ideal_width - offset.width(),
- offset,
+ Shape::legacy(context.config.comment_width -
+ shape.indent.width(),
+ shape.indent),
context.config));
}