Skip to content

Commit

Permalink
feat(napi): add ts typegen skip
Browse files Browse the repository at this point in the history
  • Loading branch information
h-a-n-a committed Dec 19, 2021
1 parent 59a7e37 commit df9dc91
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 37 deletions.
5 changes: 4 additions & 1 deletion cli/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,10 @@ async function processIntermediateTypeFile(
return idents
}

const dtsHeader = `/* eslint-disable */
const dtsHeader = `/* tslint:disable */
/* eslint-disable */
/* auto-generated by Napi-rs */
export class ExternalObject<T> {
readonly '': {
Expand Down
4 changes: 4 additions & 0 deletions crates/backend/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct NapiFn {
pub js_mod: Option<String>,
pub ts_args_type: Option<String>,
pub ts_return_type: Option<String>,
pub skip_typescript: bool,
pub comments: Vec<String>,
}

Expand Down Expand Up @@ -77,6 +78,7 @@ pub struct NapiStructField {
pub getter: bool,
pub setter: bool,
pub comments: Vec<String>,
pub skip_typescript: bool,
}

#[derive(Debug, Clone)]
Expand All @@ -96,6 +98,7 @@ pub struct NapiEnum {
pub variants: Vec<NapiEnumVariant>,
pub js_mod: Option<String>,
pub comments: Vec<String>,
pub skip_typescript: bool,
}

#[derive(Debug, Clone)]
Expand All @@ -113,6 +116,7 @@ pub struct NapiConst {
pub value: Expr,
pub js_mod: Option<String>,
pub comments: Vec<String>,
pub skip_typescript: bool,
}

#[derive(Debug, Clone)]
Expand Down
2 changes: 1 addition & 1 deletion crates/backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ macro_rules! napi_ast_impl {

#[cfg(feature = "type-def")]
impl ToTypeDef for Napi {
fn to_type_def(&self) -> TypeDef {
fn to_type_def(&self) -> Option<TypeDef> {
match self.item {
$( NapiItem::$v(ref ast) => ast.to_type_def() ),*
}
Expand Down
2 changes: 1 addition & 1 deletion crates/backend/src/typegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl ToString for TypeDef {
}

pub trait ToTypeDef {
fn to_type_def(&self) -> TypeDef;
fn to_type_def(&self) -> Option<TypeDef>;
}

static KNOWN_TYPES: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
Expand Down
11 changes: 8 additions & 3 deletions crates/backend/src/typegen/const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ use super::{ToTypeDef, TypeDef};
use crate::{js_doc_from_comments, ty_to_ts_type, typegen::add_alias, NapiConst};

impl ToTypeDef for NapiConst {
fn to_type_def(&self) -> TypeDef {
fn to_type_def(&self) -> Option<TypeDef> {
if self.skip_typescript {
return None;
}

add_alias(self.name.to_string(), self.js_name.to_string());
TypeDef {

Some(TypeDef {
kind: "const".to_owned(),
name: self.js_name.to_owned(),
def: format!(
Expand All @@ -15,6 +20,6 @@ impl ToTypeDef for NapiConst {
),
js_mod: self.js_mod.to_owned(),
js_doc: js_doc_from_comments(&self.comments),
}
})
}
}
11 changes: 8 additions & 3 deletions crates/backend/src/typegen/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ use super::{add_alias, ToTypeDef, TypeDef};
use crate::{js_doc_from_comments, NapiEnum};

impl ToTypeDef for NapiEnum {
fn to_type_def(&self) -> TypeDef {
fn to_type_def(&self) -> Option<TypeDef> {
if self.skip_typescript {
return None;
}

add_alias(self.name.to_string(), self.js_name.to_string());
TypeDef {

Some(TypeDef {
kind: "enum".to_owned(),
name: self.js_name.to_owned(),
def: self.gen_ts_variants(),
js_doc: js_doc_from_comments(&self.comments),
js_mod: self.js_mod.to_owned(),
}
})
}
}

Expand Down
10 changes: 7 additions & 3 deletions crates/backend/src/typegen/fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ use super::{ty_to_ts_type, ToTypeDef, TypeDef};
use crate::{js_doc_from_comments, CallbackArg, FnKind, NapiFn};

impl ToTypeDef for NapiFn {
fn to_type_def(&self) -> TypeDef {
fn to_type_def(&self) -> Option<TypeDef> {
if self.skip_typescript {
return None;
}

let def = format!(
r#"{prefix} {name}({args}){ret}"#,
prefix = self.gen_ts_func_prefix(),
Expand All @@ -22,13 +26,13 @@ impl ToTypeDef for NapiFn {
.unwrap_or_else(|| self.gen_ts_func_ret()),
);

TypeDef {
Some(TypeDef {
kind: "fn".to_owned(),
name: self.js_name.clone(),
def,
js_mod: self.js_mod.to_owned(),
js_doc: js_doc_from_comments(&self.comments),
}
})
}
}

Expand Down
35 changes: 23 additions & 12 deletions crates/backend/src/typegen/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ thread_local! {
}

impl ToTypeDef for NapiStruct {
fn to_type_def(&self) -> TypeDef {
fn to_type_def(&self) -> Option<TypeDef> {
CLASS_STRUCTS.with(|c| {
c.borrow_mut()
.insert(self.name.to_string(), self.js_name.clone());
});
add_alias(self.name.to_string(), self.js_name.to_string());
TypeDef {

Some(TypeDef {
kind: String::from(if self.kind == NapiStructKind::Object {
"interface"
} else {
Expand All @@ -26,36 +27,42 @@ impl ToTypeDef for NapiStruct {
def: self.gen_ts_class(),
js_mod: self.js_mod.to_owned(),
js_doc: js_doc_from_comments(&self.comments),
}
})
}
}

impl ToTypeDef for NapiImpl {
fn to_type_def(&self) -> TypeDef {
fn to_type_def(&self) -> Option<TypeDef> {
if let Some(output_type) = &self.task_output_type {
TASK_STRUCTS.with(|t| {
t.borrow_mut()
.insert(self.js_name.clone(), ty_to_ts_type(output_type, false).0);
});
}
TypeDef {

Some(TypeDef {
kind: "impl".to_owned(),
name: self.js_name.to_owned(),
def: self
.items
.iter()
.map(|f| {
format!(
"{}{}",
js_doc_from_comments(&f.comments),
f.to_type_def().def
)
.filter_map(|f| {
if f.skip_typescript {
None
} else {
Some(format!(
"{}{}",
js_doc_from_comments(&f.comments),
f.to_type_def()
.map_or(String::default(), |type_def| type_def.def)
))
}
})
.collect::<Vec<_>>()
.join("\\n"),
js_mod: self.js_mod.to_owned(),
js_doc: "".to_string(),
}
})
}
}

Expand All @@ -69,6 +76,10 @@ impl NapiStruct {
.map(|f| {
let mut field_str = String::from("");

if f.skip_typescript {
return field_str;
}

if !f.comments.is_empty() {
field_str.push_str(&js_doc_from_comments(&f.comments))
}
Expand Down
20 changes: 12 additions & 8 deletions crates/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,19 @@ fn expand(attr: TokenStream, input: TokenStream) -> BindgenResult<TokenStream> {
}

#[cfg(all(feature = "type-def", not(feature = "noop")))]
fn output_type_def(type_def_file: String, type_def: TypeDef) -> IOResult<()> {
let file = fs::OpenOptions::new()
.append(true)
.create(true)
.open(type_def_file)?;
fn output_type_def(type_def_file: String, type_def: Option<TypeDef>) -> IOResult<()> {
if type_def.is_some() {
let file = fs::OpenOptions::new()
.append(true)
.create(true)
.open(type_def_file)?;

let mut writer = BufWriter::<fs::File>::new(file);
writer.write_all(type_def.to_string().as_bytes())?;
writer.write_all("\n".as_bytes())
let mut writer = BufWriter::<fs::File>::new(file);
writer.write_all(type_def.unwrap().to_string().as_bytes())?;
writer.write_all("\n".as_bytes())
} else {
IOResult::Ok(())
}
}

#[cfg(feature = "compat-mode")]
Expand Down
2 changes: 1 addition & 1 deletion crates/macro/src/parser/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ macro_rules! attrgen {
// impl later
// (inspectable, Inspectable(Span)),
// (typescript_custom_section, TypescriptCustomSection(Span)),
// (skip_typescript, SkipTypescript(Span)),
(skip_typescript, SkipTypescript(Span)),
// (getter_with_clone, GetterWithClone(Span)),

// For testing purposes only.
Expand Down
19 changes: 15 additions & 4 deletions crates/macro/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ fn napi_fn_from_decl(
js_mod: opts.namespace().map(|(m, _)| m.to_owned()),
ts_args_type: opts.ts_args_type().map(|(m, _)| m.to_owned()),
ts_return_type: opts.ts_return_type().map(|(m, _)| m.to_owned()),
skip_typescript: opts.skip_typescript().is_some(),
}
})
}
Expand Down Expand Up @@ -606,10 +607,13 @@ impl ParseNapi for syn::ItemFn {
}
impl ParseNapi for syn::ItemStruct {
fn parse_napi(&mut self, tokens: &mut TokenStream, opts: BindgenAttrs) -> BindgenResult<Napi> {
if opts.ts_args_type().is_some() || opts.ts_return_type().is_some() {
if opts.ts_args_type().is_some()
|| opts.ts_return_type().is_some()
|| opts.skip_typescript().is_some()
{
bail_span!(
self,
"#[napi] can't be applied to a struct with #[napi(ts_args_type)] or #[napi(ts_return_type)]"
"#[napi] can't be applied to a struct with #[napi(ts_args_type)] or #[napi(ts_return_type)] or #[napi(skip_typescript)]"
);
}
let napi = self.convert_to_ast(opts);
Expand All @@ -620,10 +624,13 @@ impl ParseNapi for syn::ItemStruct {
}
impl ParseNapi for syn::ItemImpl {
fn parse_napi(&mut self, tokens: &mut TokenStream, opts: BindgenAttrs) -> BindgenResult<Napi> {
if opts.ts_args_type().is_some() || opts.ts_return_type().is_some() {
if opts.ts_args_type().is_some()
|| opts.ts_return_type().is_some()
|| opts.skip_typescript().is_some()
{
bail_span!(
self,
"#[napi] can't be applied to impl with #[napi(ts_args_type)] or #[napi(ts_return_type)]"
"#[napi] can't be applied to impl with #[napi(ts_args_type)] or #[napi(ts_return_type)] or #[napi(skip_typescript)]"
);
}
// #[napi] macro will be remove from impl items after converted to ast
Expand Down Expand Up @@ -751,6 +758,7 @@ impl ConvertToAST for syn::ItemStruct {

let ignored = field_opts.skip().is_some();
let readonly = field_opts.readonly().is_some();
let skip_typescript = field_opts.skip_typescript().is_some();

fields.push(NapiStructField {
name,
Expand All @@ -759,6 +767,7 @@ impl ConvertToAST for syn::ItemStruct {
getter: !ignored,
setter: !(ignored || readonly),
comments: extract_doc_comments(&field.attrs),
skip_typescript,
})
}

Expand Down Expand Up @@ -943,6 +952,7 @@ impl ConvertToAST for syn::ItemEnum {
variants,
js_mod: opts.namespace().map(|(m, _)| m.to_owned()),
comments: extract_doc_comments(&self.attrs),
skip_typescript: opts.skip_typescript().is_some(),
}),
})
}
Expand All @@ -961,6 +971,7 @@ impl ConvertToAST for syn::ItemConst {
value: *self.expr.clone(),
js_mod: opts.namespace().map(|(m, _)| m.to_owned()),
comments: extract_doc_comments(&self.attrs),
skip_typescript: opts.skip_typescript().is_some(),
}),
}),
_ => bail_span!(self, "only public const allowed"),
Expand Down

0 comments on commit df9dc91

Please sign in to comment.