@react-native/codegen 0.88.0-nightly-20260806-65008fcdd → 0.88.0-nightly-20260807-5fb3ebce1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/generators/modules/GenerateModuleJavaSpec.js +9 -4
- package/lib/generators/modules/GenerateModuleJavaSpec.js.flow +16 -10
- package/lib/generators/modules/GenerateModuleJniCpp.js +6 -4
- package/lib/generators/modules/GenerateModuleJniCpp.js.flow +12 -5
- package/lib/generators/modules/GenerateModuleObjCpp/serializeMethod.js +4 -0
- package/lib/generators/modules/GenerateModuleObjCpp/serializeMethod.js.flow +6 -0
- package/lib/generators/modules/Utils.js +15 -1
- package/lib/generators/modules/Utils.js.flow +42 -0
- package/package.json +1 -1
|
@@ -12,7 +12,8 @@ const {
|
|
|
12
12
|
} = require('../Utils');
|
|
13
13
|
const {
|
|
14
14
|
createAliasResolver,
|
|
15
|
-
getModules
|
|
15
|
+
getModules,
|
|
16
|
+
throwIfUnsupportedPromiseArrayBuffer
|
|
16
17
|
} = require('./Utils');
|
|
17
18
|
function FileTemplate(config) {
|
|
18
19
|
const {
|
|
@@ -118,6 +119,7 @@ function translateEventEmitterTypeToJavaType(eventEmitter, imports) {
|
|
|
118
119
|
case 'FloatTypeAnnotation':
|
|
119
120
|
case 'Int32TypeAnnotation':
|
|
120
121
|
case 'VoidTypeAnnotation':
|
|
122
|
+
case 'ArrayBufferTypeAnnotation':
|
|
121
123
|
throw new Error(`Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`);
|
|
122
124
|
default:
|
|
123
125
|
typeAnnotation.type;
|
|
@@ -203,7 +205,8 @@ function translateFunctionParamToJavaType(param, createErrorMessage, resolveAlia
|
|
|
203
205
|
imports.add('com.facebook.react.bridge.Callback');
|
|
204
206
|
return wrapOptional('Callback', isRequired);
|
|
205
207
|
case 'ArrayBufferTypeAnnotation':
|
|
206
|
-
|
|
208
|
+
imports.add('java.nio.ByteBuffer');
|
|
209
|
+
return wrapOptional('ByteBuffer', isRequired);
|
|
207
210
|
default:
|
|
208
211
|
realTypeAnnotation.type;
|
|
209
212
|
throw new Error(createErrorMessage(realTypeAnnotation.type));
|
|
@@ -285,7 +288,8 @@ function translateFunctionReturnTypeToJavaType(nullableReturnTypeAnnotation, cre
|
|
|
285
288
|
imports.add('com.facebook.react.bridge.WritableArray');
|
|
286
289
|
return wrapOptional('WritableArray', isRequired);
|
|
287
290
|
case 'ArrayBufferTypeAnnotation':
|
|
288
|
-
|
|
291
|
+
imports.add('java.nio.ByteBuffer');
|
|
292
|
+
return wrapOptional('ByteBuffer', isRequired);
|
|
289
293
|
default:
|
|
290
294
|
realTypeAnnotation.type;
|
|
291
295
|
throw new Error(createErrorMessage(realTypeAnnotation.type));
|
|
@@ -359,7 +363,7 @@ function getFalsyReturnStatementFromReturnType(nullableReturnTypeAnnotation, cre
|
|
|
359
363
|
case 'ArrayTypeAnnotation':
|
|
360
364
|
return 'return null;';
|
|
361
365
|
case 'ArrayBufferTypeAnnotation':
|
|
362
|
-
|
|
366
|
+
return 'return null;';
|
|
363
367
|
default:
|
|
364
368
|
realTypeAnnotation.type;
|
|
365
369
|
throw new Error(createErrorMessage(realTypeAnnotation.type));
|
|
@@ -447,6 +451,7 @@ module.exports = {
|
|
|
447
451
|
return buildGetConstantsMethod(method, imports, resolveAlias);
|
|
448
452
|
}
|
|
449
453
|
const [methodTypeAnnotation] = unwrapNullable(method.typeAnnotation);
|
|
454
|
+
throwIfUnsupportedPromiseArrayBuffer(method.name, methodTypeAnnotation.returnTypeAnnotation);
|
|
450
455
|
const translatedReturnType = translateFunctionReturnTypeToJavaType(methodTypeAnnotation.returnTypeAnnotation, typeName => `Unsupported return type for method ${method.name}. Found: ${typeName}`, resolveAlias, imports);
|
|
451
456
|
const returningPromise = methodTypeAnnotation.returnTypeAnnotation.type === 'PromiseTypeAnnotation';
|
|
452
457
|
const isSyncMethod = methodTypeAnnotation.returnTypeAnnotation.type !== 'VoidTypeAnnotation' && !returningPromise;
|
|
@@ -25,7 +25,11 @@ import type {AliasResolver} from './Utils';
|
|
|
25
25
|
const {unwrapNullable} = require('../../parsers/parsers-commons');
|
|
26
26
|
const {wrapOptional} = require('../TypeUtils/Java');
|
|
27
27
|
const {parseValidUnionType, toPascalCase} = require('../Utils');
|
|
28
|
-
const {
|
|
28
|
+
const {
|
|
29
|
+
createAliasResolver,
|
|
30
|
+
getModules,
|
|
31
|
+
throwIfUnsupportedPromiseArrayBuffer,
|
|
32
|
+
} = require('./Utils');
|
|
29
33
|
|
|
30
34
|
type FilesOutput = Map<string, string>;
|
|
31
35
|
|
|
@@ -170,6 +174,7 @@ function translateEventEmitterTypeToJavaType(
|
|
|
170
174
|
case 'FloatTypeAnnotation':
|
|
171
175
|
case 'Int32TypeAnnotation':
|
|
172
176
|
case 'VoidTypeAnnotation':
|
|
177
|
+
case 'ArrayBufferTypeAnnotation':
|
|
173
178
|
// TODO: Add support for these types
|
|
174
179
|
throw new Error(
|
|
175
180
|
`Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
|
|
@@ -268,9 +273,8 @@ function translateFunctionParamToJavaType(
|
|
|
268
273
|
imports.add('com.facebook.react.bridge.Callback');
|
|
269
274
|
return wrapOptional('Callback', isRequired);
|
|
270
275
|
case 'ArrayBufferTypeAnnotation':
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
);
|
|
276
|
+
imports.add('java.nio.ByteBuffer');
|
|
277
|
+
return wrapOptional('ByteBuffer', isRequired);
|
|
274
278
|
default:
|
|
275
279
|
realTypeAnnotation.type as 'MixedTypeAnnotation';
|
|
276
280
|
throw new Error(createErrorMessage(realTypeAnnotation.type));
|
|
@@ -366,9 +370,8 @@ function translateFunctionReturnTypeToJavaType(
|
|
|
366
370
|
imports.add('com.facebook.react.bridge.WritableArray');
|
|
367
371
|
return wrapOptional('WritableArray', isRequired);
|
|
368
372
|
case 'ArrayBufferTypeAnnotation':
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
);
|
|
373
|
+
imports.add('java.nio.ByteBuffer');
|
|
374
|
+
return wrapOptional('ByteBuffer', isRequired);
|
|
372
375
|
default:
|
|
373
376
|
realTypeAnnotation.type as 'MixedTypeAnnotation';
|
|
374
377
|
throw new Error(createErrorMessage(realTypeAnnotation.type));
|
|
@@ -452,9 +455,7 @@ function getFalsyReturnStatementFromReturnType(
|
|
|
452
455
|
case 'ArrayTypeAnnotation':
|
|
453
456
|
return 'return null;';
|
|
454
457
|
case 'ArrayBufferTypeAnnotation':
|
|
455
|
-
|
|
456
|
-
`${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`,
|
|
457
|
-
);
|
|
458
|
+
return 'return null;';
|
|
458
459
|
default:
|
|
459
460
|
realTypeAnnotation.type as 'MixedTypeAnnotation';
|
|
460
461
|
throw new Error(createErrorMessage(realTypeAnnotation.type));
|
|
@@ -589,6 +590,11 @@ module.exports = {
|
|
|
589
590
|
method.typeAnnotation,
|
|
590
591
|
);
|
|
591
592
|
|
|
593
|
+
throwIfUnsupportedPromiseArrayBuffer(
|
|
594
|
+
method.name,
|
|
595
|
+
methodTypeAnnotation.returnTypeAnnotation,
|
|
596
|
+
);
|
|
597
|
+
|
|
592
598
|
// Handle return type
|
|
593
599
|
const translatedReturnType = translateFunctionReturnTypeToJavaType(
|
|
594
600
|
methodTypeAnnotation.returnTypeAnnotation,
|
|
@@ -8,7 +8,8 @@ const {
|
|
|
8
8
|
} = require('../Utils');
|
|
9
9
|
const {
|
|
10
10
|
createAliasResolver,
|
|
11
|
-
getModules
|
|
11
|
+
getModules,
|
|
12
|
+
throwIfUnsupportedPromiseArrayBuffer
|
|
12
13
|
} = require('./Utils');
|
|
13
14
|
const HostFunctionTemplate = ({
|
|
14
15
|
hasteModuleName,
|
|
@@ -147,7 +148,7 @@ function translateReturnTypeToKind(nullableTypeAnnotation, resolveAlias) {
|
|
|
147
148
|
case 'ArrayTypeAnnotation':
|
|
148
149
|
return 'ArrayKind';
|
|
149
150
|
case 'ArrayBufferTypeAnnotation':
|
|
150
|
-
|
|
151
|
+
return 'ArrayBufferKind';
|
|
151
152
|
default:
|
|
152
153
|
realTypeAnnotation.type;
|
|
153
154
|
throw new Error(`Unknown prop type for returning value, found: ${realTypeAnnotation.type}"`);
|
|
@@ -224,7 +225,7 @@ function translateParamTypeToJniType(param, resolveAlias) {
|
|
|
224
225
|
case 'FunctionTypeAnnotation':
|
|
225
226
|
return 'Lcom/facebook/react/bridge/Callback;';
|
|
226
227
|
case 'ArrayBufferTypeAnnotation':
|
|
227
|
-
|
|
228
|
+
return 'Ljava/nio/ByteBuffer;';
|
|
228
229
|
default:
|
|
229
230
|
realTypeAnnotation.type;
|
|
230
231
|
throw new Error(`Unknown prop type for method arg, found: ${realTypeAnnotation.type}"`);
|
|
@@ -298,7 +299,7 @@ function translateReturnTypeToJniType(nullableTypeAnnotation, resolveAlias) {
|
|
|
298
299
|
case 'ArrayTypeAnnotation':
|
|
299
300
|
return 'Lcom/facebook/react/bridge/WritableArray;';
|
|
300
301
|
case 'ArrayBufferTypeAnnotation':
|
|
301
|
-
|
|
302
|
+
return 'Ljava/nio/ByteBuffer;';
|
|
302
303
|
default:
|
|
303
304
|
realTypeAnnotation.type;
|
|
304
305
|
throw new Error(`Unknown prop type for method return type, found: ${realTypeAnnotation.type}"`);
|
|
@@ -336,6 +337,7 @@ function translateMethodForImplementation(hasteModuleName, property, resolveAlia
|
|
|
336
337
|
const {
|
|
337
338
|
returnTypeAnnotation
|
|
338
339
|
} = propertyTypeAnnotation;
|
|
340
|
+
throwIfUnsupportedPromiseArrayBuffer(property.name, returnTypeAnnotation);
|
|
339
341
|
if (property.name === 'getConstants' && returnTypeAnnotation.type === 'ObjectTypeAnnotation' && returnTypeAnnotation.properties.length === 0) {
|
|
340
342
|
return '';
|
|
341
343
|
}
|
|
@@ -24,7 +24,11 @@ import type {AliasResolver} from './Utils';
|
|
|
24
24
|
|
|
25
25
|
const {unwrapNullable} = require('../../parsers/parsers-commons');
|
|
26
26
|
const {parseValidUnionType} = require('../Utils');
|
|
27
|
-
const {
|
|
27
|
+
const {
|
|
28
|
+
createAliasResolver,
|
|
29
|
+
getModules,
|
|
30
|
+
throwIfUnsupportedPromiseArrayBuffer,
|
|
31
|
+
} = require('./Utils');
|
|
28
32
|
|
|
29
33
|
type FilesOutput = Map<string, string>;
|
|
30
34
|
|
|
@@ -35,7 +39,8 @@ type JSReturnType =
|
|
|
35
39
|
| 'NumberKind'
|
|
36
40
|
| 'PromiseKind'
|
|
37
41
|
| 'ObjectKind'
|
|
38
|
-
| 'ArrayKind'
|
|
42
|
+
| 'ArrayKind'
|
|
43
|
+
| 'ArrayBufferKind';
|
|
39
44
|
|
|
40
45
|
const HostFunctionTemplate = ({
|
|
41
46
|
hasteModuleName,
|
|
@@ -217,7 +222,7 @@ function translateReturnTypeToKind(
|
|
|
217
222
|
case 'ArrayTypeAnnotation':
|
|
218
223
|
return 'ArrayKind';
|
|
219
224
|
case 'ArrayBufferTypeAnnotation':
|
|
220
|
-
|
|
225
|
+
return 'ArrayBufferKind';
|
|
221
226
|
default:
|
|
222
227
|
realTypeAnnotation.type as 'MixedTypeAnnotation';
|
|
223
228
|
throw new Error(
|
|
@@ -306,7 +311,7 @@ function translateParamTypeToJniType(
|
|
|
306
311
|
case 'FunctionTypeAnnotation':
|
|
307
312
|
return 'Lcom/facebook/react/bridge/Callback;';
|
|
308
313
|
case 'ArrayBufferTypeAnnotation':
|
|
309
|
-
|
|
314
|
+
return 'Ljava/nio/ByteBuffer;';
|
|
310
315
|
default:
|
|
311
316
|
realTypeAnnotation.type as 'MixedTypeAnnotation';
|
|
312
317
|
throw new Error(
|
|
@@ -392,7 +397,7 @@ function translateReturnTypeToJniType(
|
|
|
392
397
|
case 'ArrayTypeAnnotation':
|
|
393
398
|
return 'Lcom/facebook/react/bridge/WritableArray;';
|
|
394
399
|
case 'ArrayBufferTypeAnnotation':
|
|
395
|
-
|
|
400
|
+
return 'Ljava/nio/ByteBuffer;';
|
|
396
401
|
default:
|
|
397
402
|
realTypeAnnotation.type as 'MixedTypeAnnotation';
|
|
398
403
|
throw new Error(
|
|
@@ -448,6 +453,8 @@ function translateMethodForImplementation(
|
|
|
448
453
|
unwrapNullable<NativeModuleFunctionTypeAnnotation>(property.typeAnnotation);
|
|
449
454
|
const {returnTypeAnnotation} = propertyTypeAnnotation;
|
|
450
455
|
|
|
456
|
+
throwIfUnsupportedPromiseArrayBuffer(property.name, returnTypeAnnotation);
|
|
457
|
+
|
|
451
458
|
if (
|
|
452
459
|
property.name === 'getConstants' &&
|
|
453
460
|
returnTypeAnnotation.type === 'ObjectTypeAnnotation' &&
|
|
@@ -11,6 +11,9 @@ const {
|
|
|
11
11
|
capitalize,
|
|
12
12
|
parseValidUnionType
|
|
13
13
|
} = require('../../Utils');
|
|
14
|
+
const {
|
|
15
|
+
throwIfUnsupportedPromiseArrayBuffer
|
|
16
|
+
} = require('../Utils');
|
|
14
17
|
const {
|
|
15
18
|
getNamespacedStructName
|
|
16
19
|
} = require('./Utils');
|
|
@@ -51,6 +54,7 @@ function serializeMethod(hasteModuleName, property, structCollector, resolveAlia
|
|
|
51
54
|
});
|
|
52
55
|
}
|
|
53
56
|
});
|
|
57
|
+
throwIfUnsupportedPromiseArrayBuffer(methodName, propertyTypeAnnotation.returnTypeAnnotation);
|
|
54
58
|
const [returnTypeAnnotation] = unwrapNullable(propertyTypeAnnotation.returnTypeAnnotation);
|
|
55
59
|
if (returnTypeAnnotation.type === 'PromiseTypeAnnotation') {
|
|
56
60
|
methodParams.push({
|
|
@@ -26,6 +26,7 @@ const {
|
|
|
26
26
|
} = require('../../../parsers/parsers-commons');
|
|
27
27
|
const {wrapOptional} = require('../../TypeUtils/Objective-C');
|
|
28
28
|
const {capitalize, parseValidUnionType} = require('../../Utils');
|
|
29
|
+
const {throwIfUnsupportedPromiseArrayBuffer} = require('../Utils');
|
|
29
30
|
const {getNamespacedStructName} = require('./Utils');
|
|
30
31
|
const invariant = require('invariant');
|
|
31
32
|
|
|
@@ -103,6 +104,11 @@ function serializeMethod(
|
|
|
103
104
|
}
|
|
104
105
|
});
|
|
105
106
|
|
|
107
|
+
throwIfUnsupportedPromiseArrayBuffer(
|
|
108
|
+
methodName,
|
|
109
|
+
propertyTypeAnnotation.returnTypeAnnotation,
|
|
110
|
+
);
|
|
111
|
+
|
|
106
112
|
// Unwrap returnTypeAnnotation, so we check if the return type is Promise
|
|
107
113
|
// TODO(T76719514): Disallow nullable PromiseTypeAnnotations
|
|
108
114
|
const [returnTypeAnnotation] = unwrapNullable(
|
|
@@ -30,9 +30,23 @@ function isArrayRecursiveMember(parentObjectAliasName, nullableTypeAnnotation) {
|
|
|
30
30
|
const [typeAnnotation] = unwrapNullable(nullableTypeAnnotation);
|
|
31
31
|
return parentObjectAliasName !== undefined && typeAnnotation.type === 'ArrayTypeAnnotation' && ((_typeAnnotation$eleme = typeAnnotation.elementType) === null || _typeAnnotation$eleme === void 0 ? void 0 : _typeAnnotation$eleme.name) === parentObjectAliasName;
|
|
32
32
|
}
|
|
33
|
+
function throwIfUnsupportedPromiseArrayBuffer(methodName, nullableReturnTypeAnnotation) {
|
|
34
|
+
const [returnTypeAnnotation] = unwrapNullable(nullableReturnTypeAnnotation);
|
|
35
|
+
if (returnTypeAnnotation.type !== 'PromiseTypeAnnotation') {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
let elementType = returnTypeAnnotation.elementType;
|
|
39
|
+
if (elementType.type === 'NullableTypeAnnotation') {
|
|
40
|
+
elementType = elementType.typeAnnotation;
|
|
41
|
+
}
|
|
42
|
+
if (elementType.type === 'ArrayBufferTypeAnnotation') {
|
|
43
|
+
throw new Error(`Unsupported return type for method "${methodName}": Promise<ArrayBuffer> is not ` + 'supported for Android (Java/Kotlin) or iOS (ObjC) TurboModules. Use a C++ ' + '(Cxx) TurboModule, return the ArrayBuffer from a synchronous method, or resolve ' + 'the Promise with a different type. ArrayBuffer is still supported as a method ' + 'argument and as a synchronous return value on all platforms.');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
33
46
|
module.exports = {
|
|
34
47
|
createAliasResolver,
|
|
35
48
|
getModules,
|
|
36
49
|
isDirectRecursiveMember,
|
|
37
|
-
isArrayRecursiveMember
|
|
50
|
+
isArrayRecursiveMember,
|
|
51
|
+
throwIfUnsupportedPromiseArrayBuffer
|
|
38
52
|
};
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import type {
|
|
14
14
|
NativeModuleAliasMap,
|
|
15
15
|
NativeModuleObjectTypeAnnotation,
|
|
16
|
+
NativeModuleReturnTypeAnnotation,
|
|
16
17
|
NativeModuleSchema,
|
|
17
18
|
NativeModuleTypeAnnotation,
|
|
18
19
|
Nullable,
|
|
@@ -77,9 +78,50 @@ function isArrayRecursiveMember(
|
|
|
77
78
|
);
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
// Platform-native (Java/Kotlin and ObjC) TurboModules copy ArrayBuffer
|
|
82
|
+
// arguments and return ArrayBuffers zero-copy from synchronous methods, but
|
|
83
|
+
// `Promise<ArrayBuffer>` is not part of their contract.
|
|
84
|
+
//
|
|
85
|
+
// On Android it cannot work: the resolve path serializes through
|
|
86
|
+
// folly::dynamic, which cannot carry raw bytes. On iOS the resolve path is a
|
|
87
|
+
// direct ObjC->jsi conversion that would in fact produce an ArrayBuffer for an
|
|
88
|
+
// NSMutableData, so the limitation there is not technical — the guard is
|
|
89
|
+
// applied to ObjC as well to keep one cross-platform contract, so a spec that
|
|
90
|
+
// compiles for iOS cannot fail to build for Android.
|
|
91
|
+
//
|
|
92
|
+
// Reject `Promise<ArrayBuffer>` at codegen time for both native platforms so
|
|
93
|
+
// the unsupported case surfaces as a build error rather than a runtime failure
|
|
94
|
+
// or a silent iOS/Android divergence.
|
|
95
|
+
function throwIfUnsupportedPromiseArrayBuffer(
|
|
96
|
+
methodName: string,
|
|
97
|
+
nullableReturnTypeAnnotation: Nullable<NativeModuleReturnTypeAnnotation>,
|
|
98
|
+
): void {
|
|
99
|
+
const [returnTypeAnnotation] =
|
|
100
|
+
unwrapNullable<NativeModuleReturnTypeAnnotation>(
|
|
101
|
+
nullableReturnTypeAnnotation,
|
|
102
|
+
);
|
|
103
|
+
if (returnTypeAnnotation.type !== 'PromiseTypeAnnotation') {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
let elementType = returnTypeAnnotation.elementType;
|
|
107
|
+
if (elementType.type === 'NullableTypeAnnotation') {
|
|
108
|
+
elementType = elementType.typeAnnotation;
|
|
109
|
+
}
|
|
110
|
+
if (elementType.type === 'ArrayBufferTypeAnnotation') {
|
|
111
|
+
throw new Error(
|
|
112
|
+
`Unsupported return type for method "${methodName}": Promise<ArrayBuffer> is not ` +
|
|
113
|
+
'supported for Android (Java/Kotlin) or iOS (ObjC) TurboModules. Use a C++ ' +
|
|
114
|
+
'(Cxx) TurboModule, return the ArrayBuffer from a synchronous method, or resolve ' +
|
|
115
|
+
'the Promise with a different type. ArrayBuffer is still supported as a method ' +
|
|
116
|
+
'argument and as a synchronous return value on all platforms.',
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
80
121
|
module.exports = {
|
|
81
122
|
createAliasResolver,
|
|
82
123
|
getModules,
|
|
83
124
|
isDirectRecursiveMember,
|
|
84
125
|
isArrayRecursiveMember,
|
|
126
|
+
throwIfUnsupportedPromiseArrayBuffer,
|
|
85
127
|
};
|