amis-rpc-design/node_modules/@react-native/codegen/lib/parsers/flow/modules/index.js.flow

277 lines
6.8 KiB
Plaintext
Raw Normal View History

2023-10-07 19:42:30 +08:00
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
* @format
*/
'use strict';
import type {
NamedShape,
NativeModuleAliasMap,
NativeModuleEnumMap,
NativeModuleBaseTypeAnnotation,
NativeModuleTypeAnnotation,
Nullable,
} from '../../../CodegenSchema';
import type {Parser} from '../../parser';
import type {ParserErrorCapturer, TypeDeclarationMap} from '../../utils';
const {resolveTypeAnnotation} = require('../utils');
const {
unwrapNullable,
wrapNullable,
assertGenericTypeAnnotationHasExactlyOneTypeParameter,
parseObjectProperty,
} = require('../../parsers-commons');
const {
emitArrayType,
emitBoolean,
emitFunction,
emitNumber,
emitGenericObject,
emitPromise,
emitRootTag,
emitVoid,
emitString,
emitMixed,
emitUnion,
emitCommonTypes,
typeAliasResolution,
typeEnumResolution,
} = require('../../parsers-primitives');
const {
UnsupportedTypeAnnotationParserError,
UnsupportedGenericParserError,
} = require('../../errors');
function translateTypeAnnotation(
hasteModuleName: string,
/**
* TODO(T71778680): Flow-type this node.
*/
flowTypeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
enumMap: {...NativeModuleEnumMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
parser: Parser,
): Nullable<NativeModuleTypeAnnotation> {
const {nullable, typeAnnotation, typeResolutionStatus} =
resolveTypeAnnotation(flowTypeAnnotation, types);
switch (typeAnnotation.type) {
case 'GenericTypeAnnotation': {
switch (typeAnnotation.id.name) {
case 'RootTag': {
return emitRootTag(nullable);
}
case 'Promise': {
return emitPromise(
hasteModuleName,
typeAnnotation,
parser,
nullable,
types,
aliasMap,
enumMap,
tryParse,
cxxOnly,
translateTypeAnnotation,
);
}
case 'Array':
case '$ReadOnlyArray': {
return emitArrayType(
hasteModuleName,
typeAnnotation,
parser,
types,
aliasMap,
enumMap,
cxxOnly,
nullable,
translateTypeAnnotation,
);
}
case '$ReadOnly': {
assertGenericTypeAnnotationHasExactlyOneTypeParameter(
hasteModuleName,
typeAnnotation,
parser,
);
const [paramType, isParamNullable] = unwrapNullable(
translateTypeAnnotation(
hasteModuleName,
typeAnnotation.typeParameters.params[0],
types,
aliasMap,
enumMap,
tryParse,
cxxOnly,
parser,
),
);
return wrapNullable(nullable || isParamNullable, paramType);
}
default: {
const commonType = emitCommonTypes(
hasteModuleName,
types,
typeAnnotation,
aliasMap,
enumMap,
tryParse,
cxxOnly,
nullable,
parser,
);
if (!commonType) {
throw new UnsupportedGenericParserError(
hasteModuleName,
typeAnnotation,
parser,
);
}
return commonType;
}
}
}
case 'ObjectTypeAnnotation': {
// if there is any indexer, then it is a dictionary
if (typeAnnotation.indexers) {
const indexers = typeAnnotation.indexers.filter(
member => member.type === 'ObjectTypeIndexer',
);
if (indexers.length > 0) {
// check the property type to prevent developers from using unsupported types
// the return value from `translateTypeAnnotation` is unused
const propertyType = indexers[0].value;
translateTypeAnnotation(
hasteModuleName,
propertyType,
types,
aliasMap,
enumMap,
tryParse,
cxxOnly,
parser,
);
// no need to do further checking
return emitGenericObject(nullable);
}
}
const objectTypeAnnotation = {
type: 'ObjectTypeAnnotation',
// $FlowFixMe[missing-type-arg]
properties: ([
...typeAnnotation.properties,
...typeAnnotation.indexers,
]: Array<$FlowFixMe>)
.map<?NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>>(
property => {
return tryParse(() => {
return parseObjectProperty(
property,
hasteModuleName,
types,
aliasMap,
enumMap,
tryParse,
cxxOnly,
nullable,
translateTypeAnnotation,
parser,
);
});
},
)
.filter(Boolean),
};
return typeAliasResolution(
typeResolutionStatus,
objectTypeAnnotation,
aliasMap,
nullable,
);
}
case 'BooleanTypeAnnotation': {
return emitBoolean(nullable);
}
case 'NumberTypeAnnotation': {
return emitNumber(nullable);
}
case 'VoidTypeAnnotation': {
return emitVoid(nullable);
}
case 'StringTypeAnnotation': {
return emitString(nullable);
}
case 'FunctionTypeAnnotation': {
return emitFunction(
nullable,
hasteModuleName,
typeAnnotation,
types,
aliasMap,
enumMap,
tryParse,
cxxOnly,
translateTypeAnnotation,
parser,
);
}
case 'UnionTypeAnnotation': {
return emitUnion(nullable, hasteModuleName, typeAnnotation, parser);
}
case 'StringLiteralTypeAnnotation': {
// 'a' is a special case for 'a' | 'b' but the type name is different
return wrapNullable(nullable, {
type: 'UnionTypeAnnotation',
memberType: 'StringTypeAnnotation',
});
}
case 'MixedTypeAnnotation': {
if (cxxOnly) {
return emitMixed(nullable);
} else {
return emitGenericObject(nullable);
}
}
case 'EnumStringBody':
case 'EnumNumberBody': {
return typeEnumResolution(
typeAnnotation,
typeResolutionStatus,
nullable,
hasteModuleName,
enumMap,
parser,
);
}
default: {
throw new UnsupportedTypeAnnotationParserError(
hasteModuleName,
typeAnnotation,
parser.language(),
);
}
}
}
module.exports = {
flowTranslateTypeAnnotation: translateTypeAnnotation,
};