1
1
//! Module that contains skip related stuffs.
2
2
3
3
use syntax:: ast;
4
+ use syntax:: symbol:: { sym, Symbol } ;
5
+
6
+ macro_rules! sym {
7
+ ( $tt: tt) => {
8
+ Symbol :: intern( stringify!( $tt) )
9
+ } ;
10
+ }
4
11
5
12
/// Take care of skip name stack. You can update it by attributes slice or
6
13
/// by other context. Query this context to know if you need skip a block.
@@ -12,12 +19,25 @@ pub(crate) struct SkipContext {
12
19
13
20
impl SkipContext {
14
21
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
+ }
18
38
}
19
39
20
- pub ( crate ) fn update ( & mut self , mut other : SkipContext ) {
40
+ pub ( crate ) fn update ( & mut self , mut other : Self ) {
21
41
self . macros . append ( & mut other. macros ) ;
22
42
self . attributes . append ( & mut other. attributes ) ;
23
43
}
@@ -31,43 +51,18 @@ impl SkipContext {
31
51
}
32
52
}
33
53
34
- static RUSTFMT : & str = "rustfmt" ;
35
- static SKIP : & str = "skip" ;
36
-
37
54
/// Say if you're playing with `rustfmt`'s skip attribute
38
55
pub ( 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 {
40
61
return false ;
41
62
}
42
63
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 ) ,
50
66
_ => false ,
51
67
}
52
68
}
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