Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 07d80f5

Browse files
committed
combine_impls using implementing_type generics
1 parent cd0753c commit 07d80f5

File tree

1 file changed

+35
-24
lines changed

1 file changed

+35
-24
lines changed

frame/support/procedural/src/derive_impl.rs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,17 @@
1717

1818
//! Implementation of the `derive_impl` attribute macro.
1919
20-
use std::collections::{HashMap, HashSet};
21-
22-
use frame_support_procedural_tools::generate_crate_access_2018;
2320
use macro_magic::core::pretty_print;
24-
use proc_macro2::TokenStream;
21+
use proc_macro2::TokenStream as TokenStream2;
2522
use quote::{quote, ToTokens};
23+
use std::collections::HashSet;
2624
use syn::{
2725
braced, bracketed,
2826
parse::{Parse, ParseStream},
29-
parse2,
27+
parse2, parse_quote,
3028
punctuated::Punctuated,
3129
token::{Brace, Bracket},
32-
Ident, ImplItem, ItemImpl, Result, Token, TypePath,
30+
Ident, ImplItem, ItemImpl, Path, Result, Token, TypePath,
3331
};
3432

3533
mod keywords {
@@ -99,7 +97,7 @@ impl Parse for DeriveImplDef {
9997
}
10098
}
10199

102-
pub(crate) fn derive_impl_inner(input: TokenStream) -> Result<TokenStream> {
100+
pub(crate) fn derive_impl_inner(input: TokenStream2) -> Result<TokenStream2> {
103101
println!("input: {}", input);
104102
let DeriveImplDef { partial_impl_block, implementing_type, type_items, .. } = parse2(input)?;
105103

@@ -151,7 +149,7 @@ fn impl_item_ident(impl_item: &ImplItem) -> Option<Ident> {
151149
}
152150
}
153151

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 {
155153
let existing_local_keys: HashSet<Ident> = local_impl
156154
.items
157155
.iter()
@@ -163,47 +161,60 @@ fn combine_impls(local_impl: ItemImpl, foreign_impl: ItemImpl) -> ItemImpl {
163161
.filter(|impl_item| impl_item_ident(impl_item).is_none())
164162
.cloned()
165163
.collect();
164+
let source_crate_path = foreign_path.segments.first().unwrap().ident.clone();
166165
let mut final_impl = local_impl;
167166
final_impl.items.extend(
168167
foreign_impl
169168
.items
170-
.iter()
169+
.into_iter()
171170
.filter_map(|item| {
172171
if let Some(ident) = impl_item_ident(&item) {
173172
if existing_local_keys.contains(&ident) {
174-
// do not copy colliding supported items
173+
// do not copy colliding items that have an ident
175174
None
176175
} 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+
}
179186
}
180187
} 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
183190
None
184191
} else {
185-
// copy uncolliding unsupported items
192+
// copy uncolliding items without an ident verbaitm
186193
Some(item)
187194
}
188195
}
189196
})
190-
.cloned()
191197
.collect::<Vec<ImplItem>>(),
192198
);
193199
final_impl
194200
}
195201

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!("\nlocal_impl:");
211+
pretty_print(&local_tokens);
212+
197213
let local_impl = parse2::<ItemImpl>(local_tokens)?;
198214
let foreign_impl = parse2::<ItemImpl>(foreign_tokens)?;
215+
let foreign_path = parse2::<Path>(foreign_path)?;
199216

200-
println!("\nlocal_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);
207218

208219
println!("combined_impl:");
209220
pretty_print(&combined_impl.to_token_stream());

0 commit comments

Comments
 (0)