17
17
18
18
//! Implementation of the `derive_impl` attribute macro.
19
19
20
- use std:: collections:: { HashMap , HashSet } ;
21
-
22
- use frame_support_procedural_tools:: generate_crate_access_2018;
23
20
use macro_magic:: core:: pretty_print;
24
- use proc_macro2:: TokenStream ;
21
+ use proc_macro2:: TokenStream as TokenStream2 ;
25
22
use quote:: { quote, ToTokens } ;
23
+ use std:: collections:: HashSet ;
26
24
use syn:: {
27
25
braced, bracketed,
28
26
parse:: { Parse , ParseStream } ,
29
- parse2,
27
+ parse2, parse_quote ,
30
28
punctuated:: Punctuated ,
31
29
token:: { Brace , Bracket } ,
32
- Ident , ImplItem , ItemImpl , Result , Token , TypePath ,
30
+ Ident , ImplItem , ItemImpl , Path , Result , Token , TypePath ,
33
31
} ;
34
32
35
33
mod keywords {
@@ -99,7 +97,7 @@ impl Parse for DeriveImplDef {
99
97
}
100
98
}
101
99
102
- pub ( crate ) fn derive_impl_inner ( input : TokenStream ) -> Result < TokenStream > {
100
+ pub ( crate ) fn derive_impl_inner ( input : TokenStream2 ) -> Result < TokenStream2 > {
103
101
println ! ( "input: {}" , input) ;
104
102
let DeriveImplDef { partial_impl_block, implementing_type, type_items, .. } = parse2 ( input) ?;
105
103
@@ -151,7 +149,7 @@ fn impl_item_ident(impl_item: &ImplItem) -> Option<Ident> {
151
149
}
152
150
}
153
151
154
- fn combine_impls ( local_impl : ItemImpl , foreign_impl : ItemImpl ) -> ItemImpl {
152
+ fn combine_impls ( local_impl : ItemImpl , foreign_impl : ItemImpl , foreign_path : Path ) -> ItemImpl {
155
153
let existing_local_keys: HashSet < Ident > = local_impl
156
154
. items
157
155
. iter ( )
@@ -163,47 +161,60 @@ fn combine_impls(local_impl: ItemImpl, foreign_impl: ItemImpl) -> ItemImpl {
163
161
. filter ( |impl_item| impl_item_ident ( impl_item) . is_none ( ) )
164
162
. cloned ( )
165
163
. collect ( ) ;
164
+ let source_crate_path = foreign_path. segments . first ( ) . unwrap ( ) . ident . clone ( ) ;
166
165
let mut final_impl = local_impl;
167
166
final_impl. items . extend (
168
167
foreign_impl
169
168
. items
170
- . iter ( )
169
+ . into_iter ( )
171
170
. filter_map ( |item| {
172
171
if let Some ( ident) = impl_item_ident ( & item) {
173
172
if existing_local_keys. contains ( & ident) {
174
- // do not copy colliding supported items
173
+ // do not copy colliding items that have an ident
175
174
None
176
175
} else {
177
- // copy uncolliding supported items verbatim
178
- Some ( item)
176
+ if matches ! ( item, ImplItem :: Type ( _) ) {
177
+ // modify and insert uncolliding type items
178
+ let modified_item: ImplItem = parse_quote ! {
179
+ type #ident = <#foreign_path as #source_crate_path:: pallet:: DefaultConfig >:: #ident;
180
+ } ;
181
+ Some ( modified_item)
182
+ } else {
183
+ // copy uncolliding non-type items that have an ident
184
+ Some ( item)
185
+ }
179
186
}
180
187
} else {
181
- if existing_unsupported_items. contains ( item) {
182
- // do not copy colliding unsupported items
188
+ if existing_unsupported_items. contains ( & item) {
189
+ // do not copy colliding items that lack an ident
183
190
None
184
191
} else {
185
- // copy uncolliding unsupported items
192
+ // copy uncolliding items without an ident verbaitm
186
193
Some ( item)
187
194
}
188
195
}
189
196
} )
190
- . cloned ( )
191
197
. collect :: < Vec < ImplItem > > ( ) ,
192
198
) ;
193
199
final_impl
194
200
}
195
201
196
- pub fn derive_impl ( foreign_path : TokenStream , foreign_tokens : TokenStream , local_tokens : TokenStream ) -> Result < TokenStream > {
202
+ pub fn derive_impl (
203
+ foreign_path : TokenStream2 ,
204
+ foreign_tokens : TokenStream2 ,
205
+ local_tokens : TokenStream2 ,
206
+ ) -> Result < TokenStream2 > {
207
+ println ! ( "foreign_path: {}\n " , foreign_path. to_string( ) ) ;
208
+ println ! ( "foreign_impl:" ) ;
209
+ pretty_print ( & foreign_tokens) ;
210
+ println ! ( "\n local_impl:" ) ;
211
+ pretty_print ( & local_tokens) ;
212
+
197
213
let local_impl = parse2 :: < ItemImpl > ( local_tokens) ?;
198
214
let foreign_impl = parse2 :: < ItemImpl > ( foreign_tokens) ?;
215
+ let foreign_path = parse2 :: < Path > ( foreign_path) ?;
199
216
200
- println ! ( "\n local_impl:" ) ;
201
- pretty_print ( & local_impl. to_token_stream ( ) ) ;
202
- println ! ( "foreign_impl:" ) ;
203
- pretty_print ( & foreign_impl. to_token_stream ( ) ) ;
204
- println ! ( "foreign_path: {}" , foreign_path) ;
205
-
206
- let combined_impl = combine_impls ( local_impl, foreign_impl) ;
217
+ let combined_impl = combine_impls ( local_impl, foreign_impl, foreign_path) ;
207
218
208
219
println ! ( "combined_impl:" ) ;
209
220
pretty_print ( & combined_impl. to_token_stream ( ) ) ;
0 commit comments