diff --git a/crates/backend/src/typegen.rs b/crates/backend/src/typegen.rs index 7b3b9da8..0bbd2e1f 100644 --- a/crates/backend/src/typegen.rs +++ b/crates/backend/src/typegen.rs @@ -7,7 +7,7 @@ use std::collections::HashMap; use once_cell::sync::Lazy; use syn::Type; -#[derive(Default)] +#[derive(Default, Debug)] pub struct TypeDef { pub kind: String, pub name: String, @@ -149,6 +149,10 @@ pub fn ty_to_ts_type(ty: &Type, is_return_ty: bool) -> String { } else { ts_ty = Some(known_ty.to_owned()); } + } else if let Some(t) = crate::typegen::r#struct::CLASS_STRUCTS + .with(|c| c.borrow_mut().get(rust_ty.as_str()).cloned()) + { + ts_ty = Some(t); } else { // there should be runtime registered type in else ts_ty = Some(rust_ty); @@ -157,7 +161,7 @@ pub fn ty_to_ts_type(ty: &Type, is_return_ty: bool) -> String { ts_ty.unwrap_or_else(|| "any".to_owned()) } - + Type::Group(g) => ty_to_ts_type(&g.elem, is_return_ty), _ => "any".to_owned(), } } diff --git a/crates/backend/src/typegen/fn.rs b/crates/backend/src/typegen/fn.rs index 9d7c719a..4c93b3e8 100644 --- a/crates/backend/src/typegen/fn.rs +++ b/crates/backend/src/typegen/fn.rs @@ -87,6 +87,11 @@ impl NapiFn { fn gen_ts_func_ret(&self) -> String { match self.kind { FnKind::Constructor | FnKind::Setter => "".to_owned(), + FnKind::Factory => self + .parent + .clone() + .map(|i| format!(": {}", i.to_string().to_case(Case::Pascal))) + .unwrap_or_else(|| "".to_owned()), _ => { let ret = if let Some(ret) = &self.ret { let ts_type = ty_to_ts_type(ret, true); diff --git a/crates/backend/src/typegen/struct.rs b/crates/backend/src/typegen/struct.rs index 7998e0a2..3790bf75 100644 --- a/crates/backend/src/typegen/struct.rs +++ b/crates/backend/src/typegen/struct.rs @@ -6,10 +6,15 @@ use crate::{ty_to_ts_type, NapiImpl, NapiStruct, NapiStructKind}; thread_local! { pub(crate) static TASK_STRUCTS: RefCell> = Default::default(); + pub(crate) static CLASS_STRUCTS: RefCell> = Default::default(); } impl ToTypeDef for NapiStruct { fn to_type_def(&self) -> TypeDef { + CLASS_STRUCTS.with(|c| { + c.borrow_mut() + .insert(self.name.to_string(), self.js_name.clone()); + }); TypeDef { kind: String::from(if self.kind == NapiStructKind::Object { "interface" diff --git a/crates/macro/src/parser/mod.rs b/crates/macro/src/parser/mod.rs index 6708c032..de4da2f6 100644 --- a/crates/macro/src/parser/mod.rs +++ b/crates/macro/src/parser/mod.rs @@ -782,7 +782,7 @@ impl ConvertToAST for syn::ItemImpl { continue; } - if opts.constructor().is_some() { + if opts.constructor().is_some() || opts.factory().is_some() { struct_js_name = check_recorded_struct_for_impl(&struct_name, &opts)?; } diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index a1601ee9..9408013c 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -54,6 +54,13 @@ Generated by [AVA](https://avajs.dev). whoami(): string␊ static getDogKind(): Kind␊ }␊ + export class Blake2BHasher {␊ + ␊ + static withKey(key: Blake2bKey): Blake2BHasher␊ + }␊ + export class Blake2BKey {␊ + ␊ + }␊ export class ClassWithFactory {␊ name: string␊ static withName(name: string): ClassWithFactory␊ diff --git a/examples/napi/__test__/typegen.spec.ts.snap b/examples/napi/__test__/typegen.spec.ts.snap index f7edba92..d3478adf 100644 Binary files a/examples/napi/__test__/typegen.spec.ts.snap and b/examples/napi/__test__/typegen.spec.ts.snap differ diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index 2f236609..c532a62e 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -43,6 +43,13 @@ export class Animal { set name(name: string) whoami(): string static getDogKind(): Kind +} +export class Blake2BHasher { + + static withKey(key: Blake2bKey): Blake2BHasher +} +export class Blake2BKey { + } export class ClassWithFactory { name: string diff --git a/examples/napi/src/class.rs b/examples/napi/src/class.rs index 9b05a683..7d6ef668 100644 --- a/examples/napi/src/class.rs +++ b/examples/napi/src/class.rs @@ -53,3 +53,25 @@ impl Animal { Kind::Dog } } + +/// Smoking test for type generation +#[napi] +#[repr(transparent)] +pub struct Blake2bHasher(u32); + +#[napi] +impl Blake2bHasher { + #[napi(factory)] + pub fn with_key(key: &Blake2bKey) -> Self { + Blake2bHasher(key.get_inner()) + } +} + +#[napi] +pub struct Blake2bKey(u32); + +impl Blake2bKey { + fn get_inner(&self) -> u32 { + self.0 + } +}