11//! Module that contains skip related stuffs.
22
33use syntax:: ast;
4+ use syntax:: symbol:: { sym, Symbol } ;
5+
6+ macro_rules! sym {
7+ ( $tt: tt) => {
8+ Symbol :: intern( stringify!( $tt) )
9+ } ;
10+ }
411
512/// Take care of skip name stack. You can update it by attributes slice or
613/// by other context. Query this context to know if you need skip a block.
@@ -12,12 +19,25 @@ pub(crate) struct SkipContext {
1219
1320impl SkipContext {
1421 pub ( crate ) fn update_with_attrs ( & mut self , attrs : & [ ast:: Attribute ] ) {
15- self . macros . append ( & mut get_skip_names ( "macros" , attrs) ) ;
16- self . attributes
17- . append ( & mut get_skip_names ( "attributes" , attrs) ) ;
22+ fn get_skip_names ( vs : & mut Vec < String > , attr : & ast:: Attribute ) {
23+ if let Some ( list) = attr. meta_item_list ( ) {
24+ for nested_meta_item in list {
25+ if let Some ( name) = nested_meta_item. ident ( ) {
26+ vs. push ( name. to_string ( ) ) ;
27+ }
28+ }
29+ }
30+ }
31+ for attr in attrs {
32+ if is_skip_attr_with ( & attr. item . path . segments , |s| s == sym ! ( macros) ) {
33+ get_skip_names ( & mut self . macros , attr)
34+ } else if is_skip_attr_with ( & attr. item . path . segments , |s| s == sym:: attributes) {
35+ get_skip_names ( & mut self . attributes , attr)
36+ }
37+ }
1838 }
1939
20- pub ( crate ) fn update ( & mut self , mut other : SkipContext ) {
40+ pub ( crate ) fn update ( & mut self , mut other : Self ) {
2141 self . macros . append ( & mut other. macros ) ;
2242 self . attributes . append ( & mut other. attributes ) ;
2343 }
@@ -31,43 +51,18 @@ impl SkipContext {
3151 }
3252}
3353
34- static RUSTFMT : & str = "rustfmt" ;
35- static SKIP : & str = "skip" ;
36-
3754/// Say if you're playing with `rustfmt`'s skip attribute
3855pub ( crate ) fn is_skip_attr ( segments : & [ ast:: PathSegment ] ) -> bool {
39- if segments. len ( ) < 2 || segments[ 0 ] . ident . as_str ( ) != RUSTFMT {
56+ is_skip_attr_with ( segments, |s| s == sym ! ( macros) || s == sym:: attributes)
57+ }
58+
59+ fn is_skip_attr_with ( segments : & [ ast:: PathSegment ] , pred : impl FnOnce ( Symbol ) -> bool ) -> bool {
60+ if segments. len ( ) < 2 || segments[ 0 ] . ident . name != sym:: rustfmt {
4061 return false ;
4162 }
4263 match segments. len ( ) {
43- 2 => segments[ 1 ] . ident . as_str ( ) == SKIP ,
44- 3 => {
45- segments[ 1 ] . ident . as_str ( ) == SKIP
46- && [ "macros" , "attributes" ]
47- . iter ( )
48- . any ( |& n| n == segments[ 2 ] . ident . name . as_str ( ) )
49- }
64+ 2 => segments[ 1 ] . ident . name == sym ! ( skip) ,
65+ 3 => segments[ 1 ] . ident . name == sym ! ( skip) && pred ( segments[ 2 ] . ident . name ) ,
5066 _ => false ,
5167 }
5268}
53-
54- fn get_skip_names ( kind : & str , attrs : & [ ast:: Attribute ] ) -> Vec < String > {
55- let mut skip_names = vec ! [ ] ;
56- let path = format ! ( "{}::{}::{}" , RUSTFMT , SKIP , kind) ;
57- for attr in attrs {
58- // syntax::ast::Path is implemented partialEq
59- // but it is designed for segments.len() == 1
60- if format ! ( "{}" , attr. path) != path {
61- continue ;
62- }
63-
64- if let Some ( list) = attr. meta_item_list ( ) {
65- for nested_meta_item in list {
66- if let Some ( name) = nested_meta_item. ident ( ) {
67- skip_names. push ( name. to_string ( ) ) ;
68- }
69- }
70- }
71- }
72- skip_names
73- }
0 commit comments