Merge pull request #971 from napi-rs/export-type-alias

fix(napi-derive,cli): export type alias for original name
This commit is contained in:
LongYinan 2021-12-25 17:49:17 +08:00 committed by GitHub
commit 52acde32b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 90 additions and 8 deletions

View file

@ -348,6 +348,7 @@ async function findUp(dir = process.cwd()): Promise<string | null> {
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<T> {
const allDefs = lines.map((line) => JSON.parse(line) as TypeDef)
function convertDefs(defs: TypeDef[], nested = false): string {
const classes = new Map<string, { def: string; js_doc: string }>()
const classes = new Map<
string,
{ def: string; js_doc: string; original_name?: string }
>()
const impls = new Map<string, string>()
let dts = ''
const nest = nested ? 2 : 0
@ -399,7 +403,11 @@ export class ExternalObject<T> {
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<T> {
}
})
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) {

View file

@ -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| {

View file

@ -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(

View file

@ -12,6 +12,7 @@ use syn::Type;
pub struct TypeDef {
pub kind: String,
pub name: String,
pub original_name: Option<String>,
pub def: String,
pub js_mod: Option<String>,
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,
)
}

View file

@ -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,

View file

@ -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(),

View file

@ -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),

View file

@ -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()

View file

@ -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␊

View file

@ -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) => {

View file

@ -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

View file

@ -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<JsAsset> {
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;
}
}

View file

@ -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"]
}