Required Components: pass through all tokens in {} and () syntax (#18578)
# Objective #18555 added improved require syntax, but inline structs didn't support `..Default::default()` syntax (for technical reasons we can't parse the struct directly, so there is manual logic that missed this case). ## Solution When a `{}` or `()` section is encountered for a required component, rather than trying to parse the fields directly, just pass _all_ of the tokens through. This ensures no tokens are dropped, protects us against any future syntax changes, and optimizes our parsing logic (as we're dropping the field parsing logic entirely).
This commit is contained in:
parent
0a2e183476
commit
1ba9da0812
@ -9,8 +9,8 @@ use syn::{
|
|||||||
punctuated::Punctuated,
|
punctuated::Punctuated,
|
||||||
spanned::Spanned,
|
spanned::Spanned,
|
||||||
token::{Brace, Comma, Paren},
|
token::{Brace, Comma, Paren},
|
||||||
Data, DataEnum, DataStruct, DeriveInput, Expr, ExprCall, ExprPath, Field, FieldValue, Fields,
|
Data, DataEnum, DataStruct, DeriveInput, Expr, ExprCall, ExprPath, Field, Fields, Ident,
|
||||||
Ident, LitStr, Member, Path, Result, Token, Type, Visibility,
|
LitStr, Member, Path, Result, Token, Type, Visibility,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const EVENT: &str = "event";
|
pub const EVENT: &str = "event";
|
||||||
@ -603,16 +603,16 @@ impl Parse for Require {
|
|||||||
// This is a "value style" named-struct-like require
|
// This is a "value style" named-struct-like require
|
||||||
let content;
|
let content;
|
||||||
braced!(content in input);
|
braced!(content in input);
|
||||||
let fields = Punctuated::<FieldValue, Token![,]>::parse_terminated(&content)?;
|
let content = content.parse::<TokenStream2>()?;
|
||||||
let tokens: TokenStream = quote::quote! (|| #path { #fields }).into();
|
let tokens: TokenStream = quote::quote! (|| #path { #content }).into();
|
||||||
Some(TokenStream2::from(tokens))
|
Some(TokenStream2::from(tokens))
|
||||||
} else if input.peek(Paren) {
|
} else if input.peek(Paren) {
|
||||||
// This is a "value style" tuple-struct-like require
|
// This is a "value style" tuple-struct-like require
|
||||||
let content;
|
let content;
|
||||||
parenthesized!(content in input);
|
parenthesized!(content in input);
|
||||||
|
let content = content.parse::<TokenStream2>()?;
|
||||||
is_constructor_call = last_segment_is_lower;
|
is_constructor_call = last_segment_is_lower;
|
||||||
let fields = Punctuated::<Expr, Token![,]>::parse_terminated(&content)?;
|
let tokens: TokenStream = quote::quote! (|| #path (#content)).into();
|
||||||
let tokens: TokenStream = quote::quote! (|| #path (#fields)).into();
|
|
||||||
Some(TokenStream2::from(tokens))
|
Some(TokenStream2::from(tokens))
|
||||||
} else if is_enum {
|
} else if is_enum {
|
||||||
// if this is an enum, then it is an inline enum component declaration
|
// if this is an enum, then it is an inline enum component declaration
|
||||||
|
@ -166,7 +166,10 @@ use thiserror::Error;
|
|||||||
/// #[derive(Component)]
|
/// #[derive(Component)]
|
||||||
/// #[require(
|
/// #[require(
|
||||||
/// B(1), // tuple structs
|
/// B(1), // tuple structs
|
||||||
/// C { value: 1 }, // named-field structs
|
/// C { // named-field structs
|
||||||
|
/// x: 1,
|
||||||
|
/// ..Default::default()
|
||||||
|
/// },
|
||||||
/// D::One, // enum variants
|
/// D::One, // enum variants
|
||||||
/// E::ONE, // associated consts
|
/// E::ONE, // associated consts
|
||||||
/// F::new(1) // constructors
|
/// F::new(1) // constructors
|
||||||
@ -176,9 +179,10 @@ use thiserror::Error;
|
|||||||
/// #[derive(Component, PartialEq, Eq, Debug)]
|
/// #[derive(Component, PartialEq, Eq, Debug)]
|
||||||
/// struct B(u8);
|
/// struct B(u8);
|
||||||
///
|
///
|
||||||
/// #[derive(Component, PartialEq, Eq, Debug)]
|
/// #[derive(Component, PartialEq, Eq, Debug, Default)]
|
||||||
/// struct C {
|
/// struct C {
|
||||||
/// value: u8
|
/// x: u8,
|
||||||
|
/// y: u8,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// #[derive(Component, PartialEq, Eq, Debug)]
|
/// #[derive(Component, PartialEq, Eq, Debug)]
|
||||||
@ -206,7 +210,7 @@ use thiserror::Error;
|
|||||||
/// # let mut world = World::default();
|
/// # let mut world = World::default();
|
||||||
/// let id = world.spawn(A).id();
|
/// let id = world.spawn(A).id();
|
||||||
/// assert_eq!(&B(1), world.entity(id).get::<B>().unwrap());
|
/// assert_eq!(&B(1), world.entity(id).get::<B>().unwrap());
|
||||||
/// assert_eq!(&C { value: 1 }, world.entity(id).get::<C>().unwrap());
|
/// assert_eq!(&C { x: 1, y: 0 }, world.entity(id).get::<C>().unwrap());
|
||||||
/// assert_eq!(&D::One, world.entity(id).get::<D>().unwrap());
|
/// assert_eq!(&D::One, world.entity(id).get::<D>().unwrap());
|
||||||
/// assert_eq!(&E(1), world.entity(id).get::<E>().unwrap());
|
/// assert_eq!(&E(1), world.entity(id).get::<E>().unwrap());
|
||||||
/// assert_eq!(&F(1), world.entity(id).get::<F>().unwrap());
|
/// assert_eq!(&F(1), world.entity(id).get::<F>().unwrap());
|
||||||
|
Loading…
Reference in New Issue
Block a user