1 //! Module that contains skip related stuffs.
4 use rustc_ast_pretty::pprust;
6 /// Take care of skip name stack. You can update it by attributes slice or
7 /// by other context. Query this context to know if you need skip a block.
8 #[derive(Default, Clone)]
9 pub(crate) struct SkipContext {
11 attributes: Vec<String>,
15 pub(crate) fn update_with_attrs(&mut self, attrs: &[ast::Attribute]) {
16 self.macros.append(&mut get_skip_names("macros", attrs));
18 .append(&mut get_skip_names("attributes", attrs));
21 pub(crate) fn update(&mut self, mut other: SkipContext) {
22 self.macros.append(&mut other.macros);
23 self.attributes.append(&mut other.attributes);
26 pub(crate) fn skip_macro(&self, name: &str) -> bool {
27 self.macros.iter().any(|n| n == name)
30 pub(crate) fn skip_attribute(&self, name: &str) -> bool {
31 self.attributes.iter().any(|n| n == name)
35 static RUSTFMT: &str = "rustfmt";
36 static SKIP: &str = "skip";
38 /// Say if you're playing with `rustfmt`'s skip attribute
39 pub(crate) fn is_skip_attr(segments: &[ast::PathSegment]) -> bool {
40 if segments.len() < 2 || segments[0].ident.to_string() != RUSTFMT {
43 match segments.len() {
44 2 => segments[1].ident.to_string() == SKIP,
46 segments[1].ident.to_string() == SKIP
47 && ["macros", "attributes"]
49 .any(|&n| n == pprust::path_segment_to_string(&segments[2]))
55 fn get_skip_names(kind: &str, attrs: &[ast::Attribute]) -> Vec<String> {
56 let mut skip_names = vec![];
57 let path = format!("{}::{}::{}", RUSTFMT, SKIP, kind);
59 // rustc_ast::ast::Path is implemented partialEq
60 // but it is designed for segments.len() == 1
61 if let ast::AttrKind::Normal(normal) = &attr.kind {
62 if pprust::path_to_string(&normal.item.path) != path {
67 if let Some(list) = attr.meta_item_list() {
68 for nested_meta_item in list {
69 if let Some(name) = nested_meta_item.ident() {
70 skip_names.push(name.to_string());