Skip to content

Commit a7dd727

Browse files
committed
fix(yew-macro): soften deprecated html style errors by injecting deprecated functions
1 parent 9d3e9ba commit a7dd727

22 files changed

Lines changed: 405 additions & 201 deletions

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ unexpected_cfgs = { level = "warn", check-cfg = [
3030
"cfg(verbose_tests)",
3131
"cfg(yew_lints)",
3232
"cfg(nightly_yew)",
33-
"cfg(yew_macro_nightly)",
3433
"cfg(wasm_bindgen_unstable_test_coverage)"
3534
]}
3635
[workspace.dependencies]

packages/yew-macro/Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ rust-version.workspace = true
1515
[lib]
1616
proc-macro = true
1717

18-
[build-dependencies]
19-
version_check = "0.9"
20-
2118
[dependencies]
2219
proc-macro-error = "1"
2320
proc-macro2.workspace = true

packages/yew-macro/build.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/yew-macro/src/html_tree/html_block.rs

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use proc_macro2::Delimiter;
1+
use proc_macro2::{Delimiter, TokenStream};
22
use quote::{ToTokens, quote, quote_spanned};
33
use syn::buffer::Cursor;
44
use syn::parse::{Parse, ParseStream};
@@ -11,6 +11,7 @@ use crate::PeekValue;
1111
pub struct HtmlBlock {
1212
pub content: BlockContent,
1313
brace: token::Brace,
14+
pub(super) deprecations: TokenStream,
1415
}
1516

1617
pub enum BlockContent {
@@ -28,32 +29,36 @@ impl Parse for HtmlBlock {
2829
fn parse(input: ParseStream) -> syn::Result<Self> {
2930
let content;
3031
let brace = braced!(content in input);
32+
let mut deprecations = TokenStream::new();
3133
let content = if HtmlIterable::peek(content.cursor()).is_some() {
3234
BlockContent::Iterable(Box::new(content.parse()?))
3335
} else {
3436
let node: HtmlNode = content.parse()?;
3537
if let HtmlNode::Expression(ref expr) = node {
36-
check_deprecated_html_call(expr);
38+
deprecations = check_deprecated_html_call(expr);
3739
}
3840
BlockContent::Node(Box::new(node))
3941
};
4042

41-
Ok(HtmlBlock { content, brace })
43+
Ok(HtmlBlock {
44+
content,
45+
brace,
46+
deprecations,
47+
})
4248
}
4349
}
4450

4551
/// Check for deprecated `html!` usage patterns inside expression blocks.
46-
fn check_deprecated_html_call(expr: &Expr) {
52+
fn check_deprecated_html_call(expr: &Expr) -> TokenStream {
4753
// Pattern 1: { match expr { arm => html! { ... }, ... } }
4854
if let Expr::Match(match_expr) = expr {
4955
for arm in &match_expr.arms {
5056
if let Some(span) = html_macro_call_span(&arm.body) {
51-
super::emit_deprecated!(
57+
return super::deprecated_call(
5258
span,
5359
"Use bare elements in arms directly \n\nmatch value {\n pattern => \
54-
<Element />,\n}"
60+
<Element />,\n}",
5561
);
56-
return;
5762
}
5863
}
5964
}
@@ -66,13 +71,15 @@ fn check_deprecated_html_call(expr: &Expr) {
6671
.last()
6772
.and_then(stmt_tail_html_macro_span)
6873
{
69-
super::emit_deprecated!(
74+
return super::deprecated_call(
7075
span,
7176
"`html!` is not needed inside expression blocks. Use `let` bindings and bare \
72-
elements directly"
77+
elements directly",
7378
);
7479
}
7580
}
81+
82+
TokenStream::new()
7683
}
7784

7885
/// Check if a statement is a tail `html!`/`html_nested!` macro call (no trailing semicolon).
@@ -101,25 +108,41 @@ fn macro_path_html_span(path: &syn::Path) -> Option<proc_macro2::Span> {
101108

102109
impl ToTokens for HtmlBlock {
103110
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
104-
let HtmlBlock { content, .. } = self;
111+
let HtmlBlock {
112+
content,
113+
deprecations,
114+
..
115+
} = self;
105116
let new_tokens = match content {
106117
BlockContent::Iterable(html_iterable) => quote! {#html_iterable},
107118
BlockContent::Node(html_node) => quote! {#html_node},
108119
};
109120

110-
tokens.extend(quote! {#new_tokens});
121+
if deprecations.is_empty() {
122+
tokens.extend(new_tokens);
123+
} else {
124+
tokens.extend(quote! { { #deprecations #new_tokens } });
125+
}
111126
}
112127
}
113128

114129
impl ToNodeIterator for HtmlBlock {
115130
fn to_node_iterator_stream(&self) -> Option<proc_macro2::TokenStream> {
116-
let HtmlBlock { content, brace } = self;
131+
let HtmlBlock {
132+
content,
133+
brace,
134+
deprecations,
135+
} = self;
117136
let new_tokens = match content {
118137
BlockContent::Iterable(iterable) => iterable.to_node_iterator_stream(),
119138
BlockContent::Node(node) => node.to_node_iterator_stream(),
120139
}?;
121140

122-
Some(quote_spanned! {brace.span=> #new_tokens})
141+
if deprecations.is_empty() {
142+
Some(quote_spanned! {brace.span=> #new_tokens})
143+
} else {
144+
Some(quote_spanned! {brace.span=> { #deprecations #new_tokens }})
145+
}
123146
}
124147

125148
fn is_singular(&self) -> bool {

packages/yew-macro/src/html_tree/html_for.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub struct HtmlFor {
2424
iter: Expr,
2525
let_stmts: Vec<Local>,
2626
body: HtmlChildrenTree,
27+
deprecations: TokenStream,
2728
}
2829

2930
impl PeekValue<()> for HtmlFor {
@@ -53,7 +54,7 @@ impl Parse for HtmlFor {
5354
}
5455

5556
let body = HtmlChildrenTree::parse_delimited_with_nodes(&body_stream)?;
56-
super::check_unnecessary_fragment(&body);
57+
let deprecations = super::check_unnecessary_fragment(&body);
5758
// TODO: more concise code by using if-let guards (MSRV 1.95)
5859
for child in body.0.iter() {
5960
let HtmlTree::Element(element) = child else {
@@ -77,6 +78,7 @@ impl Parse for HtmlFor {
7778
iter,
7879
let_stmts,
7980
body,
81+
deprecations,
8082
})
8183
}
8284
}
@@ -88,6 +90,7 @@ impl ToTokens for HtmlFor {
8890
iter,
8991
let_stmts,
9092
body,
93+
deprecations,
9194
} = self;
9295
let acc = Ident::new("__yew_v", iter.span());
9396

@@ -129,6 +132,7 @@ impl ToTokens for HtmlFor {
129132
});
130133

131134
tokens.extend(quote!({
135+
#deprecations
132136
let mut #acc = ::std::vec::Vec::<::yew::virtual_dom::VNode>::new();
133137
::std::iter::Iterator::for_each(
134138
::std::iter::IntoIterator::into_iter(#iter),

packages/yew-macro/src/html_tree/html_match.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ enum HtmlMatchArmBody {
3030
brace: token::Brace,
3131
let_stmts: Vec<Local>,
3232
children: HtmlChildrenTree,
33+
deprecations: TokenStream,
34+
},
35+
Unbraced {
36+
tree: Box<super::HtmlTree>,
37+
deprecations: TokenStream,
3338
},
34-
Unbraced(Box<super::HtmlTree>),
3539
}
3640

3741
impl PeekValue<()> for HtmlMatch {
@@ -100,7 +104,7 @@ impl Parse for HtmlMatchArm {
100104

101105
let fat_arrow_token: Token![=>] = input.parse()?;
102106

103-
let body = if input.cursor().group(Delimiter::Brace).is_some() {
107+
let mut body = if input.cursor().group(Delimiter::Brace).is_some() {
104108
let content;
105109
let brace = braced!(content in input);
106110
let mut let_stmts = Vec::new();
@@ -112,17 +116,31 @@ impl Parse for HtmlMatchArm {
112116
}
113117
}
114118
let children = HtmlChildrenTree::parse_delimited_with_nodes(&content)?;
115-
super::check_unnecessary_fragment(&children);
119+
let deprecations = super::check_unnecessary_fragment(&children);
116120
HtmlMatchArmBody::Braced {
117121
brace,
118122
let_stmts,
119123
children,
124+
deprecations,
120125
}
121126
} else {
122-
HtmlMatchArmBody::Unbraced(Box::new(super::HtmlTree::parse_or_node(input)?))
127+
HtmlMatchArmBody::Unbraced {
128+
tree: Box::new(super::HtmlTree::parse_or_node(input)?),
129+
deprecations: TokenStream::new(),
130+
}
123131
};
124132

125-
check_arm_html_macro_call(&body);
133+
let arm_deprecations = check_arm_html_macro_call(&body);
134+
if !arm_deprecations.is_empty() {
135+
match &mut body {
136+
HtmlMatchArmBody::Braced { deprecations, .. } => {
137+
deprecations.extend(arm_deprecations)
138+
}
139+
HtmlMatchArmBody::Unbraced { deprecations, .. } => {
140+
deprecations.extend(arm_deprecations);
141+
}
142+
}
143+
}
126144

127145
let comma: Option<Token![,]> = input.parse()?;
128146

@@ -143,9 +161,11 @@ impl ToTokens for HtmlMatchArmBody {
143161
brace,
144162
let_stmts,
145163
children,
164+
deprecations,
146165
} => {
147166
tokens.extend(quote_spanned! {brace.span.span()=>
148167
{
168+
#deprecations
149169
#(#let_stmts)*
150170
::yew::virtual_dom::VNode::VList(::std::rc::Rc::new(
151171
::yew::virtual_dom::VList::with_children(
@@ -155,9 +175,12 @@ impl ToTokens for HtmlMatchArmBody {
155175
}
156176
});
157177
}
158-
Self::Unbraced(tree) => {
178+
Self::Unbraced { tree, deprecations } => {
159179
tokens.extend(quote_spanned! {tree.span()=>
160-
{ ::std::convert::Into::<::yew::virtual_dom::VNode>::into(#tree) }
180+
{
181+
#deprecations
182+
::std::convert::Into::<::yew::virtual_dom::VNode>::into(#tree)
183+
}
161184
});
162185
}
163186
}
@@ -197,22 +220,22 @@ impl ToTokens for HtmlMatch {
197220
}
198221
}
199222

200-
fn check_arm_html_macro_call(body: &HtmlMatchArmBody) {
223+
fn check_arm_html_macro_call(body: &HtmlMatchArmBody) -> TokenStream {
201224
let trees: Box<dyn Iterator<Item = &super::HtmlTree> + '_> = match body {
202225
HtmlMatchArmBody::Braced { children, .. } => Box::new(children.0.iter()),
203-
HtmlMatchArmBody::Unbraced(tree) => Box::new(std::iter::once(tree.as_ref())),
226+
HtmlMatchArmBody::Unbraced { tree, .. } => Box::new(std::iter::once(tree.as_ref())),
204227
};
205228
for tree in trees {
206229
if let super::HtmlTree::Node(node) = tree {
207230
if let HtmlNode::Expression(expr) = node.as_ref() {
208231
if let Some(span) = html_macro_call_span(expr) {
209-
super::emit_deprecated!(
232+
return super::deprecated_call(
210233
span,
211-
"`html!` is not needed in `match` arms. Use bare elements directly"
234+
"`html!` is not needed in `match` arms. Use bare elements directly",
212235
);
213-
return;
214236
}
215237
}
216238
}
217239
}
240+
TokenStream::new()
218241
}

0 commit comments

Comments
 (0)