fix(napi-derive): correct the aliased type generation
This commit is contained in:
parent
6d4b4af36f
commit
b2fea4d5b3
10 changed files with 74 additions and 9 deletions
|
@ -3,7 +3,7 @@ mod r#enum;
|
|||
mod r#fn;
|
||||
pub(crate) mod r#struct;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::{cell::RefCell, collections::HashMap};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use syn::Type;
|
||||
|
@ -17,6 +17,16 @@ pub struct TypeDef {
|
|||
pub js_doc: String,
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static ALIAS: RefCell<HashMap<String, String>> = Default::default();
|
||||
}
|
||||
|
||||
fn add_alias(name: String, alias: String) {
|
||||
ALIAS.with(|aliases| {
|
||||
aliases.borrow_mut().insert(name, alias);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn js_doc_from_comments(comments: &[String]) -> String {
|
||||
if comments.is_empty() {
|
||||
return "".to_owned();
|
||||
|
@ -248,7 +258,13 @@ pub fn ty_to_ts_type(ty: &Type, is_return_ty: bool) -> (String, bool) {
|
|||
));
|
||||
} else {
|
||||
// there should be runtime registered type in else
|
||||
ts_ty = Some((rust_ty, false));
|
||||
let type_alias = ALIAS.with(|aliases| {
|
||||
aliases
|
||||
.borrow()
|
||||
.get(rust_ty.as_str())
|
||||
.map(|a| (a.to_owned(), false))
|
||||
});
|
||||
ts_ty = type_alias.or_else(|| Some((rust_ty, false)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use super::{ToTypeDef, TypeDef};
|
||||
|
||||
use crate::{js_doc_from_comments, ty_to_ts_type, NapiConst};
|
||||
use crate::{js_doc_from_comments, ty_to_ts_type, typegen::add_alias, NapiConst};
|
||||
|
||||
impl ToTypeDef for NapiConst {
|
||||
fn to_type_def(&self) -> TypeDef {
|
||||
add_alias(self.name.to_string(), self.js_name.to_string());
|
||||
TypeDef {
|
||||
kind: "const".to_owned(),
|
||||
name: self.js_name.to_owned(),
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use super::{ToTypeDef, TypeDef};
|
||||
use super::{add_alias, ToTypeDef, TypeDef};
|
||||
use crate::{js_doc_from_comments, NapiEnum};
|
||||
|
||||
impl ToTypeDef for NapiEnum {
|
||||
fn to_type_def(&self) -> TypeDef {
|
||||
add_alias(self.name.to_string(), self.js_name.to_string());
|
||||
TypeDef {
|
||||
kind: "enum".to_owned(),
|
||||
name: self.js_name.to_owned(),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::{ToTypeDef, TypeDef};
|
||||
use super::{add_alias, ToTypeDef, TypeDef};
|
||||
use crate::{js_doc_from_comments, ty_to_ts_type, NapiImpl, NapiStruct, NapiStructKind};
|
||||
|
||||
thread_local! {
|
||||
|
@ -15,6 +15,7 @@ impl ToTypeDef for NapiStruct {
|
|||
c.borrow_mut()
|
||||
.insert(self.name.to_string(), self.js_name.clone());
|
||||
});
|
||||
add_alias(self.name.to_string(), self.js_name.to_string());
|
||||
TypeDef {
|
||||
kind: String::from(if self.kind == NapiStructKind::Object {
|
||||
"interface"
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use napi_derive_backend::{bail_span, BindgenResult, Diagnostic};
|
||||
use proc_macro2::{Delimiter, Ident, Span, TokenTree};
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
collections::HashMap,
|
||||
};
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
thread_local! {
|
||||
|
|
|
@ -78,6 +78,15 @@ Generated by [AVA](https://avajs.dev).
|
|||
age?: number | undefined | null␊
|
||||
}␊
|
||||
export function receiveAllOptionalObject(obj?: AllOptionalObject | undefined | null): void␊
|
||||
export enum ALIAS {␊
|
||||
A = 0,␊
|
||||
B = 1␊
|
||||
}␊
|
||||
export interface AliasedStruct {␊
|
||||
a: ALIAS␊
|
||||
b: number␊
|
||||
}␊
|
||||
export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void␊
|
||||
export function asyncPlus100(p: Promise<number>): Promise<number>␊
|
||||
/** This is an interface for package.json */␊
|
||||
export interface PackageJson {␊
|
||||
|
|
Binary file not shown.
|
@ -60,6 +60,9 @@ import {
|
|||
createExternalTypedArray,
|
||||
mutateTypedArray,
|
||||
receiveAllOptionalObject,
|
||||
fnReceivedAliased,
|
||||
ALIAS,
|
||||
AliasedStruct,
|
||||
} from '../'
|
||||
|
||||
test('export const', (t) => {
|
||||
|
@ -208,6 +211,15 @@ test('option object', (t) => {
|
|||
t.notThrows(() => receiveAllOptionalObject({}))
|
||||
})
|
||||
|
||||
test('aliased rust struct and enum', (t) => {
|
||||
const a: ALIAS = ALIAS.A
|
||||
const b: AliasedStruct = {
|
||||
a,
|
||||
b: 1,
|
||||
}
|
||||
t.notThrows(() => fnReceivedAliased(b, ALIAS.B))
|
||||
})
|
||||
|
||||
test('serde-json', (t) => {
|
||||
const packageJson = readPackageJson()
|
||||
t.is(packageJson.name, 'napi-rs')
|
||||
|
|
9
examples/napi/index.d.ts
vendored
9
examples/napi/index.d.ts
vendored
|
@ -68,6 +68,15 @@ export interface AllOptionalObject {
|
|||
age?: number | undefined | null
|
||||
}
|
||||
export function receiveAllOptionalObject(obj?: AllOptionalObject | undefined | null): void
|
||||
export enum ALIAS {
|
||||
A = 0,
|
||||
B = 1
|
||||
}
|
||||
export interface AliasedStruct {
|
||||
a: ALIAS
|
||||
b: number
|
||||
}
|
||||
export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void
|
||||
export function asyncPlus100(p: Promise<number>): Promise<number>
|
||||
/** This is an interface for package.json */
|
||||
export interface PackageJson {
|
||||
|
|
|
@ -42,3 +42,20 @@ fn receive_all_optional_object(obj: Option<AllOptionalObject>) -> Result<()> {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[napi(js_name = "ALIAS")]
|
||||
pub enum AliasedEnum {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
#[napi(object, js_name = "AliasedStruct")]
|
||||
pub struct StructContainsAliasedEnum {
|
||||
pub a: AliasedEnum,
|
||||
pub b: u32,
|
||||
}
|
||||
|
||||
#[napi]
|
||||
fn fn_received_aliased(mut s: StructContainsAliasedEnum, e: AliasedEnum) {
|
||||
s.a = e;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue