Skip to content
This repository was archived by the owner on Nov 5, 2024. It is now read-only.

Commit a7e6c63

Browse files
committed
use custom ctors for all kinds of JS objects
1 parent 914aa6e commit a7e6c63

File tree

4 files changed

+252
-77
lines changed

4 files changed

+252
-77
lines changed

build-convert/build.rs

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ fn field_name(f: &Field) -> String {
3131
}
3232

3333
fn build_converter(node: &Node) -> String {
34-
let set_fields: Vec<String> = node
34+
let fields: Vec<String> = node
3535
.fields
3636
.iter()
3737
.map(|f| {
3838
format!(
39-
"obj.Set(\"{name}\", convert(std::move(node->{name}), env));",
39+
"convert(std::move(node->{name}), env),",
4040
name = field_name(f)
4141
)
4242
})
@@ -47,22 +47,68 @@ fn build_converter(node: &Node) -> String {
4747
if (!node) {{
4848
return env.Null();
4949
}}
50-
Napi::Object obj = Napi::Object::New(env);
51-
obj.Set(\"type\", \"{class_name}\");
52-
{set_fields}
53-
return obj;
50+
return {class_name}Ctor.New({{
51+
{fields}
52+
}});
5453
}}",
5554
class_name = node.struct_name,
55+
fields = fields.join("\n ")
56+
)
57+
}
58+
59+
fn ctor_definition(node: &Node) -> String {
60+
format!("Napi::FunctionReference {}Ctor;", node.struct_name)
61+
}
62+
63+
fn ctor_fn_definition(node: &Node) -> String {
64+
let set_fields: Vec<String> = node
65+
.fields
66+
.iter()
67+
.enumerate()
68+
.map(|(idx, f)| {
69+
format!(
70+
"self.Set(\"{name}\", info[{idx}]);",
71+
name = field_name(f),
72+
idx = idx
73+
)
74+
})
75+
.collect();
76+
77+
format!(
78+
"Napi::Value {name}CtorFn(const Napi::CallbackInfo &info)
79+
{{
80+
Napi::Object self = info.This().As<Napi::Object>();
81+
Napi::Env env = info.Env();
82+
{set_fields}
83+
return env.Null();
84+
}}
85+
",
86+
name = node.struct_name,
5687
set_fields = set_fields.join("\n ")
5788
)
5889
}
5990

91+
fn init_exports(node: &Node) -> String {
92+
format!(
93+
"fn = Napi::Function::New(env, {name}CtorFn, \"{name}\");
94+
{name}Ctor = Napi::Persistent(fn);
95+
{name}Ctor.SuppressDestruct();
96+
exports.Set(\"{name}\", fn);
97+
",
98+
name = node.struct_name
99+
)
100+
}
101+
60102
fn main() {
61103
let path = relative_path("../convert_gen.h");
62104
let nodes = lib_ruby_parser_nodes::nodes().unwrap();
63105

106+
let ctor_definitions: Vec<String> = nodes.iter().map(ctor_definition).collect();
107+
let ctor_fn_definitions: Vec<String> = nodes.iter().map(ctor_fn_definition).collect();
108+
64109
let converters: Vec<String> = nodes.iter().map(build_converter).collect();
65110
let comparisons: Vec<String> = nodes.iter().map(build_comparison).collect();
111+
let init_exports: Vec<String> = nodes.iter().map(init_exports).collect();
66112

67113
let contents = format!(
68114
"#ifndef LIB_RUBY_PARSER_CONVERT_GEN_H
@@ -78,6 +124,9 @@ template<class> inline constexpr bool always_false_v = false;
78124
79125
namespace lib_ruby_parser_node
80126
{{
127+
{ctor_definitions}
128+
{ctor_fn_definitions}
129+
81130
Napi::Value convert(std::unique_ptr<Node> node, Napi::Env env);
82131
Napi::Value convert(Node node, Napi::Env env);
83132
Napi::Value convert(std::unique_ptr<Range> range, Napi::Env env);
@@ -126,12 +175,21 @@ namespace lib_ruby_parser_node
126175
static_assert(always_false_v<T>, \"non-exhaustive visitor!\");
127176
}}, node.inner);
128177
}}
178+
179+
void InitNodeTypes(Napi::Env env, Napi::Object exports) {{
180+
Napi::Function fn;
181+
182+
{init_exports}
183+
}}
129184
}} // namespace lib_ruby_parser_node
130185
131186
#endif // LIB_RUBY_PARSER_CONVERT_GEN_H
132187
",
133188
converters = converters.join("\n "),
134189
comparisons = comparisons.join("\n else "),
190+
ctor_definitions = ctor_definitions.join("\n "),
191+
ctor_fn_definitions = ctor_fn_definitions.join("\n "),
192+
init_exports = init_exports.join("\n ")
135193
);
136194

137195
std::fs::write(&path, &contents).unwrap();

0 commit comments

Comments
 (0)