Skip to content

Commit

Permalink
Improve diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
hamza1311 committed Oct 3, 2022
1 parent a9038da commit ca6c03f
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 18 deletions.
45 changes: 40 additions & 5 deletions packages/yew-macro/src/html_tree/html_component.rs
@@ -1,5 +1,6 @@
use proc_macro2::Span;
use quote::{quote, quote_spanned, ToTokens};
use syn::parse::discouraged::Speculative;
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::{Token, Type};
Expand Down Expand Up @@ -45,7 +46,7 @@ impl Parse for HtmlComponent {
}

let mut children = HtmlChildrenTree::new();
loop {
let close = loop {
if input.is_empty() {
return Err(syn::Error::new_spanned(
open.to_spanned(),
Expand All @@ -54,12 +55,46 @@ impl Parse for HtmlComponent {
}

if trying_to_close() {
break;
let cursor = input.cursor();
let _ = cursor
.punct()
.and_then(|(_, cursor)| cursor.punct())
.and_then(|(_, cursor)| cursor.ident())
.ok_or_else(|| {
syn::Error::new(Span::call_site(), "expected a valid closing tag (e.g.: </Component>)")
})?;

let fork = input.fork();
let lt = fork.parse::<Token![<]>()?;
let div = Some(fork.parse::<Token![/]>()?);
let ty = fork.parse::<Type>()?;
if ty != open.ty {
fn format_token_stream(ts: impl ToTokens) -> String {
let string = ts.to_token_stream().to_string();
// remove unnecessary spaces
string.replace(' ', "")
}
let open_ty = open.ty;
return Err(syn::Error::new_spanned(
quote!(#open_ty #ty),
format!(
"mismatched closing tags: expected `{}`, found `{}`",
format_token_stream(open_ty),
format_token_stream(ty)
),
));
} else {
let gt = fork.parse::<Token![>]>()?;
let close = HtmlComponentClose {
tag: TagTokens { lt, div, gt },
ty,
};
input.advance_to(&fork);
break close;
}
}
children.parse_child(input)?;
}

let close = input.parse::<HtmlComponentClose>()?;
};

if !children.is_empty() {
if let Some(children_prop) = open.props.children() {
Expand Down
30 changes: 30 additions & 0 deletions packages/yew-macro/tests/html_macro/component-fail.rs
Expand Up @@ -148,4 +148,34 @@ fn not_expressions() {
html! { <HtmlInProps header={format!("ending with semi");} /> };
}

fn mismatch_closing_tags() {
pub struct A;
impl Component for A {
type Message = ();
type Properties = ();

fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
}
}

pub struct B;
impl Component for B {
type Message = ();
type Properties = ();

fn create(_ctx: &Context<Self>) -> Self {
unimplemented!()
}
fn view(&self, _ctx: &Context<Self>) -> Html {
unimplemented!()
}
}
let _ = html! { <A></B> };
let _ = html! { <A></> };
}

fn main() {}
14 changes: 14 additions & 0 deletions packages/yew-macro/tests/html_macro/component-fail.stderr
Expand Up @@ -386,6 +386,20 @@ error: only an expression may be assigned as a property. Consider removing this
148 | html! { <HtmlInProps header={format!("ending with semi");} /> };
| ^

error: mismatched closing tags: expected `A`, found `B`
--> tests/html_macro/component-fail.rs:177:22
|
177 | let _ = html! { <A></B> };
| ^^^^^

error: expected a valid closing tag (e.g.: </Component>)
--> tests/html_macro/component-fail.rs:178:13
|
178 | let _ = html! { <A></> };
| ^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `html` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0425]: cannot find value `blah` in this scope
--> tests/html_macro/component-fail.rs:82:22
|
Expand Down
6 changes: 6 additions & 0 deletions packages/yew-macro/tests/html_macro/generic-component-fail.rs
Expand Up @@ -40,9 +40,15 @@ where
}}

fn compile_fail() {
#[allow(unused_imports)]
use std::path::Path;

html! { <Generic<String>> };
html! { <Generic<String>></Generic> };
html! { <Generic<String>></Generic<Vec<String>>> };

html! { <Generic<String>></Generic<Path>> };
html! { <Generic<String>></> };
}

fn main() {}
36 changes: 23 additions & 13 deletions packages/yew-macro/tests/html_macro/generic-component-fail.stderr
@@ -1,21 +1,31 @@
error: this opening tag has no corresponding closing tag
--> tests/html_macro/generic-component-fail.rs:43:13
--> tests/html_macro/generic-component-fail.rs:46:13
|
43 | html! { <Generic<String>> };
46 | html! { <Generic<String>> };
| ^^^^^^^^^^^^^^^^^

error[E0107]: missing generics for struct `Generic`
--> tests/html_macro/generic-component-fail.rs:44:32
error: mismatched closing tags: expected `Generic<String>`, found `Generic`
--> tests/html_macro/generic-component-fail.rs:47:14
|
44 | html! { <Generic<String>></Generic> };
| ^^^^^^^ expected 1 generic argument
47 | html! { <Generic<String>></Generic> };
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: mismatched closing tags: expected `Generic<String>`, found `Generic<Vec<String>>`
--> tests/html_macro/generic-component-fail.rs:48:14
|
48 | html! { <Generic<String>></Generic<Vec<String>>> };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: mismatched closing tags: expected `Generic<String>`, found `Generic<Path>`
--> tests/html_macro/generic-component-fail.rs:50:14
|
note: struct defined here, with 1 generic parameter: `T`
--> tests/html_macro/generic-component-fail.rs:4:12
50 | html! { <Generic<String>></Generic<Path>> };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: expected a valid closing tag (e.g.: </Component>)
--> tests/html_macro/generic-component-fail.rs:51:5
|
4 | pub struct Generic<T> {
| ^^^^^^^ -
help: add missing generic argument
51 | html! { <Generic<String>></> };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
44 | html! { <Generic<String>></Generic<T>> };
| ~~~~~~~~~~
= note: this error originates in the macro `html` (in Nightly builds, run with -Z macro-backtrace for more info)

0 comments on commit ca6c03f

Please sign in to comment.