fix(napi-derive): more accurate napi expanding error (#1854)
This commit is contained in:
parent
996310a065
commit
6f40f94d09
4 changed files with 62 additions and 29 deletions
|
@ -18,7 +18,8 @@ use proc_macro2::{Ident, Span, TokenStream};
|
|||
use quote::ToTokens;
|
||||
use syn::ext::IdentExt;
|
||||
use syn::parse::{Parse, ParseStream, Result as SynResult};
|
||||
use syn::{Attribute, ExprLit, PatType, PathSegment, Signature, Type, Visibility};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{Attribute, ExprLit, Meta, PatType, PathSegment, Signature, Type, Visibility};
|
||||
|
||||
use crate::parser::attrs::{check_recorded_struct_for_impl, record_struct};
|
||||
|
||||
|
@ -81,29 +82,61 @@ fn find_ts_arg_type_and_remove_attribute(
|
|||
ts_args_type
|
||||
);
|
||||
}
|
||||
let inner: syn::Expr = attr.parse_args()?;
|
||||
match inner {
|
||||
syn::Expr::Assign(syn::ExprAssign { left, right, .. }) => {
|
||||
let left = match *left {
|
||||
syn::Expr::Path(syn::ExprPath { path, .. }) => path,
|
||||
_ => bail_span!(left, "Expected path"),
|
||||
};
|
||||
|
||||
if !left.is_ident("ts_arg_type") {
|
||||
bail_span!(left, "Expected 'ts_arg_type'");
|
||||
match &attr.meta {
|
||||
syn::Meta::Path(_) | syn::Meta::NameValue(_) => {
|
||||
bail_span!(
|
||||
attr,
|
||||
"Expects an assignment #[napi(ts_arg_type = \"MyType\")]"
|
||||
)
|
||||
}
|
||||
syn::Meta::List(list) => {
|
||||
let mut found = false;
|
||||
list
|
||||
.parse_args_with(|tokens: &syn::parse::ParseBuffer<'_>| {
|
||||
// tokens:
|
||||
// #[napi(xxx, xxx=xxx)]
|
||||
// ^^^^^^^^^^^^
|
||||
let list = tokens.parse_terminated(Meta::parse, Token![,])?;
|
||||
|
||||
let right = match *right {
|
||||
for meta in list {
|
||||
if meta.path().is_ident("ts_arg_type") {
|
||||
match meta {
|
||||
Meta::Path(_) | Meta::List(_) => {
|
||||
return Err(syn::Error::new(
|
||||
meta.path().span(),
|
||||
"Expects an assignment (ts_arg_type = \"MyType\")",
|
||||
))
|
||||
}
|
||||
Meta::NameValue(name_value) => match name_value.value {
|
||||
syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Str(lit),
|
||||
lit: syn::Lit::Str(str),
|
||||
..
|
||||
}) => lit,
|
||||
_ => bail_span!(right, "Expected string literal"),
|
||||
};
|
||||
ts_type_attr = Some((idx, right.value()));
|
||||
}) => {
|
||||
let value = str.value();
|
||||
found = true;
|
||||
ts_type_attr = Some((idx, value));
|
||||
}
|
||||
_ => {
|
||||
return Err(syn::Error::new(
|
||||
name_value.value.span(),
|
||||
"Expects a string literal",
|
||||
))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.map_err(Diagnostic::from)?;
|
||||
|
||||
if !found {
|
||||
bail_span!(attr, "Expects a 'ts_arg_type'");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => bail_span!(inner, "Expected assignment [ts_arg_type = \"MyType\"]"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: Expected string literal
|
||||
error: Expects a string literal
|
||||
--> tests/build_error_tests/ts_arg_type_2.rs:7:41
|
||||
|
|
||||
7 | pub fn add(u: u32, #[napi(ts_arg_type = 32)] f: Option<String>) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: unexpected token
|
||||
--> tests/build_error_tests/ts_arg_type_3.rs:7:38
|
||||
error: Expects an assignment (ts_arg_type = "MyType")
|
||||
--> tests/build_error_tests/ts_arg_type_3.rs:7:27
|
||||
|
|
||||
7 | pub fn add(u: u32, #[napi(ts_arg_type, not_expected)] f: Option<String>) {
|
||||
| ^
|
||||
| ^^^^^^^^^^^
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: Expected 'ts_arg_type'
|
||||
--> tests/build_error_tests/ts_arg_type_4.rs:7:27
|
||||
error: Expects a 'ts_arg_type'
|
||||
--> tests/build_error_tests/ts_arg_type_4.rs:7:20
|
||||
|
|
||||
7 | pub fn add(u: u32, #[napi(not_expected = "obj")] f: Option<String>) {
|
||||
| ^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
Loading…
Reference in a new issue