Skip to content

Commit b5a868d

Browse files
christophpurrermeta-codesync[bot]
authored andcommitted
Add BigInt Type Support for Turbo Module Code Generation
Summary: This diff extends the React Native codegen to support BigIntTypeAnnotation. This type enables Turbo Modules to handle 64-bit integers safely by using JavaScript BigInt on the JS side and `facebook::react::BigInt` on native C++ platforms (with Java `long` for Android JNI). Changes: - Added BigIntTypeAnnotation to CodegenSchema.js - Added emitBigInt parser function in parsers-primitives.js - Added TSBigIntKeyword mapping in TypeScript parser - Updated GenerateModuleH.js for C++ header generation with `BigInt` param/return type and `jsi::BigInt` callFromJs return type - Updated GenerateModuleJavaSpec.js — BigInt maps to 'long' for JNI params but throws "not supported" for Java spec generation (not yet supported) - Updated GenerateModuleJniCpp.js with BigIntKind return type - Updated Objective-C generators: serializeMethod.js, StructCollector.js, serializeConstantsStruct.js, serializeRegularStruct.js - Updated compatibility check: ErrorFormatting.js, SortTypeAnnotations.js, TypeDiffing.js Example Turbo Module definition: ```javascript export interface Spec extends TurboModule { +getBigInt: (arg: bigint) => bigint; } ``` Changelog: [General][Added] - Add BigInt Type Support for Turbo Module Code Generation Differential Revision: D95232267
1 parent 75718e2 commit b5a868d

14 files changed

Lines changed: 71 additions & 11 deletions

File tree

packages/react-native-codegen/src/CodegenSchema.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export type Int32TypeAnnotation = Readonly<{
4242
type: 'Int32TypeAnnotation',
4343
}>;
4444

45+
export type BigIntTypeAnnotation = Readonly<{
46+
type: 'BigIntTypeAnnotation',
47+
}>;
48+
4549
export type NumberLiteralTypeAnnotation = Readonly<{
4650
type: 'NumberLiteralTypeAnnotation',
4751
value: number,
@@ -423,6 +427,7 @@ export type NativeModuleBaseTypeAnnotation =
423427
| NumberLiteralTypeAnnotation
424428
| BooleanLiteralTypeAnnotation
425429
| Int32TypeAnnotation
430+
| BigIntTypeAnnotation
426431
| DoubleTypeAnnotation
427432
| FloatTypeAnnotation
428433
| BooleanTypeAnnotation

packages/react-native-codegen/src/generators/modules/GenerateModuleH.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ function serializeArg(
119119
return wrap(val => `${val}.asNumber()`);
120120
case 'Int32TypeAnnotation':
121121
return wrap(val => `${val}.asNumber()`);
122+
case 'BigIntTypeAnnotation':
123+
return wrap(val => `jsi::Value(rt, ${val})`);
122124
case 'NumberLiteralTypeAnnotation':
123125
return wrap(val => `${val}.asNumber()`);
124126
case 'ArrayTypeAnnotation':
@@ -269,6 +271,8 @@ function translatePrimitiveJSTypeToCpp(
269271
return wrapOptional('double', isRequired);
270272
case 'Int32TypeAnnotation':
271273
return wrapOptional('int', isRequired);
274+
case 'BigIntTypeAnnotation':
275+
return wrapOptional('BigInt', isRequired);
272276
case 'BooleanTypeAnnotation':
273277
return wrapOptional('bool', isRequired);
274278
case 'BooleanLiteralTypeAnnotation':
@@ -613,6 +617,12 @@ function translateFunctionToCpp(
613617
enumMap,
614618
);
615619

620+
// BigInt methods return BigInt from C++, but the callFromJs template
621+
// parameter must be jsi::BigInt so the bridging layer converts via
622+
// Bridging<BigInt>::toJs -> jsi::BigInt -> jsi::Value.
623+
const callFromJsReturnType =
624+
returnType === 'BigInt' ? 'jsi::BigInt' : returnType;
625+
616626
let methodCallArgs = [...args].join(',\n ');
617627
if (methodCallArgs.length > 0) {
618628
methodCallArgs = `,\n ${methodCallArgs}`;
@@ -622,7 +632,7 @@ function translateFunctionToCpp(
622632
static_assert(
623633
bridging::getParameterCount(&T::${prop.name}) == ${paramTypes.length},
624634
"Expected ${prop.name}(...) to have ${paramTypes.length} parameters");
625-
${!isVoid ? (!isNullable ? 'return ' : 'auto result = ') : ''}bridging::callFromJs<${returnType}>(rt, &T::${prop.name}, static_cast<${hasteModuleName}CxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule)${methodCallArgs});${!isVoid ? (!isNullable ? '' : 'return result ? jsi::Value(std::move(*result)) : jsi::Value::null();') : 'return jsi::Value::undefined();'}\n }`;
635+
${!isVoid ? (!isNullable ? 'return ' : 'auto result = ') : ''}bridging::callFromJs<${callFromJsReturnType}>(rt, &T::${prop.name}, static_cast<${hasteModuleName}CxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule)${methodCallArgs});${!isVoid ? (!isNullable ? '' : 'return result ? jsi::Value(std::move(*result)) : jsi::Value::null();') : 'return jsi::Value::undefined();'}\n }`;
626636
}
627637
628638
type EventEmitterCpp = {

packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ function translateEventEmitterTypeToJavaType(
155155
case 'DoubleTypeAnnotation':
156156
case 'Int32TypeAnnotation':
157157
return 'double';
158+
case 'BigIntTypeAnnotation':
159+
imports.add('java.math.BigInteger');
160+
return 'BigInteger';
158161
case 'BooleanTypeAnnotation':
159162
case 'BooleanLiteralTypeAnnotation':
160163
return 'boolean';
@@ -267,9 +270,11 @@ function translateFunctionParamToJavaType(
267270
case 'FunctionTypeAnnotation':
268271
imports.add('com.facebook.react.bridge.Callback');
269272
return wrapOptional('Callback', isRequired);
270-
case 'ArrayBufferTypeAnnotation':
273+
case 'BigIntTypeAnnotation':
271274
throw new Error(
272-
`${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`,
275+
createErrorMessage(
276+
`${realTypeAnnotation.type} is not supported in Java TurboModules yet`,
277+
),
273278
);
274279
default:
275280
realTypeAnnotation.type as 'MixedTypeAnnotation';
@@ -365,9 +370,11 @@ function translateFunctionReturnTypeToJavaType(
365370
case 'ArrayTypeAnnotation':
366371
imports.add('com.facebook.react.bridge.WritableArray');
367372
return wrapOptional('WritableArray', isRequired);
368-
case 'ArrayBufferTypeAnnotation':
373+
case 'BigIntTypeAnnotation':
369374
throw new Error(
370-
`${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`,
375+
createErrorMessage(
376+
`${realTypeAnnotation.type} is not supported in Java TurboModules yet`,
377+
),
371378
);
372379
default:
373380
realTypeAnnotation.type as 'MixedTypeAnnotation';
@@ -451,10 +458,8 @@ function getFalsyReturnStatementFromReturnType(
451458
return 'return null;';
452459
case 'ArrayTypeAnnotation':
453460
return 'return null;';
454-
case 'ArrayBufferTypeAnnotation':
455-
throw new Error(
456-
`${createErrorMessage(realTypeAnnotation.type)} ArrayBuffer is only supported for C++ TurboModules.`,
457-
);
461+
case 'BigIntTypeAnnotation':
462+
throw new Error(createErrorMessage(realTypeAnnotation.type));
458463
default:
459464
realTypeAnnotation.type as 'MixedTypeAnnotation';
460465
throw new Error(createErrorMessage(realTypeAnnotation.type));

packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type JSReturnType =
3333
| 'StringKind'
3434
| 'BooleanKind'
3535
| 'NumberKind'
36+
| 'BigIntKind'
3637
| 'PromiseKind'
3738
| 'ObjectKind'
3839
| 'ArrayKind';
@@ -208,6 +209,8 @@ function translateReturnTypeToKind(
208209
return 'NumberKind';
209210
case 'Int32TypeAnnotation':
210211
return 'NumberKind';
212+
case 'BigIntTypeAnnotation':
213+
return 'BigIntKind';
211214
case 'PromiseTypeAnnotation':
212215
return 'PromiseKind';
213216
case 'GenericObjectTypeAnnotation':
@@ -297,6 +300,10 @@ function translateParamTypeToJniType(
297300
return !isRequired ? 'Ljava/lang/Double;' : 'D';
298301
case 'Int32TypeAnnotation':
299302
return !isRequired ? 'Ljava/lang/Double;' : 'D';
303+
case 'BigIntTypeAnnotation':
304+
throw new Error(
305+
`${realTypeAnnotation.type} is not supported in Java TurboModules yet`,
306+
);
300307
case 'GenericObjectTypeAnnotation':
301308
return 'Lcom/facebook/react/bridge/ReadableMap;';
302309
case 'ObjectTypeAnnotation':
@@ -383,6 +390,10 @@ function translateReturnTypeToJniType(
383390
return nullable ? 'Ljava/lang/Double;' : 'D';
384391
case 'Int32TypeAnnotation':
385392
return nullable ? 'Ljava/lang/Double;' : 'D';
393+
case 'BigIntTypeAnnotation':
394+
throw new Error(
395+
`${realTypeAnnotation.type} is not supported in Java TurboModules yet`,
396+
);
386397
case 'PromiseTypeAnnotation':
387398
return 'Lcom/facebook/react/bridge/Promise;';
388399
case 'GenericObjectTypeAnnotation':

packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'use strict';
1212

1313
import type {
14+
BigIntTypeAnnotation,
1415
BooleanLiteralTypeAnnotation,
1516
BooleanTypeAnnotation,
1617
DoubleTypeAnnotation,
@@ -72,6 +73,7 @@ export type StructTypeAnnotation =
7273
| NumberLiteralTypeAnnotation
7374
| BooleanLiteralTypeAnnotation
7475
| Int32TypeAnnotation
76+
| BigIntTypeAnnotation
7577
| DoubleTypeAnnotation
7678
| FloatTypeAnnotation
7779
| BooleanTypeAnnotation

packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ function toObjCValue(
115115
return wrapPrimitive('double');
116116
case 'Int32TypeAnnotation':
117117
return wrapPrimitive('double');
118+
case 'BigIntTypeAnnotation':
119+
return value;
118120
case 'DoubleTypeAnnotation':
119121
return wrapPrimitive('double');
120122
case 'BooleanTypeAnnotation':

packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ function toObjCValue(
106106
return RCTBridgingTo('Double');
107107
case 'Int32TypeAnnotation':
108108
return RCTBridgingTo('Double');
109+
case 'BigIntTypeAnnotation':
110+
return RCTBridgingTo('NSNumber');
109111
case 'DoubleTypeAnnotation':
110112
return RCTBridgingTo('Double');
111113
case 'BooleanTypeAnnotation':

packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStructUtils.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ function toObjCType(
5656
return wrapCxxOptional('double', isRequired);
5757
case 'DoubleTypeAnnotation':
5858
return wrapCxxOptional('double', isRequired);
59+
case 'BigIntTypeAnnotation':
60+
return wrapObjCOptional('NSNumber *', isRequired);
5961
case 'BooleanTypeAnnotation':
6062
return wrapCxxOptional('bool', isRequired);
6163
case 'BooleanLiteralTypeAnnotation':

packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type ReturnJSType =
5151
| 'ObjectKind'
5252
| 'ArrayKind'
5353
| 'NumberKind'
54+
| 'BigIntKind'
5455
| 'StringKind';
5556

5657
export type MethodSerializationOutput = Readonly<{
@@ -272,6 +273,8 @@ function getParamObjCType(
272273
return notStruct(isRequired ? 'double' : 'NSNumber *');
273274
case 'Int32TypeAnnotation':
274275
return notStruct(isRequired ? 'NSInteger' : 'NSNumber *');
276+
case 'BigIntTypeAnnotation':
277+
return notStruct(wrapOptional('NSNumber *', !nullable));
275278
case 'BooleanTypeAnnotation':
276279
return notStruct(isRequired ? 'BOOL' : 'NSNumber *');
277280
case 'BooleanLiteralTypeAnnotation':
@@ -353,6 +356,8 @@ function getReturnObjCType(
353356
return wrapOptional('NSNumber *', isRequired);
354357
case 'Int32TypeAnnotation':
355358
return wrapOptional('NSNumber *', isRequired);
359+
case 'BigIntTypeAnnotation':
360+
return wrapOptional('NSNumber *', isRequired);
356361
case 'BooleanTypeAnnotation':
357362
return wrapOptional('NSNumber *', isRequired);
358363
case 'BooleanLiteralTypeAnnotation':
@@ -431,6 +436,8 @@ function getReturnJSType(
431436
return 'NumberKind';
432437
case 'Int32TypeAnnotation':
433438
return 'NumberKind';
439+
case 'BigIntTypeAnnotation':
440+
return 'BigIntKind';
434441
case 'BooleanTypeAnnotation':
435442
return 'BooleanKind';
436443
case 'BooleanLiteralTypeAnnotation':

packages/react-native-codegen/src/parsers/parsers-primitives.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
'use strict';
1212

1313
import type {
14-
ArrayBufferTypeAnnotation,
14+
BigIntTypeAnnotation,
1515
BooleanLiteralTypeAnnotation,
1616
BooleanTypeAnnotation,
1717
DoubleTypeAnnotation,
@@ -88,6 +88,12 @@ function emitInt32Prop(
8888
};
8989
}
9090

91+
function emitBigInt(nullable: boolean): Nullable<BigIntTypeAnnotation> {
92+
return wrapNullable(nullable, {
93+
type: 'BigIntTypeAnnotation',
94+
});
95+
}
96+
9197
function emitNumber(
9298
nullable: boolean,
9399
): Nullable<NativeModuleNumberTypeAnnotation> {
@@ -664,6 +670,8 @@ function emitCommonTypes(
664670
const typeMap = {
665671
Stringish: emitStringish,
666672
Int32: emitInt32,
673+
BigInt: emitBigInt,
674+
BigIntTypeAnnotation: emitBigInt,
667675
Double: emitDouble,
668676
Float: emitFloat,
669677
UnsafeObject: emitGenericObject,

0 commit comments

Comments
 (0)