@@ -73,6 +73,108 @@ impl<F> ItemModifier for F
73
73
}
74
74
}
75
75
76
+ #[ derive( Show , Clone ) ]
77
+ pub enum Annotatable {
78
+ Item ( P < ast:: Item > ) ,
79
+ TraitItem ( ast:: TraitItem ) ,
80
+ ImplItem ( ast:: ImplItem ) ,
81
+ }
82
+
83
+ impl Annotatable {
84
+ pub fn attrs ( & self ) -> & [ ast:: Attribute ] {
85
+ match * self {
86
+ Annotatable :: Item ( ref i) => & i. attrs [ ] ,
87
+ Annotatable :: TraitItem ( ref i) => match * i {
88
+ ast:: TraitItem :: RequiredMethod ( ref tm) => & tm. attrs [ ] ,
89
+ ast:: TraitItem :: ProvidedMethod ( ref m) => & m. attrs [ ] ,
90
+ ast:: TraitItem :: TypeTraitItem ( ref at) => & at. attrs [ ] ,
91
+ } ,
92
+ Annotatable :: ImplItem ( ref i) => match * i {
93
+ ast:: ImplItem :: MethodImplItem ( ref m) => & m. attrs [ ] ,
94
+ ast:: ImplItem :: TypeImplItem ( ref t) => & t. attrs [ ] ,
95
+ }
96
+ }
97
+ }
98
+
99
+ pub fn fold_attrs ( self , attrs : Vec < ast:: Attribute > ) -> Annotatable {
100
+ match self {
101
+ Annotatable :: Item ( i) => Annotatable :: Item ( P ( ast:: Item {
102
+ attrs : attrs,
103
+ ..( * i) . clone ( )
104
+ } ) ) ,
105
+ Annotatable :: TraitItem ( i) => match i {
106
+ ast:: TraitItem :: RequiredMethod ( tm) => Annotatable :: TraitItem (
107
+ ast:: TraitItem :: RequiredMethod (
108
+ ast:: TypeMethod { attrs : attrs, ..tm } ) ) ,
109
+ ast:: TraitItem :: ProvidedMethod ( m) => Annotatable :: TraitItem (
110
+ ast:: TraitItem :: ProvidedMethod ( P (
111
+ ast:: Method { attrs : attrs, ..( * m) . clone ( ) } ) ) ) ,
112
+ ast:: TraitItem :: TypeTraitItem ( at) => Annotatable :: TraitItem (
113
+ ast:: TraitItem :: TypeTraitItem ( P (
114
+ ast:: AssociatedType { attrs : attrs, ..( * at) . clone ( ) } ) ) ) ,
115
+ } ,
116
+ Annotatable :: ImplItem ( i) => match i {
117
+ ast:: ImplItem :: MethodImplItem ( m) => Annotatable :: ImplItem (
118
+ ast:: ImplItem :: MethodImplItem ( P (
119
+ ast:: Method { attrs : attrs, ..( * m) . clone ( ) } ) ) ) ,
120
+ ast:: ImplItem :: TypeImplItem ( t) => Annotatable :: ImplItem (
121
+ ast:: ImplItem :: TypeImplItem ( P (
122
+ ast:: Typedef { attrs : attrs, ..( * t) . clone ( ) } ) ) ) ,
123
+ }
124
+ }
125
+ }
126
+
127
+ pub fn expect_item ( self ) -> P < ast:: Item > {
128
+ match self {
129
+ Annotatable :: Item ( i) => i,
130
+ _ => panic ! ( "expected Item" )
131
+ }
132
+ }
133
+
134
+ pub fn expect_trait_item ( self ) -> ast:: TraitItem {
135
+ match self {
136
+ Annotatable :: TraitItem ( i) => i,
137
+ _ => panic ! ( "expected Item" )
138
+ }
139
+ }
140
+
141
+ pub fn expect_impl_item ( self ) -> ast:: ImplItem {
142
+ match self {
143
+ Annotatable :: ImplItem ( i) => i,
144
+ _ => panic ! ( "expected Item" )
145
+ }
146
+ }
147
+ }
148
+
149
+ // A more flexible ItemModifier (ItemModifier should go away, eventually, FIXME).
150
+ // meta_item is the annotation, item is the item being modified, parent_item
151
+ // is the impl or trait item is declared in if item is part of such a thing.
152
+ // FIXME Decorators should follow the same pattern too.
153
+ pub trait MultiItemModifier {
154
+ fn expand ( & self ,
155
+ ecx : & mut ExtCtxt ,
156
+ span : Span ,
157
+ meta_item : & ast:: MetaItem ,
158
+ item : Annotatable )
159
+ -> Annotatable ;
160
+ }
161
+
162
+ impl < F > MultiItemModifier for F
163
+ where F : Fn ( & mut ExtCtxt ,
164
+ Span ,
165
+ & ast:: MetaItem ,
166
+ Annotatable ) -> Annotatable
167
+ {
168
+ fn expand ( & self ,
169
+ ecx : & mut ExtCtxt ,
170
+ span : Span ,
171
+ meta_item : & ast:: MetaItem ,
172
+ item : Annotatable )
173
+ -> Annotatable {
174
+ ( * self ) ( ecx, span, meta_item, item)
175
+ }
176
+ }
177
+
76
178
/// Represents a thing that maps token trees to Macro Results
77
179
pub trait TTMacroExpander {
78
180
fn expand < ' cx > ( & self ,
@@ -299,6 +401,10 @@ pub enum SyntaxExtension {
299
401
/// in-place.
300
402
Modifier ( Box < ItemModifier + ' static > ) ,
301
403
404
+ /// A syntax extension that is attached to an item and modifies it
405
+ /// in-place. More flexible version than Modifier.
406
+ MultiModifier ( Box < MultiItemModifier + ' static > ) ,
407
+
302
408
/// A normal, function-like syntax extension.
303
409
///
304
410
/// `bytes!` is a `NormalTT`.
0 commit comments