@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,553 @@
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
+ Nullable,
15
+ NamedShape,
16
+ SchemaType,
17
+ NativeModulePropertyShape,
18
+ NativeModuleReturnTypeAnnotation,
19
+ NativeModuleFunctionTypeAnnotation,
20
+ NativeModuleParamTypeAnnotation,
21
+ } from '../../CodegenSchema';
22
+
23
+ import type {AliasResolver} from './Utils';
24
+ const {createAliasResolver, getModules} = require('./Utils');
25
+ const {unwrapNullable} = require('../../parsers/parsers-commons');
26
+
27
+ type FilesOutput = Map<string, string>;
28
+
29
+ function FileTemplate(
30
+ config: $ReadOnly<{
31
+ packageName: string,
32
+ className: string,
33
+ jsName: string,
34
+ methods: string,
35
+ imports: string,
36
+ }>,
37
+ ): string {
38
+ const {packageName, className, jsName, methods, imports} = config;
39
+ return `
40
+ /**
41
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
42
+ *
43
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
44
+ * once the code is regenerated.
45
+ *
46
+ * ${'@'}generated by codegen project: GenerateModuleJavaSpec.js
47
+ *
48
+ * ${'@'}nolint
49
+ */
50
+
51
+ package ${packageName};
52
+
53
+ ${imports}
54
+
55
+ public abstract class ${className} extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule {
56
+ public static final String NAME = "${jsName}";
57
+
58
+ public ${className}(ReactApplicationContext reactContext) {
59
+ super(reactContext);
60
+ }
61
+
62
+ @Override
63
+ public @Nonnull String getName() {
64
+ return NAME;
65
+ }
66
+
67
+ ${methods}
68
+ }
69
+ `;
70
+ }
71
+
72
+ function MethodTemplate(
73
+ config: $ReadOnly<{
74
+ abstract: boolean,
75
+ methodBody: ?string,
76
+ methodJavaAnnotation: string,
77
+ methodName: string,
78
+ translatedReturnType: string,
79
+ traversedArgs: Array<string>,
80
+ }>,
81
+ ): string {
82
+ const {
83
+ abstract,
84
+ methodBody,
85
+ methodJavaAnnotation,
86
+ methodName,
87
+ translatedReturnType,
88
+ traversedArgs,
89
+ } = config;
90
+ const methodQualifier = abstract ? 'abstract ' : '';
91
+ const methodClosing = abstract
92
+ ? ';'
93
+ : methodBody != null && methodBody.length > 0
94
+ ? ` { ${methodBody} }`
95
+ : ' {}';
96
+ return ` ${methodJavaAnnotation}
97
+ public ${methodQualifier}${translatedReturnType} ${methodName}(${traversedArgs.join(
98
+ ', ',
99
+ )})${methodClosing}`;
100
+ }
101
+
102
+ type Param = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
103
+
104
+ function translateFunctionParamToJavaType(
105
+ param: Param,
106
+ createErrorMessage: (typeName: string) => string,
107
+ resolveAlias: AliasResolver,
108
+ imports: Set<string>,
109
+ ): string {
110
+ const {optional, typeAnnotation: nullableTypeAnnotation} = param;
111
+ const [typeAnnotation, nullable] =
112
+ unwrapNullable<NativeModuleParamTypeAnnotation>(nullableTypeAnnotation);
113
+ const isRequired = !optional && !nullable;
114
+
115
+ function wrapNullable(javaType: string, nullableType?: string) {
116
+ if (!isRequired) {
117
+ imports.add('javax.annotation.Nullable');
118
+ return `@Nullable ${nullableType ?? javaType}`;
119
+ }
120
+ return javaType;
121
+ }
122
+
123
+ // FIXME: support class alias for args
124
+ let realTypeAnnotation = typeAnnotation;
125
+ if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
126
+ realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
127
+ }
128
+
129
+ switch (realTypeAnnotation.type) {
130
+ case 'ReservedTypeAnnotation':
131
+ switch (realTypeAnnotation.name) {
132
+ case 'RootTag':
133
+ return wrapNullable('double', 'Double');
134
+ default:
135
+ (realTypeAnnotation.name: empty);
136
+ throw new Error(createErrorMessage(realTypeAnnotation.name));
137
+ }
138
+ case 'StringTypeAnnotation':
139
+ return wrapNullable('String');
140
+ case 'NumberTypeAnnotation':
141
+ return wrapNullable('double', 'Double');
142
+ case 'FloatTypeAnnotation':
143
+ return wrapNullable('double', 'Double');
144
+ case 'DoubleTypeAnnotation':
145
+ return wrapNullable('double', 'Double');
146
+ case 'Int32TypeAnnotation':
147
+ return wrapNullable('double', 'Double');
148
+ case 'BooleanTypeAnnotation':
149
+ return wrapNullable('boolean', 'Boolean');
150
+ case 'EnumDeclaration':
151
+ switch (realTypeAnnotation.memberType) {
152
+ case 'NumberTypeAnnotation':
153
+ return wrapNullable('double', 'Double');
154
+ case 'StringTypeAnnotation':
155
+ return wrapNullable('String');
156
+ default:
157
+ throw new Error(createErrorMessage(realTypeAnnotation.type));
158
+ }
159
+ case 'UnionTypeAnnotation':
160
+ switch (typeAnnotation.memberType) {
161
+ case 'NumberTypeAnnotation':
162
+ return wrapNullable('double', 'Double');
163
+ case 'ObjectTypeAnnotation':
164
+ imports.add('com.facebook.react.bridge.ReadableMap');
165
+ return wrapNullable('ReadableMap');
166
+ case 'StringTypeAnnotation':
167
+ return wrapNullable('String');
168
+ default:
169
+ throw new Error(
170
+ `Unsupported union member returning value, found: ${realTypeAnnotation.memberType}"`,
171
+ );
172
+ }
173
+ case 'ObjectTypeAnnotation':
174
+ imports.add('com.facebook.react.bridge.ReadableMap');
175
+ return wrapNullable('ReadableMap');
176
+ case 'GenericObjectTypeAnnotation':
177
+ // Treat this the same as ObjectTypeAnnotation for now.
178
+ imports.add('com.facebook.react.bridge.ReadableMap');
179
+ return wrapNullable('ReadableMap');
180
+ case 'ArrayTypeAnnotation':
181
+ imports.add('com.facebook.react.bridge.ReadableArray');
182
+ return wrapNullable('ReadableArray');
183
+ case 'FunctionTypeAnnotation':
184
+ imports.add('com.facebook.react.bridge.Callback');
185
+ return wrapNullable('Callback');
186
+ default:
187
+ (realTypeAnnotation.type: 'EnumDeclaration' | 'MixedTypeAnnotation');
188
+ throw new Error(createErrorMessage(realTypeAnnotation.type));
189
+ }
190
+ }
191
+
192
+ function translateFunctionReturnTypeToJavaType(
193
+ nullableReturnTypeAnnotation: Nullable<NativeModuleReturnTypeAnnotation>,
194
+ createErrorMessage: (typeName: string) => string,
195
+ resolveAlias: AliasResolver,
196
+ imports: Set<string>,
197
+ ): string {
198
+ const [returnTypeAnnotation, nullable] =
199
+ unwrapNullable<NativeModuleReturnTypeAnnotation>(
200
+ nullableReturnTypeAnnotation,
201
+ );
202
+
203
+ function wrapNullable(javaType: string, nullableType?: string) {
204
+ if (nullable) {
205
+ imports.add('javax.annotation.Nullable');
206
+ return `@Nullable ${nullableType ?? javaType}`;
207
+ }
208
+ return javaType;
209
+ }
210
+
211
+ // FIXME: support class alias for args
212
+ let realTypeAnnotation = returnTypeAnnotation;
213
+ if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
214
+ realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
215
+ }
216
+
217
+ switch (realTypeAnnotation.type) {
218
+ case 'ReservedTypeAnnotation':
219
+ switch (realTypeAnnotation.name) {
220
+ case 'RootTag':
221
+ return wrapNullable('double', 'Double');
222
+ default:
223
+ (realTypeAnnotation.name: empty);
224
+ throw new Error(createErrorMessage(realTypeAnnotation.name));
225
+ }
226
+ case 'VoidTypeAnnotation':
227
+ return 'void';
228
+ case 'PromiseTypeAnnotation':
229
+ return 'void';
230
+ case 'StringTypeAnnotation':
231
+ return wrapNullable('String');
232
+ case 'NumberTypeAnnotation':
233
+ return wrapNullable('double', 'Double');
234
+ case 'FloatTypeAnnotation':
235
+ return wrapNullable('double', 'Double');
236
+ case 'DoubleTypeAnnotation':
237
+ return wrapNullable('double', 'Double');
238
+ case 'Int32TypeAnnotation':
239
+ return wrapNullable('double', 'Double');
240
+ case 'BooleanTypeAnnotation':
241
+ return wrapNullable('boolean', 'Boolean');
242
+ case 'EnumDeclaration':
243
+ switch (realTypeAnnotation.memberType) {
244
+ case 'NumberTypeAnnotation':
245
+ return wrapNullable('double', 'Double');
246
+ case 'StringTypeAnnotation':
247
+ return wrapNullable('String');
248
+ default:
249
+ throw new Error(createErrorMessage(realTypeAnnotation.type));
250
+ }
251
+ case 'UnionTypeAnnotation':
252
+ switch (realTypeAnnotation.memberType) {
253
+ case 'NumberTypeAnnotation':
254
+ return wrapNullable('double', 'Double');
255
+ case 'ObjectTypeAnnotation':
256
+ imports.add('com.facebook.react.bridge.WritableMap');
257
+ return wrapNullable('WritableMap');
258
+ case 'StringTypeAnnotation':
259
+ return wrapNullable('String');
260
+ default:
261
+ throw new Error(
262
+ `Unsupported union member returning value, found: ${realTypeAnnotation.memberType}"`,
263
+ );
264
+ }
265
+ case 'ObjectTypeAnnotation':
266
+ imports.add('com.facebook.react.bridge.WritableMap');
267
+ return wrapNullable('WritableMap');
268
+ case 'GenericObjectTypeAnnotation':
269
+ imports.add('com.facebook.react.bridge.WritableMap');
270
+ return wrapNullable('WritableMap');
271
+ case 'ArrayTypeAnnotation':
272
+ imports.add('com.facebook.react.bridge.WritableArray');
273
+ return wrapNullable('WritableArray');
274
+ default:
275
+ (realTypeAnnotation.type: 'EnumDeclaration' | 'MixedTypeAnnotation');
276
+ throw new Error(createErrorMessage(realTypeAnnotation.type));
277
+ }
278
+ }
279
+
280
+ function getFalsyReturnStatementFromReturnType(
281
+ nullableReturnTypeAnnotation: Nullable<NativeModuleReturnTypeAnnotation>,
282
+ createErrorMessage: (typeName: string) => string,
283
+ resolveAlias: AliasResolver,
284
+ ): string {
285
+ const [returnTypeAnnotation, nullable] =
286
+ unwrapNullable<NativeModuleReturnTypeAnnotation>(
287
+ nullableReturnTypeAnnotation,
288
+ );
289
+
290
+ let realTypeAnnotation = returnTypeAnnotation;
291
+ if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
292
+ realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
293
+ }
294
+
295
+ switch (realTypeAnnotation.type) {
296
+ case 'ReservedTypeAnnotation':
297
+ switch (realTypeAnnotation.name) {
298
+ case 'RootTag':
299
+ return 'return 0.0;';
300
+ default:
301
+ (realTypeAnnotation.name: empty);
302
+ throw new Error(createErrorMessage(realTypeAnnotation.name));
303
+ }
304
+ case 'VoidTypeAnnotation':
305
+ return '';
306
+ case 'PromiseTypeAnnotation':
307
+ return '';
308
+ case 'NumberTypeAnnotation':
309
+ return nullable ? 'return null;' : 'return 0;';
310
+ case 'FloatTypeAnnotation':
311
+ return nullable ? 'return null;' : 'return 0.0;';
312
+ case 'DoubleTypeAnnotation':
313
+ return nullable ? 'return null;' : 'return 0.0;';
314
+ case 'Int32TypeAnnotation':
315
+ return nullable ? 'return null;' : 'return 0;';
316
+ case 'BooleanTypeAnnotation':
317
+ return nullable ? 'return null;' : 'return false;';
318
+ case 'EnumDeclaration':
319
+ switch (realTypeAnnotation.memberType) {
320
+ case 'NumberTypeAnnotation':
321
+ return nullable ? 'return null;' : 'return 0;';
322
+ case 'StringTypeAnnotation':
323
+ return nullable ? 'return null;' : 'return "";';
324
+ default:
325
+ throw new Error(createErrorMessage(realTypeAnnotation.type));
326
+ }
327
+ case 'UnionTypeAnnotation':
328
+ switch (realTypeAnnotation.memberType) {
329
+ case 'NumberTypeAnnotation':
330
+ return nullable ? 'return null;' : 'return 0;';
331
+ case 'ObjectTypeAnnotation':
332
+ return 'return null;';
333
+ case 'StringTypeAnnotation':
334
+ return nullable ? 'return null;' : 'return "";';
335
+ default:
336
+ throw new Error(
337
+ `Unsupported union member returning value, found: ${realTypeAnnotation.memberType}"`,
338
+ );
339
+ }
340
+ case 'StringTypeAnnotation':
341
+ return nullable ? 'return null;' : 'return "";';
342
+ case 'ObjectTypeAnnotation':
343
+ return 'return null;';
344
+ case 'GenericObjectTypeAnnotation':
345
+ return 'return null;';
346
+ case 'ArrayTypeAnnotation':
347
+ return 'return null;';
348
+ default:
349
+ (realTypeAnnotation.type: 'EnumDeclaration' | 'MixedTypeAnnotation');
350
+ throw new Error(createErrorMessage(realTypeAnnotation.type));
351
+ }
352
+ }
353
+
354
+ // Build special-cased runtime check for getConstants().
355
+ function buildGetConstantsMethod(
356
+ method: NativeModulePropertyShape,
357
+ imports: Set<string>,
358
+ ): string {
359
+ const [methodTypeAnnotation] =
360
+ unwrapNullable<NativeModuleFunctionTypeAnnotation>(method.typeAnnotation);
361
+ if (
362
+ methodTypeAnnotation.returnTypeAnnotation.type === 'ObjectTypeAnnotation'
363
+ ) {
364
+ const requiredProps = [];
365
+ const optionalProps = [];
366
+ const rawProperties =
367
+ methodTypeAnnotation.returnTypeAnnotation.properties || [];
368
+ rawProperties.forEach(p => {
369
+ if (p.optional || p.typeAnnotation.type === 'NullableTypeAnnotation') {
370
+ optionalProps.push(p.name);
371
+ } else {
372
+ requiredProps.push(p.name);
373
+ }
374
+ });
375
+ if (requiredProps.length === 0 && optionalProps.length === 0) {
376
+ // Nothing to validate during runtime.
377
+ return '';
378
+ }
379
+
380
+ imports.add('com.facebook.react.common.build.ReactBuildConfig');
381
+ imports.add('java.util.Arrays');
382
+ imports.add('java.util.HashSet');
383
+ imports.add('java.util.Map');
384
+ imports.add('java.util.Set');
385
+ imports.add('javax.annotation.Nullable');
386
+
387
+ const requiredPropsFragment =
388
+ requiredProps.length > 0
389
+ ? `Arrays.asList(
390
+ ${requiredProps
391
+ .sort()
392
+ .map(p => `"${p}"`)
393
+ .join(',\n ')}
394
+ )`
395
+ : '';
396
+ const optionalPropsFragment =
397
+ optionalProps.length > 0
398
+ ? `Arrays.asList(
399
+ ${optionalProps
400
+ .sort()
401
+ .map(p => `"${p}"`)
402
+ .join(',\n ')}
403
+ )`
404
+ : '';
405
+
406
+ return ` protected abstract Map<String, Object> getTypedExportedConstants();
407
+
408
+ @Override
409
+ @DoNotStrip
410
+ public final @Nullable Map<String, Object> getConstants() {
411
+ Map<String, Object> constants = getTypedExportedConstants();
412
+ if (ReactBuildConfig.DEBUG || ReactBuildConfig.IS_INTERNAL_BUILD) {
413
+ Set<String> obligatoryFlowConstants = new HashSet<>(${requiredPropsFragment});
414
+ Set<String> optionalFlowConstants = new HashSet<>(${optionalPropsFragment});
415
+ Set<String> undeclaredConstants = new HashSet<>(constants.keySet());
416
+ undeclaredConstants.removeAll(obligatoryFlowConstants);
417
+ undeclaredConstants.removeAll(optionalFlowConstants);
418
+ if (!undeclaredConstants.isEmpty()) {
419
+ throw new IllegalStateException(String.format("Native Module Flow doesn't declare constants: %s", undeclaredConstants));
420
+ }
421
+ undeclaredConstants = obligatoryFlowConstants;
422
+ undeclaredConstants.removeAll(constants.keySet());
423
+ if (!undeclaredConstants.isEmpty()) {
424
+ throw new IllegalStateException(String.format("Native Module doesn't fill in constants: %s", undeclaredConstants));
425
+ }
426
+ }
427
+ return constants;
428
+ }`;
429
+ }
430
+
431
+ return '';
432
+ }
433
+
434
+ module.exports = {
435
+ generate(
436
+ libraryName: string,
437
+ schema: SchemaType,
438
+ packageName?: string,
439
+ assumeNonnull: boolean = false,
440
+ ): FilesOutput {
441
+ const files = new Map<string, string>();
442
+ const nativeModules = getModules(schema);
443
+
444
+ const normalizedPackageName =
445
+ packageName == null ? 'com.facebook.fbreact.specs' : packageName;
446
+ const outputDir = `java/${normalizedPackageName.replace(/\./g, '/')}`;
447
+
448
+ Object.keys(nativeModules).forEach(hasteModuleName => {
449
+ const {
450
+ aliases,
451
+ excludedPlatforms,
452
+ moduleName,
453
+ spec: {properties},
454
+ } = nativeModules[hasteModuleName];
455
+ if (excludedPlatforms != null && excludedPlatforms.includes('android')) {
456
+ return;
457
+ }
458
+ const resolveAlias = createAliasResolver(aliases);
459
+ const className = `${hasteModuleName}Spec`;
460
+
461
+ const imports: Set<string> = new Set([
462
+ // Always required.
463
+ 'com.facebook.react.bridge.ReactApplicationContext',
464
+ 'com.facebook.react.bridge.ReactContextBaseJavaModule',
465
+ 'com.facebook.react.bridge.ReactMethod',
466
+ 'com.facebook.react.bridge.ReactModuleWithSpec',
467
+ 'com.facebook.react.turbomodule.core.interfaces.TurboModule',
468
+ 'com.facebook.proguard.annotations.DoNotStrip',
469
+ 'javax.annotation.Nonnull',
470
+ ]);
471
+
472
+ const methods = properties.map(method => {
473
+ if (method.name === 'getConstants') {
474
+ return buildGetConstantsMethod(method, imports);
475
+ }
476
+
477
+ const [methodTypeAnnotation] =
478
+ unwrapNullable<NativeModuleFunctionTypeAnnotation>(
479
+ method.typeAnnotation,
480
+ );
481
+
482
+ // Handle return type
483
+ const translatedReturnType = translateFunctionReturnTypeToJavaType(
484
+ methodTypeAnnotation.returnTypeAnnotation,
485
+ typeName =>
486
+ `Unsupported return type for method ${method.name}. Found: ${typeName}`,
487
+ resolveAlias,
488
+ imports,
489
+ );
490
+ const returningPromise =
491
+ methodTypeAnnotation.returnTypeAnnotation.type ===
492
+ 'PromiseTypeAnnotation';
493
+ const isSyncMethod =
494
+ methodTypeAnnotation.returnTypeAnnotation.type !==
495
+ 'VoidTypeAnnotation' && !returningPromise;
496
+
497
+ // Handle method args
498
+ const traversedArgs = methodTypeAnnotation.params.map(param => {
499
+ const translatedParam = translateFunctionParamToJavaType(
500
+ param,
501
+ typeName =>
502
+ `Unsupported type for param "${param.name}" in ${method.name}. Found: ${typeName}`,
503
+ resolveAlias,
504
+ imports,
505
+ );
506
+ return `${translatedParam} ${param.name}`;
507
+ });
508
+
509
+ if (returningPromise) {
510
+ // Promise return type requires an extra arg at the end.
511
+ imports.add('com.facebook.react.bridge.Promise');
512
+ traversedArgs.push('Promise promise');
513
+ }
514
+
515
+ const methodJavaAnnotation = `@ReactMethod${
516
+ isSyncMethod ? '(isBlockingSynchronousMethod = true)' : ''
517
+ }\n @DoNotStrip`;
518
+ const methodBody = method.optional
519
+ ? getFalsyReturnStatementFromReturnType(
520
+ methodTypeAnnotation.returnTypeAnnotation,
521
+ typeName =>
522
+ `Cannot build falsy return statement for return type for method ${method.name}. Found: ${typeName}`,
523
+ resolveAlias,
524
+ )
525
+ : null;
526
+ return MethodTemplate({
527
+ abstract: !method.optional,
528
+ methodBody,
529
+ methodJavaAnnotation,
530
+ methodName: method.name,
531
+ translatedReturnType,
532
+ traversedArgs,
533
+ });
534
+ });
535
+
536
+ files.set(
537
+ `${outputDir}/${className}.java`,
538
+ FileTemplate({
539
+ packageName: normalizedPackageName,
540
+ className,
541
+ jsName: moduleName,
542
+ methods: methods.filter(Boolean).join('\n\n'),
543
+ imports: Array.from(imports)
544
+ .sort()
545
+ .map(p => `import ${p};`)
546
+ .join('\n'),
547
+ }),
548
+ );
549
+ });
550
+
551
+ return files;
552
+ },
553
+ };