@react-native/codegen 0.72.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.
Files changed (186) hide show
  1. package/README.md +21 -0
  2. package/lib/CodegenSchema.js +11 -0
  3. package/lib/CodegenSchema.js.flow +351 -0
  4. package/lib/SchemaValidator.js +54 -0
  5. package/lib/SchemaValidator.js.flow +67 -0
  6. package/lib/cli/combine/combine-js-to-schema-cli.js +50 -0
  7. package/lib/cli/combine/combine-js-to-schema-cli.js.flow +49 -0
  8. package/lib/cli/combine/combine-js-to-schema.js +110 -0
  9. package/lib/cli/combine/combine-js-to-schema.js.flow +48 -0
  10. package/lib/cli/combine/combine-utils.js +118 -0
  11. package/lib/cli/combine/combine-utils.js.flow +85 -0
  12. package/lib/cli/generators/generate-all.js +65 -0
  13. package/lib/cli/generators/generate-all.js.flow +66 -0
  14. package/lib/cli/parser/parser-cli.js +55 -0
  15. package/lib/cli/parser/parser-cli.js.flow +18 -0
  16. package/lib/cli/parser/parser.js +35 -0
  17. package/lib/cli/parser/parser.js.flow +37 -0
  18. package/lib/cli/parser/parser.sh +15 -0
  19. package/lib/generators/RNCodegen.js +207 -0
  20. package/lib/generators/RNCodegen.js.flow +284 -0
  21. package/lib/generators/Utils.js +31 -0
  22. package/lib/generators/Utils.js.flow +33 -0
  23. package/lib/generators/__test_fixtures__/fixtures.js +79 -0
  24. package/lib/generators/__test_fixtures__/fixtures.js.flow +82 -0
  25. package/lib/generators/components/ComponentsGeneratorUtils.js +217 -0
  26. package/lib/generators/components/ComponentsGeneratorUtils.js.flow +304 -0
  27. package/lib/generators/components/CppHelpers.js +188 -0
  28. package/lib/generators/components/CppHelpers.js.flow +228 -0
  29. package/lib/generators/components/GenerateComponentDescriptorH.js +75 -0
  30. package/lib/generators/components/GenerateComponentDescriptorH.js.flow +95 -0
  31. package/lib/generators/components/GenerateComponentHObjCpp.js +327 -0
  32. package/lib/generators/components/GenerateComponentHObjCpp.js.flow +418 -0
  33. package/lib/generators/components/GenerateEventEmitterCpp.js +199 -0
  34. package/lib/generators/components/GenerateEventEmitterCpp.js.flow +273 -0
  35. package/lib/generators/components/GenerateEventEmitterH.js +224 -0
  36. package/lib/generators/components/GenerateEventEmitterH.js.flow +315 -0
  37. package/lib/generators/components/GeneratePropsCpp.js +126 -0
  38. package/lib/generators/components/GeneratePropsCpp.js.flow +161 -0
  39. package/lib/generators/components/GeneratePropsH.js +606 -0
  40. package/lib/generators/components/GeneratePropsH.js.flow +778 -0
  41. package/lib/generators/components/GeneratePropsJavaDelegate.js +287 -0
  42. package/lib/generators/components/GeneratePropsJavaDelegate.js.flow +348 -0
  43. package/lib/generators/components/GeneratePropsJavaInterface.js +237 -0
  44. package/lib/generators/components/GeneratePropsJavaInterface.js.flow +288 -0
  45. package/lib/generators/components/GeneratePropsJavaPojo/PojoCollector.js +157 -0
  46. package/lib/generators/components/GeneratePropsJavaPojo/PojoCollector.js.flow +187 -0
  47. package/lib/generators/components/GeneratePropsJavaPojo/index.js +66 -0
  48. package/lib/generators/components/GeneratePropsJavaPojo/index.js.flow +80 -0
  49. package/lib/generators/components/GeneratePropsJavaPojo/serializePojo.js +273 -0
  50. package/lib/generators/components/GeneratePropsJavaPojo/serializePojo.js.flow +296 -0
  51. package/lib/generators/components/GenerateShadowNodeCpp.js +73 -0
  52. package/lib/generators/components/GenerateShadowNodeCpp.js.flow +95 -0
  53. package/lib/generators/components/GenerateShadowNodeH.js +91 -0
  54. package/lib/generators/components/GenerateShadowNodeH.js.flow +124 -0
  55. package/lib/generators/components/GenerateStateCpp.js +70 -0
  56. package/lib/generators/components/GenerateStateCpp.js.flow +92 -0
  57. package/lib/generators/components/GenerateStateH.js +93 -0
  58. package/lib/generators/components/GenerateStateH.js.flow +111 -0
  59. package/lib/generators/components/GenerateTests.js +165 -0
  60. package/lib/generators/components/GenerateTests.js.flow +219 -0
  61. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderH.js +91 -0
  62. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderH.js.flow +107 -0
  63. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderObjCpp.js +89 -0
  64. package/lib/generators/components/GenerateThirdPartyFabricComponentsProviderObjCpp.js.flow +105 -0
  65. package/lib/generators/components/GenerateViewConfigJs.js +410 -0
  66. package/lib/generators/components/GenerateViewConfigJs.js.flow +484 -0
  67. package/lib/generators/components/JavaHelpers.js +87 -0
  68. package/lib/generators/components/JavaHelpers.js.flow +119 -0
  69. package/lib/generators/components/__test_fixtures__/fixtures.js +1641 -0
  70. package/lib/generators/components/__test_fixtures__/fixtures.js.flow +1672 -0
  71. package/lib/generators/modules/GenerateModuleCpp.js +299 -0
  72. package/lib/generators/modules/GenerateModuleCpp.js.flow +278 -0
  73. package/lib/generators/modules/GenerateModuleH.js +373 -0
  74. package/lib/generators/modules/GenerateModuleH.js.flow +355 -0
  75. package/lib/generators/modules/GenerateModuleJavaSpec.js +571 -0
  76. package/lib/generators/modules/GenerateModuleJavaSpec.js.flow +553 -0
  77. package/lib/generators/modules/GenerateModuleJniCpp.js +505 -0
  78. package/lib/generators/modules/GenerateModuleJniCpp.js.flow +523 -0
  79. package/lib/generators/modules/GenerateModuleJniH.js +138 -0
  80. package/lib/generators/modules/GenerateModuleJniH.js.flow +148 -0
  81. package/lib/generators/modules/GenerateModuleObjCpp/StructCollector.js +262 -0
  82. package/lib/generators/modules/GenerateModuleObjCpp/StructCollector.js.flow +208 -0
  83. package/lib/generators/modules/GenerateModuleObjCpp/Utils.js +25 -0
  84. package/lib/generators/modules/GenerateModuleObjCpp/Utils.js.flow +32 -0
  85. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js +337 -0
  86. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js.flow +288 -0
  87. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js +330 -0
  88. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js.flow +279 -0
  89. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js +25 -0
  90. package/lib/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js.flow +35 -0
  91. package/lib/generators/modules/GenerateModuleObjCpp/index.js +185 -0
  92. package/lib/generators/modules/GenerateModuleObjCpp/index.js.flow +219 -0
  93. package/lib/generators/modules/GenerateModuleObjCpp/serializeMethod.js +529 -0
  94. package/lib/generators/modules/GenerateModuleObjCpp/serializeMethod.js.flow +510 -0
  95. package/lib/generators/modules/GenerateModuleObjCpp/source/serializeModule.js +96 -0
  96. package/lib/generators/modules/GenerateModuleObjCpp/source/serializeModule.js.flow +121 -0
  97. package/lib/generators/modules/Utils.js +34 -0
  98. package/lib/generators/modules/Utils.js.flow +53 -0
  99. package/lib/generators/modules/__test_fixtures__/fixtures.js +1658 -0
  100. package/lib/generators/modules/__test_fixtures__/fixtures.js.flow +1669 -0
  101. package/lib/parsers/consistency/compareSnaps.js +84 -0
  102. package/lib/parsers/error-utils.js +284 -0
  103. package/lib/parsers/error-utils.js.flow +295 -0
  104. package/lib/parsers/errors.js +350 -0
  105. package/lib/parsers/errors.js.flow +439 -0
  106. package/lib/parsers/flow/components/__test_fixtures__/failures.js +583 -0
  107. package/lib/parsers/flow/components/__test_fixtures__/failures.js.flow +600 -0
  108. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js +1001 -0
  109. package/lib/parsers/flow/components/__test_fixtures__/fixtures.js.flow +1016 -0
  110. package/lib/parsers/flow/components/commands.js +104 -0
  111. package/lib/parsers/flow/components/commands.js.flow +123 -0
  112. package/lib/parsers/flow/components/componentsUtils.js +446 -0
  113. package/lib/parsers/flow/components/componentsUtils.js.flow +496 -0
  114. package/lib/parsers/flow/components/events.js +233 -0
  115. package/lib/parsers/flow/components/events.js.flow +262 -0
  116. package/lib/parsers/flow/components/extends.js +52 -0
  117. package/lib/parsers/flow/components/extends.js.flow +66 -0
  118. package/lib/parsers/flow/components/index.js +267 -0
  119. package/lib/parsers/flow/components/index.js.flow +226 -0
  120. package/lib/parsers/flow/components/options.js +72 -0
  121. package/lib/parsers/flow/components/options.js.flow +87 -0
  122. package/lib/parsers/flow/components/props.js +47 -0
  123. package/lib/parsers/flow/components/props.js.flow +60 -0
  124. package/lib/parsers/flow/components/schema.js +106 -0
  125. package/lib/parsers/flow/components/schema.js.flow +62 -0
  126. package/lib/parsers/flow/index.js +80 -0
  127. package/lib/parsers/flow/index.js.flow +85 -0
  128. package/lib/parsers/flow/modules/__test_fixtures__/failures.js +215 -0
  129. package/lib/parsers/flow/modules/__test_fixtures__/failures.js.flow +223 -0
  130. package/lib/parsers/flow/modules/__test_fixtures__/fixtures.js +724 -0
  131. package/lib/parsers/flow/modules/__test_fixtures__/fixtures.js.flow +747 -0
  132. package/lib/parsers/flow/modules/index.js +528 -0
  133. package/lib/parsers/flow/modules/index.js.flow +420 -0
  134. package/lib/parsers/flow/parser.js +109 -0
  135. package/lib/parsers/flow/parser.js.flow +83 -0
  136. package/lib/parsers/flow/utils.js +108 -0
  137. package/lib/parsers/flow/utils.js.flow +123 -0
  138. package/lib/parsers/parser.js +11 -0
  139. package/lib/parsers/parser.js.flow +70 -0
  140. package/lib/parsers/parserMock.js +96 -0
  141. package/lib/parsers/parserMock.js.flow +68 -0
  142. package/lib/parsers/parsers-commons.js +448 -0
  143. package/lib/parsers/parsers-commons.js.flow +447 -0
  144. package/lib/parsers/parsers-primitives.js +387 -0
  145. package/lib/parsers/parsers-primitives.js.flow +383 -0
  146. package/lib/parsers/parsers-utils.js +18 -0
  147. package/lib/parsers/parsers-utils.js.flow +19 -0
  148. package/lib/parsers/schema/index.js +23 -0
  149. package/lib/parsers/schema/index.js.flow +26 -0
  150. package/lib/parsers/typescript/components/__test_fixtures__/failures.js +489 -0
  151. package/lib/parsers/typescript/components/__test_fixtures__/failures.js.flow +505 -0
  152. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js +1151 -0
  153. package/lib/parsers/typescript/components/__test_fixtures__/fixtures.js.flow +1168 -0
  154. package/lib/parsers/typescript/components/commands.js +132 -0
  155. package/lib/parsers/typescript/components/commands.js.flow +151 -0
  156. package/lib/parsers/typescript/components/componentsUtils.js +471 -0
  157. package/lib/parsers/typescript/components/componentsUtils.js.flow +521 -0
  158. package/lib/parsers/typescript/components/events.js +240 -0
  159. package/lib/parsers/typescript/components/events.js.flow +262 -0
  160. package/lib/parsers/typescript/components/extends.js +88 -0
  161. package/lib/parsers/typescript/components/extends.js.flow +103 -0
  162. package/lib/parsers/typescript/components/index.js +277 -0
  163. package/lib/parsers/typescript/components/index.js.flow +239 -0
  164. package/lib/parsers/typescript/components/options.js +72 -0
  165. package/lib/parsers/typescript/components/options.js.flow +87 -0
  166. package/lib/parsers/typescript/components/props.js +39 -0
  167. package/lib/parsers/typescript/components/props.js.flow +48 -0
  168. package/lib/parsers/typescript/components/schema.js +106 -0
  169. package/lib/parsers/typescript/components/schema.js.flow +62 -0
  170. package/lib/parsers/typescript/index.js +85 -0
  171. package/lib/parsers/typescript/index.js.flow +94 -0
  172. package/lib/parsers/typescript/modules/__test_fixtures__/failures.js +160 -0
  173. package/lib/parsers/typescript/modules/__test_fixtures__/failures.js.flow +167 -0
  174. package/lib/parsers/typescript/modules/__test_fixtures__/fixtures.js +701 -0
  175. package/lib/parsers/typescript/modules/__test_fixtures__/fixtures.js.flow +727 -0
  176. package/lib/parsers/typescript/modules/index.js +543 -0
  177. package/lib/parsers/typescript/modules/index.js.flow +435 -0
  178. package/lib/parsers/typescript/parseTopLevelType.js +203 -0
  179. package/lib/parsers/typescript/parseTopLevelType.js.flow +243 -0
  180. package/lib/parsers/typescript/parser.js +105 -0
  181. package/lib/parsers/typescript/parser.js.flow +87 -0
  182. package/lib/parsers/typescript/utils.js +101 -0
  183. package/lib/parsers/typescript/utils.js.flow +115 -0
  184. package/lib/parsers/utils.js +273 -0
  185. package/lib/parsers/utils.js.flow +266 -0
  186. package/package.json +45 -0
@@ -0,0 +1,418 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ * @format
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ import type {
14
+ NamedShape,
15
+ CommandTypeAnnotation,
16
+ ComponentShape,
17
+ SchemaType,
18
+ CommandParamTypeAnnotation,
19
+ } from '../../CodegenSchema';
20
+
21
+ type FilesOutput = Map<string, string>;
22
+
23
+ function getOrdinalNumber(num: number): string {
24
+ switch (num) {
25
+ case 1:
26
+ return '1st';
27
+ case 2:
28
+ return '2nd';
29
+ case 3:
30
+ return '3rd';
31
+ }
32
+
33
+ if (num <= 20) {
34
+ return `${num}th`;
35
+ }
36
+
37
+ return 'unknown';
38
+ }
39
+
40
+ const ProtocolTemplate = ({
41
+ componentName,
42
+ methods,
43
+ }: {
44
+ componentName: string,
45
+ methods: string,
46
+ }) =>
47
+ `
48
+ @protocol RCT${componentName}ViewProtocol <NSObject>
49
+ ${methods}
50
+ @end
51
+ `.trim();
52
+
53
+ const CommandHandlerIfCaseConvertArgTemplate = ({
54
+ componentName,
55
+ expectedKind,
56
+ argNumber,
57
+ argNumberString,
58
+ expectedKindString,
59
+ argConversion,
60
+ }: {
61
+ componentName: string,
62
+ expectedKind: string,
63
+ argNumber: number,
64
+ argNumberString: string,
65
+ expectedKindString: string,
66
+ argConversion: string,
67
+ }) =>
68
+ `
69
+ NSObject *arg${argNumber} = args[${argNumber}];
70
+ #if RCT_DEBUG
71
+ if (!RCTValidateTypeOfViewCommandArgument(arg${argNumber}, ${expectedKind}, @"${expectedKindString}", @"${componentName}", commandName, @"${argNumberString}")) {
72
+ return;
73
+ }
74
+ #endif
75
+ ${argConversion}
76
+ `.trim();
77
+
78
+ const CommandHandlerIfCaseTemplate = ({
79
+ componentName,
80
+ commandName,
81
+ numArgs,
82
+ convertArgs,
83
+ commandCall,
84
+ }: {
85
+ componentName: string,
86
+ commandName: string,
87
+ numArgs: number,
88
+ convertArgs: string,
89
+ commandCall: string,
90
+ }) =>
91
+ `
92
+ if ([commandName isEqualToString:@"${commandName}"]) {
93
+ #if RCT_DEBUG
94
+ if ([args count] != ${numArgs}) {
95
+ RCTLogError(@"%@ command %@ received %d arguments, expected %d.", @"${componentName}", commandName, (int)[args count], ${numArgs});
96
+ return;
97
+ }
98
+ #endif
99
+
100
+ ${convertArgs}
101
+
102
+ ${commandCall}
103
+ return;
104
+ }
105
+ `.trim();
106
+
107
+ const CommandHandlerTemplate = ({
108
+ componentName,
109
+ ifCases,
110
+ }: {
111
+ componentName: string,
112
+ ifCases: string,
113
+ }) =>
114
+ `
115
+ RCT_EXTERN inline void RCT${componentName}HandleCommand(
116
+ id<RCT${componentName}ViewProtocol> componentView,
117
+ NSString const *commandName,
118
+ NSArray const *args)
119
+ {
120
+ ${ifCases}
121
+
122
+ #if RCT_DEBUG
123
+ RCTLogError(@"%@ received command %@, which is not a supported command.", @"${componentName}", commandName);
124
+ #endif
125
+ }
126
+ `.trim();
127
+
128
+ const FileTemplate = ({componentContent}: {componentContent: string}) =>
129
+ `
130
+ /**
131
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
132
+ *
133
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
134
+ * once the code is regenerated.
135
+ *
136
+ * ${'@'}generated by codegen project: GenerateComponentHObjCpp.js
137
+ */
138
+
139
+ #import <Foundation/Foundation.h>
140
+ #import <React/RCTDefines.h>
141
+ #import <React/RCTLog.h>
142
+
143
+ NS_ASSUME_NONNULL_BEGIN
144
+
145
+ ${componentContent}
146
+
147
+ NS_ASSUME_NONNULL_END
148
+ `.trim();
149
+
150
+ type Param = NamedShape<CommandParamTypeAnnotation>;
151
+
152
+ function getObjCParamType(param: Param): string {
153
+ const {typeAnnotation} = param;
154
+
155
+ switch (typeAnnotation.type) {
156
+ case 'ReservedTypeAnnotation':
157
+ switch (typeAnnotation.name) {
158
+ case 'RootTag':
159
+ return 'double';
160
+ default:
161
+ (typeAnnotation.name: empty);
162
+ throw new Error(`Receieved invalid type: ${typeAnnotation.name}`);
163
+ }
164
+ case 'BooleanTypeAnnotation':
165
+ return 'BOOL';
166
+ case 'DoubleTypeAnnotation':
167
+ return 'double';
168
+ case 'FloatTypeAnnotation':
169
+ return 'float';
170
+ case 'Int32TypeAnnotation':
171
+ return 'NSInteger';
172
+ case 'StringTypeAnnotation':
173
+ return 'NSString *';
174
+ default:
175
+ (typeAnnotation.type: empty);
176
+ throw new Error('Received invalid param type annotation');
177
+ }
178
+ }
179
+
180
+ function getObjCExpectedKindParamType(param: Param): string {
181
+ const {typeAnnotation} = param;
182
+
183
+ switch (typeAnnotation.type) {
184
+ case 'ReservedTypeAnnotation':
185
+ switch (typeAnnotation.name) {
186
+ case 'RootTag':
187
+ return '[NSNumber class]';
188
+ default:
189
+ (typeAnnotation.name: empty);
190
+ throw new Error(`Receieved invalid type: ${typeAnnotation.name}`);
191
+ }
192
+ case 'BooleanTypeAnnotation':
193
+ return '[NSNumber class]';
194
+ case 'DoubleTypeAnnotation':
195
+ return '[NSNumber class]';
196
+ case 'FloatTypeAnnotation':
197
+ return '[NSNumber class]';
198
+ case 'Int32TypeAnnotation':
199
+ return '[NSNumber class]';
200
+ case 'StringTypeAnnotation':
201
+ return '[NSString class]';
202
+ default:
203
+ (typeAnnotation.type: empty);
204
+ throw new Error('Received invalid param type annotation');
205
+ }
206
+ }
207
+
208
+ function getReadableExpectedKindParamType(param: Param): string {
209
+ const {typeAnnotation} = param;
210
+
211
+ switch (typeAnnotation.type) {
212
+ case 'ReservedTypeAnnotation':
213
+ switch (typeAnnotation.name) {
214
+ case 'RootTag':
215
+ return 'double';
216
+ default:
217
+ (typeAnnotation.name: empty);
218
+ throw new Error(`Receieved invalid type: ${typeAnnotation.name}`);
219
+ }
220
+ case 'BooleanTypeAnnotation':
221
+ return 'boolean';
222
+ case 'DoubleTypeAnnotation':
223
+ return 'double';
224
+ case 'FloatTypeAnnotation':
225
+ return 'float';
226
+ case 'Int32TypeAnnotation':
227
+ return 'number';
228
+ case 'StringTypeAnnotation':
229
+ return 'string';
230
+ default:
231
+ (typeAnnotation.type: empty);
232
+ throw new Error('Received invalid param type annotation');
233
+ }
234
+ }
235
+
236
+ function getObjCRightHandAssignmentParamType(
237
+ param: Param,
238
+ index: number,
239
+ ): string {
240
+ const {typeAnnotation} = param;
241
+
242
+ switch (typeAnnotation.type) {
243
+ case 'ReservedTypeAnnotation':
244
+ switch (typeAnnotation.name) {
245
+ case 'RootTag':
246
+ return `[(NSNumber *)arg${index} doubleValue]`;
247
+ default:
248
+ (typeAnnotation.name: empty);
249
+ throw new Error(`Receieved invalid type: ${typeAnnotation.name}`);
250
+ }
251
+ case 'BooleanTypeAnnotation':
252
+ return `[(NSNumber *)arg${index} boolValue]`;
253
+ case 'DoubleTypeAnnotation':
254
+ return `[(NSNumber *)arg${index} doubleValue]`;
255
+ case 'FloatTypeAnnotation':
256
+ return `[(NSNumber *)arg${index} floatValue]`;
257
+ case 'Int32TypeAnnotation':
258
+ return `[(NSNumber *)arg${index} intValue]`;
259
+ case 'StringTypeAnnotation':
260
+ return `(NSString *)arg${index}`;
261
+ default:
262
+ (typeAnnotation.type: empty);
263
+ throw new Error('Received invalid param type annotation');
264
+ }
265
+ }
266
+
267
+ function generateProtocol(
268
+ component: ComponentShape,
269
+ componentName: string,
270
+ ): string {
271
+ const methods = component.commands
272
+ .map(command => {
273
+ const params = command.typeAnnotation.params;
274
+ const paramString =
275
+ params.length === 0
276
+ ? ''
277
+ : params
278
+ .map((param, index) => {
279
+ const objCType = getObjCParamType(param);
280
+
281
+ return `${index === 0 ? '' : param.name}:(${objCType})${
282
+ param.name
283
+ }`;
284
+ })
285
+ .join(' ');
286
+ return `- (void)${command.name}${paramString};`;
287
+ })
288
+ .join('\n')
289
+ .trim();
290
+
291
+ return ProtocolTemplate({
292
+ componentName,
293
+ methods,
294
+ });
295
+ }
296
+
297
+ function generateConvertAndValidateParam(
298
+ param: Param,
299
+ index: number,
300
+ componentName: string,
301
+ ): string {
302
+ const leftSideType = getObjCParamType(param);
303
+ const expectedKind = getObjCExpectedKindParamType(param);
304
+ const expectedKindString = getReadableExpectedKindParamType(param);
305
+ const argConversion = `${leftSideType} ${
306
+ param.name
307
+ } = ${getObjCRightHandAssignmentParamType(param, index)};`;
308
+
309
+ return CommandHandlerIfCaseConvertArgTemplate({
310
+ componentName,
311
+ argConversion,
312
+ argNumber: index,
313
+ argNumberString: getOrdinalNumber(index + 1),
314
+ expectedKind,
315
+ expectedKindString,
316
+ });
317
+ }
318
+
319
+ function generateCommandIfCase(
320
+ command: NamedShape<CommandTypeAnnotation>,
321
+ componentName: string,
322
+ ) {
323
+ const params = command.typeAnnotation.params;
324
+
325
+ const convertArgs = params
326
+ .map((param, index) =>
327
+ generateConvertAndValidateParam(param, index, componentName),
328
+ )
329
+ .join('\n\n')
330
+ .trim();
331
+
332
+ const commandCallArgs =
333
+ params.length === 0
334
+ ? ''
335
+ : params
336
+ .map((param, index) => {
337
+ return `${index === 0 ? '' : param.name}:${param.name}`;
338
+ })
339
+ .join(' ');
340
+ const commandCall = `[componentView ${command.name}${commandCallArgs}];`;
341
+
342
+ return CommandHandlerIfCaseTemplate({
343
+ componentName,
344
+ commandName: command.name,
345
+ numArgs: params.length,
346
+ convertArgs,
347
+ commandCall,
348
+ });
349
+ }
350
+
351
+ function generateCommandHandler(
352
+ component: ComponentShape,
353
+ componentName: string,
354
+ ): ?string {
355
+ if (component.commands.length === 0) {
356
+ return null;
357
+ }
358
+
359
+ const ifCases = component.commands
360
+ .map(command => generateCommandIfCase(command, componentName))
361
+ .join('\n\n');
362
+
363
+ return CommandHandlerTemplate({
364
+ componentName,
365
+ ifCases,
366
+ });
367
+ }
368
+
369
+ module.exports = {
370
+ generate(
371
+ libraryName: string,
372
+ schema: SchemaType,
373
+ packageName?: string,
374
+ assumeNonnull: boolean = false,
375
+ ): FilesOutput {
376
+ const fileName = 'RCTComponentViewHelpers.h';
377
+
378
+ const componentContent = Object.keys(schema.modules)
379
+ .map(moduleName => {
380
+ const module = schema.modules[moduleName];
381
+ if (module.type !== 'Component') {
382
+ return;
383
+ }
384
+
385
+ const {components} = module;
386
+ // No components in this module
387
+ if (components == null) {
388
+ return null;
389
+ }
390
+
391
+ return Object.keys(components)
392
+ .filter(componentName => {
393
+ const component = components[componentName];
394
+ return !(
395
+ component.excludedPlatforms &&
396
+ component.excludedPlatforms.includes('iOS')
397
+ );
398
+ })
399
+ .map(componentName => {
400
+ return [
401
+ generateProtocol(components[componentName], componentName),
402
+ generateCommandHandler(components[componentName], componentName),
403
+ ]
404
+ .join('\n\n')
405
+ .trim();
406
+ })
407
+ .join('\n\n');
408
+ })
409
+ .filter(Boolean)
410
+ .join('\n\n');
411
+
412
+ const replacedTemplate = FileTemplate({
413
+ componentContent,
414
+ });
415
+
416
+ return new Map([[fileName, replacedTemplate]]);
417
+ },
418
+ };
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ *
8
+ * @format
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ const _require = require('./CppHelpers.js'),
14
+ generateEventStructName = _require.generateEventStructName;
15
+ const FileTemplate = ({events, libraryName}) => `
16
+ /**
17
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
18
+ *
19
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
20
+ * once the code is regenerated.
21
+ *
22
+ * ${'@'}generated by codegen project: GenerateEventEmitterCpp.js
23
+ */
24
+
25
+ #include <react/renderer/components/${libraryName}/EventEmitters.h>
26
+
27
+ namespace facebook {
28
+ namespace react {
29
+
30
+ ${events}
31
+
32
+ } // namespace react
33
+ } // namespace facebook
34
+ `;
35
+ const ComponentTemplate = ({
36
+ className,
37
+ eventName,
38
+ structName,
39
+ dispatchEventName,
40
+ implementation,
41
+ }) =>
42
+ `
43
+ void ${className}EventEmitter::${eventName}(${structName} event) const {
44
+ dispatchEvent("${dispatchEventName}", [event=std::move(event)](jsi::Runtime &runtime) {
45
+ ${implementation}
46
+ });
47
+ }
48
+ `.trim();
49
+ const BasicComponentTemplate = ({className, eventName, dispatchEventName}) =>
50
+ `
51
+ void ${className}EventEmitter::${eventName}() const {
52
+ dispatchEvent("${dispatchEventName}");
53
+ }
54
+ `.trim();
55
+ function generateSetter(variableName, propertyName, propertyParts) {
56
+ const trailingPeriod = propertyParts.length === 0 ? '' : '.';
57
+ const eventChain = `event.${propertyParts.join(
58
+ '.',
59
+ )}${trailingPeriod}${propertyName});`;
60
+ return `${variableName}.setProperty(runtime, "${propertyName}", ${eventChain}`;
61
+ }
62
+ function generateEnumSetter(variableName, propertyName, propertyParts) {
63
+ const trailingPeriod = propertyParts.length === 0 ? '' : '.';
64
+ const eventChain = `event.${propertyParts.join(
65
+ '.',
66
+ )}${trailingPeriod}${propertyName})`;
67
+ return `${variableName}.setProperty(runtime, "${propertyName}", toString(${eventChain});`;
68
+ }
69
+ function generateSetters(parentPropertyName, properties, propertyParts) {
70
+ const propSetters = properties
71
+ .map(eventProperty => {
72
+ const typeAnnotation = eventProperty.typeAnnotation;
73
+ switch (typeAnnotation.type) {
74
+ case 'BooleanTypeAnnotation':
75
+ return generateSetter(
76
+ parentPropertyName,
77
+ eventProperty.name,
78
+ propertyParts,
79
+ );
80
+ case 'StringTypeAnnotation':
81
+ return generateSetter(
82
+ parentPropertyName,
83
+ eventProperty.name,
84
+ propertyParts,
85
+ );
86
+ case 'Int32TypeAnnotation':
87
+ return generateSetter(
88
+ parentPropertyName,
89
+ eventProperty.name,
90
+ propertyParts,
91
+ );
92
+ case 'DoubleTypeAnnotation':
93
+ return generateSetter(
94
+ parentPropertyName,
95
+ eventProperty.name,
96
+ propertyParts,
97
+ );
98
+ case 'FloatTypeAnnotation':
99
+ return generateSetter(
100
+ parentPropertyName,
101
+ eventProperty.name,
102
+ propertyParts,
103
+ );
104
+ case 'StringEnumTypeAnnotation':
105
+ return generateEnumSetter(
106
+ parentPropertyName,
107
+ eventProperty.name,
108
+ propertyParts,
109
+ );
110
+ case 'ObjectTypeAnnotation':
111
+ const propertyName = eventProperty.name;
112
+ return `
113
+ {
114
+ auto ${propertyName} = jsi::Object(runtime);
115
+ ${generateSetters(
116
+ propertyName,
117
+ typeAnnotation.properties,
118
+ propertyParts.concat([propertyName]),
119
+ )}
120
+
121
+ ${parentPropertyName}.setProperty(runtime, "${propertyName}", ${propertyName});
122
+ }
123
+ `.trim();
124
+ default:
125
+ typeAnnotation.type;
126
+ throw new Error('Received invalid event property type');
127
+ }
128
+ })
129
+ .join('\n');
130
+ return propSetters;
131
+ }
132
+ function generateEvent(componentName, event) {
133
+ // This is a gross hack necessary because native code is sending
134
+ // events named things like topChange to JS which is then converted back to
135
+ // call the onChange prop. We should be consistent throughout the system.
136
+ // In order to migrate to this new system we have to support the current
137
+ // naming scheme. We should delete this once we are able to control this name
138
+ // throughout the system.
139
+ const dispatchEventName = `${event.name[2].toLowerCase()}${event.name.slice(
140
+ 3,
141
+ )}`;
142
+ if (event.typeAnnotation.argument) {
143
+ const implementation = `
144
+ auto payload = jsi::Object(runtime);
145
+ ${generateSetters('payload', event.typeAnnotation.argument.properties, [])}
146
+ return payload;
147
+ `.trim();
148
+ if (!event.name.startsWith('on')) {
149
+ throw new Error('Expected the event name to start with `on`');
150
+ }
151
+ return ComponentTemplate({
152
+ className: componentName,
153
+ eventName: event.name,
154
+ dispatchEventName,
155
+ structName: generateEventStructName([event.name]),
156
+ implementation,
157
+ });
158
+ }
159
+ return BasicComponentTemplate({
160
+ className: componentName,
161
+ eventName: event.name,
162
+ dispatchEventName,
163
+ });
164
+ }
165
+ module.exports = {
166
+ generate(libraryName, schema, packageName, assumeNonnull = false) {
167
+ const moduleComponents = Object.keys(schema.modules)
168
+ .map(moduleName => {
169
+ const module = schema.modules[moduleName];
170
+ if (module.type !== 'Component') {
171
+ return;
172
+ }
173
+ const components = module.components;
174
+ // No components in this module
175
+ if (components == null) {
176
+ return null;
177
+ }
178
+ return components;
179
+ })
180
+ .filter(Boolean)
181
+ .reduce((acc, components) => Object.assign(acc, components), {});
182
+ const fileName = 'EventEmitters.cpp';
183
+ const componentEmitters = Object.keys(moduleComponents)
184
+ .map(componentName => {
185
+ const component = moduleComponents[componentName];
186
+ return component.events
187
+ .map(event => {
188
+ return generateEvent(componentName, event);
189
+ })
190
+ .join('\n');
191
+ })
192
+ .join('\n');
193
+ const replacedTemplate = FileTemplate({
194
+ libraryName,
195
+ events: componentEmitters,
196
+ });
197
+ return new Map([[fileName, replacedTemplate]]);
198
+ },
199
+ };