Chore #2028: radically clean up core-macro
This commit is contained in:
8 files changed
+427
-872
No files matched your search
+49
-122
@@ -2,21 +2,15 @@
|
||||
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||
|
||||
use component::ComponentBody;
|
||||
use proc_macro::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use syn::parse::Parser;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::{parse_macro_input, Path, Token};
|
||||
use syn::parse_macro_input;
|
||||
|
||||
mod component_body;
|
||||
mod component_body_deserializers;
|
||||
mod component;
|
||||
mod props;
|
||||
mod utils;
|
||||
|
||||
// mod rsx;
|
||||
use crate::component_body::ComponentBody;
|
||||
use crate::component_body_deserializers::component::ComponentDeserializerArgs;
|
||||
use crate::component_body_deserializers::inline_props::InlinePropsDeserializerArgs;
|
||||
use dioxus_rsx as rsx;
|
||||
|
||||
#[proc_macro]
|
||||
@@ -54,6 +48,50 @@ pub fn render(tokens: TokenStream) -> TokenStream {
|
||||
rsx(tokens)
|
||||
}
|
||||
|
||||
/// Streamlines component creation.
|
||||
/// This is the recommended way of creating components,
|
||||
/// though you might want lower-level control with more advanced uses.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `no_case_check` - Doesn't enforce `PascalCase` on your component names.
|
||||
/// **This will be removed/deprecated in a future update in favor of a more complete Clippy-backed linting system.**
|
||||
/// The reasoning behind this is that Clippy allows more robust and powerful lints, whereas
|
||||
/// macros are extremely limited.
|
||||
///
|
||||
/// # Features
|
||||
/// This attribute:
|
||||
/// * Enforces that your component uses `PascalCase`.
|
||||
/// No warnings are generated for the `PascalCase`
|
||||
/// function name, but everything else will still raise a warning if it's incorrectly `PascalCase`.
|
||||
/// Does not disable warnings anywhere else, so if you, for example,
|
||||
/// accidentally don't use `snake_case`
|
||||
/// for a variable name in the function, the compiler will still warn you.
|
||||
/// * Automatically uses `#[inline_props]` if there's more than 1 parameter in the function.
|
||||
/// * Verifies the validity of your component.
|
||||
///
|
||||
/// # Examples
|
||||
/// * Without props:
|
||||
/// ```rust,ignore
|
||||
/// #[component]
|
||||
/// fn GreetBob() -> Element {
|
||||
/// rsx! { "hello, bob" }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// * With props:
|
||||
/// ```rust,ignore
|
||||
/// #[component]
|
||||
/// fn GreetBob(bob: String) -> Element {
|
||||
/// rsx! { "hello, {bob}" }
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
pub fn component(_args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
parse_macro_input!(input as ComponentBody)
|
||||
.into_token_stream()
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Derive props for a component within the component definition.
|
||||
///
|
||||
/// This macro provides a simple transformation from `Scope<{}>` to `Scope<P>`,
|
||||
@@ -82,117 +120,6 @@ pub fn render(tokens: TokenStream) -> TokenStream {
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
#[deprecated(note = "Use `#[component]` instead.")]
|
||||
pub fn inline_props(_args: TokenStream, s: TokenStream) -> TokenStream {
|
||||
let comp_body = parse_macro_input!(s as ComponentBody);
|
||||
|
||||
match comp_body.deserialize(InlinePropsDeserializerArgs {}) {
|
||||
Err(e) => e.to_compile_error().into(),
|
||||
Ok(output) => output.to_token_stream().into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const COMPONENT_ARG_CASE_CHECK_OFF: &str = "no_case_check";
|
||||
|
||||
/// Streamlines component creation.
|
||||
/// This is the recommended way of creating components,
|
||||
/// though you might want lower-level control with more advanced uses.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `no_case_check` - Doesn't enforce `PascalCase` on your component names.
|
||||
/// **This will be removed/deprecated in a future update in favor of a more complete Clippy-backed linting system.**
|
||||
/// The reasoning behind this is that Clippy allows more robust and powerful lints, whereas
|
||||
/// macros are extremely limited.
|
||||
///
|
||||
/// # Features
|
||||
/// This attribute:
|
||||
/// * Enforces that your component uses `PascalCase`.
|
||||
/// No warnings are generated for the `PascalCase`
|
||||
/// function name, but everything else will still raise a warning if it's incorrectly `PascalCase`.
|
||||
/// Does not disable warnings anywhere else, so if you, for example,
|
||||
/// accidentally don't use `snake_case`
|
||||
/// for a variable name in the function, the compiler will still warn you.
|
||||
/// * Automatically uses `#[inline_props]` if there's more than 1 parameter in the function.
|
||||
/// * Verifies the validity of your component.
|
||||
/// E.g. if it has a [`Scope`](dioxus_core::Scope) argument.
|
||||
/// Notes:
|
||||
/// * This doesn't work 100% of the time, because of macro limitations.
|
||||
/// * Provides helpful messages if your component is not correct.
|
||||
/// Possible bugs (please, report these!):
|
||||
/// * There might be bugs where it incorrectly *denies* validity.
|
||||
/// This is bad as it means that you can't use the attribute or you have to change the component.
|
||||
/// * There might be bugs where it incorrectly *confirms* validity.
|
||||
/// You will still know if the component is invalid once you use it,
|
||||
/// but the error might be less helpful.
|
||||
///
|
||||
/// # Examples
|
||||
/// * Without props:
|
||||
/// ```rust,ignore
|
||||
/// #[component]
|
||||
/// fn GreetBob() -> Element {
|
||||
/// rsx! { "hello, bob" }
|
||||
/// }
|
||||
///
|
||||
/// // is equivalent to
|
||||
///
|
||||
/// #[allow(non_snake_case)]
|
||||
/// fn GreetBob() -> Element {
|
||||
/// #[warn(non_snake_case)]
|
||||
/// #[inline(always)]
|
||||
/// fn __dx_inner_comp() -> Element {
|
||||
/// rsx! { "hello, bob" }
|
||||
/// }
|
||||
/// // There's no function call overhead since __dx_inner_comp has the #[inline(always)] attribute,
|
||||
/// // so don't worry about performance.
|
||||
/// __dx_inner_comp(cx)
|
||||
/// }
|
||||
/// ```
|
||||
/// * With props:
|
||||
/// ```rust,ignore
|
||||
/// #[component(no_case_check)]
|
||||
/// fn GreetPerson(person: String) -> Element {
|
||||
/// rsx! { "hello, {person}" }
|
||||
/// }
|
||||
///
|
||||
/// // is equivalent to
|
||||
///
|
||||
/// #[derive(Props, PartialEq)]
|
||||
/// #[allow(non_camel_case_types)]
|
||||
/// struct GreetPersonProps {
|
||||
/// person: String,
|
||||
/// }
|
||||
///
|
||||
/// #[allow(non_snake_case)]
|
||||
/// fn GreetPerson(props: GreetPersonProps>) -> Element {
|
||||
/// #[warn(non_snake_case)]
|
||||
/// #[inline(always)]
|
||||
/// fn __dx_inner_comp(props: GreetPersonProps>e) -> Element {
|
||||
/// let GreetPersonProps { person } = props;
|
||||
/// {
|
||||
/// rsx! { "hello, {person}" }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// __dx_inner_comp(cx)
|
||||
/// }
|
||||
/// ```
|
||||
// TODO: Maybe add an option to input a custom component name through the args.
|
||||
// I think that's unnecessary, but there might be some scenario where it could be useful.
|
||||
#[proc_macro_attribute]
|
||||
pub fn component(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let component_body = parse_macro_input!(input as ComponentBody);
|
||||
let case_check = match Punctuated::<Path, Token![,]>::parse_terminated.parse(args) {
|
||||
Err(e) => return e.to_compile_error().into(),
|
||||
Ok(args) => {
|
||||
if let Some(first) = args.first() {
|
||||
!first.is_ident(COMPONENT_ARG_CASE_CHECK_OFF)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match component_body.deserialize(ComponentDeserializerArgs { case_check }) {
|
||||
Err(e) => e.to_compile_error().into(),
|
||||
Ok(output) => output.to_token_stream().into(),
|
||||
}
|
||||
pub fn inline_props(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
component(args, input)
|
||||
}
|
||||
Reference in new issue
Block a user