// except according to those terms.
use syntax::attr::HasAttrs;
-use syntax::codemap::{self, BytePos, CodeMap, Pos, Span};
use syntax::parse::ParseSess;
+use syntax::source_map::{self, BytePos, Pos, SourceMap, Span};
use syntax::{ast, visit};
use attr::*;
-use codemap::{LineRangeUtils, SpanUtils};
use comment::{CodeCharKind, CommentCodeSlices, FindUncommented};
use config::{BraceStyle, Config};
use items::{
format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item,
- rewrite_associated_impl_type, rewrite_associated_type, rewrite_extern_crate,
- rewrite_type_alias, FnSig, StaticParts, StructParts,
+ rewrite_associated_impl_type, rewrite_associated_type, rewrite_existential_impl_type,
+ rewrite_existential_type, rewrite_extern_crate, rewrite_type_alias, FnSig, StaticParts,
+ StructParts,
};
use macros::{rewrite_macro, rewrite_macro_def, MacroPosition};
use rewrite::{Rewrite, RewriteContext};
use shape::{Indent, Shape};
+use source_map::{LineRangeUtils, SpanUtils};
use spanned::Spanned;
use utils::{
self, contains_skip, count_newlines, inner_attributes, mk_sp, ptr_vec_to_ref_vec,
}
pub struct FmtVisitor<'a> {
+ parent_context: Option<&'a RewriteContext<'a>>,
pub parse_session: &'a ParseSess,
- pub codemap: &'a CodeMap,
+ pub source_map: &'a SourceMap,
pub buffer: String,
pub last_pos: BytePos,
// FIXME: use an RAII util or closure for indenting
pub(crate) report: FormatReport,
}
+impl<'a> Drop for FmtVisitor<'a> {
+ fn drop(&mut self) {
+ if let Some(ctx) = self.parent_context {
+ if self.macro_rewrite_failure {
+ ctx.macro_rewrite_failure.replace(true);
+ }
+ }
+ }
+}
+
impl<'b, 'a: 'b> FmtVisitor<'a> {
+ fn set_parent_context(&mut self, context: &'a RewriteContext) {
+ self.parent_context = Some(context);
+ }
+
pub fn shape(&self) -> Shape {
Shape::indented(self.block_indent, self.config)
}
fn visit_stmt(&mut self, stmt: &ast::Stmt) {
debug!(
"visit_stmt: {:?} {:?}",
- self.codemap.lookup_char_pos(stmt.span.lo()),
- self.codemap.lookup_char_pos(stmt.span.hi())
+ self.source_map.lookup_char_pos(stmt.span.lo()),
+ self.source_map.lookup_char_pos(stmt.span.hi())
);
match stmt.node {
ast::StmtKind::Item(ref item) => {
self.visit_item(item);
+ // Handle potential `;` after the item.
+ self.format_missing(stmt.span.hi());
}
ast::StmtKind::Local(..) | ast::StmtKind::Expr(..) | ast::StmtKind::Semi(..) => {
if contains_skip(get_attrs_from_stmt(stmt)) {
self.push_skipped_with_span(stmt.span());
} else {
- let rewrite = stmt.rewrite(&self.get_context(), self.shape());
+ let shape = self.shape();
+ let rewrite = self.with_context(|ctx| stmt.rewrite(&ctx, shape));
self.push_rewrite(stmt.span(), rewrite)
}
}
) {
debug!(
"visit_block: {:?} {:?}",
- self.codemap.lookup_char_pos(b.span.lo()),
- self.codemap.lookup_char_pos(b.span.hi())
+ self.source_map.lookup_char_pos(b.span.lo()),
+ self.source_map.lookup_char_pos(b.span.hi())
);
// Check if this block has braces.
item.attrs.first()
} else {
first_stmt.attrs().first()
- }.and_then(|attr| {
+ }
+ .and_then(|attr| {
// Some stmts can have embedded attributes.
// e.g. `match { #![attr] ... }`
let attr_lo = attr.span.lo();
let indent = self.block_indent;
let block;
let rewrite = match fk {
- visit::FnKind::ItemFn(ident, _, _, _, _, b) | visit::FnKind::Method(ident, _, _, b) => {
+ visit::FnKind::ItemFn(ident, _, _, b) | visit::FnKind::Method(ident, _, _, b) => {
block = b;
self.rewrite_fn(
indent,
let where_span_end = snippet
.find_uncommented("{")
.map(|x| BytePos(x as u32) + source!(self, item.span).lo());
- let rw = format_impl(&self.get_context(), item, self.block_indent, where_span_end);
+ let block_indent = self.block_indent;
+ let rw =
+ self.with_context(|ctx| format_impl(&ctx, item, block_indent, where_span_end));
self.push_rewrite(item.span, rw);
}
ast::ItemKind::Trait(..) => {
- let rw = format_trait(&self.get_context(), item, self.block_indent);
+ let block_indent = self.block_indent;
+ let rw = self.with_context(|ctx| format_trait(&ctx, item, block_indent));
self.push_rewrite(item.span, rw);
}
ast::ItemKind::TraitAlias(ref generics, ref generic_bounds) => {
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => {
self.visit_static(&StaticParts::from_item(item));
}
- ast::ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
+ ast::ItemKind::Fn(ref decl, fn_header, ref generics, ref body) => {
let inner_attrs = inner_attributes(&item.attrs);
self.visit_fn(
- visit::FnKind::ItemFn(item.ident, unsafety, constness, abi, &item.vis, body),
+ visit::FnKind::ItemFn(item.ident, fn_header, &item.vis, body),
generics,
decl,
item.span,
ty,
generics,
&item.vis,
- item.span,
+ );
+ self.push_rewrite(item.span, rewrite);
+ }
+ ast::ItemKind::Existential(ref generic_bounds, ref generics) => {
+ let rewrite = rewrite_existential_type(
+ &self.get_context(),
+ self.block_indent,
+ item.ident,
+ generic_bounds,
+ generics,
+ &item.vis,
);
self.push_rewrite(item.span, rewrite);
}
let rewrite = rewrite_associated_type(
ti.ident,
type_default.as_ref(),
+ &ti.generics,
Some(generic_bounds),
&self.get_context(),
self.block_indent,
ii.ident,
ii.defaultness,
Some(ty),
- None,
+ &ii.generics,
&self.get_context(),
self.block_indent,
);
self.push_rewrite(ii.span, rewrite);
}
+ ast::ImplItemKind::Existential(ref generic_bounds) => {
+ let rewrite = rewrite_existential_impl_type(
+ &self.get_context(),
+ ii.ident,
+ &ii.generics,
+ generic_bounds,
+ self.block_indent,
+ );
+ self.push_rewrite(ii.span, rewrite);
+ }
ast::ImplItemKind::Macro(ref mac) => {
self.visit_mac(mac, Some(ii.ident), MacroPosition::Item);
}
}
pub fn from_context(ctx: &'a RewriteContext) -> FmtVisitor<'a> {
- FmtVisitor::from_codemap(
+ let mut visitor = FmtVisitor::from_source_map(
ctx.parse_session,
ctx.config,
ctx.snippet_provider,
ctx.report.clone(),
- )
+ );
+ visitor.set_parent_context(ctx);
+ visitor
}
- pub(crate) fn from_codemap(
+ pub(crate) fn from_source_map(
parse_session: &'a ParseSess,
config: &'a Config,
snippet_provider: &'a SnippetProvider,
report: FormatReport,
) -> FmtVisitor<'a> {
FmtVisitor {
+ parent_context: None,
parse_session,
- codemap: parse_session.codemap(),
+ source_map: parse_session.source_map(),
buffer: String::with_capacity(snippet_provider.big_snippet.len() * 2),
last_pos: BytePos(0),
block_indent: Indent::empty(),
pub fn visit_attrs(&mut self, attrs: &[ast::Attribute], style: ast::AttrStyle) -> bool {
for attr in attrs {
if attr.name() == DEPR_SKIP_ANNOTATION {
- let file_name = self.codemap.span_to_filename(attr.span).into();
+ let file_name = self.source_map.span_to_filename(attr.span).into();
self.report.append(
file_name,
vec![FormattingError::from_span(
- &attr.span,
- &self.codemap,
+ attr.span,
+ &self.source_map,
ErrorKind::DeprecatedAttr,
)],
);
- } else if attr.path.segments[0].ident.to_string() == "rustfmt" {
- if attr.path.segments.len() == 1
- || attr.path.segments[1].ident.to_string() != "skip"
- {
- let file_name = self.codemap.span_to_filename(attr.span).into();
- self.report.append(
- file_name,
- vec![FormattingError::from_span(
- &attr.span,
- &self.codemap,
- ErrorKind::BadAttr,
- )],
- );
- }
+ } else if attr.path.segments[0].ident.to_string() == "rustfmt"
+ && (attr.path.segments.len() == 1
+ || attr.path.segments[1].ident.to_string() != "skip")
+ {
+ let file_name = self.source_map.span_to_filename(attr.span).into();
+ self.report.append(
+ file_name,
+ vec![FormattingError::from_span(
+ attr.span,
+ &self.source_map,
+ ErrorKind::BadAttr,
+ )],
+ );
}
}
if contains_skip(attrs) {
}
}
- pub fn format_separate_mod(&mut self, m: &ast::Mod, filemap: &codemap::FileMap) {
+ pub fn format_separate_mod(&mut self, m: &ast::Mod, source_file: &source_map::SourceFile) {
self.block_indent = Indent::empty();
self.walk_mod_items(m);
- self.format_missing_with_indent(filemap.end_pos);
+ self.format_missing_with_indent(source_file.end_pos);
}
pub fn skip_empty_lines(&mut self, end_pos: BytePos) {
where
F: Fn(&RewriteContext) -> Option<String>,
{
- let result;
- let macro_rewrite_failure = {
- let context = self.get_context();
- result = f(&context);
- unsafe { *context.macro_rewrite_failure.as_ptr() }
- };
- self.macro_rewrite_failure |= macro_rewrite_failure;
+ let context = self.get_context();
+ let result = f(&context);
+ self.macro_rewrite_failure |= *context.macro_rewrite_failure.borrow();
result
}
pub fn get_context(&self) -> RewriteContext {
RewriteContext {
parse_session: self.parse_session,
- codemap: self.codemap,
+ source_map: self.source_map,
config: self.config,
inside_macro: RefCell::new(false),
use_block: RefCell::new(false),