Allow macro invocations as prop values (#2687)

* fix: macro invocations in props #2267

convert macro invocation Item statements to Exprs

* remove now useless braces in docs
This commit is contained in:
WorldSEnder 2022-05-18 07:58:46 +02:00 committed by GitHub
parent b82a5ba56b
commit 6f6c61b975
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 2 deletions

View File

@ -120,6 +120,15 @@ fn strip_braces(block: ExprBlock) -> syn::Result<Expr> {
let stmt = stmts.remove(0); let stmt = stmts.remove(0);
match stmt { match stmt {
Stmt::Expr(expr) => Ok(expr), Stmt::Expr(expr) => Ok(expr),
// See issue #2267, we want to parse macro invocations as expressions
Stmt::Item(syn::Item::Macro(mac))
if mac.ident.is_none() && mac.semi_token.is_none() =>
{
Ok(Expr::Macro(syn::ExprMacro {
attrs: mac.attrs,
mac: mac.mac,
}))
}
Stmt::Semi(_expr, semi) => Err(syn::Error::new_spanned( Stmt::Semi(_expr, semi) => Err(syn::Error::new_spanned(
semi, semi,
"only an expression may be assigned as a property. Consider removing this \ "only an expression may be assigned as a property. Consider removing this \

View File

@ -118,7 +118,18 @@ fn compile_fail() {
html! { <Child {std::f64::consts::PI} /> }; html! { <Child {std::f64::consts::PI} /> };
html! { <Child {7 + 6} /> }; html! { <Child {7 + 6} /> };
html! { <Child {children.len()} /> }; html! { <Child {children.len()} /> };
}
#[derive(Clone, Properties, PartialEq)]
pub struct HtmlInPropsProperties {
pub header: ::yew::Html,
}
#[function_component]
fn HtmlInProps(props: &HtmlInPropsProperties) -> Html { let _ = (); unimplemented!() }
fn not_expressions() {
html! { <HtmlInProps header={macro_rules! declare { }} /> };
html! { <HtmlInProps header={format!("ending with semi");} /> };
} }
fn main() {} fn main() {}

View File

@ -255,6 +255,18 @@ error: missing label for property value. If trying to use the shorthand property
120 | html! { <Child {children.len()} /> }; 120 | html! { <Child {children.len()} /> };
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: only an expression may be assigned as a property
--> tests/html_macro/component-fail.rs:131:34
|
131 | html! { <HtmlInProps header={macro_rules! declare { }} /> };
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: only an expression may be assigned as a property. Consider removing this semicolon
--> tests/html_macro/component-fail.rs:132:61
|
132 | html! { <HtmlInProps header={format!("ending with semi");} /> };
| ^
error[E0425]: cannot find value `blah` in this scope error[E0425]: cannot find value `blah` in this scope
--> tests/html_macro/component-fail.rs:68:22 --> tests/html_macro/component-fail.rs:68:22
| |

View File

@ -43,6 +43,8 @@ pub struct ContainerProperties {
pub int: ::std::primitive::i32, pub int: ::std::primitive::i32,
#[prop_or_default] #[prop_or_default]
pub children: ::yew::Children, pub children: ::yew::Children,
#[prop_or_default]
pub header: ::yew::Html,
} }
pub struct Container; pub struct Container;
@ -273,6 +275,9 @@ fn compile_pass() {
<Container int=1 children={::yew::html::ChildrenRenderer::new( <Container int=1 children={::yew::html::ChildrenRenderer::new(
::std::vec![::yew::html!{ "::std::string::String" }] ::std::vec![::yew::html!{ "::std::string::String" }]
)} /> )} />
<Container int=1 header={::yew::html!{
<Child int=2 />
}} />
</> </>
}; };

View File

@ -241,9 +241,9 @@ pub fn render_page(with_sidebar: bool) -> Html {
if with_sidebar { if with_sidebar {
// Page with sidebar // Page with sidebar
html! { html! {
<Page sidebar={{html_nested! { <Page sidebar={html_nested! {
<PageSideBar /> <PageSideBar />
}}} /> }} />
} }
} else { } else {
// Page without sidebar // Page without sidebar