From 46b7e9282d4f9b59fed37bda4648f0d5df3cfb32 Mon Sep 17 00:00:00 2001 From: Luca Fulchir Date: Tue, 3 Dec 2024 17:26:53 +0100 Subject: [PATCH] probably wrong way to connect repo to pkgs Signed-off-by: Luca Fulchir --- bok-macro/src/pkgs.rs | 132 +++++++++++++++++++++++------- bok-macro/src/repos.rs | 38 +++++---- bok-utils/src/main.rs | 2 +- bok-utils/src/repos/mod.rs | 4 +- bok-utils/src/repos/pkgs/one.rs | 8 +- bok-utils/src/repos/pkgs/three.rs | 8 +- bok-utils/src/repos/pkgs/two.rs | 10 ++- 7 files changed, 148 insertions(+), 54 deletions(-) diff --git a/bok-macro/src/pkgs.rs b/bok-macro/src/pkgs.rs index 3afebba..38082cf 100644 --- a/bok-macro/src/pkgs.rs +++ b/bok-macro/src/pkgs.rs @@ -55,15 +55,27 @@ pub(crate) fn package( use ::syn::spanned::Spanned; return ::syn::Error::new( local.fields.span(), - "unnamed fields are not supported", + "#[::bok::package()]: unnamed fields are not supported", ) .to_compile_error() .into(); }; let local_attrs = local.attrs.iter(); - let generics = local.generics; let ident = local.ident; let vis = local.vis; + let local_generics = local.generics; + if local_generics.params.len() != 0 { + return ::syn::Error::new( + local_span, + "#[::bok::package()]: a package can not have generics", + ) + .to_compile_error() + .into(); + }; + let generic_struct: ::syn::ItemStruct = ::syn::parse_quote! { + pub struct test where R: ::std::fmt::Debug + 'static {} + }; + let (_, generics, where_clause) = generic_struct.generics.split_for_impl(); let source_path = parse_macro_input!(__source_path as ::syn::Path); @@ -72,7 +84,7 @@ pub(crate) fn package( use ::syn::spanned::Spanned; return ::syn::Error::new( base.fields.span(), - "unnamed fields are not supported", + "#[::bok::package(..)]: base: unnamed fields are not supported", ) .to_compile_error() .into(); @@ -95,8 +107,14 @@ pub(crate) fn package( _bok_base: ::std::marker::PhantomData<#source_path> }) .unwrap(); + let repo_marker = ::syn::Field::parse_named + .parse2(quote! { + _bok_repo: ::std::marker::PhantomData + }) + .unwrap(); base_fields_extra.push(pkg_version); base_fields_extra.push(base_marker); + base_fields_extra.push(repo_marker); } None => { return ::syn::Error::new( @@ -114,7 +132,10 @@ pub(crate) fn package( for f in base_fields.named.iter() { let Some(id) = &f.ident else { continue }; // don't add 'version' again - if id.to_string() == "version" || id.to_string() == "_bok_base" { + if id.to_string() == "version" + || id.to_string() == "_bok_base" + || id.to_string() == "_bok_repo" + { continue; } // compiler error if you try to extend a package while @@ -144,12 +165,13 @@ pub(crate) fn package( let mut all_fields = Vec::new(); all_fields.extend(local_fields.named.iter()); all_fields.extend(base_fields_extra.iter()); + quote! { #(#local_attrs) * #[::macro_magic::export_tokens] #[derive(::bok::Package, ::std::fmt::Debug, Clone)] - #vis struct #ident<#generics> { + #vis struct #ident #generics #where_clause{ #(#all_fields), * } @@ -175,7 +197,7 @@ pub(crate) fn deps_build( }; let local_attrs = local.attrs.iter(); let local_fields = local_fields.named.iter(); - let generics = local.generics; + let (_, generics, where_clause) = local.generics.split_for_impl(); let ident = local.ident; let vis = local.vis; @@ -190,7 +212,7 @@ pub(crate) fn deps_build( quote! { #(#local_attrs) * - #vis struct #ident<#generics> { + #vis struct #ident #generics #where_clause{ #(#local_fields), * } @@ -480,6 +502,17 @@ pub(crate) fn package_impl_base_add( } } + let pkg_type = ast.self_ty.clone(); + let generic_struct: ::syn::ItemImpl = ::syn::parse_quote! { + impl test for #pkg_type + where + R: ::std::fmt::Debug + 'static + {} + }; + + ast.generics = generic_struct.generics; + ast.self_ty = generic_struct.self_ty; + ast.items.push(name); ast.items.push(path); ast.items.push(version); @@ -584,7 +617,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { }; let all_fields = elements.iter().filter_map(|field| { if let Some(id) = field.ident.clone() { - if id.to_string() != "version" && id.to_string() != "_bok_base" { + if id.to_string() != "version" + && id.to_string() != "_bok_base" + && id.to_string() != "_bok_repo" + { return Some(&field.ident); } } @@ -594,7 +630,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { let all_fields3 = all_fields.clone(); let all_fields_mut = elements.iter().filter_map(|field| { if let Some(id) = field.ident.clone() { - if id.to_string() != "version" && id.to_string() != "_bok_base" { + if id.to_string() != "version" + && id.to_string() != "_bok_base" + && id.to_string() != "_bok_repo" + { return Some(quote::format_ident!("{}_mut", id.to_string())); } } @@ -602,7 +641,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { }); let all_types = elements.iter().filter_map(|field| { if let Some(id) = field.ident.clone() { - if id.to_string() != "version" && id.to_string() != "_bok_base" { + if id.to_string() != "version" + && id.to_string() != "_bok_base" + && id.to_string() != "_bok_repo" + { return Some(&field.ty); } } @@ -611,7 +653,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { let all_types2 = all_types.clone(); let non_opt_fields = elements.iter().filter_map(|field| { if let Some(id) = field.ident.clone() { - if id.to_string() == "version" || id.to_string() == "_bok_base" { + if id.to_string() == "version" + || id.to_string() == "_bok_base" + || id.to_string() == "_bok_repo" + { return None; } } @@ -630,7 +675,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { }); let opt_fields = elements.iter().filter_map(|field| { if let Some(id) = field.ident.clone() { - if id.to_string() == "version" || id.to_string() == "_bok_base" { + if id.to_string() == "version" + || id.to_string() == "_bok_base" + || id.to_string() == "_bok_repo" + { return None; } } @@ -649,7 +697,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { }); let non_opt_types = elements.iter().filter_map(|field| { if let Some(id) = field.ident.clone() { - if id.to_string() == "version" || id.to_string() == "_bok_base" { + if id.to_string() == "version" + || id.to_string() == "_bok_base" + || id.to_string() == "_bok_repo" + { return None; } } @@ -668,7 +719,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { }); let opt_types = elements.iter().filter_map(|field| { if let Some(id) = field.ident.clone() { - if id.to_string() == "version" || id.to_string() == "_bok_base" { + if id.to_string() == "version" + || id.to_string() == "_bok_base" + || id.to_string() == "_bok_repo" + { return None; } } @@ -719,14 +773,20 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { } let expanded = quote! { - impl ::core::fmt::Display for #name { + impl ::core::fmt::Display for #name + where + R: ::std::fmt::Debug + { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) ->::core::fmt::Result { - <#name as ::bok::PkgCode>::fmt(self, f) + <#name as ::bok::PkgCode>::fmt(self, f) } } - impl ::bok::PkgCode for #name { + impl ::bok::PkgCode for #name + where + R: ::std::fmt::Debug +'static + { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) ->::core::fmt::Result { @@ -786,15 +846,18 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { f.write_str(&formatted) } } - impl #name { + impl #name + where + R: ::std::fmt::Debug +'static + ::core::default::Default + { pub fn as_pkg(&self) -> &dyn ::bok::Pkg { self } pub fn as_pkg_mut(&mut self) -> &mut dyn ::bok::Pkg { self } - pub fn builder() -> #name_builder { - #name_builder::default() + pub fn builder() -> #name_builder { + #name_builder::::default() } #(pub fn #all_fields2(&self) -> &#all_types { &self.#all_fields2 @@ -804,25 +867,32 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { })* } #[derive(::std::default::Default, ::std::fmt::Debug)] - pub struct #name_builder { + pub struct #name_builder + where + R: ::std::fmt::Debug +'static + { + _bok_repo: ::std::marker::PhantomData, #(#non_opt_fields: ::std::option::Option<#non_opt_types>,)* #(#opt_fields: ::std::option::Option<#opt_types>,)* } - impl ::bok::PkgBuilder for #name_builder2 { + impl ::bok::PkgBuilder for #name_builder2 + where + R: ::std::fmt::Debug + 'static + { fn name(&self) -> ::bok::PkgName { use ::bok::Pkg; - #name::default().name() + #name::::default().name() } fn path(&self) -> ::bok::Path<::bok::PkgName> { use ::bok::Pkg; - #name::default().path() + #name::::default().path() } fn version(&self) -> ::bok::Version { use ::bok::Pkg; - #name::default().version() + #name::::default().version() } fn default_unused(&mut self) -> &mut dyn ::bok::PkgBuilder { - let def = #name::default(); + let def = #name::::default(); #(if self.#non_opt_fields5.is_none() { self.#non_opt_fields5 = Some(def.#non_opt_fields5); })* @@ -834,16 +904,20 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { return ::std::result::Result::Err("unset field".into()); })* Ok( - Box::new(#name { + Box::new(#name:: { _bok_base: ::std::marker::PhantomData::default(), - version: #name::default().version, + _bok_repo: ::std::marker::PhantomData::default(), + version: #name::::default().version, #(#non_opt_fields3 : self.#non_opt_fields3.clone().unwrap(),)* #(#opt_fields2 : self.#opt_fields2.clone(),)* }) ) } } - impl #name_builder3 { + impl #name_builder3 + where + R: ::std::fmt::Debug +'static + { pub fn as_any(&self) -> &dyn ::std::any::Any { self } diff --git a/bok-macro/src/repos.rs b/bok-macro/src/repos.rs index 6afee70..783dfb7 100644 --- a/bok-macro/src/repos.rs +++ b/bok-macro/src/repos.rs @@ -74,7 +74,7 @@ pub(crate) fn repository( _ => true, } }); - let generics = local.generics; + let (_, generics, where_clause) = local.generics.split_for_impl(); let ident = local.ident; let vis = local.vis; @@ -149,7 +149,7 @@ pub(crate) fn repository( * #[::macro_magic::export_tokens] #[derive(::bok::Repository, Debug)] - #vis struct #ident<#generics> { + #vis struct #ident #generics #where_clause { #(#all_fields), * } @@ -226,6 +226,10 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream { let pkgs_num: usize = all_pkgs.len(); let (pkg_names, pkg_types): (Vec, Vec<::syn::Path>) = all_pkgs.into_iter().map(|(a, b)| (a, b)).unzip(); + let pkg_ident = pkg_types + .iter() + .map(|p| p.segments.last().unwrap().ident.clone()) + .collect::>(); quote! { impl ::bok::Repository for #name { @@ -244,7 +248,7 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream { } fn get(&self, pkg_name: &str) -> Option<::std::boxed::Box> { match pkg_name { - #(#pkg_names => Some(::std::boxed::Box::new(#pkg_types::default())),) + #(#pkg_names => Some(::std::boxed::Box::new(self.#pkg_ident())),) * _ => None, } @@ -259,7 +263,7 @@ pub(crate) fn repo_packages( ) -> TokenStream { let local = parse_macro_input!(input as ItemStruct); let local_attrs = local.attrs.iter(); - let generics = local.generics; + let (_, generics, where_clause) = local.generics.split_for_impl(); let ident = local.ident; let vis = local.vis; use ::syn::spanned::Spanned; @@ -390,7 +394,7 @@ pub(crate) fn repo_packages( quote! { #(#local_attrs) * - #vis struct #ident<#generics> { + #vis struct #ident #generics #where_clause { #(#all_fields), * } @@ -443,7 +447,7 @@ pub(crate) fn repo_impl_methods( } let local_attrs = local.attrs.iter(); - let generics = local.generics; + let (_, generics, where_clause) = local.generics.split_for_impl(); let ::syn::Type::Path(local_tp) = local.self_ty.as_ref() else { return ::syn::Error::new( proc_macro2::Span::call_site(), @@ -519,9 +523,16 @@ pub(crate) fn repo_impl_methods( // don't try to add it again continue; } + + let mut t_id_build = t_id.clone(); + if let ::syn::PathArguments::AngleBracketed(args) = + &mut t_id_build.segments.last_mut().unwrap().arguments + { + args.colon2_token = Some(::syn::token::PathSep::default()); + } let pkg_fn: ::syn::ImplItemFn = ::syn::parse_quote! { pub fn #pkg_name(&self) -> #t_id { - #t_id::default() + #t_id_build::default() } }; fn_to_add.push(pkg_fn); @@ -534,10 +545,9 @@ pub(crate) fn repo_impl_methods( for p_type in all_pkgs_types.into_iter() { let bok_dep_trait = { let mut tmp = p_type.clone(); - tmp.segments.last_mut().unwrap().ident = quote::format_ident!( - "BokDeps{}", - tmp.segments.last().unwrap().ident - ); + let last = tmp.segments.last_mut().unwrap(); + last.ident = quote::format_ident!("BokDeps{}", last.ident); + last.arguments = ::syn::PathArguments::None; tmp }; let pkg_trait_impl = &bok_dep_trait; @@ -552,7 +562,7 @@ pub(crate) fn repo_impl_methods( quote! { #(#local_attrs) * - impl #local_ident<#generics> { + impl #local_ident #generics #where_clause { #(#items) * #(#new_fn) @@ -576,7 +586,7 @@ pub(crate) fn repo_impl_pkg_deps( .expect("#[::bok_macro::repo_impl_pkg_deps()]: no trait found") .1; let local_attrs = local.attrs.iter(); - let generics = local.generics; + let (_, generics, where_clause) = local.generics.split_for_impl(); let ident = &local.self_ty; //let deps = Vec::<::syn::TraitItemFn>::new(); @@ -601,7 +611,7 @@ pub(crate) fn repo_impl_pkg_deps( quote! { #(#local_attrs) * - impl #impl_trait for #ident<#generics> { + impl #impl_trait for #ident #generics #where_clause { #(#deps) * } diff --git a/bok-utils/src/main.rs b/bok-utils/src/main.rs index 5233bc5..781ca60 100644 --- a/bok-utils/src/main.rs +++ b/bok-utils/src/main.rs @@ -37,7 +37,7 @@ impl TP for P { */ fn main() { - let one = repos::pkgs::one::One::default(); + //let one = repos::pkgs::one::One::default(); let pkgs1 = repos::Pkgs1::default(); let pkgs2 = repos::Pkgs2::default(); diff --git a/bok-utils/src/repos/mod.rs b/bok-utils/src/repos/mod.rs index 6b2268d..8ea62ef 100644 --- a/bok-utils/src/repos/mod.rs +++ b/bok-utils/src/repos/mod.rs @@ -30,7 +30,7 @@ use ::bok::repository; /// /// Base repository with some packages #[::bok::repository(::bok::RepositoryEmpty)] -#[::bok::repo_packages(pkgs::one::One)] +#[::bok::repo_packages(pkgs::one::One)] #[derive(::std::default::Default)] pub struct Pkgs1 { r1: i32, @@ -42,7 +42,7 @@ impl Pkgs1 {} /// /// This repository extends and changes Pkgs1 #[::bok::repository(Pkgs1)] -#[::bok::repo_packages(pkgs::two::Two)] +#[::bok::repo_packages(pkgs::two::Two)] #[derive(::std::default::Default)] pub struct Pkgs2 { r2: i32, diff --git a/bok-utils/src/repos/pkgs/one.rs b/bok-utils/src/repos/pkgs/one.rs index bbb444c..a4d592d 100644 --- a/bok-utils/src/repos/pkgs/one.rs +++ b/bok-utils/src/repos/pkgs/one.rs @@ -16,8 +16,6 @@ */ use ::bok::package; -//use ::bok::{package, PkgEmpty}; -//use ::bok::*; /// Example package /// Automatically implements `.builder().my_attr(42).build()` pattern @@ -27,10 +25,14 @@ pub struct One { pub my_attr: u32, } -impl ::std::default::Default for One { +impl ::std::default::Default for One +where + R: ::std::fmt::Debug, +{ fn default() -> Self { One { _bok_base: ::std::marker::PhantomData::default(), + _bok_repo: ::std::marker::PhantomData::default(), my_attr: 1, version: ::bok::Version { major: 0, diff --git a/bok-utils/src/repos/pkgs/three.rs b/bok-utils/src/repos/pkgs/three.rs index 7f801f6..742969b 100644 --- a/bok-utils/src/repos/pkgs/three.rs +++ b/bok-utils/src/repos/pkgs/three.rs @@ -19,15 +19,19 @@ use ::bok::package; /// Example package #[::bok::package(::bok::PkgEmpty)] -#[::bok::deps_build(super::One)] +#[::bok::deps_build(super::One)] pub struct Three { pub my_attr: u32, } -impl ::std::default::Default for Three { +impl ::std::default::Default for Three +where + R: ::std::fmt::Debug, +{ fn default() -> Self { Three { _bok_base: ::std::marker::PhantomData::default(), + _bok_repo: ::std::marker::PhantomData::default(), version: ::bok::Version { major: 0, minor: 0, diff --git a/bok-utils/src/repos/pkgs/two.rs b/bok-utils/src/repos/pkgs/two.rs index efc073a..ea46aa7 100644 --- a/bok-utils/src/repos/pkgs/two.rs +++ b/bok-utils/src/repos/pkgs/two.rs @@ -18,16 +18,20 @@ use ::bok::package; /// Example package -#[::bok::package(super::one::One)] -#[::bok::deps_build(super::one::One)] +#[::bok::package(super::one::One)] +#[::bok::deps_build(super::one::One)] pub struct Two { pub my_attr2: u32, } -impl ::std::default::Default for Two { +impl ::std::default::Default for Two +where + R: ::std::fmt::Debug, +{ fn default() -> Self { Two { _bok_base: ::std::marker::PhantomData::default(), + _bok_repo: ::std::marker::PhantomData::default(), my_attr: 2, my_attr2: 2, version: ::bok::Version {