Skip to content

Commit

Permalink
Remove deprecated class=(...) syntax (#3497)
Browse files Browse the repository at this point in the history
* removed class=(...) syntax

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

* fixed tests, silenced all unused_must_use warnings

* fixed wasm test
  • Loading branch information
its-the-shrimp authored Oct 28, 2023
1 parent 6ae67b6 commit bae0141
Show file tree
Hide file tree
Showing 17 changed files with 172 additions and 264 deletions.
66 changes: 14 additions & 52 deletions packages/yew-macro/src/html_tree/html_element.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand All @@ -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 })
}
}
Expand Down
20 changes: 2 additions & 18 deletions packages/yew-macro/src/props/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -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;
Expand Down
16 changes: 8 additions & 8 deletions packages/yew-macro/tests/html_macro/block-pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
28 changes: 14 additions & 14 deletions packages/yew-macro/tests/html_macro/component-any-children-pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 />
Expand All @@ -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 />
Expand All @@ -183,7 +183,7 @@ fn compile_pass() {
</>
};

::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 string="child" />
<Child int=1 />
Expand All @@ -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(|_| ()))} />
Expand All @@ -219,15 +219,15 @@ fn compile_pass() {
};

let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child int=1 r#ref={node_ref} />
</>
};

let int = 1;
let node_ref = <::yew::NodeRef as ::std::default::Default>::default();
::yew::html! {
_ = ::yew::html! {
<>
<Child {int} r#ref={node_ref} />
</>
Expand All @@ -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>
Expand Down Expand Up @@ -292,7 +292,7 @@ fn compile_pass() {
]
};

::yew::html! {
_ = ::yew::html! {
<>
{
::std::iter::Iterator::collect::<::yew::virtual_dom::VNode>(
Expand Down Expand Up @@ -321,9 +321,9 @@ fn compile_pass() {
</>
};

::yew::html_nested! { 1 };
_ = ::yew::html_nested! { 1 };

::yew::html! {
_ = ::yew::html! {
<RenderPropComp>
{|_arg| {}}
</RenderPropComp>
Expand Down
Loading

0 comments on commit bae0141

Please sign in to comment.