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
2 changes: 1 addition & 1 deletion crates/cgp-macro-lib/src/derive_component/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ pub fn derive_component_with_ast(
)?;

let mut item_impls = vec![
consumer_impl,
provider_impl,
consumer_impl,
use_context_impl,
use_context_is_provider_impl,
];
Expand Down
3 changes: 2 additions & 1 deletion crates/cgp-macro-lib/src/derive_getter/blanket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::derive_getter::{
ContextArg, ReceiverMode, derive_getter_constraint, derive_getter_method,
};
use crate::symbol::symbol_from_string;
use crate::type_component::get_bounds_and_replace_self_assoc_type;

pub fn derive_blanket_impl(
context_type: &Ident,
Expand Down Expand Up @@ -39,7 +40,7 @@ pub fn derive_blanket_impl(
type #field_assoc_type_ident = #field_assoc_type_ident;
});

let field_constraints = &field_assoc_type.bounds;
let field_constraints = get_bounds_and_replace_self_assoc_type(field_assoc_type);

generics.make_where_clause().predicates.push(parse2(quote! {
#field_assoc_type_ident: #field_constraints
Expand Down
3 changes: 2 additions & 1 deletion crates/cgp-macro-lib/src/derive_getter/use_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::derive_getter::{
ContextArg, ReceiverMode, derive_getter_constraint, derive_getter_method,
};
use crate::parse::ComponentSpec;
use crate::type_component::get_bounds_and_replace_self_assoc_type;

pub fn derive_use_field_impl(
spec: &ComponentSpec,
Expand Down Expand Up @@ -43,7 +44,7 @@ pub fn derive_use_field_impl(
type #field_assoc_type_ident = #field_assoc_type_ident;
});

let field_constraints = &field_assoc_type.bounds;
let field_constraints = get_bounds_and_replace_self_assoc_type(field_assoc_type);

provider_generics
.make_where_clause()
Expand Down
3 changes: 2 additions & 1 deletion crates/cgp-macro-lib/src/derive_getter/use_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::derive_getter::{
};
use crate::parse::ComponentSpec;
use crate::symbol::symbol_from_string;
use crate::type_component::get_bounds_and_replace_self_assoc_type;

pub fn derive_use_fields_impl(
spec: &ComponentSpec,
Expand All @@ -36,7 +37,7 @@ pub fn derive_use_fields_impl(
type #field_assoc_type_ident = #field_assoc_type_ident;
});

let field_constraints = &field_assoc_type.bounds;
let field_constraints = get_bounds_and_replace_self_assoc_type(field_assoc_type);

provider_generics
.make_where_clause()
Expand Down
3 changes: 2 additions & 1 deletion crates/cgp-macro-lib/src/derive_getter/with_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use syn::{Generics, Ident, ItemImpl, ItemTrait, TraitItemType, parse_quote, pars
use crate::derive_getter::getter_field::GetterField;
use crate::derive_getter::{ContextArg, FieldMode, ReceiverMode, derive_getter_method};
use crate::parse::ComponentSpec;
use crate::type_component::get_bounds_and_replace_self_assoc_type;

pub fn derive_with_provider_impl(
spec: &ComponentSpec,
Expand Down Expand Up @@ -50,7 +51,7 @@ pub fn derive_with_provider_impl(
type #field_assoc_type_ident = #field_assoc_type_ident;
});

let field_constraints = &field_assoc_type.bounds;
let field_constraints = get_bounds_and_replace_self_assoc_type(field_assoc_type);

provider_generics
.make_where_clause()
Expand Down
6 changes: 4 additions & 2 deletions crates/cgp-macro-lib/src/entrypoints/cgp_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use syn::{Ident, ItemTrait, parse_quote, parse2};

use crate::derive_component::derive_component_with_ast;
use crate::parse::{ComponentSpec, Entries};
use crate::type_component::{derive_type_alias, derive_type_providers, extract_item_type};
use crate::type_component::{
derive_type_alias, derive_type_providers, extract_item_type_from_trait,
};

pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> syn::Result<TokenStream> {
let mut entries = if let Ok(provider_ident) = parse2::<Ident>(attrs.clone()) {
Expand All @@ -18,7 +20,7 @@ pub fn cgp_type(attrs: TokenStream, body: TokenStream) -> syn::Result<TokenStrea

let consumer_trait: ItemTrait = syn::parse2(body)?;

let item_type = extract_item_type(&consumer_trait)?.clone();
let item_type = extract_item_type_from_trait(&consumer_trait)?.clone();

entries.entry("provider".into()).or_insert_with(|| {
let provider_name = Ident::new(
Expand Down
19 changes: 10 additions & 9 deletions crates/cgp-macro-lib/src/type_component/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ use syn::{

use crate::derive_provider::derive_is_provider_for;
use crate::parse::ComponentSpec;
use crate::type_component::replace::get_bounds_and_replace_self_assoc_type;

pub fn extract_item_type(consumer_trait: &ItemTrait) -> syn::Result<&TraitItemType> {
pub fn extract_item_type_from_trait(consumer_trait: &ItemTrait) -> syn::Result<&TraitItemType> {
if consumer_trait.items.len() != 1 {
return Err(Error::new(
consumer_trait.span(),
Expand Down Expand Up @@ -67,11 +68,11 @@ pub fn derive_type_providers(
) -> syn::Result<Vec<ItemImpl>> {
let context_name = &spec.context_type;

let component_name = {
let component_name: Type = {
let name = &spec.component_name;
let params = &spec.component_params;
parse2::<Type>(quote! { #name < #params > })
}?;
parse2(quote! { #name < #params > })?
};

let provider_trait_name = &provider_trait.ident;

Expand All @@ -85,7 +86,7 @@ pub fn derive_type_providers(

let type_name = &item_type.ident;

let type_bounds = &item_type.bounds;
let type_bounds = get_bounds_and_replace_self_assoc_type(item_type);

let use_type_impl: ItemImpl = parse2(quote! {
impl< #type_name, #impl_generics_params >
Expand All @@ -102,15 +103,15 @@ pub fn derive_type_providers(
let use_type_is_provider_impl = derive_is_provider_for(&component_name, &use_type_impl)?;

let with_provider_impl: ItemImpl = parse2(quote! {
impl< __Provider__, #impl_generics_params >
impl< __Provider__, #type_name, #impl_generics_params >
#provider_trait_name #type_generics
for WithProvider< __Provider__ >
where
__Provider__: ProvideType< #context_name, #component_name >,
__Provider__::Type: #type_bounds,
__Provider__: ProvideType< #context_name, #component_name, Type = #type_name >,
#type_name: #type_bounds,
#predicates
{
type #type_name = __Provider__::Type;
type #type_name = #type_name;
}
})?;

Expand Down
2 changes: 2 additions & 0 deletions crates/cgp-macro-lib/src/type_component/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod derive;
mod replace;

pub use derive::*;
pub use replace::*;
39 changes: 39 additions & 0 deletions crates/cgp-macro-lib/src/type_component/replace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// pub fn replace_self_assoc_type

use syn::punctuated::Punctuated;
use syn::token::Plus;
use syn::visit_mut::{VisitMut, visit_type_mut, visit_type_param_bound_mut};
use syn::{Ident, TraitItemType, Type, TypeParamBound, parse_quote};

pub fn get_bounds_and_replace_self_assoc_type(
item_type: &TraitItemType,
) -> Punctuated<TypeParamBound, Plus> {
let mut bounds = item_type.bounds.clone();
let mut visitor = ReplaceSelfAssocTypeVisitor {
type_ident: item_type.ident.clone(),
};

for bound in &mut bounds {
visit_type_param_bound_mut(&mut visitor, bound);
}

bounds
}

pub struct ReplaceSelfAssocTypeVisitor {
pub type_ident: Ident,
}

impl VisitMut for ReplaceSelfAssocTypeVisitor {
fn visit_type_mut(&mut self, node: &mut Type) {
if let Type::Path(type_path) = node {
let type_ident = &self.type_ident;
if type_path == &parse_quote! { Self :: #type_ident } {
*node = parse_quote!(#type_ident);
return;
}
}

visit_type_mut(self, node);
}
}
54 changes: 46 additions & 8 deletions crates/cgp-tests/tests/cgp_fn_tests/use_type.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,56 @@
use core::f64;
use std::ops::Mul;

use cgp::prelude::*;

#[cgp_type]
pub trait HasScalarType {
type Scalar;
type Scalar: Mul<Output = Self::Scalar> + Clone;
}

#[cgp_fn]
#[use_type(HasScalarType::Scalar)]
pub fn rectangle_area(&self, #[implicit] width: Scalar, #[implicit] height: Scalar) -> Scalar
where
Scalar: Mul<Output = Scalar> + Clone,
{
let res: Scalar = width * height;
res
#[extend(HasScalarType)]
pub fn rectangle_area(
&self,
#[implicit] width: Self::Scalar,
#[implicit] height: Self::Scalar,
) -> Self::Scalar {
width * height
}

#[derive(HasField)]
pub struct F32Rectangle {
pub width: f32,
pub height: f32,
}

impl HasScalarType for F32Rectangle {
type Scalar = f32;
}

#[derive(HasField)]
pub struct F64Rectangle {
pub width: f64,
pub height: f64,
}

impl HasScalarType for F64Rectangle {
type Scalar = f64;
}

#[test]
fn test_rectangle_area() {
let f32_rectangle = F32Rectangle {
width: 3.0,
height: 4.0,
};

assert_eq!(f32_rectangle.rectangle_area(), 12.0);

let f64_rectangle = F64Rectangle {
width: 3.0,
height: 4.0,
};

assert_eq!(f64_rectangle.rectangle_area(), 12.0);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod basic;
pub mod extend;
pub mod foreign;
pub mod self_referential;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use core::ops::Mul;

use cgp::prelude::*;

#[cgp_type]
pub trait HasScalarType {
type Scalar: Mul<Output = Self::Scalar> + Clone;
}

pub struct App;

delegate_components! {
App {
ScalarTypeProviderComponent:
UseType<f64>,
}
}

check_components! {
CanUseApp for App {
ScalarTypeProviderComponent,
}
}
2 changes: 2 additions & 0 deletions crates/cgp-tests/tests/getter_tests/assoc_type/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pub mod auto_getter;
pub mod getter;
pub mod self_referential;
pub mod self_referential_auto;
29 changes: 29 additions & 0 deletions crates/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use core::ops::Mul;

use cgp::prelude::*;

#[cgp_getter]
pub trait HasScalar {
type Scalar: Mul<Output = Self::Scalar> + Clone;

fn scalar(&self) -> &Self::Scalar;
}

#[derive(HasField)]
pub struct App {
pub scalar: f64,
}

delegate_components! {
App {
ScalarGetterComponent:
UseField<Symbol!("scalar")>,
}
}

#[test]
fn test_auto_getter_scalar() {
let app = App { scalar: 2.0 };

assert_eq!(*app.scalar(), 2.0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use core::ops::Mul;

use cgp::prelude::*;

#[cgp_auto_getter]
pub trait HasScalarType {
type Scalar: Mul<Output = Self::Scalar> + Clone;

fn scalar(&self) -> &Self::Scalar;
}

#[derive(HasField)]
pub struct App {
pub scalar: f64,
}

#[test]
fn test_auto_getter_scalar() {
let app = App { scalar: 2.0 };

assert_eq!(*app.scalar(), 2.0);
}
Loading