From 556ace8f3302d9dd0b5aec237c3aa49caf58d7dd Mon Sep 17 00:00:00 2001 From: LongYinan Date: Sat, 25 Dec 2021 17:35:47 +0800 Subject: [PATCH] fix(napi-derive,cli): export type alias for original name --- cli/src/build.ts | 18 +++++++++-- crates/backend/src/codegen/fn.rs | 3 +- crates/backend/src/codegen/struct.rs | 2 +- crates/backend/src/typegen.rs | 9 +++++- crates/backend/src/typegen/const.rs | 1 + crates/backend/src/typegen/enum.rs | 1 + crates/backend/src/typegen/fn.rs | 1 + crates/backend/src/typegen/struct.rs | 2 ++ examples/napi/__test__/typegen.spec.ts.md | 12 ++++++++ examples/napi/__test__/typegen.spec.ts.snap | Bin 2141 -> 2208 bytes examples/napi/__test__/values.spec.ts | 3 ++ examples/napi/index.d.ts | 12 ++++++++ examples/napi/src/class.rs | 32 ++++++++++++++++++++ tsconfig.json | 2 +- 14 files changed, 90 insertions(+), 8 deletions(-) diff --git a/cli/src/build.ts b/cli/src/build.ts index ec7acc8e..0aea66f4 100644 --- a/cli/src/build.ts +++ b/cli/src/build.ts @@ -348,6 +348,7 @@ async function findUp(dir = process.cwd()): Promise { interface TypeDef { kind: 'fn' | 'struct' | 'impl' | 'enum' | 'interface' name: string + original_name?: string def: string js_mod?: string js_doc: string @@ -388,7 +389,10 @@ export class ExternalObject { const allDefs = lines.map((line) => JSON.parse(line) as TypeDef) function convertDefs(defs: TypeDef[], nested = false): string { - const classes = new Map() + const classes = new Map< + string, + { def: string; js_doc: string; original_name?: string } + >() const impls = new Map() let dts = '' const nest = nested ? 2 : 0 @@ -399,7 +403,11 @@ export class ExternalObject { if (!nested) { idents.push(def.name) } - classes.set(def.name, { def: def.def, js_doc: def.js_doc }) + classes.set(def.name, { + original_name: def.original_name, + def: def.def, + js_doc: def.js_doc, + }) break case 'impl': impls.set(def.name, `${def.js_doc}${def.def}`) @@ -429,9 +437,13 @@ export class ExternalObject { } }) - for (const [name, { js_doc, def }] of classes.entries()) { + for (const [name, { js_doc, def, original_name }] of classes.entries()) { const implDef = impls.get(name) + if (original_name && name !== original_name) { + dts += indentLines(`export type ${original_name} = ${name}\n`, nest) + } + dts += indentLines(`${js_doc}export class ${name} {`, nest) if (def) { diff --git a/crates/backend/src/codegen/fn.rs b/crates/backend/src/codegen/fn.rs index fed1373e..0c2300a0 100644 --- a/crates/backend/src/codegen/fn.rs +++ b/crates/backend/src/codegen/fn.rs @@ -47,10 +47,9 @@ impl TryToTokens for NapiFn { quote! { #native_call } } else if self.kind == FnKind::Constructor { quote! { - let call_from_factory = napi::bindgen_prelude::___CALL_FROM_FACTORY.load(std::sync::atomic::Ordering::Relaxed); // constructor function is called from class `factory` // so we should skip the original `constructor` logic - if call_from_factory { + if napi::bindgen_prelude::___CALL_FROM_FACTORY.load(std::sync::atomic::Ordering::Relaxed) { return std::ptr::null_mut(); } napi::bindgen_prelude::CallbackInfo::<#args_len>::new(env, cb, None).and_then(|mut cb| { diff --git a/crates/backend/src/codegen/struct.rs b/crates/backend/src/codegen/struct.rs index 539d46d5..06302a43 100644 --- a/crates/backend/src/codegen/struct.rs +++ b/crates/backend/src/codegen/struct.rs @@ -188,7 +188,6 @@ impl NapiStruct { "Failed to construct class `{}`", #js_name_str )?; - napi::bindgen_prelude::___CALL_FROM_FACTORY.store(false, std::sync::atomic::Ordering::Relaxed); napi::check_status!( napi::sys::napi_wrap( env, @@ -201,6 +200,7 @@ impl NapiStruct { "Failed to wrap native object of class `{}`", #js_name_str )?; + napi::bindgen_prelude::___CALL_FROM_FACTORY.store(false, std::sync::atomic::Ordering::Relaxed); Ok(result) } else { Err(napi::bindgen_prelude::Error::new( diff --git a/crates/backend/src/typegen.rs b/crates/backend/src/typegen.rs index 58f9caa5..b17907a6 100644 --- a/crates/backend/src/typegen.rs +++ b/crates/backend/src/typegen.rs @@ -12,6 +12,7 @@ use syn::Type; pub struct TypeDef { pub kind: String, pub name: String, + pub original_name: Option, pub def: String, pub js_mod: Option, pub js_doc: String, @@ -78,12 +79,18 @@ impl ToString for TypeDef { } else { "".to_owned() }; + let original_name = if let Some(original_name) = &self.original_name { + format!(", \"original_name\": \"{}\"", original_name) + } else { + "".to_owned() + }; format!( - r#"{{"kind": "{}", "name": "{}", "js_doc": "{}", "def": "{}"{}}}"#, + r#"{{"kind": "{}", "name": "{}", "js_doc": "{}", "def": "{}"{}{}}}"#, self.kind, self.name, escape_json(&self.js_doc), escape_json(&self.def), + original_name, js_mod, ) } diff --git a/crates/backend/src/typegen/const.rs b/crates/backend/src/typegen/const.rs index 1ae5b808..7def2c14 100644 --- a/crates/backend/src/typegen/const.rs +++ b/crates/backend/src/typegen/const.rs @@ -13,6 +13,7 @@ impl ToTypeDef for NapiConst { Some(TypeDef { kind: "const".to_owned(), name: self.js_name.to_owned(), + original_name: Some(self.name.to_string()), def: format!( "export const {}: {}", &self.js_name, diff --git a/crates/backend/src/typegen/enum.rs b/crates/backend/src/typegen/enum.rs index c22666f8..6f3c1efe 100644 --- a/crates/backend/src/typegen/enum.rs +++ b/crates/backend/src/typegen/enum.rs @@ -12,6 +12,7 @@ impl ToTypeDef for NapiEnum { Some(TypeDef { kind: "enum".to_owned(), name: self.js_name.to_owned(), + original_name: Some(self.name.to_string()), def: self.gen_ts_variants(), js_doc: js_doc_from_comments(&self.comments), js_mod: self.js_mod.to_owned(), diff --git a/crates/backend/src/typegen/fn.rs b/crates/backend/src/typegen/fn.rs index 45297793..65a7e2ff 100644 --- a/crates/backend/src/typegen/fn.rs +++ b/crates/backend/src/typegen/fn.rs @@ -29,6 +29,7 @@ impl ToTypeDef for NapiFn { Some(TypeDef { kind: "fn".to_owned(), name: self.js_name.clone(), + original_name: None, def, js_mod: self.js_mod.to_owned(), js_doc: js_doc_from_comments(&self.comments), diff --git a/crates/backend/src/typegen/struct.rs b/crates/backend/src/typegen/struct.rs index afbe5227..d1bee1ca 100644 --- a/crates/backend/src/typegen/struct.rs +++ b/crates/backend/src/typegen/struct.rs @@ -24,6 +24,7 @@ impl ToTypeDef for NapiStruct { "struct" }), name: self.js_name.to_owned(), + original_name: Some(self.name.to_string()), def: self.gen_ts_class(), js_mod: self.js_mod.to_owned(), js_doc: js_doc_from_comments(&self.comments), @@ -43,6 +44,7 @@ impl ToTypeDef for NapiImpl { Some(TypeDef { kind: "impl".to_owned(), name: self.js_name.to_owned(), + original_name: None, def: self .items .iter() diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index b8d3c8dd..23907a13 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -156,10 +156,12 @@ Generated by [AVA](https://avajs.dev). constructor(name: string)␊ getCount(): number␊ }␊ + export type Blake2bHasher = Blake2BHasher␊ /** Smoking test for type generation */␊ export class Blake2BHasher {␊ static withKey(key: Blake2bKey): Blake2BHasher␊ }␊ + export type Blake2bKey = Blake2BKey␊ export class Blake2BKey { }␊ export class Context {␊ maybeNeed?: boolean | undefined | null␊ @@ -179,6 +181,16 @@ Generated by [AVA](https://avajs.dev). getMaskColor(): string␊ getName(): string␊ }␊ + export type JsAssets = Assets␊ + export class Assets {␊ + constructor()␊ + get(id: number): JsAsset | undefined | null␊ + }␊ + export type JsAsset = Asset␊ + export class Asset {␊ + constructor()␊ + get filePath(): number␊ + }␊ 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 ff404ed7920740490a7cc2834a52a5cffe2d49c6..fbdb529de3a9774ede0c11652cf20ca32a8d60ee 100644 GIT binary patch literal 2208 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 Tdg(WkyOsX|{K-x+WElVeSTGfk diff --git a/examples/napi/__test__/values.spec.ts b/examples/napi/__test__/values.spec.ts index 99ce7fa2..c0a010fc 100644 --- a/examples/napi/__test__/values.spec.ts +++ b/examples/napi/__test__/values.spec.ts @@ -71,6 +71,7 @@ import { returnUndefined, Dog, Bird, + Assets, } from '../' test('export const', (t) => { @@ -130,6 +131,8 @@ test('class', (t) => { t.deepEqual(dog.returnOtherClass(), new Dog('Doge')) t.deepEqual(dog.returnOtherClassWithCustomConstructor(), new Bird('parrot')) t.is(dog.returnOtherClassWithCustomConstructor().getCount(), 1234) + const assets = new Assets() + t.is(assets.get(1)?.filePath, 1) }) test('class factory', (t) => { diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index a64af8ad..3453c31c 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -146,10 +146,12 @@ export class Bird { constructor(name: string) getCount(): number } +export type Blake2bHasher = Blake2BHasher /** Smoking test for type generation */ export class Blake2BHasher { static withKey(key: Blake2bKey): Blake2BHasher } +export type Blake2bKey = Blake2BKey export class Blake2BKey { } export class Context { maybeNeed?: boolean | undefined | null @@ -169,6 +171,16 @@ export class NinjaTurtle { getMaskColor(): string getName(): string } +export type JsAssets = Assets +export class Assets { + constructor() + get(id: number): JsAsset | undefined | null +} +export type JsAsset = Asset +export class Asset { + constructor() + get filePath(): number +} export class ClassWithFactory { name: string static withName(name: string): ClassWithFactory diff --git a/examples/napi/src/class.rs b/examples/napi/src/class.rs index f1d5e720..554d417d 100644 --- a/examples/napi/src/class.rs +++ b/examples/napi/src/class.rs @@ -202,3 +202,35 @@ impl NinjaTurtle { self.name.as_str() } } + +#[napi(js_name = "Assets")] +pub struct JsAssets {} + +#[napi] +impl JsAssets { + #[napi(constructor)] + pub fn new() -> Self { + JsAssets {} + } + + #[napi] + pub fn get(&mut self, _id: u32) -> Option { + Some(JsAsset {}) + } +} + +#[napi(js_name = "Asset")] +pub struct JsAsset {} + +#[napi] +impl JsAsset { + #[napi(constructor)] + pub fn new() -> Self { + Self {} + } + + #[napi(getter)] + pub fn get_file_path(&self) -> u32 { + return 1; + } +} diff --git a/tsconfig.json b/tsconfig.json index 16988746..5de32776 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,5 +27,5 @@ "lib": ["dom", "DOM.Iterable", "ES2019", "ES2020", "esnext"] }, "include": ["."], - "exclude": ["node_modules", "bench", "cli/scripts", "scripts"] + "exclude": ["node_modules", "bench", "cli/scripts", "scripts", "examples"] }