Skip to main content

napi_derive_backend/
ast.rs

1use convert_case::Case;
2use proc_macro2::{Ident, Literal, Span};
3use syn::{Attribute, Expr, Type};
4
5#[derive(Debug, Clone)]
6pub struct NapiFn {
7  pub name: Ident,
8  pub js_name: String,
9  pub symbol_for: Option<(String, Span)>,
10  /// The `Symbol` member name, e.g. `iterator` for `Symbol.iterator`.
11  pub well_known_symbol: Option<(String, Span)>,
12  pub module_exports: bool,
13  pub attrs: Vec<Attribute>,
14  pub args: Vec<NapiFnArg>,
15  pub ret: Option<syn::Type>,
16  pub is_ret_result: bool,
17  pub is_async: bool,
18  pub within_async_runtime: bool,
19  pub fn_self: Option<FnSelf>,
20  pub kind: FnKind,
21  pub vis: syn::Visibility,
22  pub parent: Option<Ident>,
23  pub parent_js_name: Option<String>,
24  pub strict: bool,
25  pub return_if_invalid: bool,
26  pub js_mod: Option<String>,
27  pub ts_generic_types: Option<String>,
28  pub ts_type: Option<String>,
29  pub ts_args_type: Option<String>,
30  pub ts_return_type: Option<String>,
31  pub skip_typescript: bool,
32  pub comments: Vec<String>,
33  pub parent_is_generator: bool,
34  pub parent_is_async_generator: bool,
35  pub writable: bool,
36  pub enumerable: bool,
37  pub configurable: bool,
38  pub catch_unwind: bool,
39  pub unsafe_: bool,
40  pub register_name: Ident,
41  pub no_export: bool,
42}
43
44#[derive(Debug, Clone)]
45pub struct CallbackArg {
46  pub pat: Box<syn::Pat>,
47  pub args: Vec<syn::Type>,
48  pub ret: Option<syn::Type>,
49}
50
51#[derive(Debug, Clone)]
52pub struct NapiFnArg {
53  pub kind: NapiFnArgKind,
54  pub ts_arg_type: Option<String>,
55}
56
57impl NapiFnArg {
58  /// if type was overridden with `#[napi(ts_arg_type = "...")]` use that instead
59  pub fn use_overridden_type_or(&self, default: impl FnOnce() -> String) -> String {
60    self.ts_arg_type.as_ref().cloned().unwrap_or_else(default)
61  }
62}
63
64#[derive(Debug, Clone)]
65pub enum NapiFnArgKind {
66  PatType(Box<syn::PatType>),
67  Callback(Box<CallbackArg>),
68}
69
70#[derive(Debug, Clone, PartialEq, Eq)]
71pub enum FnKind {
72  Normal,
73  Constructor,
74  Factory,
75  Getter,
76  Setter,
77}
78
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub enum FnSelf {
81  Value,
82  Ref,
83  MutRef,
84}
85
86#[derive(Debug, Clone)]
87pub struct NapiStruct {
88  pub name: Ident,
89  pub js_name: String,
90  pub comments: Vec<String>,
91  pub js_mod: Option<String>,
92  pub use_nullable: bool,
93  pub register_name: Ident,
94  pub kind: NapiStructKind,
95  pub has_lifetime: bool,
96  pub is_generator: bool,
97  pub is_async_generator: bool,
98  /// Optional crate-unique salt from `#[napi(type_tag = "...")]`. When set on a
99  /// class it REPLACES the default `crate@version` identity component of the
100  /// content-derived class type tag (module_path + ClassName still apply), so a
101  /// class's tag cannot collide with an unrelated addon that happens to share
102  /// the same crate name@version + module path + class name. `None` keeps the
103  /// default `crate@version::module_path::ClassName` derivation. Runtime-only;
104  /// never emitted into TypeScript.
105  pub type_tag: Option<String>,
106}
107
108#[derive(Debug, Clone)]
109pub enum NapiStructKind {
110  Transparent(NapiTransparent),
111  Class(NapiClass),
112  Object(NapiObject),
113  StructuredEnum(NapiStructuredEnum),
114  Array(NapiArray),
115}
116
117#[derive(Debug, Clone)]
118pub struct NapiTransparent {
119  pub ty: Type,
120  pub object_from_js: bool,
121  pub object_to_js: bool,
122}
123
124#[derive(Debug, Clone)]
125pub struct NapiClass {
126  pub fields: Vec<NapiStructField>,
127  pub ctor: bool,
128  pub implement_iterator: bool,
129  pub implement_async_iterator: bool,
130  pub is_tuple: bool,
131  pub use_custom_finalize: bool,
132}
133
134#[derive(Debug, Clone)]
135pub struct NapiObject {
136  pub fields: Vec<NapiStructField>,
137  pub object_from_js: bool,
138  pub object_to_js: bool,
139  pub is_tuple: bool,
140}
141
142#[derive(Debug, Clone)]
143pub struct NapiArray {
144  pub fields: Vec<NapiStructField>,
145  pub object_from_js: bool,
146  pub object_to_js: bool,
147}
148
149#[derive(Debug, Clone)]
150pub struct NapiStructuredEnum {
151  pub variants: Vec<NapiStructuredEnumVariant>,
152  pub object_from_js: bool,
153  pub object_to_js: bool,
154  pub discriminant: String,
155  pub discriminant_case: Option<Case<'static>>,
156}
157
158#[derive(Debug, Clone)]
159pub struct NapiStructuredEnumVariant {
160  pub name: Ident,
161  pub fields: Vec<NapiStructField>,
162  pub is_tuple: bool,
163}
164
165#[derive(Debug, Clone)]
166pub struct NapiStructField {
167  pub name: syn::Member,
168  pub js_name: String,
169  pub symbol_for: Option<(String, Span)>,
170  /// The `Symbol` member name, e.g. `iterator` for `Symbol.iterator`.
171  pub well_known_symbol: Option<(String, Span)>,
172  pub ty: syn::Type,
173  pub getter: bool,
174  pub setter: bool,
175  pub writable: bool,
176  pub enumerable: bool,
177  pub configurable: bool,
178  pub comments: Vec<String>,
179  pub skip_typescript: bool,
180  pub ts_type: Option<String>,
181  pub has_lifetime: bool,
182}
183
184#[derive(Debug, Clone)]
185pub struct NapiImpl {
186  pub name: Ident,
187  pub js_name: String,
188  pub has_lifetime: bool,
189  pub items: Vec<NapiFn>,
190  pub task_output_type: Option<Type>,
191  pub iterator_yield_type: Option<Type>,
192  pub iterator_next_type: Option<Type>,
193  pub iterator_return_type: Option<Type>,
194  pub async_iterator_yield_type: Option<Type>,
195  pub async_iterator_next_type: Option<Type>,
196  pub async_iterator_return_type: Option<Type>,
197  pub js_mod: Option<String>,
198  pub comments: Vec<String>,
199  pub register_name: Ident,
200}
201
202#[derive(Debug, Clone)]
203pub struct NapiEnum {
204  pub name: Ident,
205  pub js_name: String,
206  pub variants: Vec<NapiEnumVariant>,
207  pub js_mod: Option<String>,
208  pub comments: Vec<String>,
209  pub skip_typescript: bool,
210  pub register_name: Ident,
211  pub is_string_enum: bool,
212  pub object_from_js: bool,
213  pub object_to_js: bool,
214}
215
216#[derive(Debug, Clone)]
217pub enum NapiEnumValue {
218  String(String),
219  Number(i32),
220}
221
222impl From<&NapiEnumValue> for Literal {
223  fn from(val: &NapiEnumValue) -> Self {
224    match val {
225      NapiEnumValue::String(string) => Literal::string(string),
226      NapiEnumValue::Number(number) => Literal::i32_unsuffixed(number.to_owned()),
227    }
228  }
229}
230
231#[derive(Debug, Clone)]
232pub struct NapiEnumVariant {
233  pub name: Ident,
234  pub val: NapiEnumValue,
235  pub comments: Vec<String>,
236}
237
238#[derive(Debug, Clone)]
239pub struct NapiConst {
240  pub name: Ident,
241  pub js_name: String,
242  pub type_name: Type,
243  pub value: Expr,
244  pub js_mod: Option<String>,
245  pub comments: Vec<String>,
246  pub skip_typescript: bool,
247  pub register_name: Ident,
248}
249
250#[derive(Debug, Clone)]
251pub struct NapiMod {
252  pub name: Ident,
253  pub js_name: String,
254}
255
256#[derive(Debug, Clone)]
257pub struct NapiType {
258  pub name: Ident,
259  pub js_name: String,
260  pub value: Type,
261  pub register_name: Ident,
262  pub skip_typescript: bool,
263  pub js_mod: Option<String>,
264  pub comments: Vec<String>,
265}