@react-native-windows/codegen 0.70.0 → 0.71.0-preview.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +97 -10
- package/lib-commonjs/Cli.js +18 -187
- package/lib-commonjs/Cli.js.map +1 -1
- package/lib-commonjs/generators/AliasGen.d.ts +1 -1
- package/lib-commonjs/generators/AliasGen.js.map +1 -1
- package/lib-commonjs/generators/AliasManaging.d.ts +1 -1
- package/lib-commonjs/generators/AliasManaging.js.map +1 -1
- package/lib-commonjs/generators/GenerateNM2.d.ts +3 -3
- package/lib-commonjs/generators/GenerateNM2.js +2 -2
- package/lib-commonjs/generators/GenerateNM2.js.map +1 -1
- package/lib-commonjs/generators/GenerateTypeScript.d.ts +1 -1
- package/lib-commonjs/generators/GenerateTypeScript.js.map +1 -1
- package/lib-commonjs/generators/ObjectTypes.d.ts +1 -1
- package/lib-commonjs/generators/ObjectTypes.js.map +1 -1
- package/lib-commonjs/generators/ParamTypes.d.ts +1 -1
- package/lib-commonjs/generators/ParamTypes.js.map +1 -1
- package/lib-commonjs/generators/ReturnTypes.d.ts +1 -1
- package/lib-commonjs/generators/ReturnTypes.js.map +1 -1
- package/lib-commonjs/generators/ValidateConstants.d.ts +1 -1
- package/lib-commonjs/generators/ValidateConstants.js.map +1 -1
- package/lib-commonjs/generators/ValidateMethods.d.ts +1 -1
- package/lib-commonjs/generators/ValidateMethods.js +2 -2
- package/lib-commonjs/generators/ValidateMethods.js.map +1 -1
- package/lib-commonjs/index.d.ts +39 -0
- package/lib-commonjs/index.js +209 -0
- package/lib-commonjs/index.js.map +1 -0
- package/package.json +18 -15
- package/src/Cli.ts +18 -279
- package/src/generators/AliasGen.ts +1 -1
- package/src/generators/AliasManaging.ts +1 -1
- package/src/generators/GenerateNM2.ts +4 -4
- package/src/generators/GenerateTypeScript.ts +1 -1
- package/src/generators/ObjectTypes.ts +4 -1
- package/src/generators/ParamTypes.ts +1 -1
- package/src/generators/ReturnTypes.ts +1 -1
- package/src/generators/ValidateConstants.ts +1 -1
- package/src/generators/ValidateMethods.ts +3 -3
- package/src/index.ts +363 -0
package/src/Cli.ts
CHANGED
|
@@ -6,18 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import yargs from 'yargs';
|
|
9
|
-
import
|
|
10
|
-
import fs from '@react-native-windows/fs';
|
|
11
|
-
import globby from 'globby';
|
|
12
|
-
import {createNM2Generator} from './generators/GenerateNM2';
|
|
13
|
-
import {
|
|
14
|
-
generateTypeScript,
|
|
15
|
-
setOptionalTurboModule,
|
|
16
|
-
} from './generators/GenerateTypeScript';
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
import {parseFile} from 'react-native-tscodegen/lib/rncodegen/src/parsers/flow';
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
import schemaValidator from 'react-native-tscodegen/lib/rncodegen/src/schemaValidator';
|
|
9
|
+
import {runCodeGen} from './index';
|
|
21
10
|
|
|
22
11
|
const argv = yargs.options({
|
|
23
12
|
file: {
|
|
@@ -25,20 +14,31 @@ const argv = yargs.options({
|
|
|
25
14
|
describe: 'file which contains spec',
|
|
26
15
|
},
|
|
27
16
|
files: {
|
|
28
|
-
type: '
|
|
17
|
+
type: 'string',
|
|
18
|
+
array: true,
|
|
29
19
|
describe: 'glob patterns for files which contains specs',
|
|
30
20
|
},
|
|
31
|
-
|
|
21
|
+
modulesTypeScriptTypes: {
|
|
32
22
|
type: 'boolean',
|
|
33
23
|
describe: 'generate turbo module definition files in TypeScript',
|
|
34
24
|
default: false,
|
|
35
25
|
},
|
|
36
|
-
|
|
26
|
+
modulesCxx: {
|
|
27
|
+
type: 'boolean',
|
|
28
|
+
describe: 'generate C++ JSI turbo module spec files',
|
|
29
|
+
default: false,
|
|
30
|
+
},
|
|
31
|
+
modulesWindows: {
|
|
32
|
+
type: 'boolean',
|
|
33
|
+
describe: 'generate turbo module spec files for REACT_MODULE',
|
|
34
|
+
default: false,
|
|
35
|
+
},
|
|
36
|
+
methodOnly: {
|
|
37
37
|
type: 'boolean',
|
|
38
38
|
describe: 'generate only method metadata in C++ turbo module spec',
|
|
39
39
|
default: false,
|
|
40
40
|
},
|
|
41
|
-
|
|
41
|
+
outputDirectory: {
|
|
42
42
|
type: 'string',
|
|
43
43
|
describe: 'output directory',
|
|
44
44
|
default: 'codegen',
|
|
@@ -46,6 +46,7 @@ const argv = yargs.options({
|
|
|
46
46
|
test: {
|
|
47
47
|
type: 'boolean',
|
|
48
48
|
describe: 'Verify that the generated output is unchanged',
|
|
49
|
+
default: false,
|
|
49
50
|
},
|
|
50
51
|
namespace: {
|
|
51
52
|
type: 'string',
|
|
@@ -59,271 +60,9 @@ const argv = yargs.options({
|
|
|
59
60
|
},
|
|
60
61
|
}).argv;
|
|
61
62
|
|
|
62
|
-
import {SchemaType} from 'react-native-tscodegen';
|
|
63
|
-
|
|
64
|
-
interface Options {
|
|
65
|
-
libraryName: string;
|
|
66
|
-
schema: SchemaType;
|
|
67
|
-
outputDirectory: string;
|
|
68
|
-
moduleSpecName: string;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface Config {
|
|
72
|
-
generators: any[] /*Generators[]*/;
|
|
73
|
-
test?: boolean;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/*
|
|
77
|
-
const GENERATORS = {
|
|
78
|
-
descriptors: [generateComponentDescriptorH.generate],
|
|
79
|
-
events: [
|
|
80
|
-
generateEventEmitterCpp.generate,
|
|
81
|
-
generateEventEmitterH.generate,
|
|
82
|
-
generateModuleHObjCpp.generate,
|
|
83
|
-
generateModuleMm.generate,
|
|
84
|
-
],
|
|
85
|
-
props: [
|
|
86
|
-
generateComponentHObjCpp.generate,
|
|
87
|
-
generatePropsCpp.generate,
|
|
88
|
-
generatePropsH.generate,
|
|
89
|
-
generatePropsJavaInterface.generate,
|
|
90
|
-
generatePropsJavaDelegate.generate,
|
|
91
|
-
],
|
|
92
|
-
modules: [generateModuleCpp.generate, generateModuleH.generate],
|
|
93
|
-
tests: [generateTests.generate],
|
|
94
|
-
'shadow-nodes': [
|
|
95
|
-
generateShadowNodeCpp.generate,
|
|
96
|
-
generateShadowNodeH.generate,
|
|
97
|
-
],
|
|
98
|
-
};
|
|
99
|
-
*/
|
|
100
|
-
|
|
101
|
-
function normalizeFileMap(
|
|
102
|
-
map: Map<string, string>,
|
|
103
|
-
outputDir: string,
|
|
104
|
-
outMap: Map<string, string>,
|
|
105
|
-
): void {
|
|
106
|
-
for (const [fileName, contents] of map) {
|
|
107
|
-
const location = path.join(outputDir, fileName);
|
|
108
|
-
outMap.set(path.normalize(location), contents);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function checkFilesForChanges(
|
|
113
|
-
map: Map<string, string>,
|
|
114
|
-
outputDir: string,
|
|
115
|
-
): boolean {
|
|
116
|
-
let hasChanges = false;
|
|
117
|
-
|
|
118
|
-
const allExistingFiles = globby
|
|
119
|
-
.sync(`${outputDir}/**`)
|
|
120
|
-
.map(_ => path.normalize(_))
|
|
121
|
-
.sort();
|
|
122
|
-
const allGeneratedFiles = [...map.keys()].map(_ => path.normalize(_)).sort();
|
|
123
|
-
|
|
124
|
-
if (
|
|
125
|
-
allExistingFiles.length !== allGeneratedFiles.length ||
|
|
126
|
-
!allExistingFiles.every((val, index) => val === allGeneratedFiles[index])
|
|
127
|
-
)
|
|
128
|
-
return true;
|
|
129
|
-
|
|
130
|
-
for (const [fileName, contents] of map) {
|
|
131
|
-
if (!fs.existsSync(fileName)) {
|
|
132
|
-
hasChanges = true;
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const currentContents = fs.readFileSync(fileName, 'utf8');
|
|
137
|
-
if (currentContents !== contents) {
|
|
138
|
-
console.error(`- ${fileName} has changed`);
|
|
139
|
-
hasChanges = true;
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return hasChanges;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function writeMapToFiles(map: Map<string, string>, outputDir: string) {
|
|
148
|
-
let success = true;
|
|
149
|
-
|
|
150
|
-
// This ensures that we delete any generated files from modules that have been deleted
|
|
151
|
-
const allExistingFiles = globby.sync(`${outputDir}/**`);
|
|
152
|
-
allExistingFiles.forEach(existingFile => {
|
|
153
|
-
if (!map.has(path.normalize(existingFile))) {
|
|
154
|
-
fs.unlinkSync(existingFile);
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
for (const [fileName, contents] of map) {
|
|
159
|
-
try {
|
|
160
|
-
fs.mkdirSync(path.dirname(fileName), {recursive: true});
|
|
161
|
-
|
|
162
|
-
if (fs.existsSync(fileName)) {
|
|
163
|
-
const currentContents = fs.readFileSync(fileName, 'utf8');
|
|
164
|
-
// Don't update the files if there are no changes as this breaks incremental builds
|
|
165
|
-
if (currentContents === contents) {
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
fs.writeFileSync(fileName, contents);
|
|
171
|
-
} catch (error) {
|
|
172
|
-
success = false;
|
|
173
|
-
console.error(`Failed to write ${fileName} to ${fileName}`, error);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return success;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function parseFlowFile(filename: string): SchemaType {
|
|
181
|
-
try {
|
|
182
|
-
const schema = parseFile(filename);
|
|
183
|
-
// there will be at most one turbo module per file
|
|
184
|
-
const moduleName = Object.keys(schema.modules)[0];
|
|
185
|
-
if (moduleName) {
|
|
186
|
-
const spec = schema.modules[moduleName];
|
|
187
|
-
if (spec.type === 'NativeModule') {
|
|
188
|
-
const contents = fs.readFileSync(filename, 'utf8');
|
|
189
|
-
if (contents) {
|
|
190
|
-
// This is a temporary implementation until such information is added to the schema in facebook/react-native
|
|
191
|
-
if (contents.includes('TurboModuleRegistry.get<')) {
|
|
192
|
-
setOptionalTurboModule(spec, true);
|
|
193
|
-
} else if (contents.includes('TurboModuleRegistry.getEnforcing<')) {
|
|
194
|
-
setOptionalTurboModule(spec, false);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return schema;
|
|
200
|
-
} catch (e) {
|
|
201
|
-
if (e instanceof Error) {
|
|
202
|
-
e.message = `(${filename}): ${e.message}`;
|
|
203
|
-
}
|
|
204
|
-
throw e;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function combineSchemas(files: string[]): SchemaType {
|
|
209
|
-
return files.reduce(
|
|
210
|
-
(merged, filename) => {
|
|
211
|
-
const contents = fs.readFileSync(filename, 'utf8');
|
|
212
|
-
if (
|
|
213
|
-
contents &&
|
|
214
|
-
(/export\s+default\s+\(?codegenNativeComponent</.test(contents) ||
|
|
215
|
-
contents.includes('extends TurboModule'))
|
|
216
|
-
) {
|
|
217
|
-
const schema = parseFlowFile(filename);
|
|
218
|
-
merged.modules = {...merged.modules, ...schema.modules};
|
|
219
|
-
}
|
|
220
|
-
return merged;
|
|
221
|
-
},
|
|
222
|
-
{modules: {}},
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function generate(
|
|
227
|
-
{libraryName, schema, outputDirectory, moduleSpecName}: Options,
|
|
228
|
-
{/*generators,*/ test}: Config,
|
|
229
|
-
): boolean {
|
|
230
|
-
schemaValidator.validate(schema);
|
|
231
|
-
|
|
232
|
-
const componentOutputdir = path.join(
|
|
233
|
-
outputDirectory,
|
|
234
|
-
'react/components',
|
|
235
|
-
libraryName,
|
|
236
|
-
);
|
|
237
|
-
|
|
238
|
-
const generatedFiles = new Map<string, string>();
|
|
239
|
-
|
|
240
|
-
generatedFiles.set(
|
|
241
|
-
path.join(outputDirectory, '.clang-format'),
|
|
242
|
-
'DisableFormat: true\nSortIncludes: false',
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
const generateNM2 = createNM2Generator({
|
|
246
|
-
namespace: argv.namespace,
|
|
247
|
-
methodonly: argv.methodonly,
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
const generatorPropsH =
|
|
251
|
-
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsH').generate;
|
|
252
|
-
const generatorPropsCPP =
|
|
253
|
-
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsCPP').generate;
|
|
254
|
-
const generatorShadowNodeH =
|
|
255
|
-
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeH').generate;
|
|
256
|
-
const generatorShadowNodeCPP =
|
|
257
|
-
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeCPP').generate;
|
|
258
|
-
const generatorComponentDescriptorH =
|
|
259
|
-
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateComponentDescriptorH').generate;
|
|
260
|
-
const generatorEventEmitterH =
|
|
261
|
-
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterH').generate;
|
|
262
|
-
const generatorEventEmitterCPP =
|
|
263
|
-
require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterCpp').generate;
|
|
264
|
-
|
|
265
|
-
normalizeFileMap(
|
|
266
|
-
generateNM2(libraryName, schema, moduleSpecName),
|
|
267
|
-
outputDirectory,
|
|
268
|
-
generatedFiles,
|
|
269
|
-
);
|
|
270
|
-
|
|
271
|
-
if (argv.ts) {
|
|
272
|
-
normalizeFileMap(
|
|
273
|
-
generateTypeScript(libraryName, schema, moduleSpecName),
|
|
274
|
-
outputDirectory,
|
|
275
|
-
generatedFiles,
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (
|
|
280
|
-
Object.keys(schema.modules).some(
|
|
281
|
-
moduleName => schema.modules[moduleName].type === 'Component',
|
|
282
|
-
)
|
|
283
|
-
) {
|
|
284
|
-
const componentGenerators = [
|
|
285
|
-
generatorPropsH,
|
|
286
|
-
generatorPropsCPP,
|
|
287
|
-
generatorShadowNodeH,
|
|
288
|
-
generatorShadowNodeCPP,
|
|
289
|
-
generatorComponentDescriptorH,
|
|
290
|
-
generatorEventEmitterH,
|
|
291
|
-
generatorEventEmitterCPP,
|
|
292
|
-
];
|
|
293
|
-
|
|
294
|
-
componentGenerators.forEach(generator => {
|
|
295
|
-
const generated: Map<string, string> = generator(
|
|
296
|
-
libraryName,
|
|
297
|
-
schema,
|
|
298
|
-
moduleSpecName,
|
|
299
|
-
);
|
|
300
|
-
normalizeFileMap(generated, componentOutputdir, generatedFiles);
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (test === true) {
|
|
305
|
-
return checkFilesForChanges(generatedFiles, outputDirectory);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return writeMapToFiles(generatedFiles, outputDirectory);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
63
|
if ((argv.file && argv.files) || (!argv.file && !argv.files)) {
|
|
312
64
|
console.error('You must specify either --file or --files.');
|
|
313
65
|
process.exit(1);
|
|
314
66
|
}
|
|
315
67
|
|
|
316
|
-
|
|
317
|
-
if (argv.file) {
|
|
318
|
-
schema = parseFlowFile(argv.file);
|
|
319
|
-
} else {
|
|
320
|
-
schema = combineSchemas(globby.sync(argv.files as string[]));
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const libraryName = argv.libraryName;
|
|
324
|
-
const moduleSpecName = 'moduleSpecName';
|
|
325
|
-
const outputDirectory = argv.outdir;
|
|
326
|
-
generate(
|
|
327
|
-
{libraryName, schema, outputDirectory, moduleSpecName},
|
|
328
|
-
{generators: [], test: false},
|
|
329
|
-
);
|
|
68
|
+
runCodeGen(argv);
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
import {SchemaType} from 'react-native-tscodegen';
|
|
9
|
+
import type {SchemaType} from 'react-native-tscodegen';
|
|
10
10
|
import {AliasMap, setPreferredModuleName} from './AliasManaging';
|
|
11
11
|
import {createAliasMap, generateAliases} from './AliasGen';
|
|
12
12
|
import {generateValidateConstants} from './ValidateConstants';
|
|
@@ -44,11 +44,11 @@ struct ::_MODULE_NAME_::Spec : winrt::Microsoft::ReactNative::TurboModuleSpec {
|
|
|
44
44
|
`;
|
|
45
45
|
|
|
46
46
|
export function createNM2Generator({
|
|
47
|
+
methodOnly,
|
|
47
48
|
namespace,
|
|
48
|
-
methodonly,
|
|
49
49
|
}: {
|
|
50
|
+
methodOnly: boolean;
|
|
50
51
|
namespace: string;
|
|
51
|
-
methodonly: boolean;
|
|
52
52
|
}) {
|
|
53
53
|
return (
|
|
54
54
|
_libraryName: string,
|
|
@@ -85,7 +85,7 @@ ${methods[0]}
|
|
|
85
85
|
|
|
86
86
|
// prepare constants
|
|
87
87
|
const constants = generateValidateConstants(nativeModule, aliases);
|
|
88
|
-
if (constants !== undefined && !
|
|
88
|
+
if (constants !== undefined && !methodOnly) {
|
|
89
89
|
tuples = `
|
|
90
90
|
static constexpr auto constants = std::tuple{
|
|
91
91
|
${constants[0]}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
import {NativeModuleSchema} from 'react-native-tscodegen';
|
|
9
|
+
import type {NativeModuleSchema} from 'react-native-tscodegen';
|
|
10
10
|
import {AliasMap, getAnonymousAliasCppName} from './AliasManaging';
|
|
11
11
|
|
|
12
12
|
export function generateValidateConstants(
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import type {
|
|
10
10
|
NativeModuleFunctionTypeAnnotation,
|
|
11
11
|
NativeModulePropertyShape,
|
|
12
12
|
NativeModuleSchema,
|
|
@@ -45,7 +45,7 @@ function getPossibleMethodSignatures(
|
|
|
45
45
|
funcType.returnTypeAnnotation,
|
|
46
46
|
aliases,
|
|
47
47
|
baseAliasName,
|
|
48
|
-
)} ${prop.name}(${args.join(', ')}) noexcept { /* implementation */ }
|
|
48
|
+
)} ${prop.name}(${args.join(', ')}) noexcept { /* implementation */ }`;
|
|
49
49
|
|
|
50
50
|
const staticsig = `REACT_${isMethodSync(funcType) ? 'SYNC_' : ''}METHOD(${
|
|
51
51
|
prop.name
|
|
@@ -53,7 +53,7 @@ function getPossibleMethodSignatures(
|
|
|
53
53
|
funcType.returnTypeAnnotation,
|
|
54
54
|
aliases,
|
|
55
55
|
baseAliasName,
|
|
56
|
-
)} ${prop.name}(${args.join(', ')}) noexcept { /* implementation */ }
|
|
56
|
+
)} ${prop.name}(${args.join(', ')}) noexcept { /* implementation */ }`;
|
|
57
57
|
|
|
58
58
|
return [sig, staticsig];
|
|
59
59
|
}
|