mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Introduce TypeUtils (#42122)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/42122 This diff introduces the `TypeUtils` directory where we can put platform-specific, context-independent type transformations. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D52291837 fbshipit-source-id: 561b9c494aab5bfee3b3c668d3346bbd320e5266
This commit is contained in:
committed by
Facebook GitHub Bot
parent
327df8a719
commit
82f8cf1836
+16
-14
@@ -15,6 +15,10 @@ import type {ConstantsStruct, StructTypeAnnotation} from '../StructCollector';
|
||||
import type {StructSerilizationOutput} from './serializeStruct';
|
||||
|
||||
const {unwrapNullable} = require('../../../../parsers/parsers-commons');
|
||||
const {wrapOptional: wrapCxxOptional} = require('../../../TypeUtils/Cxx');
|
||||
const {
|
||||
wrapOptional: wrapObjCOptional,
|
||||
} = require('../../../TypeUtils/Objective-C');
|
||||
const {capitalize} = require('../../../Utils');
|
||||
const {getNamespacedStructName, getSafePropertyName} = require('../Utils');
|
||||
|
||||
@@ -78,15 +82,12 @@ function toObjCType(
|
||||
): string {
|
||||
const [typeAnnotation, nullable] = unwrapNullable(nullableTypeAnnotation);
|
||||
const isRequired = !nullable && !isOptional;
|
||||
const wrapOptional = (type: string) => {
|
||||
return isRequired ? type : `std::optional<${type}>`;
|
||||
};
|
||||
|
||||
switch (typeAnnotation.type) {
|
||||
case 'ReservedTypeAnnotation':
|
||||
switch (typeAnnotation.name) {
|
||||
case 'RootTag':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
default:
|
||||
(typeAnnotation.name: empty);
|
||||
throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`);
|
||||
@@ -94,19 +95,19 @@ function toObjCType(
|
||||
case 'StringTypeAnnotation':
|
||||
return 'NSString *';
|
||||
case 'NumberTypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'FloatTypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'Int32TypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'DoubleTypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'BooleanTypeAnnotation':
|
||||
return wrapOptional('bool');
|
||||
return wrapCxxOptional('bool', isRequired);
|
||||
case 'EnumDeclaration':
|
||||
switch (typeAnnotation.memberType) {
|
||||
case 'NumberTypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'StringTypeAnnotation':
|
||||
return 'NSString *';
|
||||
default:
|
||||
@@ -115,17 +116,18 @@ function toObjCType(
|
||||
);
|
||||
}
|
||||
case 'GenericObjectTypeAnnotation':
|
||||
return isRequired ? 'id<NSObject> ' : 'id<NSObject> _Nullable ';
|
||||
return wrapObjCOptional('id<NSObject>', isRequired);
|
||||
case 'ArrayTypeAnnotation':
|
||||
if (typeAnnotation.elementType == null) {
|
||||
return isRequired ? 'id<NSObject> ' : 'id<NSObject> _Nullable ';
|
||||
return wrapObjCOptional('id<NSObject>', isRequired);
|
||||
}
|
||||
|
||||
return wrapOptional(
|
||||
return wrapCxxOptional(
|
||||
`std::vector<${toObjCType(
|
||||
hasteModuleName,
|
||||
typeAnnotation.elementType,
|
||||
)}>`,
|
||||
isRequired,
|
||||
);
|
||||
case 'TypeAliasTypeAnnotation':
|
||||
const structName = capitalize(typeAnnotation.name);
|
||||
@@ -133,7 +135,7 @@ function toObjCType(
|
||||
hasteModuleName,
|
||||
structName,
|
||||
);
|
||||
return wrapOptional(`${namespacedStructName}::Builder`);
|
||||
return wrapCxxOptional(`${namespacedStructName}::Builder`, isRequired);
|
||||
default:
|
||||
(typeAnnotation.type: empty);
|
||||
throw new Error(
|
||||
|
||||
+16
-14
@@ -15,6 +15,10 @@ import type {RegularStruct, StructTypeAnnotation} from '../StructCollector';
|
||||
import type {StructSerilizationOutput} from './serializeStruct';
|
||||
|
||||
const {unwrapNullable} = require('../../../../parsers/parsers-commons');
|
||||
const {wrapOptional: wrapCxxOptional} = require('../../../TypeUtils/Cxx');
|
||||
const {
|
||||
wrapOptional: wrapObjCOptional,
|
||||
} = require('../../../TypeUtils/Objective-C');
|
||||
const {capitalize} = require('../../../Utils');
|
||||
const {getNamespacedStructName, getSafePropertyName} = require('../Utils');
|
||||
|
||||
@@ -69,15 +73,12 @@ function toObjCType(
|
||||
): string {
|
||||
const [typeAnnotation, nullable] = unwrapNullable(nullableTypeAnnotation);
|
||||
const isRequired = !nullable && !isOptional;
|
||||
const wrapOptional = (type: string) => {
|
||||
return isRequired ? type : `std::optional<${type}>`;
|
||||
};
|
||||
|
||||
switch (typeAnnotation.type) {
|
||||
case 'ReservedTypeAnnotation':
|
||||
switch (typeAnnotation.name) {
|
||||
case 'RootTag':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
default:
|
||||
(typeAnnotation.name: empty);
|
||||
throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`);
|
||||
@@ -85,19 +86,19 @@ function toObjCType(
|
||||
case 'StringTypeAnnotation':
|
||||
return 'NSString *';
|
||||
case 'NumberTypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'FloatTypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'Int32TypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'DoubleTypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'BooleanTypeAnnotation':
|
||||
return wrapOptional('bool');
|
||||
return wrapCxxOptional('bool', isRequired);
|
||||
case 'EnumDeclaration':
|
||||
switch (typeAnnotation.memberType) {
|
||||
case 'NumberTypeAnnotation':
|
||||
return wrapOptional('double');
|
||||
return wrapCxxOptional('double', isRequired);
|
||||
case 'StringTypeAnnotation':
|
||||
return 'NSString *';
|
||||
default:
|
||||
@@ -106,16 +107,17 @@ function toObjCType(
|
||||
);
|
||||
}
|
||||
case 'GenericObjectTypeAnnotation':
|
||||
return isRequired ? 'id<NSObject> ' : 'id<NSObject> _Nullable';
|
||||
return wrapObjCOptional('id<NSObject>', isRequired);
|
||||
case 'ArrayTypeAnnotation':
|
||||
if (typeAnnotation.elementType == null) {
|
||||
return isRequired ? 'id<NSObject> ' : 'id<NSObject> _Nullable';
|
||||
return wrapObjCOptional('id<NSObject>', isRequired);
|
||||
}
|
||||
return wrapOptional(
|
||||
return wrapCxxOptional(
|
||||
`facebook::react::LazyVector<${toObjCType(
|
||||
hasteModuleName,
|
||||
typeAnnotation.elementType,
|
||||
)}>`,
|
||||
isRequired,
|
||||
);
|
||||
case 'TypeAliasTypeAnnotation':
|
||||
const structName = capitalize(typeAnnotation.name);
|
||||
@@ -123,7 +125,7 @@ function toObjCType(
|
||||
hasteModuleName,
|
||||
structName,
|
||||
);
|
||||
return wrapOptional(namespacedStructName);
|
||||
return wrapCxxOptional(namespacedStructName, isRequired);
|
||||
default:
|
||||
(typeAnnotation.type: empty);
|
||||
throw new Error(
|
||||
|
||||
Vendored
+32
-37
@@ -24,6 +24,7 @@ const {
|
||||
unwrapNullable,
|
||||
wrapNullable,
|
||||
} = require('../../../parsers/parsers-commons');
|
||||
const {wrapOptional} = require('../../TypeUtils/Objective-C');
|
||||
const {capitalize} = require('../../Utils');
|
||||
const {getNamespacedStructName} = require('./Utils');
|
||||
const invariant = require('invariant');
|
||||
@@ -188,11 +189,7 @@ function getParamObjCType(
|
||||
): $ReadOnly<{objCType: string, isStruct: boolean}> {
|
||||
const {name: paramName, typeAnnotation: nullableTypeAnnotation} = param;
|
||||
const [typeAnnotation, nullable] = unwrapNullable(nullableTypeAnnotation);
|
||||
const notRequired = param.optional || nullable;
|
||||
|
||||
function wrapIntoNullableIfNeeded(generatedType: string) {
|
||||
return nullable ? `${generatedType} _Nullable` : generatedType;
|
||||
}
|
||||
const isRequired = !param.optional && !nullable;
|
||||
|
||||
const isStruct = (objCType: string) => ({
|
||||
isStruct: true,
|
||||
@@ -220,7 +217,7 @@ function getParamObjCType(
|
||||
* type Animal = {};
|
||||
* Array<Animal> => NSArray<JS::NativeSampleTurboModule::Animal *>, etc.
|
||||
*/
|
||||
return notStruct(wrapIntoNullableIfNeeded('NSArray *'));
|
||||
return notStruct(wrapOptional('NSArray *', !nullable));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +248,7 @@ function getParamObjCType(
|
||||
case 'ReservedTypeAnnotation':
|
||||
switch (structTypeAnnotation.name) {
|
||||
case 'RootTag':
|
||||
return notStruct(notRequired ? 'NSNumber *' : 'double');
|
||||
return notStruct(isRequired ? 'double' : 'NSNumber *');
|
||||
default:
|
||||
(structTypeAnnotation.name: empty);
|
||||
throw new Error(
|
||||
@@ -259,30 +256,30 @@ function getParamObjCType(
|
||||
);
|
||||
}
|
||||
case 'StringTypeAnnotation':
|
||||
return notStruct(wrapIntoNullableIfNeeded('NSString *'));
|
||||
return notStruct(wrapOptional('NSString *', !nullable));
|
||||
case 'NumberTypeAnnotation':
|
||||
return notStruct(notRequired ? 'NSNumber *' : 'double');
|
||||
return notStruct(isRequired ? 'double' : 'NSNumber *');
|
||||
case 'FloatTypeAnnotation':
|
||||
return notStruct(notRequired ? 'NSNumber *' : 'double');
|
||||
return notStruct(isRequired ? 'double' : 'NSNumber *');
|
||||
case 'DoubleTypeAnnotation':
|
||||
return notStruct(notRequired ? 'NSNumber *' : 'double');
|
||||
return notStruct(isRequired ? 'double' : 'NSNumber *');
|
||||
case 'Int32TypeAnnotation':
|
||||
return notStruct(notRequired ? 'NSNumber *' : 'double');
|
||||
return notStruct(isRequired ? 'double' : 'NSNumber *');
|
||||
case 'BooleanTypeAnnotation':
|
||||
return notStruct(notRequired ? 'NSNumber *' : 'BOOL');
|
||||
return notStruct(isRequired ? 'BOOL' : 'NSNumber *');
|
||||
case 'EnumDeclaration':
|
||||
switch (typeAnnotation.memberType) {
|
||||
case 'NumberTypeAnnotation':
|
||||
return notStruct(notRequired ? 'NSNumber *' : 'double');
|
||||
return notStruct(isRequired ? 'double' : 'NSNumber *');
|
||||
case 'StringTypeAnnotation':
|
||||
return notStruct(wrapIntoNullableIfNeeded('NSString *'));
|
||||
return notStruct(wrapOptional('NSString *', !nullable));
|
||||
default:
|
||||
throw new Error(
|
||||
`Unsupported enum type for param "${paramName}" in ${methodName}. Found: ${typeAnnotation.type}`,
|
||||
);
|
||||
}
|
||||
case 'GenericObjectTypeAnnotation':
|
||||
return notStruct(wrapIntoNullableIfNeeded('NSDictionary *'));
|
||||
return notStruct(wrapOptional('NSDictionary *', !nullable));
|
||||
default:
|
||||
(structTypeAnnotation.type: empty);
|
||||
throw new Error(
|
||||
@@ -296,10 +293,7 @@ function getReturnObjCType(
|
||||
nullableTypeAnnotation: Nullable<NativeModuleReturnTypeAnnotation>,
|
||||
): string {
|
||||
const [typeAnnotation, nullable] = unwrapNullable(nullableTypeAnnotation);
|
||||
|
||||
function wrapIntoNullableIfNeeded(generatedType: string) {
|
||||
return nullable ? `${generatedType} _Nullable` : generatedType;
|
||||
}
|
||||
const isRequired = !nullable;
|
||||
|
||||
switch (typeAnnotation.type) {
|
||||
case 'VoidTypeAnnotation':
|
||||
@@ -307,24 +301,25 @@ function getReturnObjCType(
|
||||
case 'PromiseTypeAnnotation':
|
||||
return 'void';
|
||||
case 'ObjectTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSDictionary *');
|
||||
return wrapOptional('NSDictionary *', isRequired);
|
||||
case 'TypeAliasTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSDictionary *');
|
||||
return wrapOptional('NSDictionary *', isRequired);
|
||||
case 'ArrayTypeAnnotation':
|
||||
if (typeAnnotation.elementType == null) {
|
||||
return wrapIntoNullableIfNeeded('NSArray<id<NSObject>> *');
|
||||
return wrapOptional('NSArray<id<NSObject>> *', isRequired);
|
||||
}
|
||||
|
||||
return wrapIntoNullableIfNeeded(
|
||||
return wrapOptional(
|
||||
`NSArray<${getReturnObjCType(
|
||||
methodName,
|
||||
typeAnnotation.elementType,
|
||||
)}> *`,
|
||||
isRequired,
|
||||
);
|
||||
case 'ReservedTypeAnnotation':
|
||||
switch (typeAnnotation.name) {
|
||||
case 'RootTag':
|
||||
return wrapIntoNullableIfNeeded('NSNumber *');
|
||||
return wrapOptional('NSNumber *', isRequired);
|
||||
default:
|
||||
(typeAnnotation.name: empty);
|
||||
throw new Error(
|
||||
@@ -334,23 +329,23 @@ function getReturnObjCType(
|
||||
case 'StringTypeAnnotation':
|
||||
// TODO: Can NSString * returns not be _Nullable?
|
||||
// In the legacy codegen, we don't surround NSSTring * with _Nullable
|
||||
return wrapIntoNullableIfNeeded('NSString *');
|
||||
return wrapOptional('NSString *', isRequired);
|
||||
case 'NumberTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSNumber *');
|
||||
return wrapOptional('NSNumber *', isRequired);
|
||||
case 'FloatTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSNumber *');
|
||||
return wrapOptional('NSNumber *', isRequired);
|
||||
case 'DoubleTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSNumber *');
|
||||
return wrapOptional('NSNumber *', isRequired);
|
||||
case 'Int32TypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSNumber *');
|
||||
return wrapOptional('NSNumber *', isRequired);
|
||||
case 'BooleanTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSNumber *');
|
||||
return wrapOptional('NSNumber *', isRequired);
|
||||
case 'EnumDeclaration':
|
||||
switch (typeAnnotation.memberType) {
|
||||
case 'NumberTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSNumber *');
|
||||
return wrapOptional('NSNumber *', isRequired);
|
||||
case 'StringTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSString *');
|
||||
return wrapOptional('NSString *', isRequired);
|
||||
default:
|
||||
throw new Error(
|
||||
`Unsupported enum return type for ${methodName}. Found: ${typeAnnotation.type}`,
|
||||
@@ -359,20 +354,20 @@ function getReturnObjCType(
|
||||
case 'UnionTypeAnnotation':
|
||||
switch (typeAnnotation.memberType) {
|
||||
case 'NumberTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSNumber *');
|
||||
return wrapOptional('NSNumber *', isRequired);
|
||||
case 'ObjectTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSDictionary *');
|
||||
return wrapOptional('NSDictionary *', isRequired);
|
||||
case 'StringTypeAnnotation':
|
||||
// TODO: Can NSString * returns not be _Nullable?
|
||||
// In the legacy codegen, we don't surround NSSTring * with _Nullable
|
||||
return wrapIntoNullableIfNeeded('NSString *');
|
||||
return wrapOptional('NSString *', isRequired);
|
||||
default:
|
||||
throw new Error(
|
||||
`Unsupported union return type for ${methodName}, found: ${typeAnnotation.memberType}"`,
|
||||
);
|
||||
}
|
||||
case 'GenericObjectTypeAnnotation':
|
||||
return wrapIntoNullableIfNeeded('NSDictionary *');
|
||||
return wrapOptional('NSDictionary *', isRequired);
|
||||
default:
|
||||
(typeAnnotation.type: 'MixedTypeAnnotation');
|
||||
throw new Error(
|
||||
|
||||
Reference in New Issue
Block a user