@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,778 @@
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
+ import type {ComponentShape} from '../../CodegenSchema';
13
+
14
+ const {
15
+ getNativeTypeFromAnnotation,
16
+ getLocalImports,
17
+ } = require('./ComponentsGeneratorUtils.js');
18
+
19
+ const {
20
+ convertDefaultTypeToString,
21
+ getEnumMaskName,
22
+ getEnumName,
23
+ toSafeCppString,
24
+ generateStructName,
25
+ toIntEnumValueName,
26
+ } = require('./CppHelpers.js');
27
+
28
+ import type {
29
+ ExtendsPropsShape,
30
+ NamedShape,
31
+ PropTypeAnnotation,
32
+ SchemaType,
33
+ } from '../../CodegenSchema';
34
+
35
+ // File path -> contents
36
+ type FilesOutput = Map<string, string>;
37
+ type StructsMap = Map<string, string>;
38
+
39
+ const FileTemplate = ({
40
+ imports,
41
+ componentClasses,
42
+ }: {
43
+ imports: string,
44
+ componentClasses: string,
45
+ }) => `
46
+ /**
47
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
48
+ *
49
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
50
+ * once the code is regenerated.
51
+ *
52
+ * ${'@'}generated by codegen project: GeneratePropsH.js
53
+ */
54
+ #pragma once
55
+
56
+ ${imports}
57
+
58
+ namespace facebook {
59
+ namespace react {
60
+
61
+ ${componentClasses}
62
+
63
+ } // namespace react
64
+ } // namespace facebook
65
+ `;
66
+
67
+ const ClassTemplate = ({
68
+ enums,
69
+ structs,
70
+ className,
71
+ props,
72
+ extendClasses,
73
+ }: {
74
+ enums: string,
75
+ structs: string,
76
+ className: string,
77
+ props: string,
78
+ extendClasses: string,
79
+ }) =>
80
+ `
81
+ ${enums}
82
+ ${structs}
83
+ class JSI_EXPORT ${className} final${extendClasses} {
84
+ public:
85
+ ${className}() = default;
86
+ ${className}(const PropsParserContext& context, const ${className} &sourceProps, const RawProps &rawProps);
87
+
88
+ #pragma mark - Props
89
+
90
+ ${props}
91
+ };
92
+ `.trim();
93
+
94
+ const EnumTemplate = ({
95
+ enumName,
96
+ values,
97
+ fromCases,
98
+ toCases,
99
+ }: {
100
+ enumName: string,
101
+ values: string,
102
+ fromCases: string,
103
+ toCases: string,
104
+ }) =>
105
+ `
106
+ enum class ${enumName} { ${values} };
107
+
108
+ static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ${enumName} &result) {
109
+ auto string = (std::string)value;
110
+ ${fromCases}
111
+ abort();
112
+ }
113
+
114
+ static inline std::string toString(const ${enumName} &value) {
115
+ switch (value) {
116
+ ${toCases}
117
+ }
118
+ }
119
+ `.trim();
120
+
121
+ const IntEnumTemplate = ({
122
+ enumName,
123
+ values,
124
+ fromCases,
125
+ toCases,
126
+ }: {
127
+ enumName: string,
128
+ values: string,
129
+ fromCases: string,
130
+ toCases: string,
131
+ }) =>
132
+ `
133
+ enum class ${enumName} { ${values} };
134
+
135
+ static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ${enumName} &result) {
136
+ assert(value.hasType<int>());
137
+ auto integerValue = (int)value;
138
+ switch (integerValue) {${fromCases}
139
+ }
140
+ abort();
141
+ }
142
+
143
+ static inline std::string toString(const ${enumName} &value) {
144
+ switch (value) {
145
+ ${toCases}
146
+ }
147
+ }
148
+ `.trim();
149
+
150
+ const StructTemplate = ({
151
+ structName,
152
+ fields,
153
+ fromCases,
154
+ }: {
155
+ structName: string,
156
+ fields: string,
157
+ fromCases: string,
158
+ }) =>
159
+ `struct ${structName} {
160
+ ${fields}
161
+ };
162
+
163
+ static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ${structName} &result) {
164
+ auto map = (butter::map<std::string, RawValue>)value;
165
+
166
+ ${fromCases}
167
+ }
168
+
169
+ static inline std::string toString(const ${structName} &value) {
170
+ return "[Object ${structName}]";
171
+ }
172
+ `.trim();
173
+
174
+ const ArrayConversionFunctionTemplate = ({
175
+ structName,
176
+ }: {
177
+ structName: string,
178
+ }) => `static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector<${structName}> &result) {
179
+ auto items = (std::vector<RawValue>)value;
180
+ for (const auto &item : items) {
181
+ ${structName} newItem;
182
+ fromRawValue(context, item, newItem);
183
+ result.emplace_back(newItem);
184
+ }
185
+ }
186
+ `;
187
+
188
+ const DoubleArrayConversionFunctionTemplate = ({
189
+ structName,
190
+ }: {
191
+ structName: string,
192
+ }) => `static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector<std::vector<${structName}>> &result) {
193
+ auto items = (std::vector<std::vector<RawValue>>)value;
194
+ for (const std::vector<RawValue> &item : items) {
195
+ auto nestedArray = std::vector<${structName}>{};
196
+ for (const RawValue &nestedItem : item) {
197
+ ${structName} newItem;
198
+ fromRawValue(context, nestedItem, newItem);
199
+ nestedArray.emplace_back(newItem);
200
+ }
201
+ result.emplace_back(nestedArray);
202
+ }
203
+ }
204
+ `;
205
+
206
+ const ArrayEnumTemplate = ({
207
+ enumName,
208
+ enumMask,
209
+ values,
210
+ fromCases,
211
+ toCases,
212
+ }: {
213
+ enumName: string,
214
+ enumMask: string,
215
+ values: string,
216
+ fromCases: string,
217
+ toCases: string,
218
+ }) =>
219
+ `
220
+ using ${enumMask} = uint32_t;
221
+
222
+ enum class ${enumName}: ${enumMask} {
223
+ ${values}
224
+ };
225
+
226
+ constexpr bool operator&(
227
+ ${enumMask} const lhs,
228
+ enum ${enumName} const rhs) {
229
+ return lhs & static_cast<${enumMask}>(rhs);
230
+ }
231
+
232
+ constexpr ${enumMask} operator|(
233
+ ${enumMask} const lhs,
234
+ enum ${enumName} const rhs) {
235
+ return lhs | static_cast<${enumMask}>(rhs);
236
+ }
237
+
238
+ constexpr void operator|=(
239
+ ${enumMask} &lhs,
240
+ enum ${enumName} const rhs) {
241
+ lhs = lhs | static_cast<${enumMask}>(rhs);
242
+ }
243
+
244
+ static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ${enumMask} &result) {
245
+ auto items = std::vector<std::string>{value};
246
+ for (const auto &item : items) {
247
+ ${fromCases}
248
+ abort();
249
+ }
250
+ }
251
+
252
+ static inline std::string toString(const ${enumMask} &value) {
253
+ auto result = std::string{};
254
+ auto separator = std::string{", "};
255
+
256
+ ${toCases}
257
+ if (!result.empty()) {
258
+ result.erase(result.length() - separator.length());
259
+ }
260
+ return result;
261
+ }
262
+ `.trim();
263
+
264
+ function getClassExtendString(component: ComponentShape): string {
265
+ if (component.extendsProps.length === 0) {
266
+ throw new Error('Invalid: component.extendsProps is empty');
267
+ }
268
+ const extendString =
269
+ ' : ' +
270
+ component.extendsProps
271
+ .map(extendProps => {
272
+ switch (extendProps.type) {
273
+ case 'ReactNativeBuiltInType':
274
+ switch (extendProps.knownTypeName) {
275
+ case 'ReactNativeCoreViewProps':
276
+ return 'public ViewProps';
277
+ default:
278
+ (extendProps.knownTypeName: empty);
279
+ throw new Error('Invalid knownTypeName');
280
+ }
281
+ default:
282
+ (extendProps.type: empty);
283
+ throw new Error('Invalid extended type');
284
+ }
285
+ })
286
+ .join(' ');
287
+
288
+ return extendString;
289
+ }
290
+
291
+ function convertValueToEnumOption(value: string): string {
292
+ return toSafeCppString(value);
293
+ }
294
+
295
+ function generateArrayEnumString(
296
+ componentName: string,
297
+ name: string,
298
+ options: $ReadOnlyArray<string>,
299
+ ): string {
300
+ const enumName = getEnumName(componentName, name);
301
+
302
+ const values = options
303
+ .map((option, index) => `${toSafeCppString(option)} = 1 << ${index}`)
304
+ .join(',\n ');
305
+
306
+ const fromCases = options
307
+ .map(
308
+ option =>
309
+ `if (item == "${option}") {
310
+ result |= ${enumName}::${toSafeCppString(option)};
311
+ continue;
312
+ }`,
313
+ )
314
+ .join('\n ');
315
+
316
+ const toCases = options
317
+ .map(
318
+ option =>
319
+ `if (value & ${enumName}::${toSafeCppString(option)}) {
320
+ result += "${option}" + separator;
321
+ }`,
322
+ )
323
+ .join('\n' + ' ');
324
+
325
+ return ArrayEnumTemplate({
326
+ enumName,
327
+ enumMask: getEnumMaskName(enumName),
328
+ values,
329
+ fromCases,
330
+ toCases,
331
+ });
332
+ }
333
+
334
+ function generateStringEnum(
335
+ componentName: string,
336
+ prop: NamedShape<PropTypeAnnotation>,
337
+ ) {
338
+ const typeAnnotation = prop.typeAnnotation;
339
+ if (typeAnnotation.type === 'StringEnumTypeAnnotation') {
340
+ const values: $ReadOnlyArray<string> = typeAnnotation.options;
341
+ const enumName = getEnumName(componentName, prop.name);
342
+
343
+ const fromCases = values
344
+ .map(
345
+ value =>
346
+ `if (string == "${value}") { result = ${enumName}::${convertValueToEnumOption(
347
+ value,
348
+ )}; return; }`,
349
+ )
350
+ .join('\n' + ' ');
351
+
352
+ const toCases = values
353
+ .map(
354
+ value =>
355
+ `case ${enumName}::${convertValueToEnumOption(
356
+ value,
357
+ )}: return "${value}";`,
358
+ )
359
+ .join('\n' + ' ');
360
+
361
+ return EnumTemplate({
362
+ enumName,
363
+ values: values.map(toSafeCppString).join(', '),
364
+ fromCases: fromCases,
365
+ toCases: toCases,
366
+ });
367
+ }
368
+
369
+ return '';
370
+ }
371
+
372
+ function generateIntEnum(
373
+ componentName: string,
374
+ prop: NamedShape<PropTypeAnnotation>,
375
+ ) {
376
+ const typeAnnotation = prop.typeAnnotation;
377
+ if (typeAnnotation.type === 'Int32EnumTypeAnnotation') {
378
+ const values: $ReadOnlyArray<number> = typeAnnotation.options;
379
+ const enumName = getEnumName(componentName, prop.name);
380
+
381
+ const fromCases = values
382
+ .map(
383
+ value =>
384
+ `
385
+ case ${value}:
386
+ result = ${enumName}::${toIntEnumValueName(prop.name, value)};
387
+ return;`,
388
+ )
389
+ .join('');
390
+
391
+ const toCases = values
392
+ .map(
393
+ value =>
394
+ `case ${enumName}::${toIntEnumValueName(
395
+ prop.name,
396
+ value,
397
+ )}: return "${value}";`,
398
+ )
399
+ .join('\n' + ' ');
400
+
401
+ const valueVariables = values
402
+ .map(val => `${toIntEnumValueName(prop.name, val)} = ${val}`)
403
+ .join(', ');
404
+
405
+ return IntEnumTemplate({
406
+ enumName,
407
+ values: valueVariables,
408
+ fromCases,
409
+ toCases,
410
+ });
411
+ }
412
+
413
+ return '';
414
+ }
415
+
416
+ function generateEnumString(
417
+ componentName: string,
418
+ component: ComponentShape,
419
+ ): string {
420
+ return component.props
421
+ .map(prop => {
422
+ if (
423
+ prop.typeAnnotation.type === 'ArrayTypeAnnotation' &&
424
+ prop.typeAnnotation.elementType.type === 'StringEnumTypeAnnotation'
425
+ ) {
426
+ return generateArrayEnumString(
427
+ componentName,
428
+ prop.name,
429
+ prop.typeAnnotation.elementType.options,
430
+ );
431
+ }
432
+
433
+ if (prop.typeAnnotation.type === 'StringEnumTypeAnnotation') {
434
+ return generateStringEnum(componentName, prop);
435
+ }
436
+
437
+ if (prop.typeAnnotation.type === 'Int32EnumTypeAnnotation') {
438
+ return generateIntEnum(componentName, prop);
439
+ }
440
+
441
+ if (prop.typeAnnotation.type === 'ObjectTypeAnnotation') {
442
+ return prop.typeAnnotation.properties
443
+ .map(property => {
444
+ if (property.typeAnnotation.type === 'StringEnumTypeAnnotation') {
445
+ return generateStringEnum(componentName, property);
446
+ } else if (
447
+ property.typeAnnotation.type === 'Int32EnumTypeAnnotation'
448
+ ) {
449
+ return generateIntEnum(componentName, property);
450
+ }
451
+ return null;
452
+ })
453
+ .filter(Boolean)
454
+ .join('\n');
455
+ }
456
+ })
457
+ .filter(Boolean)
458
+ .join('\n');
459
+ }
460
+
461
+ function generatePropsString(
462
+ componentName: string,
463
+ props: $ReadOnlyArray<NamedShape<PropTypeAnnotation>>,
464
+ ) {
465
+ return props
466
+ .map(prop => {
467
+ const nativeType = getNativeTypeFromAnnotation(componentName, prop, []);
468
+ const defaultValue = convertDefaultTypeToString(componentName, prop);
469
+
470
+ return `${nativeType} ${prop.name}{${defaultValue}};`;
471
+ })
472
+ .join('\n' + ' ');
473
+ }
474
+
475
+ function getExtendsImports(
476
+ extendsProps: $ReadOnlyArray<ExtendsPropsShape>,
477
+ ): Set<string> {
478
+ const imports: Set<string> = new Set();
479
+
480
+ imports.add('#include <react/renderer/core/PropsParserContext.h>');
481
+ imports.add('#include <jsi/jsi.h>');
482
+
483
+ extendsProps.forEach(extendProps => {
484
+ switch (extendProps.type) {
485
+ case 'ReactNativeBuiltInType':
486
+ switch (extendProps.knownTypeName) {
487
+ case 'ReactNativeCoreViewProps':
488
+ imports.add(
489
+ '#include <react/renderer/components/view/ViewProps.h>',
490
+ );
491
+ return;
492
+ default:
493
+ (extendProps.knownTypeName: empty);
494
+ throw new Error('Invalid knownTypeName');
495
+ }
496
+ default:
497
+ (extendProps.type: empty);
498
+ throw new Error('Invalid extended type');
499
+ }
500
+ });
501
+
502
+ return imports;
503
+ }
504
+
505
+ function generateStructsForComponent(
506
+ componentName: string,
507
+ component: ComponentShape,
508
+ ): string {
509
+ const structs = generateStructs(componentName, component.props, []);
510
+ const structArray = Array.from(structs.values());
511
+ if (structArray.length < 1) {
512
+ return '';
513
+ }
514
+ return structArray.join('\n\n');
515
+ }
516
+
517
+ function generateStructs(
518
+ componentName: string,
519
+ properties: $ReadOnlyArray<NamedShape<PropTypeAnnotation>>,
520
+ nameParts: Array<string>,
521
+ ): StructsMap {
522
+ const structs: StructsMap = new Map();
523
+ properties.forEach(prop => {
524
+ const typeAnnotation = prop.typeAnnotation;
525
+ if (typeAnnotation.type === 'ObjectTypeAnnotation') {
526
+ // Recursively visit all of the object properties.
527
+ // Note: this is depth first so that the nested structs are ordered first.
528
+ const elementProperties = typeAnnotation.properties;
529
+ const nestedStructs = generateStructs(
530
+ componentName,
531
+ elementProperties,
532
+ nameParts.concat([prop.name]),
533
+ );
534
+ nestedStructs.forEach(function (value, key) {
535
+ structs.set(key, value);
536
+ });
537
+
538
+ generateStruct(
539
+ structs,
540
+ componentName,
541
+ nameParts.concat([prop.name]),
542
+ typeAnnotation.properties,
543
+ );
544
+ }
545
+
546
+ if (
547
+ prop.typeAnnotation.type === 'ArrayTypeAnnotation' &&
548
+ prop.typeAnnotation.elementType.type === 'ObjectTypeAnnotation'
549
+ ) {
550
+ // Recursively visit all of the object properties.
551
+ // Note: this is depth first so that the nested structs are ordered first.
552
+ const elementProperties = prop.typeAnnotation.elementType.properties;
553
+ const nestedStructs = generateStructs(
554
+ componentName,
555
+ elementProperties,
556
+ nameParts.concat([prop.name]),
557
+ );
558
+ nestedStructs.forEach(function (value, key) {
559
+ structs.set(key, value);
560
+ });
561
+
562
+ // Generate this struct and its conversion function.
563
+ generateStruct(
564
+ structs,
565
+ componentName,
566
+ nameParts.concat([prop.name]),
567
+ elementProperties,
568
+ );
569
+
570
+ // Generate the conversion function for std:vector<Object>.
571
+ // Note: This needs to be at the end since it references the struct above.
572
+ structs.set(
573
+ `${[componentName, ...nameParts.concat([prop.name])].join(
574
+ '',
575
+ )}ArrayStruct`,
576
+ ArrayConversionFunctionTemplate({
577
+ structName: generateStructName(
578
+ componentName,
579
+ nameParts.concat([prop.name]),
580
+ ),
581
+ }),
582
+ );
583
+ }
584
+ if (
585
+ prop.typeAnnotation.type === 'ArrayTypeAnnotation' &&
586
+ prop.typeAnnotation.elementType.type === 'ArrayTypeAnnotation' &&
587
+ prop.typeAnnotation.elementType.elementType.type ===
588
+ 'ObjectTypeAnnotation'
589
+ ) {
590
+ // Recursively visit all of the object properties.
591
+ // Note: this is depth first so that the nested structs are ordered first.
592
+ const elementProperties =
593
+ prop.typeAnnotation.elementType.elementType.properties;
594
+ const nestedStructs = generateStructs(
595
+ componentName,
596
+ elementProperties,
597
+ nameParts.concat([prop.name]),
598
+ );
599
+ nestedStructs.forEach(function (value, key) {
600
+ structs.set(key, value);
601
+ });
602
+
603
+ // Generate this struct and its conversion function.
604
+ generateStruct(
605
+ structs,
606
+ componentName,
607
+ nameParts.concat([prop.name]),
608
+ elementProperties,
609
+ );
610
+
611
+ // Generate the conversion function for std:vector<Object>.
612
+ // Note: This needs to be at the end since it references the struct above.
613
+ structs.set(
614
+ `${[componentName, ...nameParts.concat([prop.name])].join(
615
+ '',
616
+ )}ArrayArrayStruct`,
617
+ DoubleArrayConversionFunctionTemplate({
618
+ structName: generateStructName(
619
+ componentName,
620
+ nameParts.concat([prop.name]),
621
+ ),
622
+ }),
623
+ );
624
+ }
625
+ });
626
+
627
+ return structs;
628
+ }
629
+
630
+ function generateStruct(
631
+ structs: StructsMap,
632
+ componentName: string,
633
+ nameParts: $ReadOnlyArray<string>,
634
+ properties: $ReadOnlyArray<NamedShape<PropTypeAnnotation>>,
635
+ ): void {
636
+ const structNameParts = nameParts;
637
+ const structName = generateStructName(componentName, structNameParts);
638
+
639
+ const fields = properties
640
+ .map(property => {
641
+ return `${getNativeTypeFromAnnotation(
642
+ componentName,
643
+ property,
644
+ structNameParts,
645
+ )} ${property.name};`;
646
+ })
647
+ .join('\n' + ' ');
648
+
649
+ properties.forEach((property: NamedShape<PropTypeAnnotation>) => {
650
+ const name = property.name;
651
+ switch (property.typeAnnotation.type) {
652
+ case 'BooleanTypeAnnotation':
653
+ return;
654
+ case 'StringTypeAnnotation':
655
+ return;
656
+ case 'Int32TypeAnnotation':
657
+ return;
658
+ case 'DoubleTypeAnnotation':
659
+ return;
660
+ case 'FloatTypeAnnotation':
661
+ return;
662
+ case 'ReservedPropTypeAnnotation':
663
+ return;
664
+ case 'ArrayTypeAnnotation':
665
+ return;
666
+ case 'StringEnumTypeAnnotation':
667
+ return;
668
+ case 'Int32EnumTypeAnnotation':
669
+ return;
670
+ case 'DoubleTypeAnnotation':
671
+ return;
672
+ case 'ObjectTypeAnnotation':
673
+ const props = property.typeAnnotation.properties;
674
+ if (props == null) {
675
+ throw new Error(
676
+ `Properties are expected for ObjectTypeAnnotation (see ${name} in ${componentName})`,
677
+ );
678
+ }
679
+ generateStruct(structs, componentName, nameParts.concat([name]), props);
680
+ return;
681
+ default:
682
+ (property.typeAnnotation.type: empty);
683
+ throw new Error(
684
+ `Received invalid component property type ${property.typeAnnotation.type}`,
685
+ );
686
+ }
687
+ });
688
+
689
+ const fromCases = properties
690
+ .map(property => {
691
+ const variable = 'tmp_' + property.name;
692
+ return `auto ${variable} = map.find("${property.name}");
693
+ if (${variable} != map.end()) {
694
+ fromRawValue(context, ${variable}->second, result.${property.name});
695
+ }`;
696
+ })
697
+ .join('\n ');
698
+
699
+ structs.set(
700
+ structName,
701
+ StructTemplate({
702
+ structName,
703
+ fields,
704
+ fromCases,
705
+ }),
706
+ );
707
+ }
708
+
709
+ module.exports = {
710
+ generate(
711
+ libraryName: string,
712
+ schema: SchemaType,
713
+ packageName?: string,
714
+ assumeNonnull: boolean = false,
715
+ ): FilesOutput {
716
+ const fileName = 'Props.h';
717
+
718
+ const allImports: Set<string> = new Set();
719
+
720
+ const componentClasses = Object.keys(schema.modules)
721
+ .map(moduleName => {
722
+ const module = schema.modules[moduleName];
723
+ if (module.type !== 'Component') {
724
+ return;
725
+ }
726
+
727
+ const {components} = module;
728
+ // No components in this module
729
+ if (components == null) {
730
+ return null;
731
+ }
732
+
733
+ return Object.keys(components)
734
+ .map(componentName => {
735
+ const component = components[componentName];
736
+
737
+ const newName = `${componentName}Props`;
738
+ const structString = generateStructsForComponent(
739
+ componentName,
740
+ component,
741
+ );
742
+ const enumString = generateEnumString(componentName, component);
743
+ const propsString = generatePropsString(
744
+ componentName,
745
+ component.props,
746
+ );
747
+ const extendString = getClassExtendString(component);
748
+ const extendsImports = getExtendsImports(component.extendsProps);
749
+ const imports = getLocalImports(component.props);
750
+
751
+ // $FlowFixMe[method-unbinding] added when improving typing for this parameters
752
+ extendsImports.forEach(allImports.add, allImports);
753
+ // $FlowFixMe[method-unbinding] added when improving typing for this parameters
754
+ imports.forEach(allImports.add, allImports);
755
+
756
+ const replacedTemplate = ClassTemplate({
757
+ enums: enumString,
758
+ structs: structString,
759
+ className: newName,
760
+ extendClasses: extendString,
761
+ props: propsString,
762
+ });
763
+
764
+ return replacedTemplate;
765
+ })
766
+ .join('\n\n');
767
+ })
768
+ .filter(Boolean)
769
+ .join('\n\n');
770
+
771
+ const replacedTemplate = FileTemplate({
772
+ componentClasses,
773
+ imports: Array.from(allImports).sort().join('\n'),
774
+ });
775
+
776
+ return new Map([[fileName, replacedTemplate]]);
777
+ },
778
+ };