1+ import assert from "node:assert/strict" ;
12import fs from "node:fs" ;
23import path from "node:path" ;
34import cp from "node:child_process" ;
78 getNodeApiFunctions ,
89} from "../src/node-api-functions.js" ;
910
11+ import * as weakNodeApiGenerator from "./generators/weak-node-api.js" ;
12+
1013export const OUTPUT_PATH = path . join ( import . meta. dirname , "../generated" ) ;
1114
1215type GenerateFileOptions = {
@@ -20,10 +23,18 @@ async function generateFile({
2023 fileName,
2124 generator,
2225} : GenerateFileOptions ) {
23- const output = generator ( functions ) ;
26+ const generated = generator ( functions ) ;
27+ const output = `// This file is generated - don't edit it directly\n\n${ generated } ` ;
2428 const outputPath = path . join ( OUTPUT_PATH , fileName ) ;
2529 await fs . promises . writeFile ( outputPath , output , "utf-8" ) ;
26- cp . spawnSync ( "clang-format" , [ "-i" , outputPath ] , { stdio : "inherit" } ) ;
30+ const { status, stderr = "No error output" } = cp . spawnSync (
31+ "clang-format" ,
32+ [ "-i" , outputPath ] ,
33+ {
34+ encoding : "utf8" ,
35+ } ,
36+ ) ;
37+ assert . equal ( status , 0 , `Failed to format ${ fileName } : ${ stderr } ` ) ;
2738}
2839
2940async function run ( ) {
@@ -33,92 +44,15 @@ async function run() {
3344 await generateFile ( {
3445 functions,
3546 fileName : "weak_node_api.hpp" ,
36- generator : generateHeader ,
47+ generator : weakNodeApiGenerator . generateHeader ,
3748 } ) ;
3849 await generateFile ( {
3950 functions,
4051 fileName : "weak_node_api.cpp" ,
41- generator : generateSource ,
52+ generator : weakNodeApiGenerator . generateSource ,
4253 } ) ;
4354}
4455
45- export function generateFunctionDecl ( {
46- returnType,
47- name,
48- argumentTypes,
49- } : FunctionDecl ) {
50- return `${ returnType } (*${ name } )(${ argumentTypes . join ( ", " ) } );` ;
51- }
52-
53- /**
54- * Generates source code for a version script for the given Node API version.
55- */
56- export function generateHeader ( functions : FunctionDecl [ ] ) {
57- return `
58- // This file is generated by react-native-node-api
59- #include <node_api.h> // Node-API
60- #include <stdio.h> // fprintf()
61- #include <stdlib.h> // abort()
62-
63- // Ideally we would have just used NAPI_NO_RETURN, but
64- // __declspec(noreturn) (when building with Microsoft Visual C++) cannot be used on members of a struct
65- // TODO: If we targeted C++23 we could use std::unreachable()
66-
67- #if defined(__GNUC__)
68- #define WEAK_NODE_API_UNREACHABLE __builtin_unreachable();
69- #else
70- #define WEAK_NODE_API_UNREACHABLE __assume(0);
71- #endif
72-
73- // Generate the struct of function pointers
74- struct WeakNodeApiHost {
75- ${ functions . map ( generateFunctionDecl ) . join ( "\n" ) }
76- };
77- typedef void(*InjectHostFunction)(const WeakNodeApiHost&);
78- extern "C" void inject_weak_node_api_host(const WeakNodeApiHost& host);
79- ` ;
80- }
81-
82- function generateFunctionImpl ( {
83- returnType,
84- name,
85- argumentTypes,
86- noReturn,
87- } : FunctionDecl ) {
88- return `
89- extern "C" ${ returnType } ${ name } (
90- ${ argumentTypes . map ( ( type , index ) => `${ type } arg${ index } ` ) . join ( ", " ) }
91- ) {
92- if (g_host.${ name } == nullptr) {
93- fprintf(stderr, "Node-API function '${ name } ' called before it was injected!\\n");
94- abort();
95- }
96- ${ returnType === "void" ? "" : "return " } g_host.${ name } (
97- ${ argumentTypes . map ( ( _ , index ) => `arg${ index } ` ) . join ( ", " ) }
98- );
99- ${ noReturn ? "WEAK_NODE_API_UNREACHABLE" : "" }
100- };
101- ` ;
102- }
103-
104- /**
105- * Generates source code for a version script for the given Node API version.
106- */
107- export function generateSource ( functions : FunctionDecl [ ] ) {
108- return `
109- // This file is generated by react-native-node-api
110- #include "weak_node_api.hpp" // Generated header
111-
112- WeakNodeApiHost g_host;
113- void inject_weak_node_api_host(const WeakNodeApiHost& host) {
114- g_host = host;
115- };
116-
117- // Generate function calling into the host
118- ${ functions . map ( generateFunctionImpl ) . join ( "\n" ) }
119- ` ;
120- }
121-
12256run ( ) . catch ( ( err ) => {
12357 console . error ( err ) ;
12458 process . exitCode = 1 ;
0 commit comments