diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/attr.rs | 6 | ||||
| -rw-r--r-- | src/formatting.rs | 7 | ||||
| -rw-r--r-- | src/lib.rs | 1 | ||||
| -rw-r--r-- | src/macros.rs | 5 | ||||
| -rw-r--r-- | src/rewrite.rs | 3 | ||||
| -rw-r--r-- | src/skip.rs | 73 | ||||
| -rw-r--r-- | src/test/mod.rs | 1 | ||||
| -rw-r--r-- | src/utils.rs | 20 | ||||
| -rw-r--r-- | src/visitor.rs | 33 |
9 files changed, 97 insertions, 52 deletions
diff --git a/src/attr.rs b/src/attr.rs index 8497917ab06..1c9092ea629 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -319,9 +319,13 @@ impl Rewrite for ast::Attribute { if self.is_sugared_doc { rewrite_doc_comment(snippet, shape.comment(context.config), context.config) } else { + let should_skip = self + .ident() + .map(|s| context.skip_context.skip_attribute(&s.name.as_str())) + .unwrap_or(false); let prefix = attr_prefix(self); - if contains_comment(snippet) { + if should_skip || contains_comment(snippet) { return Some(snippet.to_owned()); } diff --git a/src/formatting.rs b/src/formatting.rs index 0faeb5102f2..879ddc61b13 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -17,7 +17,7 @@ use crate::comment::{CharClasses, FullCodeCharKind}; use crate::config::{Config, FileName, Verbosity}; use crate::ignore_path::IgnorePathSet; use crate::issues::BadIssueSeeker; -use crate::utils::{count_newlines, get_skip_macro_names}; +use crate::utils::count_newlines; use crate::visitor::{FmtVisitor, SnippetProvider}; use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session}; @@ -158,10 +158,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { &snippet_provider, self.report.clone(), ); - visitor - .skip_macro_names - .borrow_mut() - .append(&mut get_skip_macro_names(&self.krate.attrs)); + visitor.skip_context.update_with_attrs(&self.krate.attrs); // Format inner attributes if available. if !self.krate.attrs.is_empty() && is_root { diff --git a/src/lib.rs b/src/lib.rs index 1b4ce663313..a672e2cc8aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,6 +69,7 @@ mod reorder; mod rewrite; pub(crate) mod rustfmt_diff; mod shape; +mod skip; pub(crate) mod source_file; pub(crate) mod source_map; mod spanned; diff --git a/src/macros.rs b/src/macros.rs index c42010f77b2..0fbc7521ad7 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -211,9 +211,8 @@ pub(crate) fn rewrite_macro( position: MacroPosition, ) -> Option<String> { let should_skip = context - .skip_macro_names - .borrow() - .contains(&context.snippet(mac.node.path.span).to_owned()); + .skip_context + .skip_macro(&context.snippet(mac.node.path.span).to_owned()); if should_skip { None } else { diff --git a/src/rewrite.rs b/src/rewrite.rs index 9a955dbd91b..606aafc9ebd 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -8,6 +8,7 @@ use syntax::source_map::{SourceMap, Span}; use crate::config::{Config, IndentStyle}; use crate::shape::Shape; +use crate::skip::SkipContext; use crate::visitor::SnippetProvider; use crate::FormatReport; @@ -39,7 +40,7 @@ pub(crate) struct RewriteContext<'a> { // Used for `format_snippet` pub(crate) macro_rewrite_failure: RefCell<bool>, pub(crate) report: FormatReport, - pub(crate) skip_macro_names: RefCell<Vec<String>>, + pub(crate) skip_context: SkipContext, } impl<'a> RewriteContext<'a> { diff --git a/src/skip.rs b/src/skip.rs new file mode 100644 index 00000000000..6b4e04a7173 --- /dev/null +++ b/src/skip.rs @@ -0,0 +1,73 @@ +//! Module that contains skip related stuffs. + +use syntax::ast; + +/// Take care of skip name stack. You can update it by attributes slice or +/// by other context. Query this context to know if you need skip a block. +#[derive(Default, Clone)] +pub(crate) struct SkipContext { + macros: Vec<String>, + attributes: Vec<String>, +} + +impl SkipContext { + pub(crate) fn update_with_attrs(&mut self, attrs: &[ast::Attribute]) { + self.macros.append(&mut get_skip_names("macros", attrs)); + self.attributes + .append(&mut get_skip_names("attributes", attrs)); + } + + pub(crate) fn update(&mut self, mut other: SkipContext) { + self.macros.append(&mut other.macros); + self.attributes.append(&mut other.attributes); + } + + pub(crate) fn skip_macro(&self, name: &str) -> bool { + self.macros.iter().any(|n| n == name) + } + + pub(crate) fn skip_attribute(&self, name: &str) -> bool { + self.attributes.iter().any(|n| n == name) + } +} + +static RUSTFMT: &'static str = "rustfmt"; +static SKIP: &'static str = "skip"; + +/// Say if you're playing with `rustfmt`'s skip attribute +pub(crate) fn is_skip_attr(segments: &[ast::PathSegment]) -> bool { + if segments.len() < 2 || segments[0].ident.to_string() != RUSTFMT { + return false; + } + match segments.len() { + 2 => segments[1].ident.to_string() == SKIP, + 3 => { + segments[1].ident.to_string() == SKIP + && ["macros", "attributes"] + .iter() + .any(|&n| n == &segments[2].ident.name.as_str()) + } + _ => false, + } +} + +fn get_skip_names(kind: &str, attrs: &[ast::Attribute]) -> Vec<String> { + let mut skip_names = vec![]; + let path = format!("{}::{}::{}", RUSTFMT, SKIP, kind); + for attr in attrs { + // syntax::ast::Path is implemented partialEq + // but it is designed for segments.len() == 1 + if format!("{}", attr.path) != path { + continue; + } + + if let Some(list) = attr.meta_item_list() { + for nested_meta_item in list { + if let Some(name) = nested_meta_item.ident() { + skip_names.push(name.to_string()); + } + } + } + } + skip_names +} diff --git a/src/test/mod.rs b/src/test/mod.rs index 10aad268a8d..a7063c76f28 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -26,6 +26,7 @@ const SKIP_FILE_WHITE_LIST: &[&str] = &[ // so we do not want to test this file directly. "configs/skip_children/foo/mod.rs", "issue-3434/no_entry.rs", + "issue-3665/sub_mod.rs", // These files and directory are a part of modules defined inside `cfg_if!`. "cfg_if/mod.rs", "cfg_if/detect", diff --git a/src/utils.rs b/src/utils.rs index 1a4941aa72e..9adc9390111 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -638,26 +638,6 @@ pub(crate) fn unicode_str_width(s: &str) -> usize { s.width() } -pub(crate) fn get_skip_macro_names(attrs: &[ast::Attribute]) -> Vec<String> { - let mut skip_macro_names = vec![]; - for attr in attrs { - // syntax::ast::Path is implemented partialEq - // but it is designed for segments.len() == 1 - if format!("{}", attr.path) != "rustfmt::skip::macros" { - continue; - } - - if let Some(list) = attr.meta_item_list() { - for nested_meta_item in list { - if let Some(name) = nested_meta_item.ident() { - skip_macro_names.push(name.to_string()); - } - } - } - } - skip_macro_names -} - #[cfg(test)] mod test { use super::*; diff --git a/src/visitor.rs b/src/visitor.rs index d145693b9aa..35291cecfb5 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -17,12 +17,13 @@ use crate::items::{ use crate::macros::{rewrite_macro, rewrite_macro_def, MacroPosition}; use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; +use crate::skip::{is_skip_attr, SkipContext}; use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; use crate::stmt::Stmt; use crate::utils::{ - self, contains_skip, count_newlines, depr_skip_annotation, get_skip_macro_names, - inner_attributes, mk_sp, ptr_vec_to_ref_vec, rewrite_ident, stmt_expr, + self, contains_skip, count_newlines, depr_skip_annotation, inner_attributes, mk_sp, + ptr_vec_to_ref_vec, rewrite_ident, stmt_expr, }; use crate::{ErrorKind, FormatReport, FormattingError}; @@ -67,7 +68,7 @@ pub(crate) struct FmtVisitor<'a> { pub(crate) skipped_range: Vec<(usize, usize)>, pub(crate) macro_rewrite_failure: bool, pub(crate) report: FormatReport, - pub(crate) skip_macro_names: RefCell<Vec<String>>, + pub(crate) skip_context: SkipContext, } impl<'a> Drop for FmtVisitor<'a> { @@ -347,10 +348,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // the AST lumps them all together. let filtered_attrs; let mut attrs = &item.attrs; - let temp_skip_macro_names = self.skip_macro_names.clone(); - self.skip_macro_names - .borrow_mut() - .append(&mut get_skip_macro_names(&attrs)); + let skip_context_saved = self.skip_context.clone(); + self.skip_context.update_with_attrs(&attrs); let should_visit_node_again = match item.node { // For use/extern crate items, skip rewriting attributes but check for a skip attribute. @@ -501,7 +500,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } }; } - self.skip_macro_names = temp_skip_macro_names; + self.skip_context = skip_context_saved; } pub(crate) fn visit_trait_item(&mut self, ti: &ast::TraitItem) { @@ -656,10 +655,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ctx.snippet_provider, ctx.report.clone(), ); - visitor - .skip_macro_names - .borrow_mut() - .append(&mut ctx.skip_macro_names.borrow().clone()); + visitor.skip_context.update(ctx.skip_context.clone()); visitor.set_parent_context(ctx); visitor } @@ -684,7 +680,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { skipped_range: vec![], macro_rewrite_failure: false, report, - skip_macro_names: RefCell::new(vec![]), + skip_context: Default::default(), } } @@ -741,14 +737,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { if segments[0].ident.to_string() != "rustfmt" { return false; } - - match segments.len() { - 2 => segments[1].ident.to_string() != "skip", - 3 => { - segments[1].ident.to_string() != "skip" || segments[2].ident.to_string() != "macros" - } - _ => false, - } + !is_skip_attr(segments) } fn walk_mod_items(&mut self, m: &ast::Mod) { @@ -881,7 +870,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { snippet_provider: self.snippet_provider, macro_rewrite_failure: RefCell::new(false), report: self.report.clone(), - skip_macro_names: self.skip_macro_names.clone(), + skip_context: self.skip_context.clone(), } } } |
