fix non extending attributes
This commit is contained in:
1 parent
7b51bb8060
commit
b60671e0fe
6 files changed
+70
-48
No files matched your search
+1
-6
@@ -1,9 +1,4 @@
|
|||||||
use crate::dioxus_elements::ExtendedDivMarker;
|
use dioxus::prelude::*;
|
||||||
use dioxus::{
|
|
||||||
core::{exports::bumpalo::Bump, Attribute, HasAttributesBox},
|
|
||||||
html::{ExtendedGlobalAttributesMarker, GlobalAttributesExtension},
|
|
||||||
prelude::*,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut dom = VirtualDom::new(app);
|
let mut dom = VirtualDom::new(app);
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ mod struct_info {
|
|||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::visit::Visit;
|
use syn::visit::Visit;
|
||||||
use syn::{Expr, Ident};
|
use syn::{parse_quote, Expr, Ident};
|
||||||
|
|
||||||
use super::field_info::{FieldBuilderAttr, FieldInfo};
|
use super::field_info::{FieldBuilderAttr, FieldInfo};
|
||||||
use super::util::{
|
use super::util::{
|
||||||
@@ -611,10 +611,17 @@ mod struct_info {
|
|||||||
// Therefore, we will generate code that shortcircuits the "comparison" in memoization
|
// Therefore, we will generate code that shortcircuits the "comparison" in memoization
|
||||||
let are_there_generics = !self.generics.params.is_empty();
|
let are_there_generics = !self.generics.params.is_empty();
|
||||||
|
|
||||||
|
let extend_lifetime = self.extend_lifetime()?;
|
||||||
|
|
||||||
let generics = self.generics.clone();
|
let generics = self.generics.clone();
|
||||||
let (_, ty_generics, where_clause) = generics.split_for_impl();
|
let (_, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
let impl_generics = self.generics.clone();
|
let impl_generics = self.modify_generics(|g| {
|
||||||
let (impl_generics, b_initial_generics, _) = impl_generics.split_for_impl();
|
if extend_lifetime.is_none() {
|
||||||
|
g.params.insert(0, parse_quote!('__bump));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let (impl_generics, _, _) = impl_generics.split_for_impl();
|
||||||
|
let (_, b_initial_generics, _) = self.generics.split_for_impl();
|
||||||
let all_fields_param = syn::GenericParam::Type(
|
let all_fields_param = syn::GenericParam::Type(
|
||||||
syn::Ident::new("TypedBuilderFields", proc_macro2::Span::call_site()).into(),
|
syn::Ident::new("TypedBuilderFields", proc_macro2::Span::call_site()).into(),
|
||||||
);
|
);
|
||||||
@@ -712,9 +719,21 @@ Finally, call `.build()` to create the instance of `{name}`.
|
|||||||
let name = f.name;
|
let name = f.name;
|
||||||
quote!(#name: Vec::new())
|
quote!(#name: Vec::new())
|
||||||
});
|
});
|
||||||
let extend_lifetime = self
|
let has_extend_fields = self.extend_fields().next().is_some();
|
||||||
.extend_lifetime()?
|
let take_bump = if has_extend_fields {
|
||||||
.unwrap_or(syn::Lifetime::new("'_", proc_macro2::Span::call_site()));
|
quote!(bump: _cx.bump(),)
|
||||||
|
} else {
|
||||||
|
quote!()
|
||||||
|
};
|
||||||
|
let bump_field = if has_extend_fields {
|
||||||
|
quote!(bump: & #extend_lifetime ::dioxus::core::exports::bumpalo::Bump,)
|
||||||
|
} else {
|
||||||
|
quote!()
|
||||||
|
};
|
||||||
|
let extend_lifetime = extend_lifetime.unwrap_or(syn::Lifetime::new(
|
||||||
|
"'__bump",
|
||||||
|
proc_macro2::Span::call_site(),
|
||||||
|
));
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
impl #impl_generics #name #ty_generics #where_clause {
|
impl #impl_generics #name #ty_generics #where_clause {
|
||||||
@@ -723,7 +742,7 @@ Finally, call `.build()` to create the instance of `{name}`.
|
|||||||
#vis fn builder(_cx: & #extend_lifetime ::dioxus::prelude::ScopeState) -> #builder_name #generics_with_empty {
|
#vis fn builder(_cx: & #extend_lifetime ::dioxus::prelude::ScopeState) -> #builder_name #generics_with_empty {
|
||||||
#builder_name {
|
#builder_name {
|
||||||
#(#extend_fields_value,)*
|
#(#extend_fields_value,)*
|
||||||
bump: _cx.bump(),
|
#take_bump
|
||||||
fields: #empties_tuple,
|
fields: #empties_tuple,
|
||||||
_phantom: ::core::default::Default::default(),
|
_phantom: ::core::default::Default::default(),
|
||||||
}
|
}
|
||||||
@@ -735,7 +754,7 @@ Finally, call `.build()` to create the instance of `{name}`.
|
|||||||
#[allow(dead_code, non_camel_case_types, non_snake_case)]
|
#[allow(dead_code, non_camel_case_types, non_snake_case)]
|
||||||
#vis struct #builder_name #b_generics {
|
#vis struct #builder_name #b_generics {
|
||||||
#(#extend_fields,)*
|
#(#extend_fields,)*
|
||||||
bump: & #extend_lifetime ::dioxus::core::exports::bumpalo::Bump,
|
#bump_field
|
||||||
fields: #all_fields_param,
|
fields: #all_fields_param,
|
||||||
_phantom: (#( #phantom_generics ),*),
|
_phantom: (#( #phantom_generics ),*),
|
||||||
}
|
}
|
||||||
@@ -862,22 +881,23 @@ Finally, call `.build()` to create the instance of `{name}`.
|
|||||||
quote!(#name: self.#name)
|
quote!(#name: self.#name)
|
||||||
});
|
});
|
||||||
|
|
||||||
let extends_impl = field.builder_attr.extends.iter().map(|path| {
|
|
||||||
let name_str = path_to_single_string(path).unwrap();
|
|
||||||
let camel_name = name_str.to_case(Case::UpperCamel);
|
|
||||||
let marker_name = Ident::new(
|
|
||||||
format!("Extended{}Marker", &camel_name).as_str(),
|
|
||||||
path.span(),
|
|
||||||
);
|
|
||||||
quote! {
|
|
||||||
impl #impl_generics #marker_name for #builder_name < #( #ty_generics ),* > #where_clause {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let extend_lifetime = self.extend_lifetime()?.ok_or(Error::new_spanned(
|
let extend_lifetime = self.extend_lifetime()?.ok_or(Error::new_spanned(
|
||||||
field_name,
|
field_name,
|
||||||
"Unable to find lifetime for extended field. Please specify it manually",
|
"Unable to find lifetime for extended field. Please specify it manually",
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
|
let extends_impl = field.builder_attr.extends.iter().map(|path| {
|
||||||
|
let name_str = path_to_single_string(path).unwrap();
|
||||||
|
let camel_name = name_str.to_case(Case::UpperCamel);
|
||||||
|
let marker_name = Ident::new(
|
||||||
|
format!("{}Extension", &camel_name).as_str(),
|
||||||
|
path.span(),
|
||||||
|
);
|
||||||
|
quote! {
|
||||||
|
impl #impl_generics dioxus_elements::extensions::#marker_name < #extend_lifetime > for #builder_name < #( #ty_generics ),* > #where_clause {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
impl #impl_generics ::dioxus::prelude::HasAttributesBox<#extend_lifetime> for #builder_name < #( #ty_generics ),* > #where_clause {
|
impl #impl_generics ::dioxus::prelude::HasAttributesBox<#extend_lifetime> for #builder_name < #( #ty_generics ),* > #where_clause {
|
||||||
fn push_attribute(
|
fn push_attribute(
|
||||||
@@ -1035,6 +1055,11 @@ Finally, call `.build()` to create the instance of `{name}`.
|
|||||||
let name = f.name;
|
let name = f.name;
|
||||||
quote!(#name: self.#name)
|
quote!(#name: self.#name)
|
||||||
});
|
});
|
||||||
|
let forward_bump = if self.extend_fields().next().is_some() {
|
||||||
|
quote!(bump: self.bump,)
|
||||||
|
} else {
|
||||||
|
quote!()
|
||||||
|
};
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#[allow(dead_code, non_camel_case_types, missing_docs)]
|
#[allow(dead_code, non_camel_case_types, missing_docs)]
|
||||||
@@ -1045,7 +1070,7 @@ Finally, call `.build()` to create the instance of `{name}`.
|
|||||||
let ( #(#descructuring,)* ) = self.fields;
|
let ( #(#descructuring,)* ) = self.fields;
|
||||||
#builder_name {
|
#builder_name {
|
||||||
#(#forward_extended_fields,)*
|
#(#forward_extended_fields,)*
|
||||||
bump: self.bump,
|
#forward_bump
|
||||||
fields: ( #(#reconstructing,)* ),
|
fields: ( #(#reconstructing,)* ),
|
||||||
_phantom: self._phantom,
|
_phantom: self._phantom,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ pub mod prelude {
|
|||||||
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, has_context,
|
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, has_context,
|
||||||
provide_context, provide_context_to_scope, provide_root_context, push_future,
|
provide_context, provide_context_to_scope, provide_root_context, push_future,
|
||||||
remove_future, schedule_update_any, spawn, spawn_forever, suspend, throw, AnyValue,
|
remove_future, schedule_update_any, spawn, spawn_forever, suspend, throw, AnyValue,
|
||||||
AttributeType, Component, Element, Event, EventHandler, Fragment, HasAttributesBox,
|
Attribute, AttributeType, Component, Element, Event, EventHandler, Fragment,
|
||||||
IntoAttributeValue, LazyNodes, MountedAttribute, Properties, Runtime, RuntimeGuard, Scope,
|
HasAttributesBox, IntoAttributeValue, LazyNodes, MountedAttribute, Properties, Runtime,
|
||||||
ScopeId, ScopeState, Scoped, TaskId, Template, TemplateAttribute, TemplateNode, Throw,
|
RuntimeGuard, Scope, ScopeId, ScopeState, Scoped, TaskId, Template, TemplateAttribute,
|
||||||
VNode, VirtualDom,
|
TemplateNode, Throw, VNode, VirtualDom,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,13 +39,13 @@ impl Parse for ImplExtensionAttributes {
|
|||||||
impl ToTokens for ImplExtensionAttributes {
|
impl ToTokens for ImplExtensionAttributes {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
||||||
let name = &self.name;
|
let name = &self.name;
|
||||||
let camel_name = name.to_string().to_case(Case::UpperCamel);
|
let name_string = name.to_string();
|
||||||
|
let camel_name = name_string
|
||||||
|
.strip_prefix("r#")
|
||||||
|
.unwrap_or(&name_string)
|
||||||
|
.to_case(Case::UpperCamel);
|
||||||
let impl_name = Ident::new(format!("{}Impl", &camel_name).as_str(), name.span());
|
let impl_name = Ident::new(format!("{}Impl", &camel_name).as_str(), name.span());
|
||||||
let extension_name = Ident::new(format!("{}Extension", &camel_name).as_str(), name.span());
|
let extension_name = Ident::new(format!("{}Extension", &camel_name).as_str(), name.span());
|
||||||
let marker_name = Ident::new(
|
|
||||||
format!("Extended{}Marker", &camel_name).as_str(),
|
|
||||||
name.span(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if !self.is_element {
|
if !self.is_element {
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
@@ -54,11 +54,6 @@ impl ToTokens for ImplExtensionAttributes {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let defs = self.attrs.iter().map(|ident| {
|
|
||||||
quote! {
|
|
||||||
fn #ident(self, value: impl IntoAttributeValue<'a>) -> Self;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let impls = self.attrs.iter().map(|ident| {
|
let impls = self.attrs.iter().map(|ident| {
|
||||||
let d = if self.is_element {
|
let d = if self.is_element {
|
||||||
quote! { #name::#ident }
|
quote! { #name::#ident }
|
||||||
@@ -73,12 +68,7 @@ impl ToTokens for ImplExtensionAttributes {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
pub trait #marker_name {}
|
pub trait #extension_name<'a>: HasAttributesBox<'a> + Sized {
|
||||||
|
|
||||||
pub trait #extension_name<'a> {
|
|
||||||
#(#defs)*
|
|
||||||
}
|
|
||||||
impl<'a, T> #extension_name<'a> for T where T: HasAttributesBox<'a> + #marker_name {
|
|
||||||
#(#impls)*
|
#(#impls)*
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -111,8 +111,6 @@ macro_rules! impl_element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalAttributes for $name {}
|
impl GlobalAttributes for $name {}
|
||||||
|
|
||||||
impl_extension_attributes![ELEMENT $name { $($fil,)* }];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
@@ -289,6 +287,13 @@ macro_rules! builder_constructors {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
)*
|
)*
|
||||||
|
|
||||||
|
pub(crate) mod extensions {
|
||||||
|
use super::*;
|
||||||
|
$(
|
||||||
|
impl_extension_attributes![ELEMENT $name { $($fil,)* }];
|
||||||
|
)*
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,14 @@ pub use render_template::*;
|
|||||||
|
|
||||||
mod eval;
|
mod eval;
|
||||||
|
|
||||||
|
pub mod extensions {
|
||||||
|
pub use crate::elements::extensions::*;
|
||||||
|
pub use crate::global_attributes::{GlobalAttributesExtension, SvgAttributesExtension};
|
||||||
|
}
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
pub use crate::elements::extensions::*;
|
||||||
pub use crate::eval::*;
|
pub use crate::eval::*;
|
||||||
pub use crate::events::*;
|
pub use crate::events::*;
|
||||||
|
pub use crate::global_attributes::{GlobalAttributesExtension, SvgAttributesExtension};
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user