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,9 +19,9 @@ 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 ) ) ;
22
+ self . macros . append ( & mut get_skip_names ( attrs , sym ! ( macros ) ) ) ;
16
23
self . attributes
17
- . append ( & mut get_skip_names ( "attributes" , attrs ) ) ;
24
+ . append ( & mut get_skip_names ( attrs , sym :: attributes ) ) ;
18
25
}
19
26
20
27
pub ( crate ) fn update ( & mut self , mut other : SkipContext ) {
@@ -31,40 +38,42 @@ impl SkipContext {
31
38
}
32
39
}
33
40
34
- static RUSTFMT : & str = "rustfmt" ;
35
- static SKIP : & str = "skip" ;
36
-
37
41
/// Say if you're playing with `rustfmt`'s skip attribute
38
42
pub ( crate ) fn is_skip_attr ( segments : & [ ast:: PathSegment ] ) -> bool {
39
- if segments. len ( ) < 2 || segments[ 0 ] . ident . as_str ( ) != RUSTFMT {
43
+ if segments. len ( ) < 2 || segments[ 0 ] . ident . name != sym :: rustfmt {
40
44
return false ;
41
45
}
42
46
match segments. len ( ) {
43
- 2 => segments[ 1 ] . ident . as_str ( ) == SKIP ,
47
+ 2 => segments[ 1 ] . ident . name == sym ! ( skip ) ,
44
48
3 => {
45
- segments[ 1 ] . ident . as_str ( ) == SKIP
46
- && [ "macros" , "attributes" ]
47
- . iter ( )
48
- . any ( |& n| n == segments[ 2 ] . ident . name . as_str ( ) )
49
+ segments[ 1 ] . ident . name == sym ! ( skip)
50
+ && ( segments[ 2 ] . ident . name == sym ! ( macros)
51
+ || segments[ 2 ] . ident . name == sym:: attributes)
49
52
}
50
53
_ => false ,
51
54
}
52
55
}
53
56
54
- fn get_skip_names ( kind : & str , attrs : & [ ast:: Attribute ] ) -> Vec < String > {
57
+ fn is_skip_attr_with_symbol ( segments : & [ ast:: PathSegment ] , kind : Symbol ) -> bool {
58
+ if segments. len ( ) < 2 || segments[ 0 ] . ident . name != sym:: rustfmt {
59
+ return false ;
60
+ }
61
+ match segments. len ( ) {
62
+ 2 => segments[ 1 ] . ident . name == sym ! ( skip) ,
63
+ 3 => segments[ 1 ] . ident . name == sym ! ( skip) && segments[ 2 ] . ident . name == kind,
64
+ _ => false ,
65
+ }
66
+ }
67
+
68
+ fn get_skip_names ( attrs : & [ ast:: Attribute ] , kind : Symbol ) -> Vec < String > {
55
69
let mut skip_names = vec ! [ ] ;
56
- let path = format ! ( "{}::{}::{}" , RUSTFMT , SKIP , kind) ;
57
70
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 ( ) ) ;
71
+ if is_skip_attr_with_symbol ( & attr. item . path . segments , kind) {
72
+ if let Some ( list) = attr. meta_item_list ( ) {
73
+ for nested_meta_item in list {
74
+ if let Some ( name) = nested_meta_item. ident ( ) {
75
+ skip_names. push ( name. to_string ( ) ) ;
76
+ }
68
77
}
69
78
}
70
79
}
0 commit comments