X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fvisitor.rs;h=63e2c6bdcac57c88c8128682b20880aaa8975a67;hb=6fb188bd43840f4a99c6a4b4cdbdb21ccf3304e7;hp=4fabb3301fc0b2a589a62abc9bf7aeb69e4cebdd;hpb=2f03180040b0a3c0a0e5dcd75670a9323f5f312d;p=rust.git diff --git a/src/visitor.rs b/src/visitor.rs index 4fabb3301fc..63e2c6bdcac 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -9,12 +9,11 @@ // 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::{ @@ -26,6 +25,7 @@ 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, @@ -60,8 +60,9 @@ pub fn new(start_pos: BytePos, big_snippet: &'a str) -> Self { } 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 @@ -75,7 +76,21 @@ pub struct FmtVisitor<'a> { 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) } @@ -83,19 +98,22 @@ pub fn shape(&self) -> Shape { 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) } } @@ -119,8 +137,8 @@ pub fn visit_block( ) { 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. @@ -140,7 +158,8 @@ pub fn visit_block( 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(); @@ -253,7 +272,6 @@ fn close_block(&mut self, unindent_comment: bool) { // Note that this only gets called for function definitions. Required methods // on traits do not get handled here. - // FIXME(topecongiro) Format async fn (#2812). fn visit_fn( &mut self, fk: visit::FnKind, @@ -349,11 +367,14 @@ pub fn visit_item(&mut self, item: &ast::Item) { 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) => { @@ -477,6 +498,7 @@ pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) { let rewrite = rewrite_associated_type( ti.ident, type_default.as_ref(), + &ti.generics, Some(generic_bounds), &self.get_context(), self.block_indent, @@ -515,7 +537,7 @@ pub fn visit_impl_item(&mut self, ii: &ast::ImplItem) { ii.ident, ii.defaultness, Some(ty), - None, + &ii.generics, &self.get_context(), self.block_indent, ); @@ -525,6 +547,7 @@ pub fn visit_impl_item(&mut self, ii: &ast::ImplItem) { let rewrite = rewrite_existential_impl_type( &self.get_context(), ii.ident, + &ii.generics, generic_bounds, self.block_indent, ); @@ -575,23 +598,26 @@ pub fn push_skipped_with_span(&mut self, span: Span) { } 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(), @@ -617,29 +643,28 @@ pub fn snippet(&'b self, span: Span) -> &'a str { 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) { @@ -741,10 +766,10 @@ fn format_mod( } } - 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) { @@ -766,20 +791,16 @@ pub fn with_context(&mut self, f: F) -> Option where F: Fn(&RewriteContext) -> Option, { - 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),