Remove deprecated class=(...) syntax (#3497)

* removed class=(...) syntax

* made DynamicName::expr a group instead of a block

* fixed tests, silenced all unused_must_use warnings

* fixed wasm test
This commit is contained in:
Tim Kurdov 2023-10-28 16:36:56 +01:00 committed by GitHub
parent 6ae67b6843
commit bae0141f98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 172 additions and 264 deletions

View File

@ -1,13 +1,13 @@
use proc_macro2::{Delimiter, Span, TokenStream};
use proc_macro2::{Delimiter, Group, Span, TokenStream};
use proc_macro_error::emit_warning;
use quote::{quote, quote_spanned, ToTokens};
use syn::buffer::Cursor;
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::{Block, Expr, Ident, Lit, LitStr, Token};
use syn::{Expr, Ident, Lit, LitStr, Token};
use super::{HtmlChildrenTree, HtmlDashedName, TagTokens};
use crate::props::{ClassesForm, ElementProps, Prop, PropDirective};
use crate::props::{ElementProps, Prop, PropDirective};
use crate::stringify::{Stringify, Value};
use crate::{is_ide_completion, non_capitalized_ascii, Peek, PeekValue};
@ -190,39 +190,11 @@ impl ToTokens for HtmlElement {
))
},
);
let class_attr = classes.as_ref().and_then(|classes| match classes {
ClassesForm::Tuple(classes) => {
let span = classes.span();
let classes: Vec<_> = classes.elems.iter().collect();
let n = classes.len();
let deprecation_warning = quote_spanned! {span=>
#[deprecated(
note = "the use of `(...)` with the attribute `class` is deprecated and will be removed in version 0.19. Use the `classes!` macro instead."
)]
fn deprecated_use_of_class() {}
if false {
deprecated_use_of_class();
};
};
Some((
LitStr::new("class", span),
Value::Dynamic(quote! {
{
#deprecation_warning
let mut __yew_classes = ::yew::html::Classes::with_capacity(#n);
#(__yew_classes.push(#classes);)*
__yew_classes
}
}),
None,
))
}
ClassesForm::Single(classes) => {
match classes.try_into_lit() {
let class_attr =
classes
.as_ref()
.and_then(|classes| match classes.value.try_into_lit() {
Some(lit) => {
if lit.value().is_empty() {
None
@ -235,17 +207,16 @@ impl ToTokens for HtmlElement {
}
}
None => {
let expr = &classes.value;
Some((
LitStr::new("class", classes.span()),
LitStr::new("class", classes.label.span()),
Value::Dynamic(quote! {
::std::convert::Into::<::yew::html::Classes>::into(#classes)
::std::convert::Into::<::yew::html::Classes>::into(#expr)
}),
None,
))
}
}
}
});
});
fn apply_as(directive: Option<&PropDirective>) -> TokenStream {
match directive {
@ -383,7 +354,7 @@ impl ToTokens for HtmlElement {
}
TagName::Expr(name) => {
let vtag = Ident::new("__yew_vtag", name.span());
let expr = &name.expr;
let expr = name.expr.as_ref().map(Group::stream);
let vtag_name = Ident::new("__yew_vtag_name", expr.span());
let void_children = Ident::new("__yew_void_children", Span::mixed_site());
@ -411,10 +382,6 @@ impl ToTokens for HtmlElement {
// this way we get a nice error message (with the correct span) when the expression
// doesn't return a valid value
quote_spanned! {expr.span()=> {
#[allow(unused_braces)]
// e.g. html!{<@{"div"}/>} will set `#expr` to `{"div"}`
// (note the extra braces). Hence the need for the `allow`.
// Anyways to remove the braces?
let mut #vtag_name = ::std::convert::Into::<
::yew::virtual_dom::AttrValue
>::into(#expr);
@ -500,7 +467,7 @@ fn wrap_attr_value<T: ToTokens>(value: T) -> TokenStream {
pub struct DynamicName {
at: Token![@],
expr: Option<Block>,
expr: Option<Group>,
}
impl Peek<'_, ()> for DynamicName {
@ -524,12 +491,7 @@ impl Parse for DynamicName {
fn parse(input: ParseStream) -> syn::Result<Self> {
let at = input.parse()?;
// the expression block is optional, closing tags don't have it.
let expr = if input.cursor().group(Delimiter::Brace).is_some() {
Some(input.parse()?)
} else {
None
};
let expr = input.parse().ok();
Ok(Self { at, expr })
}
}

View File

@ -2,27 +2,13 @@ use std::collections::HashSet;
use once_cell::sync::Lazy;
use syn::parse::{Parse, ParseStream};
use syn::{Expr, ExprTuple};
use super::{Prop, Props, SpecialProps};
pub enum ClassesForm {
Tuple(ExprTuple),
Single(Box<Expr>),
}
impl ClassesForm {
fn from_expr(expr: Expr) -> Self {
match expr {
Expr::Tuple(expr_tuple) => ClassesForm::Tuple(expr_tuple),
expr => ClassesForm::Single(Box::new(expr)),
}
}
}
pub struct ElementProps {
pub attributes: Vec<Prop>,
pub listeners: Vec<Prop>,
pub classes: Option<ClassesForm>,
pub classes: Option<Prop>,
pub booleans: Vec<Prop>,
pub value: Option<Prop>,
pub checked: Option<Prop>,
@ -42,9 +28,7 @@ impl Parse for ElementProps {
let booleans =
props.drain_filter(|prop| BOOLEAN_SET.contains(prop.label.to_string().as_str()));
let classes = props
.pop("class")
.map(|prop| ClassesForm::from_expr(prop.value));
let classes = props.pop("class");
let value = props.pop("value");
let checked = props.pop("checked");
let special = props.special;

View File

@ -37,27 +37,27 @@ pub struct u8;
pub struct usize;
fn main() {
::yew::html! { <>{ "Hi" }</> };
::yew::html! { <>{ ::std::format!("Hello") }</> };
::yew::html! { <>{ ::std::string::ToString::to_string("Hello") }</> };
_ = ::yew::html! { <>{ "Hi" }</> };
_ = ::yew::html! { <>{ ::std::format!("Hello") }</> };
_ = ::yew::html! { <>{ ::std::string::ToString::to_string("Hello") }</> };
let msg = "Hello";
::yew::html! { <div>{ msg }</div> };
_ = ::yew::html! { <div>{ msg }</div> };
let subview = ::yew::html! { "subview!" };
::yew::html! { <div>{ subview }</div> };
_ = ::yew::html! { <div>{ subview }</div> };
let subview = || ::yew::html! { "subview!" };
::yew::html! { <div>{ subview() }</div> };
_ = ::yew::html! { <div>{ subview() }</div> };
::yew::html! {
_ = ::yew::html! {
<ul>
{ for ::std::iter::Iterator::map(0..3, |num| { ::yew::html! { <span>{ num }</span> }}) }
</ul>
};
let item = |num| ::yew::html! { <li>{ ::std::format!("item {}!", num) }</li> };
::yew::html! {
_ = ::yew::html! {
<ul>
{ for ::std::iter::Iterator::map(0..3, item) }
</ul>

View File

@ -159,10 +159,10 @@ pub fn RenderPropComp(_props: &RenderPropProps) -> ::yew::Html {
}
fn compile_pass() {
::yew::html! { <Child int=1 /> };
::yew::html! { <Child int=1 r#fn=1 /> };
_ = ::yew::html! { <Child int=1 /> };
_ = ::yew::html! { <Child int=1 r#fn=1 /> };
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 />
<scoped::Child int=1 />
@ -171,7 +171,7 @@ fn compile_pass() {
let props = <<Child as ::yew::Component>::Properties as ::std::default::Default>::default();
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child ..::std::clone::Clone::clone(&props) />
<Child int={1} ..props />
@ -183,7 +183,7 @@ fn compile_pass() {
</>
};
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 string="child" />
<Child int=1 />
@ -199,17 +199,17 @@ fn compile_pass() {
};
let name_expr = "child";
::yew::html! {
_ = ::yew::html! {
<Child int=1 string={name_expr} />
};
let string = "child";
let int = 1;
::yew::html! {
_ = ::yew::html! {
<Child {int} {string} />
};
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 />
<Child int=1 optional_callback={::std::option::Option::Some(<::yew::Callback<()> as ::std::convert::From<_>>::from(|_| ()))} />
@ -219,7 +219,7 @@ fn compile_pass() {
};
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 r#ref={node_ref} />
</>
@ -227,7 +227,7 @@ fn compile_pass() {
let int = 1;
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child {int} r#ref={node_ref} />
</>
@ -236,7 +236,7 @@ fn compile_pass() {
let props = <<Container as ::yew::Component>::Properties as ::std::default::Default>::default();
let child_props =
<<Child as ::yew::Component>::Properties as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Container int=1 />
<Container int=1></Container>
@ -292,7 +292,7 @@ fn compile_pass() {
]
};
::yew::html! {
_ = ::yew::html! {
<>
{
::std::iter::Iterator::collect::<::yew::virtual_dom::VNode>(
@ -321,9 +321,9 @@ fn compile_pass() {
</>
};
::yew::html_nested! { 1 };
_ = ::yew::html_nested! { 1 };
::yew::html! {
_ = ::yew::html! {
<RenderPropComp>
{|_arg| {}}
</RenderPropComp>

View File

@ -167,10 +167,10 @@ mod scoped {
}
fn compile_pass() {
::yew::html! { <Child int=1 /> };
::yew::html! { <Child int=1 r#fn=1 /> };
_ = ::yew::html! { <Child int=1 /> };
_ = ::yew::html! { <Child int=1 r#fn=1 /> };
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 />
<scoped::Child int=1 />
@ -179,7 +179,7 @@ fn compile_pass() {
let props = <<Child as ::yew::Component>::Properties as ::std::default::Default>::default();
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child ..::std::clone::Clone::clone(&props) />
<Child int={1} ..props />
@ -191,7 +191,7 @@ fn compile_pass() {
</>
};
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 string="child" />
<Child int=1 />
@ -207,17 +207,17 @@ fn compile_pass() {
};
let name_expr = "child";
::yew::html! {
_ = ::yew::html! {
<Child int=1 string={name_expr} />
};
let string = "child";
let int = 1;
::yew::html! {
_ = ::yew::html! {
<Child {int} {string} />
};
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 />
<Child int=1 optional_callback={::std::option::Option::Some(<::yew::Callback<()> as ::std::convert::From<_>>::from(|_| ()))} />
@ -227,7 +227,7 @@ fn compile_pass() {
};
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 r#ref={node_ref} />
</>
@ -235,7 +235,7 @@ fn compile_pass() {
let int = 1;
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child {int} r#ref={node_ref} />
</>
@ -244,7 +244,7 @@ fn compile_pass() {
let props = <<Container as ::yew::Component>::Properties as ::std::default::Default>::default();
let child_props =
<<Child as ::yew::Component>::Properties as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Container int=1 />
<Container int=1></Container>
@ -287,7 +287,7 @@ fn compile_pass() {
</>
};
::yew::html! {
_ = ::yew::html! {
<>
<ChildContainer int=1 />
<ChildContainer int=1></ChildContainer>
@ -296,7 +296,7 @@ fn compile_pass() {
</>
};
::yew::html! {
_ = ::yew::html! {
<ChildContainer int=1>
<AltChild />
<Child int=1 />
@ -318,13 +318,13 @@ fn compile_pass() {
::yew::html_nested! { <Child int=1 /> },
::yew::html_nested! { <Child int=2 /> },
];
::yew::html! {
_ = ::yew::html! {
<ChildContainer int=1>
{ ::std::clone::Clone::clone(&children) }
</ChildContainer>
};
// https://github.com/yewstack/yew/issues/1527
::yew::html! {
_ = ::yew::html! {
<ChildContainer int=1>
{ for children }
</ChildContainer>
@ -343,7 +343,7 @@ fn compile_pass() {
]
};
::yew::html! {
_ = ::yew::html! {
<>
{
::std::iter::Iterator::collect::<::yew::virtual_dom::VNode>(
@ -372,7 +372,7 @@ fn compile_pass() {
</>
};
::yew::html_nested! { 1 };
_ = ::yew::html_nested! { 1 };
}
#[derive(

View File

@ -43,17 +43,16 @@ fn main() {
move || ::std::option::Option::unwrap(::std::iter::Iterator::next(&mut it))
};
::yew::html! {
_ = ::yew::html! {
<@{ dyn_tag() }>
<@{ next_extra_tag() } class="extra-a"/>
<@{ next_extra_tag() } class="extra-b"/>
</@>
};
::yew::html! {
_ = ::yew::html! {
<@{
let tag = dyn_tag();
if tag == "test" {
if dyn_tag() == "test" {
"div"
} else {
"a"

View File

@ -76,11 +76,7 @@ fn compile_fail() {
// type mismatch
html! { <@{55}></@> };
// check for deprecation warning
html! { <div class={("deprecated", "warning")} /> };
// Missing curly braces
html! { <div class=("deprecated", "warning") /> };
html! { <input ref=() /> };
html! { <input ref=() ref=() /> };
html! { <input onfocus=Some(5) /> };

View File

@ -142,38 +142,14 @@ error: dynamic closing tags must not have a body (hint: replace it with just `</
75 | html! { <@{"test"}></@{"test"}> };
| ^^^^^^^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Tuple {
attrs: [],
paren_token: Paren,
elems: [
Expr::Lit {
attrs: [],
lit: Lit::Str {
token: "deprecated",
},
},
Comma,
Expr::Lit {
attrs: [],
lit: Lit::Str {
token: "warning",
},
},
],
}
--> tests/html_macro/element-fail.rs:83:24
|
83 | html! { <div class=("deprecated", "warning") /> };
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Tuple {
attrs: [],
paren_token: Paren,
elems: [],
}
--> tests/html_macro/element-fail.rs:84:24
--> tests/html_macro/element-fail.rs:80:24
|
84 | html! { <input ref=() /> };
80 | html! { <input ref=() /> };
| ^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Tuple {
@ -181,9 +157,9 @@ error: the property value must be either a literal or enclosed in braces. Consid
paren_token: Paren,
elems: [],
}
--> tests/html_macro/element-fail.rs:85:24
--> tests/html_macro/element-fail.rs:81:24
|
85 | html! { <input ref=() ref=() /> };
81 | html! { <input ref=() ref=() /> };
| ^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Call {
@ -197,7 +173,7 @@ error: the property value must be either a literal or enclosed in braces. Consid
PathSegment {
ident: Ident {
ident: "Some",
span: #0 bytes(2632..2636),
span: #0 bytes(2482..2486),
},
arguments: PathArguments::None,
},
@ -214,9 +190,9 @@ error: the property value must be either a literal or enclosed in braces. Consid
},
],
}
--> tests/html_macro/element-fail.rs:86:28
--> tests/html_macro/element-fail.rs:82:28
|
86 | html! { <input onfocus=Some(5) /> };
82 | html! { <input onfocus=Some(5) /> };
| ^^^^^^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Path {
@ -228,16 +204,16 @@ error: the property value must be either a literal or enclosed in braces. Consid
PathSegment {
ident: Ident {
ident: "NotToString",
span: #0 bytes(2672..2683),
span: #0 bytes(2522..2533),
},
arguments: PathArguments::None,
},
],
},
}
--> tests/html_macro/element-fail.rs:87:27
--> tests/html_macro/element-fail.rs:83:27
|
87 | html! { <input string=NotToString /> };
83 | html! { <input string=NotToString /> };
| ^^^^^^^^^^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Call {
@ -251,7 +227,7 @@ error: the property value must be either a literal or enclosed in braces. Consid
PathSegment {
ident: Ident {
ident: "Some",
span: #0 bytes(2711..2715),
span: #0 bytes(2561..2565),
},
arguments: PathArguments::None,
},
@ -269,7 +245,7 @@ error: the property value must be either a literal or enclosed in braces. Consid
PathSegment {
ident: Ident {
ident: "NotToString",
span: #0 bytes(2716..2727),
span: #0 bytes(2566..2577),
},
arguments: PathArguments::None,
},
@ -278,9 +254,9 @@ error: the property value must be either a literal or enclosed in braces. Consid
},
],
}
--> tests/html_macro/element-fail.rs:88:22
--> tests/html_macro/element-fail.rs:84:22
|
88 | html! { <a media=Some(NotToString) /> };
84 | html! { <a media=Some(NotToString) /> };
| ^^^^^^^^^^^^^^^^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Call {
@ -294,7 +270,7 @@ error: the property value must be either a literal or enclosed in braces. Consid
PathSegment {
ident: Ident {
ident: "Some",
span: #0 bytes(2755..2759),
span: #0 bytes(2605..2609),
},
arguments: PathArguments::None,
},
@ -311,9 +287,9 @@ error: the property value must be either a literal or enclosed in braces. Consid
},
],
}
--> tests/html_macro/element-fail.rs:89:21
--> tests/html_macro/element-fail.rs:85:21
|
89 | html! { <a href=Some(5) /> };
85 | html! { <a href=Some(5) /> };
| ^^^^^^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Tuple {
@ -321,9 +297,9 @@ error: the property value must be either a literal or enclosed in braces. Consid
paren_token: Paren,
elems: [],
}
--> tests/html_macro/element-fail.rs:90:25
--> tests/html_macro/element-fail.rs:86:25
|
90 | html! { <input type=() /> };
86 | html! { <input type=() /> };
| ^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Tuple {
@ -331,9 +307,9 @@ error: the property value must be either a literal or enclosed in braces. Consid
paren_token: Paren,
elems: [],
}
--> tests/html_macro/element-fail.rs:91:26
--> tests/html_macro/element-fail.rs:87:26
|
91 | html! { <input value=() /> };
87 | html! { <input value=() /> };
| ^^
error: the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.: Expr::Path {
@ -345,26 +321,18 @@ error: the property value must be either a literal or enclosed in braces. Consid
PathSegment {
ident: Ident {
ident: "NotToString",
span: #0 bytes(2862..2873),
span: #0 bytes(2712..2723),
},
arguments: PathArguments::None,
},
],
},
}
--> tests/html_macro/element-fail.rs:92:27
--> tests/html_macro/element-fail.rs:88:27
|
92 | html! { <input string=NotToString /> };
88 | html! { <input string=NotToString /> };
| ^^^^^^^^^^^
warning: use of deprecated function `compile_fail::deprecated_use_of_class`: the use of `(...)` with the attribute `class` is deprecated and will be removed in version 0.19. Use the `classes!` macro instead.
--> tests/html_macro/element-fail.rs:80:25
|
80 | html! { <div class={("deprecated", "warning")} /> };
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
error[E0308]: mismatched types
--> tests/html_macro/element-fail.rs:36:28
|
@ -662,10 +630,10 @@ error[E0277]: the trait bound `(): IntoPropValue<yew::NodeRef>` is not satisfied
= note: this error originates in the macro `html` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `implicit_clone::unsync::IString: From<{integer}>` is not satisfied
--> tests/html_macro/element-fail.rs:77:15
--> tests/html_macro/element-fail.rs:77:16
|
77 | html! { <@{55}></@> };
| ^^^^ the trait `From<{integer}>` is not implemented for `implicit_clone::unsync::IString`
| ^^ the trait `From<{integer}>` is not implemented for `implicit_clone::unsync::IString`
|
= help: the following other types implement trait `From<T>`:
<implicit_clone::unsync::IString as From<&'static str>>

View File

@ -76,24 +76,24 @@ where
}
fn compile_pass() {
::yew::html! { <Generic<::std::string::String> /> };
::yew::html! { <Generic<(u8, bool)> /> };
::yew::html! { <Generic<(u8, bool)> ></Generic<(u8, bool)>> };
::yew::html! { <Generic<::std::string::String> ></Generic<::std::string::String>> };
_ = ::yew::html! { <Generic<::std::string::String> /> };
_ = ::yew::html! { <Generic<(u8, bool)> /> };
_ = ::yew::html! { <Generic<(u8, bool)> ></Generic<(u8, bool)>> };
_ = ::yew::html! { <Generic<::std::string::String> ></Generic<::std::string::String>> };
::yew::html! { <Generic<::std::vec::Vec<::std::string::String>> /> };
::yew::html! { <Generic<::std::vec::Vec<::std::string::String>>></ Generic<::std::vec::Vec<::std::string::String>>> };
_ = ::yew::html! { <Generic<::std::vec::Vec<::std::string::String>> /> };
_ = ::yew::html! { <Generic<::std::vec::Vec<::std::string::String>>></ Generic<::std::vec::Vec<::std::string::String>>> };
::yew::html! { <Generic<::std::primitive::usize> /> };
::yew::html! { <Generic<::std::primitive::usize>></Generic<::std::primitive::usize>> };
::yew::html! { <Generic<::std::string::String, > /> };
::yew::html! { <Generic<::std::string::String, >></Generic<::std::string::String,>> };
_ = ::yew::html! { <Generic<::std::primitive::usize> /> };
_ = ::yew::html! { <Generic<::std::primitive::usize>></Generic<::std::primitive::usize>> };
_ = ::yew::html! { <Generic<::std::string::String, > /> };
_ = ::yew::html! { <Generic<::std::string::String, >></Generic<::std::string::String,>> };
::yew::html! { <Generic2<::std::string::String, ::std::string::String> /> };
::yew::html! { <Generic2<::std::string::String, ::std::string::String>></Generic2<::std::string::String, ::std::string::String>> };
_ = ::yew::html! { <Generic2<::std::string::String, ::std::string::String> /> };
_ = ::yew::html! { <Generic2<::std::string::String, ::std::string::String>></Generic2<::std::string::String, ::std::string::String>> };
::yew::html! { <Generic2<::std::string::String, ::std::string::String, > /> };
::yew::html! { <Generic2<::std::string::String, ::std::string::String, >></Generic2<::std::string::String, ::std::string::String, >> };
_ = ::yew::html! { <Generic2<::std::string::String, ::std::string::String, > /> };
_ = ::yew::html! { <Generic2<::std::string::String, ::std::string::String, >></Generic2<::std::string::String, ::std::string::String, >> };
}
fn main() {}

View File

@ -48,7 +48,7 @@ fn compile_pass() {
let attr_val_none: ::std::option::Option<::yew::virtual_dom::AttrValue> = ::std::option::Option::None;
::yew::html! {
_ = ::yew::html! {
<div>
<div data-key="abc"></div>
<div ref={&parent_ref}></div>
@ -92,8 +92,7 @@ fn compile_pass() {
</@>
<@{
let tag = dyn_tag();
if tag == "test" {
if dyn_tag() == "test" {
"div"
} else {
"a"
@ -113,17 +112,17 @@ fn compile_pass() {
::yew::html! { <span>{ "Hello" }</span> },
::yew::html! { <span>{ "World" }</span> },
];
::yew::html! { <div>{children}</div> };
_ = ::yew::html! { <div>{children}</div> };
// handle misleading angle brackets
::yew::html! { <div data-val={<::std::string::String as ::std::default::Default>::default()}></div> };
::yew::html! { <div><a data-val={<::std::string::String as ::std::default::Default>::default()} /></div> };
_ = ::yew::html! { <div data-val={<::std::string::String as ::std::default::Default>::default()}></div> };
_ = ::yew::html! { <div><a data-val={<::std::string::String as ::std::default::Default>::default()} /></div> };
// test for https://github.com/yewstack/yew/issues/2810
::yew::html! { <div data-type="date" data-as="calender" /> };
_ = ::yew::html! { <div data-type="date" data-as="calender" /> };
let option_vnode = ::std::option::Option::Some(::yew::html! {});
::yew::html! { <div>{option_vnode}</div> };
_ = ::yew::html! { <div>{option_vnode}</div> };
}
fn main() {}

View File

@ -1,35 +1,35 @@
#![no_implicit_prelude]
fn compile_pass_lit() {
::yew::html! { if true {} };
::yew::html! { if true { <div/> } };
::yew::html! { if true { <div/><div/> } };
::yew::html! { if true { <><div/><div/></> } };
::yew::html! { if true { { ::yew::html! {} } } };
::yew::html! { if true { { { let _x = 42; ::yew::html! {} } } } };
::yew::html! { if true {} else {} };
::yew::html! { if true {} else if true {} };
::yew::html! { if true {} else if true {} else {} };
::yew::html! { if let ::std::option::Option::Some(text) = ::std::option::Option::Some("text") { <span>{ text }</span> } };
::yew::html! { <><div/>if true {}<div/></> };
::yew::html! { <div>if true {}</div> };
_ = ::yew::html! { if true {} };
_ = ::yew::html! { if true { <div/> } };
_ = ::yew::html! { if true { <div/><div/> } };
_ = ::yew::html! { if true { <><div/><div/></> } };
_ = ::yew::html! { if true { { ::yew::html! {} } } };
_ = ::yew::html! { if true { { { let _x = 42; ::yew::html! {} } } } };
_ = ::yew::html! { if true {} else {} };
_ = ::yew::html! { if true {} else if true {} };
_ = ::yew::html! { if true {} else if true {} else {} };
_ = ::yew::html! { if let ::std::option::Option::Some(text) = ::std::option::Option::Some("text") { <span>{ text }</span> } };
_ = ::yew::html! { <><div/>if true {}<div/></> };
_ = ::yew::html! { <div>if true {}</div> };
}
fn compile_pass_expr() {
let condition = true;
::yew::html! { if condition {} };
::yew::html! { if condition { <div/> } };
::yew::html! { if condition { <div/><div/> } };
::yew::html! { if condition { <><div/><div/></> } };
::yew::html! { if condition { { ::yew::html! {} } } };
::yew::html! { if condition { { { let _x = 42; ::yew::html! {} } } } };
::yew::html! { if condition {} else {} };
::yew::html! { if condition {} else if condition {} };
::yew::html! { if condition {} else if condition {} else {} };
::yew::html! { if let ::std::option::Option::Some(text) = ::std::option::Option::Some("text") { <span>{ text }</span> } };
::yew::html! { <><div/>if condition {}<div/></> };
::yew::html! { <div>if condition {}</div> };
_ = ::yew::html! { if condition {} };
_ = ::yew::html! { if condition { <div/> } };
_ = ::yew::html! { if condition { <div/><div/> } };
_ = ::yew::html! { if condition { <><div/><div/></> } };
_ = ::yew::html! { if condition { { ::yew::html! {} } } };
_ = ::yew::html! { if condition { { { let _x = 42; ::yew::html! {} } } } };
_ = ::yew::html! { if condition {} else {} };
_ = ::yew::html! { if condition {} else if condition {} };
_ = ::yew::html! { if condition {} else if condition {} else {} };
_ = ::yew::html! { if let ::std::option::Option::Some(text) = ::std::option::Option::Some("text") { <span>{ text }</span> } };
_ = ::yew::html! { <><div/>if condition {}<div/></> };
_ = ::yew::html! { <div>if condition {}</div> };
}
fn main() {}

View File

@ -37,23 +37,23 @@ pub struct u8;
pub struct usize;
fn compile_pass() {
::yew::html! { "" };
::yew::html! { 'a' };
::yew::html! { "hello" };
::yew::html! { 42 };
::yew::html! { 1.234 };
_ = ::yew::html! { "" };
_ = ::yew::html! { 'a' };
_ = ::yew::html! { "hello" };
_ = ::yew::html! { 42 };
_ = ::yew::html! { 1.234 };
::yew::html! { <span>{ "" }</span> };
::yew::html! { <span>{ 'a' }</span> };
::yew::html! { <span>{ "hello" }</span> };
::yew::html! { <span>{ 42 }</span> };
::yew::html! { <span>{ 1.234 }</span> };
_ = ::yew::html! { <span>{ "" }</span> };
_ = ::yew::html! { <span>{ 'a' }</span> };
_ = ::yew::html! { <span>{ "hello" }</span> };
_ = ::yew::html! { <span>{ 42 }</span> };
_ = ::yew::html! { <span>{ 1.234 }</span> };
::yew::html! { ::std::format!("Hello") };
::yew::html! { {<::std::string::String as ::std::convert::From<&::std::primitive::str>>::from("Hello") } };
_ = ::yew::html! { ::std::format!("Hello") };
_ = ::yew::html! { {<::std::string::String as ::std::convert::From<&::std::primitive::str>>::from("Hello") } };
let msg = "Hello";
::yew::html! { msg };
_ = ::yew::html! { msg };
}
fn main() {}

View File

@ -45,13 +45,13 @@ fn empty_iter() -> impl ::std::iter::Iterator<Item = ::yew::Html> {
}
fn main() {
::yew::html! { for empty_iter() };
::yew::html! { for { empty_iter() } };
_ = ::yew::html! { for empty_iter() };
_ = ::yew::html! { for { empty_iter() } };
let empty = empty_vec();
::yew::html! { for empty };
_ = ::yew::html! { for empty };
::yew::html! { for empty_vec() };
::yew::html! { for ::std::iter::IntoIterator::into_iter(empty_vec()) };
::yew::html! { for ::std::iter::Iterator::map(0..3, |num| { ::yew::html! { <span>{ num }</span> } }) };
_ = ::yew::html! { for empty_vec() };
_ = ::yew::html! { for ::std::iter::IntoIterator::into_iter(empty_vec()) };
_ = ::yew::html! { for ::std::iter::Iterator::map(0..3, |num| { ::yew::html! { <span>{ num }</span> } }) };
}

View File

@ -37,15 +37,15 @@ pub struct u8;
pub struct usize;
fn main() {
::yew::html! {};
::yew::html! { <></> };
::yew::html! {
_ = ::yew::html! {};
_ = ::yew::html! { <></> };
_ = ::yew::html! {
<>
<></>
<></>
</>
};
::yew::html! {
_ = ::yew::html! {
<key={::std::string::ToString::to_string("key")}>
</>
};
@ -54,5 +54,5 @@ fn main() {
::yew::html! { <span>{ "Hello" }</span> },
::yew::html! { <span>{ "World" }</span> },
];
::yew::html! { <>{ children }</> };
_ = ::yew::html! { <>{ children }</> };
}

View File

@ -37,23 +37,23 @@ pub struct u8;
pub struct usize;
fn main() {
::yew::html! { "" };
::yew::html! { 'a' };
::yew::html! { "hello" };
::yew::html! { "42" };
::yew::html! { "1.234" };
::yew::html! { "true" };
_ = ::yew::html! { "" };
_ = ::yew::html! { 'a' };
_ = ::yew::html! { "hello" };
_ = ::yew::html! { "42" };
_ = ::yew::html! { "1.234" };
_ = ::yew::html! { "true" };
::yew::html! { <span>{ "" }</span> };
::yew::html! { <span>{ 'a' }</span> };
::yew::html! { <span>{ "hello" }</span> };
::yew::html! { <span>{ "42" }</span> };
::yew::html! { <span>{ "1.234" }</span> };
::yew::html! { <span>{ "true" }</span> };
_ = ::yew::html! { <span>{ "" }</span> };
_ = ::yew::html! { <span>{ 'a' }</span> };
_ = ::yew::html! { <span>{ "hello" }</span> };
_ = ::yew::html! { <span>{ "42" }</span> };
_ = ::yew::html! { <span>{ "1.234" }</span> };
_ = ::yew::html! { <span>{ "true" }</span> };
::yew::html! { ::std::format!("Hello") };
::yew::html! { ::std::string::ToString::to_string("Hello") };
_ = ::yew::html! { ::std::format!("Hello") };
_ = ::yew::html! { ::std::string::ToString::to_string("Hello") };
let msg = "Hello";
::yew::html! { msg };
_ = ::yew::html! { msg };
}

View File

@ -39,7 +39,7 @@ pub struct usize;
fn main() {
// Ensure Rust keywords can be used as element names.
// See: #1771
::yew::html! {
_ = ::yew::html! {
<a class="btn btn-primary" href="https://example.org/">
<svg class="bi" fill="currentColor">
<use href="/bootstrap-icons.svg#wrench"/>
@ -49,7 +49,7 @@ fn main() {
};
// some general SVG
::yew::html! {
_ = ::yew::html! {
<svg width="149" height="147" viewBox="0 0 149 147" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M60.5776 13.8268L51.8673 42.6431L77.7475 37.331L60.5776 13.8268Z" fill="#DEB819"/>
<path d="M108.361 94.9937L138.708 90.686L115.342 69.8642" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>

View File

@ -830,11 +830,11 @@ mod tests {
fn dynamic_tags_work() {
let (root, scope, parent) = setup_parent();
let elem = html! { <@{
let elem = html! { <@{{
let mut builder = String::new();
builder.push('a');
builder
}/> };
}}/> };
let (_, mut elem) = elem.attach(&root, &scope, &parent, DomSlot::at_end());
let vtag = assert_btag_mut(&mut elem);