Skip to content
Snippets Groups Projects
Commit de987514 authored by MrGVSV's avatar MrGVSV
Browse files

Revert "Added widget_props attribute macro"

This reverts commit 5bca7d20.
parent 5bca7d20
No related branches found
No related tags found
No related merge requests found
...@@ -23,7 +23,7 @@ use use_effect::UseEffect; ...@@ -23,7 +23,7 @@ use use_effect::UseEffect;
use widget::ConstructedWidget; use widget::ConstructedWidget;
use crate::widget::Widget; use crate::widget::Widget;
use crate::widget_props::{add_widget_props}; use crate::widget_props::impl_widget_props;
#[proc_macro] #[proc_macro]
#[proc_macro_error] #[proc_macro_error]
...@@ -75,16 +75,10 @@ pub fn widget(args: TokenStream, item: TokenStream) -> TokenStream { ...@@ -75,16 +75,10 @@ pub fn widget(args: TokenStream, item: TokenStream) -> TokenStream {
function_component::create_function_widget(f, widget_args) function_component::create_function_widget(f, widget_args)
} }
#[proc_macro_attribute]
#[proc_macro_error]
pub fn widget_props(args: TokenStream, item: TokenStream) -> TokenStream {
add_widget_props(args, item)
}
#[proc_macro_derive(WidgetProps, attributes(prop_field))] #[proc_macro_derive(WidgetProps, attributes(prop_field))]
#[proc_macro_error] #[proc_macro_error]
pub fn derive_widget_props(item: TokenStream) -> TokenStream { pub fn derive_widget_props(item: TokenStream) -> TokenStream {
widget_props::derive_widget_props(item) impl_widget_props(item)
} }
#[proc_macro_derive(DynPartialEq)] #[proc_macro_derive(DynPartialEq)]
......
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::{Ident, Span}; use proc_macro2::{Ident};
use proc_macro_error::{emit_error, emit_warning}; use proc_macro_error::{emit_error, emit_warning};
use quote::{format_ident, quote, ToTokens}; use quote::quote;
use syn::{AttributeArgs, Data, DeriveInput, Field, Fields, Generics, ItemStruct, Meta, NestedMeta, parse_macro_input, spanned::Spanned}; use syn::{AttributeArgs, Data, DeriveInput, Field, Fields, ItemStruct, Meta, NestedMeta, parse_macro_input, spanned::Spanned};
use syn::parse::Parser;
use crate::attribute::Attribute; use crate::attribute::Attribute;
use crate::get_core_crate; use crate::get_core_crate;
...@@ -12,28 +11,10 @@ use crate::get_core_crate; ...@@ -12,28 +11,10 @@ use crate::get_core_crate;
/// The ident for the props helper attribute (`#[prop_field(Children)]`) /// The ident for the props helper attribute (`#[prop_field(Children)]`)
const PROPS_HELPER_IDENT: &str = "prop_field"; const PROPS_HELPER_IDENT: &str = "prop_field";
const PROP_CHILDREN: CommonProps = CommonProps { const PROP_CHILDREN: &str = "Children";
key: "Children", const PROP_STYLE: &str = "Styles";
ident: "children", const PROP_ON_EVENT: &str = "OnEvent";
}; const PROP_FOCUSABLE: &str = "Focusable";
const PROP_STYLE: CommonProps = CommonProps {
key: "Styles",
ident: "styles",
};
const PROP_ON_EVENT: CommonProps = CommonProps {
key: "OnEvent",
ident: "on_event",
};
const PROP_FOCUSABLE: CommonProps = CommonProps {
key: "Focusable",
ident: "focusable",
};
#[derive(Default)]
struct CommonProps {
key: &'static str,
ident: &'static str,
}
#[derive(Default)] #[derive(Default)]
struct PropsHelpers { struct PropsHelpers {
...@@ -43,75 +24,15 @@ struct PropsHelpers { ...@@ -43,75 +24,15 @@ struct PropsHelpers {
focusable_ident: Option<Ident>, focusable_ident: Option<Ident>,
} }
pub(crate) fn derive_widget_props(input: TokenStream) -> TokenStream { pub(crate) fn impl_widget_props(input: TokenStream) -> TokenStream {
let DeriveInput { let DeriveInput {
ident, data, generics, attrs, .. ident, data, generics, ..
} = parse_macro_input!(input); } = parse_macro_input!(input);
let has_widget_props_attr = attrs.iter().any(|attr| { check_naming_convention(&ident);
if let Ok(meta) = attr.parse_meta() {
let path = meta.path().to_token_stream().to_string();
path.ends_with("widget_props")
} else {
false
}
});
if has_widget_props_attr {
// Has the #[widget_props(...)] attribute -> Let that macro handle the impl
return TokenStream::new();
}
let helpers = process_data(data); let helpers = process_data(data);
impl_widget_props(&ident, &generics, helpers)
}
pub(crate) fn add_widget_props(attrs: TokenStream, item: TokenStream) -> TokenStream {
let mut prop_struct = parse_macro_input!(item as ItemStruct);
let args = parse_macro_input!(attrs as AttributeArgs);
let helpers = insert_common_props(&mut prop_struct, args);
emit_warning!(prop_struct.span(), "Attrs: {:?}", prop_struct.attrs);
let has_derive = prop_struct.attrs.iter().any(|attr| {
if let Ok(meta) = attr.parse_meta() {
let path = meta.path().to_token_stream().to_string();
if !path.ends_with("derive") {
return false;
}
if let Meta::List(list) = meta {
return list.nested.iter().any(|nested| {
if let NestedMeta::Meta(meta) = nested {
let path = meta.path().to_token_stream().to_string();
return path.ends_with("WidgetProps");
}
false
});
}
}
false
});
let impl_stream = if has_derive {
// Derive has definitely not been applied yet -> Let it
proc_macro2::TokenStream::new()
} else {
// Derive may or may not have been applied already -> Implement (it should have detected this macro and skipped)
proc_macro2::TokenStream::from(impl_widget_props(&prop_struct.ident, &prop_struct.generics, helpers))
};
let output = quote! {
#prop_struct
#impl_stream
};
output.into()
}
fn impl_widget_props(ident: &Ident, generics: &Generics, helpers: PropsHelpers) -> TokenStream {
let children_return = quote_clone_field(helpers.children_ident); let children_return = quote_clone_field(helpers.children_ident);
let styles_return = quote_clone_field(helpers.styles_ident); let styles_return = quote_clone_field(helpers.styles_ident);
let on_event_return = quote_clone_field(helpers.on_event_ident); let on_event_return = quote_clone_field(helpers.on_event_ident);
...@@ -143,82 +64,6 @@ fn impl_widget_props(ident: &Ident, generics: &Generics, helpers: PropsHelpers) ...@@ -143,82 +64,6 @@ fn impl_widget_props(ident: &Ident, generics: &Generics, helpers: PropsHelpers)
output.into() output.into()
} }
fn insert_common_props(prop_struct: &mut ItemStruct, args: AttributeArgs) -> PropsHelpers {
let mut helpers = PropsHelpers::default();
let kayak_core = get_core_crate();
for arg in args {
match arg {
NestedMeta::Meta(meta) => {
match meta {
Meta::Path(path) => {
if path.segments.len() > 1 {
emit_error!(path.span(), "Invalid argument: {}", path.to_token_stream().to_string())
} else {
let ident = path.get_ident().unwrap();
match ident.to_string().as_str() {
key if key == PROP_CHILDREN.key => {
push_field_raw(
prop_struct, key, PROP_CHILDREN.ident, quote!(Option<#kayak_core::Children>),
);
helpers.children_ident = Some(Ident::new(PROP_CHILDREN.ident, ident.span()));
}
key if key == PROP_STYLE.key => {
push_field_raw(
prop_struct, key, PROP_STYLE.ident, quote!(Option<#kayak_core::styles::Style>),
);
helpers.styles_ident = Some(Ident::new(PROP_STYLE.ident, ident.span()));
}
key if key == PROP_ON_EVENT.key => {
push_field_raw(
prop_struct, key, PROP_ON_EVENT.ident, quote!(Option<#kayak_core::OnEvent>),
);
helpers.on_event_ident = Some(Ident::new(PROP_ON_EVENT.ident, ident.span()));
}
key if key == PROP_FOCUSABLE.key => {
push_field_raw(
prop_struct, key, PROP_FOCUSABLE.ident, quote!(Option<bool>),
);
helpers.focusable_ident = Some(Ident::new(PROP_FOCUSABLE.ident, ident.span()));
}
err => emit_error!(ident.span(), "Invalid attribute: {}", err)
}
}
}
err => emit_error!(err.span(), "Invalid argument: {:?}", err)
}
}
err => emit_error!(err.span(), "Invalid argument: {:?}", err)
}
}
helpers
}
fn push_field_raw(prop_struct: &mut ItemStruct, field_key: &str, field_name: &str, field_type: proc_macro2::TokenStream) {
let attr = quote::format_ident!("{}", PROPS_HELPER_IDENT);
let key = quote::format_ident!("{}", field_key);
let ident = quote::format_ident!("{}", field_name);
let field = quote::quote! {
#[#attr(#key)]
pub #ident: #field_type
};
push_field(prop_struct, field);
}
fn push_field(prop_struct: &mut ItemStruct, field: proc_macro2::TokenStream) {
let span = prop_struct.span();
match &mut prop_struct.fields {
Fields::Named(fields) => {
let field = Field::parse_named.parse2(quote! {
#field
}).unwrap();
fields.named.push(field);
}
Fields::Unit => emit_error!(span, "Cannot be unit struct"),
Fields::Unnamed(fields) => emit_error!(fields.span(), "Cannot be tuple struct"),
}
}
/// Checks for the widget props naming convention (`<Widget Name>Props`), emitting a warning if not followed /// Checks for the widget props naming convention (`<Widget Name>Props`), emitting a warning if not followed
fn check_naming_convention(ident: &Ident) { fn check_naming_convention(ident: &Ident) {
let name = ident.to_string(); let name = ident.to_string();
...@@ -273,12 +118,13 @@ fn process_field(field: Field, props: &mut PropsHelpers) { ...@@ -273,12 +118,13 @@ fn process_field(field: Field, props: &mut PropsHelpers) {
}; };
if let Some(ident) = ident { if let Some(ident) = ident {
match ident.to_string().as_str() { let ident_str = ident.to_string();
key if key == PROP_CHILDREN.key => props.children_ident = field.ident.clone(), match ident_str.as_str() {
key if key == PROP_STYLE.key => props.styles_ident = field.ident.clone(), PROP_CHILDREN => props.children_ident = field.ident.clone(),
key if key == PROP_ON_EVENT.key => props.on_event_ident = field.ident.clone(), PROP_STYLE => props.styles_ident = field.ident.clone(),
key if key == PROP_FOCUSABLE.key => props.focusable_ident = field.ident.clone(), PROP_ON_EVENT => props.on_event_ident = field.ident.clone(),
err => emit_error!(ident.span(), "Invalid attribute: {}", err) PROP_FOCUSABLE => props.focusable_ident = field.ident.clone(),
err => emit_error!(err.span(), "Invalid attribute: {}", err)
} }
} }
} }
......
pub mod core { pub mod core {
pub use kayak_core::*; pub use kayak_core::*;
pub use kayak_render_macros::{constructor, render, rsx, use_effect, use_state, widget, WidgetProps, widget_props}; pub use kayak_render_macros::{constructor, render, rsx, use_effect, use_state, widget, WidgetProps};
} }
#[cfg(feature = "bevy_renderer")] #[cfg(feature = "bevy_renderer")]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment