Skip to content

Commit a7eeef2

Browse files
authored
Fix use of self inside default trait method implementation body (#179)
* Move replace self helpers to separate module * Fix use of self inside default trait method implementation body
1 parent 3b8befa commit a7eeef2

File tree

13 files changed

+111
-52
lines changed

13 files changed

+111
-52
lines changed

crates/cgp-macro-lib/src/derive_component/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,8 @@ mod delegate_type;
55
mod derive;
66
mod provider_impl;
77
mod provider_trait;
8-
mod replace_self_receiver;
9-
mod replace_self_type;
108
mod signature_args;
11-
mod snake_case;
129
mod use_context_impl;
1310
mod use_delegate_impl;
1411

1512
pub use derive::*;
16-
pub use replace_self_receiver::*;
17-
pub use replace_self_type::*;
18-
pub use snake_case::*;

crates/cgp-macro-lib/src/derive_component/provider_trait.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ use syn::punctuated::Punctuated;
55
use syn::token::Comma;
66
use syn::{Ident, ItemTrait, TraitItem, TypeParamBound, parse2};
77

8-
use crate::derive_component::replace_self_receiver::replace_self_receiver_in_signature;
9-
use crate::derive_component::replace_self_type::{
8+
use crate::parse::parse_is_provider_params;
9+
use crate::replace_self::{
1010
iter_parse_and_replace_self_type, parse_and_replace_self_type,
11+
replace_self_receiver_in_signature, replace_self_var, to_snake_case_ident,
1112
};
12-
use crate::derive_component::to_snake_case_ident;
13-
use crate::parse::parse_is_provider_params;
1413

1514
pub fn derive_provider_trait(
1615
component_name: &Ident,
@@ -85,16 +84,23 @@ pub fn derive_provider_trait(
8584

8685
// Replace self type and argument into context type argument
8786
{
87+
let context_var = to_snake_case_ident(context_type);
88+
8889
for item in provider_trait.items.iter_mut() {
8990
let mut replaced_item =
9091
parse_and_replace_self_type(item, context_type, &local_assoc_types)?;
9192

9293
if let TraitItem::Fn(func) = &mut replaced_item {
9394
replace_self_receiver_in_signature(
9495
&mut func.sig,
95-
&to_snake_case_ident(context_type),
96+
&context_var,
9697
context_type.to_token_stream(),
9798
);
99+
100+
if let Some(block) = &mut func.default {
101+
let replaced = replace_self_var(block.to_token_stream(), &context_var);
102+
*block = parse2(replaced)?;
103+
}
98104
}
99105

100106
*item = replaced_item;

crates/cgp-macro-lib/src/derive_getter/parse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use syn::{
99
Signature, TraitItem, TraitItemFn, Type, TypePath, parse_quote, parse2,
1010
};
1111

12-
use crate::derive_component::replace_self_type;
1312
use crate::derive_getter::getter_field::GetterField;
1413
use crate::derive_getter::{FieldMode, ReceiverMode};
14+
use crate::replace_self::replace_self_type;
1515

1616
pub fn parse_getter_fields(
1717
context_type: &Ident,

crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
use proc_macro2::{Group, Span, TokenStream, TokenTree};
2-
use quote::{ToTokens, format_ident, quote};
1+
use proc_macro2::{Span, TokenStream};
2+
use quote::{ToTokens, quote};
33
use syn::parse::discouraged::Speculative;
44
use syn::parse::{Parse, ParseStream};
55
use syn::spanned::Spanned;
66
use syn::token::{Colon, For};
77
use syn::{Error, FnArg, Ident, ImplItem, ItemImpl, Type, parse2};
88

9-
use crate::derive_component::{replace_self_receiver, replace_self_type, to_snake_case_ident};
109
use crate::derive_provider::{
1110
derive_component_name_from_provider_impl, derive_is_provider_for, derive_provider_struct,
1211
};
1312
use crate::parse::SimpleType;
13+
use crate::replace_self::{
14+
replace_self_receiver, replace_self_type, replace_self_var, to_snake_case_ident,
15+
};
1416

1517
pub fn cgp_impl(attr: TokenStream, body: TokenStream) -> syn::Result<TokenStream> {
1618
let spec: ImplProviderSpec = parse2(attr)?;
@@ -153,35 +155,3 @@ pub fn transform_impl_trait(
153155

154156
Ok(out_impl)
155157
}
156-
157-
fn replace_self_var(stream: TokenStream, replaced_ident: &Ident) -> TokenStream {
158-
let self_ident = format_ident!("self");
159-
160-
let mut result_stream: Vec<TokenTree> = Vec::new();
161-
162-
let token_iter = stream.into_iter();
163-
164-
for tree in token_iter {
165-
match tree {
166-
TokenTree::Ident(ident) => {
167-
if ident == self_ident {
168-
result_stream.push(TokenTree::Ident(replaced_ident.clone()));
169-
} else {
170-
result_stream.push(TokenTree::Ident(ident));
171-
}
172-
}
173-
TokenTree::Group(group) => {
174-
let replaced_stream = replace_self_var(group.stream(), replaced_ident);
175-
let replaced_group = Group::new(group.delimiter(), replaced_stream);
176-
177-
result_stream.push(TokenTree::Group(replaced_group));
178-
}
179-
TokenTree::Punct(punct) => {
180-
result_stream.push(TokenTree::Punct(punct));
181-
}
182-
TokenTree::Literal(lit) => result_stream.push(TokenTree::Literal(lit)),
183-
}
184-
}
185-
186-
result_stream.into_iter().collect()
187-
}

crates/cgp-macro-lib/src/entrypoints/cgp_preset.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use syn::token::{At, Comma};
77
use syn::{GenericParam, Ident, ItemTrait, TypeParamBound, parse_quote, parse2};
88

99
use crate::delegate_components::{define_struct, impl_delegate_components};
10-
use crate::derive_component::to_snake_case_str;
1110
use crate::parse::{DefinePreset, DelegateEntry, ImplGenerics, SimpleType};
1211
use crate::preset::{define_substitution_macro, impl_components_is_preset};
12+
use crate::replace_self::to_snake_case_str;
1313

1414
pub fn define_preset(body: TokenStream) -> syn::Result<TokenStream> {
1515
let ast: DefinePreset = syn::parse2(body)?;

crates/cgp-macro-lib/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub(crate) mod for_each_replace;
2323
pub(crate) mod parse;
2424
pub(crate) mod preset;
2525
pub(crate) mod product;
26+
pub(crate) mod replace_self;
2627
pub(crate) mod symbol;
2728
pub(crate) mod type_component;
2829

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
mod replace_self_receiver;
2+
mod replace_self_type;
3+
mod replace_self_var;
4+
mod snake_case;
5+
6+
pub use replace_self_receiver::*;
7+
pub use replace_self_type::*;
8+
pub use replace_self_var::*;
9+
pub use snake_case::*;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use proc_macro2::{Group, TokenStream, TokenTree};
2+
use quote::format_ident;
3+
use syn::Ident;
4+
5+
pub fn replace_self_var(stream: TokenStream, replaced_ident: &Ident) -> TokenStream {
6+
let self_ident = format_ident!("self");
7+
8+
let mut result_stream: Vec<TokenTree> = Vec::new();
9+
10+
let token_iter = stream.into_iter();
11+
12+
for tree in token_iter {
13+
match tree {
14+
TokenTree::Ident(ident) => {
15+
if ident == self_ident {
16+
result_stream.push(TokenTree::Ident(replaced_ident.clone()));
17+
} else {
18+
result_stream.push(TokenTree::Ident(ident));
19+
}
20+
}
21+
TokenTree::Group(group) => {
22+
let replaced_stream = replace_self_var(group.stream(), replaced_ident);
23+
let replaced_group = Group::new(group.delimiter(), replaced_stream);
24+
25+
result_stream.push(TokenTree::Group(replaced_group));
26+
}
27+
TokenTree::Punct(punct) => {
28+
result_stream.push(TokenTree::Punct(punct));
29+
}
30+
TokenTree::Literal(lit) => result_stream.push(TokenTree::Literal(lit)),
31+
}
32+
}
33+
34+
result_stream.into_iter().collect()
35+
}

0 commit comments

Comments
 (0)