@@ -73,6 +73,108 @@ impl<F> ItemModifier for F
7373 }
7474}
7575
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+
76178/// Represents a thing that maps token trees to Macro Results
77179pub trait TTMacroExpander {
78180 fn expand < ' cx > ( & self ,
@@ -299,6 +401,10 @@ pub enum SyntaxExtension {
299401 /// in-place.
300402 Modifier ( Box < ItemModifier + ' static > ) ,
301403
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+
302408 /// A normal, function-like syntax extension.
303409 ///
304410 /// `bytes!` is a `NormalTT`.
0 commit comments