@react-native-windows/codegen 0.65.0 → 0.66.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.json CHANGED
@@ -2,30 +2,197 @@
2
2
  "name": "@react-native-windows/codegen",
3
3
  "entries": [
4
4
  {
5
- "date": "Mon, 23 Aug 2021 15:08:33 GMT",
6
- "tag": "@react-native-windows/codegen_v0.65.0",
7
- "version": "0.65.0",
5
+ "date": "Mon, 24 Jan 2022 16:10:41 GMT",
6
+ "tag": "@react-native-windows/codegen_v0.66.1",
7
+ "version": "0.66.1",
8
8
  "comments": {
9
9
  "patch": [
10
10
  {
11
- "comment": "Promote 0.65 to latest",
11
+ "comment": "Promote 0.66 to legacy",
12
12
  "author": "ngerlem@microsoft.com",
13
- "commit": "6b2df206699d51f2be4595391735344a2f53af01",
13
+ "commit": "919d91a3e9845f9a60417fb8e47a36d7caedbc28",
14
14
  "package": "@react-native-windows/codegen"
15
15
  }
16
16
  ]
17
17
  }
18
18
  },
19
19
  {
20
- "date": "Mon, 31 May 2021 15:23:18 GMT",
21
- "tag": "@react-native-windows/codegen_v0.65.0-preview.1",
22
- "version": "0.65.0-preview.1",
20
+ "date": "Mon, 11 Oct 2021 15:07:19 GMT",
21
+ "tag": "@react-native-windows/codegen_v0.66.0",
22
+ "version": "0.66.0",
23
+ "comments": {
24
+ "patch": [
25
+ {
26
+ "comment": "Promote 0.66 to latest",
27
+ "author": "ngerlem@microsoft.com",
28
+ "commit": "5d1e5ae98139204e02f0ac5d8c06ae7ee1157395",
29
+ "package": "@react-native-windows/codegen"
30
+ }
31
+ ]
32
+ }
33
+ },
34
+ {
35
+ "date": "Fri, 03 Sep 2021 18:48:19 GMT",
36
+ "tag": "@react-native-windows/codegen_v0.66.0-preview.1",
37
+ "version": "0.66.0-preview.1",
38
+ "comments": {
39
+ "prerelease": [
40
+ {
41
+ "comment": "Promote 0.66 to preview",
42
+ "author": "ngerlem@microsoft.com",
43
+ "commit": "cf1dcfbe108028869e326bb2bdab370949f7dac8",
44
+ "package": "@react-native-windows/codegen"
45
+ }
46
+ ]
47
+ }
48
+ },
49
+ {
50
+ "date": "Fri, 03 Sep 2021 05:06:04 GMT",
51
+ "tag": "@react-native-windows/codegen_v0.0.0-canary.11",
52
+ "version": "0.0.0-canary.11",
53
+ "comments": {
54
+ "prerelease": [
55
+ {
56
+ "comment": "Generate aliased struct for turbo module",
57
+ "author": "53799235+ZihanChen-MSFT@users.noreply.github.com",
58
+ "commit": "b23b6bd01813b9d4ab843f397b7611e3e22d8508",
59
+ "package": "@react-native-windows/codegen"
60
+ }
61
+ ]
62
+ }
63
+ },
64
+ {
65
+ "date": "Thu, 02 Sep 2021 05:08:16 GMT",
66
+ "tag": "@react-native-windows/codegen_v0.0.0-canary.10",
67
+ "version": "0.0.0-canary.10",
68
+ "comments": {
69
+ "none": [
70
+ {
71
+ "comment": "Remove path patch in rnw-codegen",
72
+ "author": "53799235+ZihanChen-MSFT@users.noreply.github.com",
73
+ "commit": "6cd806bb2486db76195edd47e949f6a9424fc6cb",
74
+ "package": "@react-native-windows/codegen"
75
+ }
76
+ ]
77
+ }
78
+ },
79
+ {
80
+ "date": "Fri, 27 Aug 2021 05:06:34 GMT",
81
+ "tag": "@react-native-windows/codegen_v0.0.0-canary.10",
82
+ "version": "0.0.0-canary.10",
83
+ "comments": {
84
+ "none": [
85
+ {
86
+ "comment": "Bump react-native-tscodegen to catch up react-native 0.65",
87
+ "author": "53799235+ZihanChen-MSFT@users.noreply.github.com",
88
+ "commit": "420edbedb4cbe4b40f2541e466f98bd9e177e26a",
89
+ "package": "@react-native-windows/codegen"
90
+ }
91
+ ]
92
+ }
93
+ },
94
+ {
95
+ "date": "Thu, 05 Aug 2021 05:07:20 GMT",
96
+ "tag": "@react-native-windows/codegen_v0.0.0-canary.10",
97
+ "version": "0.0.0-canary.10",
98
+ "comments": {
99
+ "prerelease": [
100
+ {
101
+ "comment": "Do not write codegen files if the contents have not changed, as this breaks incremental builds",
102
+ "author": "30809111+acoates-ms@users.noreply.github.com",
103
+ "commit": "3b92733ab97670e6eb2d944f65ff341994e80517",
104
+ "package": "@react-native-windows/codegen"
105
+ }
106
+ ]
107
+ }
108
+ },
109
+ {
110
+ "date": "Sat, 24 Jul 2021 05:05:52 GMT",
111
+ "tag": "@react-native-windows/codegen_v0.0.0-canary.9",
112
+ "version": "0.0.0-canary.9",
113
+ "comments": {
114
+ "none": [
115
+ {
116
+ "comment": "Replace @rnw-scripts/jest-out-of-tree-resolver with @rnx-kit/jest-resolver",
117
+ "author": "4123478+tido64@users.noreply.github.com",
118
+ "commit": "a311022ebc0c1d8070d7e54312197f486c470d33",
119
+ "package": "@react-native-windows/codegen"
120
+ }
121
+ ]
122
+ }
123
+ },
124
+ {
125
+ "date": "Fri, 11 Jun 2021 05:08:55 GMT",
126
+ "tag": "@react-native-windows/codegen_v0.0.0-canary.9",
127
+ "version": "0.0.0-canary.9",
128
+ "comments": {
129
+ "patch": [
130
+ {
131
+ "comment": "Bump @rnw-scripts/just-task to v2.2.0",
132
+ "author": "ngerlem@microsoft.com",
133
+ "commit": "3d7c8d8fcf14a3cbda83a93c85b0bcf1e4e4f829",
134
+ "package": "@react-native-windows/codegen"
135
+ }
136
+ ]
137
+ }
138
+ },
139
+ {
140
+ "date": "Wed, 09 Jun 2021 05:10:07 GMT",
141
+ "tag": "@react-native-windows/codegen_v0.0.0-canary.8",
142
+ "version": "0.0.0-canary.8",
143
+ "comments": {
144
+ "patch": [
145
+ {
146
+ "comment": "Bump @rnw-scripts/just-task to v2.1.3",
147
+ "author": "igklemen@microsoft.com",
148
+ "commit": "2ba41a4f087cc3bf16cbe799575923fc7a626009",
149
+ "package": "@react-native-windows/codegen"
150
+ },
151
+ {
152
+ "comment": "Bump @rnw-scripts/jest-unittest-config to v1.2.3",
153
+ "author": "igklemen@microsoft.com",
154
+ "commit": "2ba41a4f087cc3bf16cbe799575923fc7a626009",
155
+ "package": "@react-native-windows/codegen"
156
+ }
157
+ ]
158
+ }
159
+ },
160
+ {
161
+ "date": "Thu, 03 Jun 2021 05:09:47 GMT",
162
+ "tag": "@react-native-windows/codegen_v0.0.0-canary.7",
163
+ "version": "0.0.0-canary.7",
23
164
  "comments": {
24
165
  "prerelease": [
25
166
  {
26
- "comment": "Promote 0.65 to preview",
167
+ "comment": "Enable esModuleInterop Repo Wide",
168
+ "author": "ngerlem@microsoft.com",
169
+ "commit": "6c871e6ba27888804c776e5deeefbc7064e181d0",
170
+ "package": "@react-native-windows/codegen"
171
+ }
172
+ ],
173
+ "patch": [
174
+ {
175
+ "comment": "Bump @rnw-scripts/just-task to v2.1.2",
176
+ "author": "ngerlem@microsoft.com",
177
+ "commit": "b481f0a4ea68a8100860eb061902b715fca6652e",
178
+ "package": "@react-native-windows/codegen"
179
+ },
180
+ {
181
+ "comment": "Bump @rnw-scripts/ts-config to v2.0.0",
182
+ "author": "ngerlem@microsoft.com",
183
+ "commit": "6c871e6ba27888804c776e5deeefbc7064e181d0",
184
+ "package": "@react-native-windows/codegen"
185
+ },
186
+ {
187
+ "comment": "Bump @rnw-scripts/eslint-config to v1.1.7",
188
+ "author": "ngerlem@microsoft.com",
189
+ "commit": "b481f0a4ea68a8100860eb061902b715fca6652e",
190
+ "package": "@react-native-windows/codegen"
191
+ },
192
+ {
193
+ "comment": "Bump @rnw-scripts/jest-unittest-config to v1.2.2",
27
194
  "author": "ngerlem@microsoft.com",
28
- "commit": "3d6d7f00b51a68c7ab7c3b3e50cdb2be8b17929f",
195
+ "commit": "b481f0a4ea68a8100860eb061902b715fca6652e",
29
196
  "package": "@react-native-windows/codegen"
30
197
  }
31
198
  ]
package/CHANGELOG.md CHANGED
@@ -1,24 +1,80 @@
1
1
  # Change Log - @react-native-windows/codegen
2
2
 
3
- This log was last generated on Mon, 23 Aug 2021 15:08:33 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 24 Jan 2022 16:10:41 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## 0.65.0
7
+ ## 0.66.1
8
8
 
9
- Mon, 23 Aug 2021 15:08:33 GMT
9
+ Mon, 24 Jan 2022 16:10:41 GMT
10
10
 
11
11
  ### Patches
12
12
 
13
- - Promote 0.65 to latest (ngerlem@microsoft.com)
13
+ - Promote 0.66 to legacy (ngerlem@microsoft.com)
14
14
 
15
- ## 0.65.0-preview.1
15
+ ## 0.66.0
16
16
 
17
- Mon, 31 May 2021 15:23:18 GMT
17
+ Mon, 11 Oct 2021 15:07:19 GMT
18
+
19
+ ### Patches
20
+
21
+ - Promote 0.66 to latest (ngerlem@microsoft.com)
22
+
23
+ ## 0.66.0-preview.1
24
+
25
+ Fri, 03 Sep 2021 18:48:19 GMT
26
+
27
+ ### Changes
28
+
29
+ - Promote 0.66 to preview (ngerlem@microsoft.com)
30
+
31
+ ## 0.0.0-canary.11
32
+
33
+ Fri, 03 Sep 2021 05:06:04 GMT
34
+
35
+ ### Changes
36
+
37
+ - Generate aliased struct for turbo module (53799235+ZihanChen-MSFT@users.noreply.github.com)
38
+
39
+ ## 0.0.0-canary.10
40
+
41
+ Thu, 05 Aug 2021 05:07:20 GMT
42
+
43
+ ### Changes
44
+
45
+ - Do not write codegen files if the contents have not changed, as this breaks incremental builds (30809111+acoates-ms@users.noreply.github.com)
46
+
47
+ ## 0.0.0-canary.9
48
+
49
+ Fri, 11 Jun 2021 05:08:55 GMT
50
+
51
+ ### Patches
52
+
53
+ - Bump @rnw-scripts/just-task to v2.2.0 (ngerlem@microsoft.com)
54
+
55
+ ## 0.0.0-canary.8
56
+
57
+ Wed, 09 Jun 2021 05:10:07 GMT
58
+
59
+ ### Patches
60
+
61
+ - Bump @rnw-scripts/just-task to v2.1.3 (igklemen@microsoft.com)
62
+ - Bump @rnw-scripts/jest-unittest-config to v1.2.3 (igklemen@microsoft.com)
63
+
64
+ ## 0.0.0-canary.7
65
+
66
+ Thu, 03 Jun 2021 05:09:47 GMT
67
+
68
+ ### Patches
69
+
70
+ - Bump @rnw-scripts/just-task to v2.1.2 (ngerlem@microsoft.com)
71
+ - Bump @rnw-scripts/ts-config to v2.0.0 (ngerlem@microsoft.com)
72
+ - Bump @rnw-scripts/eslint-config to v1.1.7 (ngerlem@microsoft.com)
73
+ - Bump @rnw-scripts/jest-unittest-config to v1.2.2 (ngerlem@microsoft.com)
18
74
 
19
75
  ### Changes
20
76
 
21
- - Promote 0.65 to preview (ngerlem@microsoft.com)
77
+ - Enable esModuleInterop Repo Wide (ngerlem@microsoft.com)
22
78
 
23
79
  ## 0.0.0-canary.6
24
80
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native-windows/codegen",
3
- "version": "0.65.0",
3
+ "version": "0.66.1",
4
4
  "description": "Generators for react-native-codegen targeting react-native-windows",
5
5
  "main": "index.js",
6
6
  "repository": "https://github.com/microsoft/react-native-windows",
@@ -21,15 +21,15 @@
21
21
  "chalk": "^4.1.0",
22
22
  "globby": "^9.2.0",
23
23
  "mustache": "^4.0.1",
24
- "react-native-tscodegen": "0.66.1",
24
+ "react-native-tscodegen": "0.68.3",
25
25
  "source-map-support": "^0.5.19",
26
26
  "yargs": "^16.2.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@rnw-scripts/eslint-config": "1.1.6",
30
- "@rnw-scripts/jest-unittest-config": "1.2.1",
31
- "@rnw-scripts/just-task": "2.1.1",
32
- "@rnw-scripts/ts-config": "1.1.0",
29
+ "@rnw-scripts/eslint-config": "1.1.7",
30
+ "@rnw-scripts/jest-unittest-config": "1.2.3",
31
+ "@rnw-scripts/just-task": "2.2.0",
32
+ "@rnw-scripts/ts-config": "2.0.0",
33
33
  "@types/chalk": "^2.2.0",
34
34
  "@types/globby": "^9.1.0",
35
35
  "@types/jest": "^26.0.20",
@@ -43,7 +43,7 @@
43
43
  "typescript": "^3.8.3"
44
44
  },
45
45
  "beachball": {
46
- "defaultNpmTag": "latest",
46
+ "defaultNpmTag": "v0.66-stable",
47
47
  "disallowedChangeTypes": [
48
48
  "major",
49
49
  "minor",
package/src/Cli.ts CHANGED
@@ -5,15 +5,15 @@
5
5
  * @format
6
6
  */
7
7
 
8
- import * as yargs from 'yargs';
9
- import * as path from 'path';
10
- import * as fs from 'fs';
11
- import * as globby from 'globby';
8
+ import yargs from 'yargs';
9
+ import path from 'path';
10
+ import fs from 'fs';
11
+ import globby from 'globby';
12
12
  import {createNM2Generator} from './generators/GenerateNM2';
13
13
  // @ts-ignore
14
14
  import {parseFile} from 'react-native-tscodegen/lib/rncodegen/src/parsers/flow';
15
15
  // @ts-ignore
16
- import * as schemaValidator from 'react-native-tscodegen/lib/rncodegen/src/schemaValidator';
16
+ import schemaValidator from 'react-native-tscodegen/lib/rncodegen/src/schemaValidator';
17
17
 
18
18
  const argv = yargs.options({
19
19
  file: {
@@ -79,20 +79,42 @@ const GENERATORS = {
79
79
  };
80
80
  */
81
81
 
82
+ function normalizeFileMap(
83
+ map: Map<string, string>,
84
+ outputDir: string,
85
+ outMap: Map<string, string>,
86
+ ): void {
87
+ for (const [fileName, contents] of map) {
88
+ const location = path.join(outputDir, fileName);
89
+ outMap.set(path.normalize(location), contents);
90
+ }
91
+ }
92
+
82
93
  function checkFilesForChanges(
83
94
  map: Map<string, string>,
84
95
  outputDir: string,
85
96
  ): boolean {
86
97
  let hasChanges = false;
87
98
 
88
- for (const [contents, fileName] of map) {
89
- const location = path.join(outputDir, fileName);
90
- if (!fs.existsSync(location)) {
99
+ const allExistingFiles = globby
100
+ .sync(`${outputDir}/**`)
101
+ .map(_ => path.normalize(_))
102
+ .sort();
103
+ const allGeneratedFiles = [...map.keys()].map(_ => path.normalize(_)).sort();
104
+
105
+ if (
106
+ allExistingFiles.length !== allGeneratedFiles.length ||
107
+ !allExistingFiles.every((val, index) => val === allGeneratedFiles[index])
108
+ )
109
+ return true;
110
+
111
+ for (const [fileName, contents] of map) {
112
+ if (!fs.existsSync(fileName)) {
91
113
  hasChanges = true;
92
114
  continue;
93
115
  }
94
116
 
95
- const currentContents = fs.readFileSync(location, 'utf8');
117
+ const currentContents = fs.readFileSync(fileName, 'utf8');
96
118
  if (currentContents !== contents) {
97
119
  console.error(`- ${fileName} has changed`);
98
120
  hasChanges = true;
@@ -105,20 +127,48 @@ function checkFilesForChanges(
105
127
 
106
128
  function writeMapToFiles(map: Map<string, string>, outputDir: string) {
107
129
  let success = true;
108
- map.forEach((contents: string, fileName: string) => {
130
+
131
+ // This ensures that we delete any generated files from modules that have been deleted
132
+ const allExistingFiles = globby.sync(`${outputDir}/**`);
133
+ allExistingFiles.forEach(existingFile => {
134
+ if (!map.has(path.normalize(existingFile))) {
135
+ fs.unlinkSync(existingFile);
136
+ }
137
+ });
138
+
139
+ for (const [fileName, contents] of map) {
109
140
  try {
110
- const location = path.join(outputDir, fileName);
111
- fs.mkdirSync(path.dirname(location), {recursive: true});
112
- fs.writeFileSync(location, contents);
141
+ fs.mkdirSync(path.dirname(fileName), {recursive: true});
142
+
143
+ if (fs.existsSync(fileName)) {
144
+ const currentContents = fs.readFileSync(fileName, 'utf8');
145
+ // Don't update the files if there are no changes as this breaks incremental builds
146
+ if (currentContents === contents) {
147
+ continue;
148
+ }
149
+ }
150
+
151
+ fs.writeFileSync(fileName, contents);
113
152
  } catch (error) {
114
153
  success = false;
115
- console.error(`Failed to write ${fileName} to ${outputDir}`, error);
154
+ console.error(`Failed to write ${fileName} to ${fileName}`, error);
116
155
  }
117
- });
156
+ }
118
157
 
119
158
  return success;
120
159
  }
121
160
 
161
+ function parseFlowFile(filename: string): SchemaType {
162
+ try {
163
+ return parseFile(filename);
164
+ } catch (e) {
165
+ if (e instanceof Error) {
166
+ e.message = `(${filename}): ${e.message}`;
167
+ }
168
+ throw e;
169
+ }
170
+ }
171
+
122
172
  function combineSchemas(files: string[]): SchemaType {
123
173
  return files.reduce(
124
174
  (merged, filename) => {
@@ -128,11 +178,8 @@ function combineSchemas(files: string[]): SchemaType {
128
178
  (/export\s+default\s+\(?codegenNativeComponent</.test(contents) ||
129
179
  contents.includes('extends TurboModule'))
130
180
  ) {
131
- const schema = parseFile(filename);
132
-
133
- if (schema && schema.modules) {
134
- merged.modules = {...merged.modules, ...schema.modules};
135
- }
181
+ const schema = parseFlowFile(filename);
182
+ merged.modules = {...merged.modules, ...schema.modules};
136
183
  }
137
184
  return merged;
138
185
  },
@@ -152,15 +199,12 @@ function generate(
152
199
  libraryName,
153
200
  );
154
201
 
155
- const generatedModuleFiles = [];
156
- const generatedComponentFiles = [];
157
- /*
158
- for (const name of generators) {
159
- for (const generator of GENERATORS[name]) {
160
- generatedFiles.push(...generator(libraryName, schema, moduleSpecName));
161
- }
162
- }
163
- */
202
+ const generatedFiles = new Map<string, string>();
203
+
204
+ generatedFiles.set(
205
+ path.join(outputDirectory, '.clang-format'),
206
+ 'DisableFormat: true\nSortIncludes: false',
207
+ );
164
208
 
165
209
  const generateNM2 = createNM2Generator({namespace: argv.namespace});
166
210
  const generatorPropsH = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsH')
@@ -176,37 +220,35 @@ function generate(
176
220
  const generatorEventEmitterH = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterH')
177
221
  .generate;
178
222
 
179
- generatedModuleFiles.push(
180
- ...generateNM2(libraryName, schema, moduleSpecName),
223
+ normalizeFileMap(
224
+ generateNM2(libraryName, schema, moduleSpecName),
225
+ outputDirectory,
226
+ generatedFiles,
181
227
  );
182
228
 
183
- generatedComponentFiles.push(
184
- ...generatorPropsH(libraryName, schema, moduleSpecName),
185
- ...generatorPropsCPP(libraryName, schema, moduleSpecName),
186
- ...generatorShadowNodeH(libraryName, schema, moduleSpecName),
187
- ...generatorShadowNodeCPP(libraryName, schema, moduleSpecName),
188
- ...generatorComponentDescriptorH(libraryName, schema, moduleSpecName),
189
- ...generatorEventEmitterH(libraryName, schema, moduleSpecName),
190
- );
229
+ const componentGenerators = [
230
+ generatorPropsH,
231
+ generatorPropsCPP,
232
+ generatorShadowNodeH,
233
+ generatorShadowNodeCPP,
234
+ generatorComponentDescriptorH,
235
+ generatorEventEmitterH,
236
+ ];
191
237
 
192
- const moduleFilesToUpdate = new Map<string, string>([
193
- ...generatedModuleFiles,
194
- ]);
195
- const componentFilesToUpdate = new Map<string, string>([
196
- ...generatedComponentFiles,
197
- ]);
238
+ componentGenerators.forEach(generator => {
239
+ const generated: Map<string, string> = generator(
240
+ libraryName,
241
+ schema,
242
+ moduleSpecName,
243
+ );
244
+ normalizeFileMap(generated, componentOutputdir, generatedFiles);
245
+ });
198
246
 
199
247
  if (test === true) {
200
- return (
201
- checkFilesForChanges(moduleFilesToUpdate, outputDirectory) &&
202
- checkFilesForChanges(componentFilesToUpdate, componentOutputdir)
203
- );
248
+ return checkFilesForChanges(generatedFiles, outputDirectory);
204
249
  }
205
250
 
206
- return (
207
- writeMapToFiles(moduleFilesToUpdate, outputDirectory) &&
208
- writeMapToFiles(componentFilesToUpdate, componentOutputdir)
209
- );
251
+ return writeMapToFiles(generatedFiles, outputDirectory);
210
252
  }
211
253
 
212
254
  if ((argv.file && argv.files) || (!argv.file && !argv.files)) {
@@ -216,7 +258,7 @@ if ((argv.file && argv.files) || (!argv.file && !argv.files)) {
216
258
 
217
259
  let schema: SchemaType;
218
260
  if (argv.file) {
219
- schema = parseFile(argv.file);
261
+ schema = parseFlowFile(argv.file);
220
262
  } else {
221
263
  schema = combineSchemas(globby.sync(argv.files as string[]));
222
264
  }
@@ -7,13 +7,17 @@
7
7
  'use strict';
8
8
 
9
9
  import {
10
+ NativeModuleFunctionTypeAnnotation,
11
+ NativeModulePropertyShape,
10
12
  SchemaType,
11
- MethodTypeShape,
12
- // FunctionTypeAnnotation,
13
- FunctionTypeAnnotationParam,
14
- FunctionTypeAnnotationParamTypeAnnotation,
15
- FunctionTypeAnnotationReturn,
16
13
  } from 'react-native-tscodegen';
14
+ import {
15
+ getAliasCppName,
16
+ setPreferredModuleName,
17
+ translateObjectBody,
18
+ } from './ObjectTypes';
19
+ import {translateArgs, translateSpecArgs} from './ParamTypes';
20
+ import {translateImplReturnType, translateSpecReturnType} from './ReturnTypes';
17
21
 
18
22
  type FilesOutput = Map<string, string>;
19
23
 
@@ -31,7 +35,7 @@ const moduleTemplate = `
31
35
  #include <tuple>
32
36
 
33
37
  namespace ::_NAMESPACE_:: {
34
-
38
+ ::_MODULE_ALIASED_STRUCTS_::
35
39
  struct ::_MODULE_NAME_::Spec : winrt::Microsoft::ReactNative::TurboModuleSpec {
36
40
  static constexpr auto methods = std::tuple{
37
41
  ::_MODULE_PROPERTIES_TUPLE_::
@@ -48,250 +52,81 @@ struct ::_MODULE_NAME_::Spec : winrt::Microsoft::ReactNative::TurboModuleSpec {
48
52
  } // namespace ::_NAMESPACE_::
49
53
  `;
50
54
 
51
- function translateSpecFunctionParam(
52
- param: FunctionTypeAnnotationParam,
53
- ): string {
54
- switch (param.typeAnnotation.type) {
55
- case 'StringTypeAnnotation':
56
- return 'std::string';
57
- case 'NumberTypeAnnotation':
58
- case 'FloatTypeAnnotation':
59
- return 'double';
60
- case 'Int32TypeAnnotation':
61
- return 'int';
62
- case 'BooleanTypeAnnotation':
63
- return 'bool';
64
- case 'FunctionTypeAnnotation': {
65
- // Ideally we'd get more information about the expected parameters of the callback
66
- // But the current schema doesn't seem to provide the necessary information.
67
- return 'Callback<React::JSValue>';
68
- }
69
- case 'ArrayTypeAnnotation':
70
- // Ideally we'd get more information about the expected type of the array
71
- // But the current schema doesn't seem to provide the necessary information.
72
- return 'React::JSValueArray';
73
- case 'GenericObjectTypeAnnotation':
74
- return 'React::JSValueObject';
75
- case 'ObjectTypeAnnotation':
76
- // TODO we have more information here, and could create a more specific type
77
- return 'React::JSValueObject';
78
- case 'ReservedFunctionValueTypeAnnotation':
79
- // (#6597)
80
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
81
- if (param.typeAnnotation.name !== 'RootTag')
82
- throw new Error(
83
- `Unknown reserved function: ${param.typeAnnotation.name} in translateSpecFunctionParam`,
84
- );
85
- return 'double';
86
- default:
87
- throw new Error(
88
- `Unhandled type in translateSpecFunctionParam: ${param.typeAnnotation.type}`,
89
- );
90
- }
91
- }
92
-
93
- function translateFunctionParam(param: FunctionTypeAnnotationParam): string {
94
- switch (param.typeAnnotation.type) {
95
- case 'StringTypeAnnotation':
96
- return 'std::string';
97
- case 'NumberTypeAnnotation':
98
- case 'FloatTypeAnnotation':
99
- return 'double';
100
- case 'Int32TypeAnnotation':
101
- return 'int';
102
- case 'BooleanTypeAnnotation':
103
- return 'bool';
104
- case 'FunctionTypeAnnotation': {
105
- // Ideally we'd get more information about the expected parameters of the callback
106
- // But the current schema doesn't seem to provide the necessary information.
107
- return 'std::function<void(React::JSValue const &)> const &';
108
- }
109
- case 'ArrayTypeAnnotation':
110
- // Ideally we'd get more information about the expected type of the array
111
- // But the current schema doesn't seem to provide the necessary information.
112
- return 'React::JSValueArray &&';
113
- case 'GenericObjectTypeAnnotation':
114
- return 'React::JSValueObject &&';
115
- case 'ObjectTypeAnnotation':
116
- // TODO we have more information here, and could create a more specific type
117
- return 'React::JSValueObject &&';
118
- case 'ReservedFunctionValueTypeAnnotation':
119
- // (#6597)
120
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
121
- if (param.typeAnnotation.name !== 'RootTag')
122
- throw new Error(
123
- `Unknown reserved function: ${param.typeAnnotation.name} in translateFunctionParam`,
124
- );
125
- return 'double';
126
- default:
127
- throw new Error(
128
- `Unhandled type in translateFunctionParam: ${param.typeAnnotation.type} in translateFunctionParam`,
129
- );
130
- }
131
- }
132
-
133
- function translateSpecReturnType(
134
- type:
135
- | FunctionTypeAnnotationParamTypeAnnotation
136
- | FunctionTypeAnnotationReturn,
137
- ) {
138
- switch (type.type) {
139
- case 'VoidTypeAnnotation':
140
- return 'void';
141
- case 'StringTypeAnnotation':
142
- return 'std::string';
143
- case 'NumberTypeAnnotation':
144
- case 'FloatTypeAnnotation':
145
- return 'double';
146
- case 'Int32TypeAnnotation':
147
- return 'int';
148
- case 'BooleanTypeAnnotation':
149
- return 'bool';
150
- case 'GenericPromiseTypeAnnotation':
151
- return 'void';
152
- case 'ArrayTypeAnnotation':
153
- // Ideally we'd get more information about the expected type of the array
154
- // But the current schema doesn't seem to provide the necessary information.
155
- return 'React::JSValueArray';
156
- case 'GenericObjectTypeAnnotation':
157
- return 'React::JSValueObject';
158
- case 'ReservedFunctionValueTypeAnnotation':
159
- // (#6597)
160
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
161
- if (type.name !== 'RootTag')
162
- throw new Error(
163
- `Unknown reserved function: ${type.name} in translateSpecReturnType`,
164
- );
165
- return 'double';
166
- default:
167
- throw new Error(
168
- `Unhandled type in translateSpecReturnType: ${type.type}`,
169
- );
170
- }
171
- }
172
-
173
- function translateImplReturnType(
174
- type:
175
- | FunctionTypeAnnotationParamTypeAnnotation
176
- | FunctionTypeAnnotationReturn,
177
- ) {
178
- switch (type.type) {
179
- case 'VoidTypeAnnotation':
180
- return 'void';
181
- case 'StringTypeAnnotation':
182
- return 'std::string';
183
- case 'NumberTypeAnnotation':
184
- case 'FloatTypeAnnotation':
185
- return 'double';
186
- case 'Int32TypeAnnotation':
187
- return 'int';
188
- case 'BooleanTypeAnnotation':
189
- return 'bool';
190
- case 'GenericPromiseTypeAnnotation':
191
- return 'void';
192
- case 'ArrayTypeAnnotation':
193
- // Ideally we'd get more information about the expected type of the array
194
- // But the current schema doesn't seem to provide the necessary information.
195
- return 'React::JSValueArray';
196
- case 'GenericObjectTypeAnnotation':
197
- return 'React::JSValueObject';
198
- case 'ReservedFunctionValueTypeAnnotation':
199
- // (#6597)
200
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
201
- if (type.name !== 'RootTag')
202
- throw new Error(
203
- `Unknown reserved function: ${type.name} in translateSpecReturnType`,
204
- );
205
- return 'double';
206
- default:
207
- throw new Error(
208
- `Unhandled type in translateImplReturnType: ${type.type}`,
209
- );
210
- }
211
- }
212
-
213
- function translateSpecArgs(params: ReadonlyArray<FunctionTypeAnnotationParam>) {
214
- return params.map(param => {
215
- const translatedParam = translateSpecFunctionParam(param);
216
- return `${translatedParam}`;
217
- });
218
- }
219
-
220
- function translateArgs(params: ReadonlyArray<FunctionTypeAnnotationParam>) {
221
- return params.map(param => {
222
- const translatedParam = translateFunctionParam(param);
223
- return `${translatedParam} ${param.name}`;
224
- });
225
- }
226
-
227
- function isMethodSync(prop: MethodTypeShape) {
55
+ function isMethodSync(funcType: NativeModuleFunctionTypeAnnotation) {
228
56
  return (
229
- prop.typeAnnotation.returnTypeAnnotation.type !== 'VoidTypeAnnotation' &&
230
- prop.typeAnnotation.returnTypeAnnotation.type !==
231
- 'GenericPromiseTypeAnnotation'
57
+ funcType.returnTypeAnnotation.type !== 'VoidTypeAnnotation' &&
58
+ funcType.returnTypeAnnotation.type !== 'PromiseTypeAnnotation'
232
59
  );
233
60
  }
234
61
 
235
- function isPromise(prop: MethodTypeShape) {
236
- return (
237
- prop.typeAnnotation.returnTypeAnnotation.type ===
238
- 'GenericPromiseTypeAnnotation'
239
- );
62
+ function isMethodReturnPromise(funcType: NativeModuleFunctionTypeAnnotation) {
63
+ return funcType.returnTypeAnnotation.type === 'PromiseTypeAnnotation';
240
64
  }
241
65
 
242
- function getPossibleMethodSignatures(prop: MethodTypeShape): string[] {
243
- const args = translateArgs(prop.typeAnnotation.params);
244
- if (isPromise(prop)) {
66
+ function getPossibleMethodSignatures(
67
+ prop: NativeModulePropertyShape,
68
+ funcType: NativeModuleFunctionTypeAnnotation,
69
+ ): string[] {
70
+ const args = translateArgs(funcType.params);
71
+ if (isMethodReturnPromise(funcType)) {
245
72
  // Sadly, currently, the schema doesn't currently provide us information on the type of the promise.
246
73
  args.push('React::ReactPromise<React::JSValue> &&result');
247
74
  }
248
75
 
249
- // TODO be much more exhastive on the possible method signatures that can be used..
250
- const sig = `REACT_${isMethodSync(prop) ? 'SYNC_' : ''}METHOD(${
76
+ // TODO: be much more exhastive on the possible method signatures that can be used..
77
+ const sig = `REACT_${isMethodSync(funcType) ? 'SYNC_' : ''}METHOD(${
251
78
  prop.name
252
- }) ${translateImplReturnType(prop.typeAnnotation.returnTypeAnnotation)} ${
79
+ }) ${translateImplReturnType(funcType.returnTypeAnnotation)} ${
253
80
  prop.name
254
81
  }(${args.join(', ')}) noexcept { /* implementation */ }}`;
255
82
 
256
- const staticsig = `REACT_${isMethodSync(prop) ? 'SYNC_' : ''}METHOD(${
83
+ const staticsig = `REACT_${isMethodSync(funcType) ? 'SYNC_' : ''}METHOD(${
257
84
  prop.name
258
- }) static ${translateImplReturnType(
259
- prop.typeAnnotation.returnTypeAnnotation,
260
- )} ${prop.name}(${args.join(', ')}) noexcept { /* implementation */ }}`;
85
+ }) static ${translateImplReturnType(funcType.returnTypeAnnotation)} ${
86
+ prop.name
87
+ }(${args.join(', ')}) noexcept { /* implementation */ }}`;
261
88
 
262
89
  return [sig, staticsig];
263
90
  }
264
91
 
265
- function translatePossibleMethodSignatures(prop: MethodTypeShape): string {
266
- return getPossibleMethodSignatures(prop)
92
+ function translatePossibleMethodSignatures(
93
+ prop: NativeModulePropertyShape,
94
+ funcType: NativeModuleFunctionTypeAnnotation,
95
+ ): string {
96
+ return getPossibleMethodSignatures(prop, funcType)
267
97
  .map(sig => `" ${sig}\\n"`)
268
98
  .join('\n ');
269
99
  }
270
100
 
271
101
  function renderProperties(
272
- properties: ReadonlyArray<MethodTypeShape>,
102
+ properties: ReadonlyArray<NativeModulePropertyShape>,
273
103
  tuple: boolean,
274
104
  ): string {
275
105
  // We skip the constants for now, since we dont have Spec file validation of them.
276
106
  return properties
277
107
  .filter(prop => prop.name !== 'getConstants')
278
108
  .map((prop, index) => {
279
- const params = prop.typeAnnotation.params;
109
+ // TODO: prop.optional === true
110
+ // TODO: prop.typeAnnotation.type === 'NullableTypeAnnotation'
111
+ const funcType =
112
+ prop.typeAnnotation.type === 'NullableTypeAnnotation'
113
+ ? prop.typeAnnotation.typeAnnotation
114
+ : prop.typeAnnotation;
280
115
 
281
- const traversedArgs = translateSpecArgs(params);
116
+ const traversedArgs = translateSpecArgs(funcType.params);
282
117
 
283
118
  const translatedReturnParam = translateSpecReturnType(
284
- prop.typeAnnotation.returnTypeAnnotation,
119
+ funcType.returnTypeAnnotation,
285
120
  );
286
121
 
287
- if (isPromise(prop)) {
122
+ if (isMethodReturnPromise(funcType)) {
288
123
  // Sadly, currently, the schema doesn't currently provide us information on the type of the promise.
289
124
  traversedArgs.push('Promise<React::JSValue>');
290
125
  }
291
126
 
292
127
  if (tuple) {
293
128
  return ` ${
294
- isMethodSync(prop) ? 'Sync' : ''
129
+ isMethodSync(funcType) ? 'Sync' : ''
295
130
  }Method<${translatedReturnParam}(${traversedArgs.join(
296
131
  ', ',
297
132
  )}) noexcept>{${index}, L"${prop.name}"},`;
@@ -299,7 +134,7 @@ function renderProperties(
299
134
  return ` REACT_SHOW_METHOD_SPEC_ERRORS(
300
135
  ${index},
301
136
  "${prop.name}",
302
- ${translatePossibleMethodSignatures(prop)});`;
137
+ ${translatePossibleMethodSignatures(prop, funcType)});`;
303
138
  }
304
139
  })
305
140
  .join('\n');
@@ -313,30 +148,47 @@ export function createNM2Generator({namespace}: {namespace: string}) {
313
148
  ): FilesOutput => {
314
149
  const files = new Map<string, string>();
315
150
 
316
- const nativeModules = Object.keys(schema.modules)
317
- .map(moduleName => schema.modules[moduleName].nativeModules)
318
- .filter(Boolean)
319
- .reduce((acc, components) => Object.assign(acc, components), {});
151
+ for (const moduleName of Object.keys(schema.modules)) {
152
+ const nativeModule = schema.modules[moduleName];
153
+ // from 0.65 facebook's react-native-codegen
154
+ // the module name has the Native prefix comparing to 0.63
155
+ // when reading files we provided
156
+ const preferredModuleName = moduleName.startsWith('Native')
157
+ ? moduleName.substr(6)
158
+ : moduleName;
159
+ setPreferredModuleName(preferredModuleName);
160
+
161
+ if (nativeModule.type === 'NativeModule') {
162
+ console.log(`Generating Native${preferredModuleName}Spec.g.h`);
163
+
164
+ let traversedAliasedStructs = '';
165
+ for (const aliasName of Object.keys(nativeModule.aliases)) {
166
+ const aliasType = nativeModule.aliases[aliasName];
167
+ traversedAliasedStructs = `${traversedAliasedStructs}
168
+ REACT_STRUCT(${getAliasCppName(aliasName)})
169
+ struct ${getAliasCppName(aliasName)} {
170
+ ${translateObjectBody(aliasType, ' ')}
171
+ };
172
+ `;
173
+ }
320
174
 
321
- if (nativeModules) {
322
- Object.keys(nativeModules).forEach(name => {
323
- console.log(`Generating Native${name}Spec.g.h`);
324
- const {properties} = nativeModules[name];
175
+ const properties = nativeModule.spec.properties;
325
176
  const traversedProperties = renderProperties(properties, false);
326
177
  const traversedPropertyTuples = renderProperties(properties, true);
327
178
 
328
179
  files.set(
329
- `Native${name}Spec.g.h`,
180
+ `Native${preferredModuleName}Spec.g.h`,
330
181
  moduleTemplate
182
+ .replace(/::_MODULE_ALIASED_STRUCTS_::/g, traversedAliasedStructs)
331
183
  .replace(/::_MODULE_PROPERTIES_TUPLE_::/g, traversedPropertyTuples)
332
184
  .replace(
333
185
  /::_MODULE_PROPERTIES_SPEC_ERRORS_::/g,
334
186
  traversedProperties,
335
187
  )
336
- .replace(/::_MODULE_NAME_::/g, name)
188
+ .replace(/::_MODULE_NAME_::/g, preferredModuleName)
337
189
  .replace(/::_NAMESPACE_::/g, namespace),
338
190
  );
339
- });
191
+ }
340
192
  }
341
193
 
342
194
  return files;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ * Licensed under the MIT License.
4
+ * @format
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ import {
10
+ NativeModuleBaseTypeAnnotation,
11
+ NativeModuleObjectTypeAnnotation,
12
+ NamedShape,
13
+ Nullable,
14
+ } from 'react-native-tscodegen';
15
+
16
+ let preferredModuleName: string = '';
17
+
18
+ export function setPreferredModuleName(moduleName: string): void {
19
+ preferredModuleName = moduleName;
20
+ }
21
+
22
+ export function getAliasCppName(typeName: string): string {
23
+ return `${preferredModuleName}Spec_${typeName}`;
24
+ }
25
+
26
+ function translateField(
27
+ type: Nullable<NativeModuleBaseTypeAnnotation>,
28
+ ): string {
29
+ // avoid: Property 'type' does not exist on type 'never'
30
+ const returnType = type.type;
31
+ switch (type.type) {
32
+ case 'StringTypeAnnotation':
33
+ return 'std::string';
34
+ case 'NumberTypeAnnotation':
35
+ case 'FloatTypeAnnotation':
36
+ case 'DoubleTypeAnnotation':
37
+ return 'double';
38
+ case 'Int32TypeAnnotation':
39
+ return 'int';
40
+ case 'BooleanTypeAnnotation':
41
+ return 'bool';
42
+ case 'ArrayTypeAnnotation':
43
+ // TODO: type.elementType
44
+ return 'React::JSValueArray';
45
+ case 'GenericObjectTypeAnnotation':
46
+ return 'React::JSValueObject';
47
+ case 'ObjectTypeAnnotation':
48
+ // TODO: we have more information here, and could create a more specific type
49
+ return 'React::JSValueObject';
50
+ case 'ReservedTypeAnnotation': {
51
+ // avoid: Property 'name' does not exist on type 'never'
52
+ const name = type.name;
53
+ // (#6597)
54
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
55
+ if (name !== 'RootTag')
56
+ throw new Error(
57
+ `Unknown reserved function: ${name} in translateReturnType`,
58
+ );
59
+ return 'double';
60
+ }
61
+ case 'TypeAliasTypeAnnotation':
62
+ return getAliasCppName(type.name);
63
+ case 'NullableTypeAnnotation':
64
+ return `std::optional<${translateField(type.typeAnnotation)}>`;
65
+ default:
66
+ throw new Error(`Unhandled type in translateReturnType: ${returnType}`);
67
+ }
68
+ }
69
+
70
+ export function translateObjectBody(
71
+ type: NativeModuleObjectTypeAnnotation,
72
+ prefix: string,
73
+ ) {
74
+ return type.properties
75
+ .map((prop: NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>) => {
76
+ let propType = prop.typeAnnotation;
77
+ if (prop.optional && propType.type !== 'NullableTypeAnnotation') {
78
+ propType = {type: 'NullableTypeAnnotation', typeAnnotation: propType};
79
+ }
80
+ const first = `${prefix}REACT_FIELD(${prop.name})`;
81
+ const second = `${prefix}${translateField(propType)} ${prop.name};`;
82
+ return `${first}\n${second}`;
83
+ })
84
+ .join('\n');
85
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ * Licensed under the MIT License.
4
+ * @format
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ import {
10
+ NamedShape,
11
+ NativeModuleParamTypeAnnotation,
12
+ Nullable,
13
+ } from 'react-native-tscodegen';
14
+ import {getAliasCppName} from './ObjectTypes';
15
+
16
+ type NativeModuleParamShape = NamedShape<
17
+ Nullable<NativeModuleParamTypeAnnotation>
18
+ >;
19
+
20
+ function decorateType(type: string, forSpec: boolean): string {
21
+ return forSpec ? type : `${type} &&`;
22
+ }
23
+
24
+ function translateParam(
25
+ param: NativeModuleParamTypeAnnotation,
26
+ forSpec: boolean,
27
+ ): string {
28
+ // avoid: Property 'type' does not exist on type 'never'
29
+ const paramType = param.type;
30
+ switch (param.type) {
31
+ case 'StringTypeAnnotation':
32
+ return 'std::string';
33
+ case 'NumberTypeAnnotation':
34
+ case 'FloatTypeAnnotation':
35
+ case 'DoubleTypeAnnotation':
36
+ return 'double';
37
+ case 'Int32TypeAnnotation':
38
+ return 'int';
39
+ case 'BooleanTypeAnnotation':
40
+ return 'bool';
41
+ case 'FunctionTypeAnnotation': {
42
+ // TODO: type.params && type.returnTypeAnnotation
43
+ if (forSpec) {
44
+ return 'Callback<React::JSValue>';
45
+ } else {
46
+ return 'std::function<void(React::JSValue const &)> const &';
47
+ }
48
+ }
49
+ case 'ArrayTypeAnnotation':
50
+ // TODO: type.elementType
51
+ return decorateType('React::JSValueArray', forSpec);
52
+ case 'GenericObjectTypeAnnotation':
53
+ return decorateType('React::JSValueObject', forSpec);
54
+ case 'ObjectTypeAnnotation':
55
+ // TODO: we have more information here, and could create a more specific type
56
+ return decorateType('React::JSValueObject', forSpec);
57
+ case 'ReservedTypeAnnotation': {
58
+ // avoid: Property 'name' does not exist on type 'never'
59
+ const name = param.name;
60
+ // (#6597)
61
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
62
+ if (name !== 'RootTag')
63
+ throw new Error(`Unknown reserved function: ${name} in translateParam`);
64
+ return 'double';
65
+ }
66
+ case 'TypeAliasTypeAnnotation':
67
+ return decorateType(getAliasCppName(param.name), forSpec);
68
+ default:
69
+ throw new Error(`Unhandled type in translateParam: ${paramType}`);
70
+ }
71
+ }
72
+
73
+ function translateSpecFunctionParam(param: NativeModuleParamShape): string {
74
+ switch (param.typeAnnotation.type) {
75
+ case 'NullableTypeAnnotation':
76
+ // TODO: should be
77
+ // return `std::optional<${translateParam(
78
+ // param.typeAnnotation.typeAnnotation,
79
+ // true,
80
+ // )}>`;
81
+ return translateParam(param.typeAnnotation.typeAnnotation, true);
82
+ default:
83
+ return translateParam(param.typeAnnotation, true);
84
+ }
85
+ }
86
+
87
+ function translateFunctionParam(param: NativeModuleParamShape): string {
88
+ switch (param.typeAnnotation.type) {
89
+ case 'NullableTypeAnnotation':
90
+ // TODO: should be
91
+ // return `std::optional<${translateParam(
92
+ // param.typeAnnotation.typeAnnotation,
93
+ // false,
94
+ // )}>`;
95
+ return translateParam(param.typeAnnotation.typeAnnotation, false);
96
+ default:
97
+ return translateParam(param.typeAnnotation, false);
98
+ }
99
+ }
100
+
101
+ export function translateSpecArgs(
102
+ params: ReadonlyArray<NativeModuleParamShape>,
103
+ ) {
104
+ return params.map(param => {
105
+ const translatedParam = translateSpecFunctionParam(param);
106
+ return `${translatedParam}`;
107
+ });
108
+ }
109
+
110
+ export function translateArgs(params: ReadonlyArray<NativeModuleParamShape>) {
111
+ return params.map(param => {
112
+ const translatedParam = translateFunctionParam(param);
113
+ return `${translatedParam} ${param.name}`;
114
+ });
115
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation.
3
+ * Licensed under the MIT License.
4
+ * @format
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ import {
10
+ NativeModuleReturnTypeAnnotation,
11
+ Nullable,
12
+ } from 'react-native-tscodegen';
13
+ import {getAliasCppName} from './ObjectTypes';
14
+
15
+ function translateReturnType(
16
+ type: Nullable<NativeModuleReturnTypeAnnotation>,
17
+ ): string {
18
+ // avoid: Property 'type' does not exist on type 'never'
19
+ const returnType = type.type;
20
+ switch (type.type) {
21
+ case 'VoidTypeAnnotation':
22
+ case 'PromiseTypeAnnotation':
23
+ return 'void';
24
+ case 'StringTypeAnnotation':
25
+ return 'std::string';
26
+ case 'NumberTypeAnnotation':
27
+ case 'FloatTypeAnnotation':
28
+ case 'DoubleTypeAnnotation':
29
+ return 'double';
30
+ case 'Int32TypeAnnotation':
31
+ return 'int';
32
+ case 'BooleanTypeAnnotation':
33
+ return 'bool';
34
+ case 'ArrayTypeAnnotation':
35
+ // TODO: type.elementType
36
+ return 'React::JSValueArray';
37
+ case 'GenericObjectTypeAnnotation':
38
+ return 'React::JSValueObject';
39
+ case 'ObjectTypeAnnotation':
40
+ // TODO: we have more information here, and could create a more specific type
41
+ return 'React::JSValueObject';
42
+ case 'ReservedTypeAnnotation': {
43
+ // avoid: Property 'name' does not exist on type 'never'
44
+ const name = type.name;
45
+ // (#6597)
46
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
47
+ if (name !== 'RootTag')
48
+ throw new Error(
49
+ `Unknown reserved function: ${name} in translateReturnType`,
50
+ );
51
+ return 'double';
52
+ }
53
+ case 'TypeAliasTypeAnnotation':
54
+ return getAliasCppName(type.name);
55
+ case 'NullableTypeAnnotation':
56
+ // TODO: should be `std::optional<${translateReturnType(type.typeAnnotation)}>`;
57
+ return translateReturnType(type.typeAnnotation);
58
+ default:
59
+ throw new Error(`Unhandled type in translateReturnType: ${returnType}`);
60
+ }
61
+ }
62
+
63
+ export function translateSpecReturnType(
64
+ type: Nullable<NativeModuleReturnTypeAnnotation>,
65
+ ) {
66
+ return translateReturnType(type);
67
+ }
68
+
69
+ export function translateImplReturnType(
70
+ type: Nullable<NativeModuleReturnTypeAnnotation>,
71
+ ) {
72
+ return translateReturnType(type);
73
+ }