Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions crates/cgp-macro-lib/src/derive_component/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@ mod delegate_type;
mod derive;
mod provider_impl;
mod provider_trait;
mod replace_self_receiver;
mod replace_self_type;
mod signature_args;
mod snake_case;
mod use_context_impl;
mod use_delegate_impl;

pub use derive::*;
pub use replace_self_receiver::*;
pub use replace_self_type::*;
pub use snake_case::*;
16 changes: 11 additions & 5 deletions crates/cgp-macro-lib/src/derive_component/provider_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ use syn::punctuated::Punctuated;
use syn::token::Comma;
use syn::{Ident, ItemTrait, TraitItem, TypeParamBound, parse2};

use crate::derive_component::replace_self_receiver::replace_self_receiver_in_signature;
use crate::derive_component::replace_self_type::{
use crate::parse::parse_is_provider_params;
use crate::replace_self::{
iter_parse_and_replace_self_type, parse_and_replace_self_type,
replace_self_receiver_in_signature, replace_self_var, to_snake_case_ident,
};
use crate::derive_component::to_snake_case_ident;
use crate::parse::parse_is_provider_params;

pub fn derive_provider_trait(
component_name: &Ident,
Expand Down Expand Up @@ -85,16 +84,23 @@ pub fn derive_provider_trait(

// Replace self type and argument into context type argument
{
let context_var = to_snake_case_ident(context_type);

for item in provider_trait.items.iter_mut() {
let mut replaced_item =
parse_and_replace_self_type(item, context_type, &local_assoc_types)?;

if let TraitItem::Fn(func) = &mut replaced_item {
replace_self_receiver_in_signature(
&mut func.sig,
&to_snake_case_ident(context_type),
&context_var,
context_type.to_token_stream(),
);

if let Some(block) = &mut func.default {
let replaced = replace_self_var(block.to_token_stream(), &context_var);
*block = parse2(replaced)?;
}
}

*item = replaced_item;
Expand Down
2 changes: 1 addition & 1 deletion crates/cgp-macro-lib/src/derive_getter/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use syn::{
Signature, TraitItem, TraitItemFn, Type, TypePath, parse_quote, parse2,
};

use crate::derive_component::replace_self_type;
use crate::derive_getter::getter_field::GetterField;
use crate::derive_getter::{FieldMode, ReceiverMode};
use crate::replace_self::replace_self_type;

pub fn parse_getter_fields(
context_type: &Ident,
Expand Down
40 changes: 5 additions & 35 deletions crates/cgp-macro-lib/src/entrypoints/cgp_impl.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use proc_macro2::{Group, Span, TokenStream, TokenTree};
use quote::{ToTokens, format_ident, quote};
use proc_macro2::{Span, TokenStream};
use quote::{ToTokens, quote};
use syn::parse::discouraged::Speculative;
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::token::{Colon, For};
use syn::{Error, FnArg, Ident, ImplItem, ItemImpl, Type, parse2};

use crate::derive_component::{replace_self_receiver, replace_self_type, to_snake_case_ident};
use crate::derive_provider::{
derive_component_name_from_provider_impl, derive_is_provider_for, derive_provider_struct,
};
use crate::parse::SimpleType;
use crate::replace_self::{
replace_self_receiver, replace_self_type, replace_self_var, to_snake_case_ident,
};

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

Ok(out_impl)
}

fn replace_self_var(stream: TokenStream, replaced_ident: &Ident) -> TokenStream {
let self_ident = format_ident!("self");

let mut result_stream: Vec<TokenTree> = Vec::new();

let token_iter = stream.into_iter();

for tree in token_iter {
match tree {
TokenTree::Ident(ident) => {
if ident == self_ident {
result_stream.push(TokenTree::Ident(replaced_ident.clone()));
} else {
result_stream.push(TokenTree::Ident(ident));
}
}
TokenTree::Group(group) => {
let replaced_stream = replace_self_var(group.stream(), replaced_ident);
let replaced_group = Group::new(group.delimiter(), replaced_stream);

result_stream.push(TokenTree::Group(replaced_group));
}
TokenTree::Punct(punct) => {
result_stream.push(TokenTree::Punct(punct));
}
TokenTree::Literal(lit) => result_stream.push(TokenTree::Literal(lit)),
}
}

result_stream.into_iter().collect()
}
2 changes: 1 addition & 1 deletion crates/cgp-macro-lib/src/entrypoints/cgp_preset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use syn::token::{At, Comma};
use syn::{GenericParam, Ident, ItemTrait, TypeParamBound, parse_quote, parse2};

use crate::delegate_components::{define_struct, impl_delegate_components};
use crate::derive_component::to_snake_case_str;
use crate::parse::{DefinePreset, DelegateEntry, ImplGenerics, SimpleType};
use crate::preset::{define_substitution_macro, impl_components_is_preset};
use crate::replace_self::to_snake_case_str;

pub fn define_preset(body: TokenStream) -> syn::Result<TokenStream> {
let ast: DefinePreset = syn::parse2(body)?;
Expand Down
1 change: 1 addition & 0 deletions crates/cgp-macro-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub(crate) mod for_each_replace;
pub(crate) mod parse;
pub(crate) mod preset;
pub(crate) mod product;
pub(crate) mod replace_self;
pub(crate) mod symbol;
pub(crate) mod type_component;

Expand Down
9 changes: 9 additions & 0 deletions crates/cgp-macro-lib/src/replace_self/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod replace_self_receiver;
mod replace_self_type;
mod replace_self_var;
mod snake_case;

pub use replace_self_receiver::*;
pub use replace_self_type::*;
pub use replace_self_var::*;
pub use snake_case::*;
35 changes: 35 additions & 0 deletions crates/cgp-macro-lib/src/replace_self/replace_self_var.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use proc_macro2::{Group, TokenStream, TokenTree};
use quote::format_ident;
use syn::Ident;

pub fn replace_self_var(stream: TokenStream, replaced_ident: &Ident) -> TokenStream {
let self_ident = format_ident!("self");

let mut result_stream: Vec<TokenTree> = Vec::new();

let token_iter = stream.into_iter();

for tree in token_iter {
match tree {
TokenTree::Ident(ident) => {
if ident == self_ident {
result_stream.push(TokenTree::Ident(replaced_ident.clone()));
} else {
result_stream.push(TokenTree::Ident(ident));
}
}
TokenTree::Group(group) => {
let replaced_stream = replace_self_var(group.stream(), replaced_ident);
let replaced_group = Group::new(group.delimiter(), replaced_stream);

result_stream.push(TokenTree::Group(replaced_group));
}
TokenTree::Punct(punct) => {
result_stream.push(TokenTree::Punct(punct));
}
TokenTree::Literal(lit) => result_stream.push(TokenTree::Literal(lit)),
}
}

result_stream.into_iter().collect()
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ pub fn to_snake_case_str(val: &str) -> String {
}

pub fn to_snake_case_ident(val: &Ident) -> Ident {
Ident::new(
&format!("__{}__", to_snake_case_str(&val.to_string())),
Span::call_site(),
)
let str_val = val.to_string();
let mut snake_case_val = to_snake_case_str(&str_val);
if !str_val.starts_with('_') {
snake_case_val = format!("__{}__", snake_case_val);
}

Ident::new(&snake_case_val, Span::call_site())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use cgp::prelude::*;

#[cgp_getter]
pub trait HasName {
fn name(&self) -> &str {
"John"
}
}

#[cgp_component(Greeter)]
pub trait CanGreet: HasName {
fn greet(&self) -> String {
format!("Hello, {}!", self.name())
}
}

pub struct UseDefault;

#[cgp_impl(UseDefault)]
impl<Context> NameGetter for Context {}

#[cgp_impl(UseDefault)]
impl<Context: HasName> Greeter for Context {}

#[test]
fn test_default_method_impl() {
pub struct App;

delegate_components! {
App {
[
NameGetterComponent,
GreeterComponent,
]:
UseDefault,
}
}

assert_eq!(App.greet(), "Hello, John!");
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod constant;
pub mod default_impl;
pub mod lifetime;
pub mod sized;
Loading