jiuyiUniapp/service/node_modules/@react-native/codegen/lib/parsers/parserMock.js.flow

501 lines
12 KiB
Plaintext

/**
* 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 {
ExtendsPropsShape,
NamedShape,
NativeModuleAliasMap,
NativeModuleEnumMap,
NativeModuleEnumMember,
NativeModuleEnumMemberType,
NativeModuleParamTypeAnnotation,
Nullable,
PropTypeAnnotation,
SchemaType,
UnionTypeAnnotationMemberType,
} from '../CodegenSchema';
import type {ParserType} from './errors';
import type {
GetSchemaInfoFN,
GetTypeAnnotationFN,
Parser,
ResolveTypeAnnotationFN,
} from './parser';
import type {
ParserErrorCapturer,
PropAST,
TypeDeclarationMap,
TypeResolutionStatus,
} from './utils';
import invariant from 'invariant';
const {
UnsupportedObjectPropertyTypeAnnotationParserError,
} = require('./errors');
const {parseFlowAndThrowErrors} = require('./flow/parseFlowAndThrowErrors');
const {buildPropSchema} = require('./parsers-commons');
const {flattenProperties} = require('./typescript/components/componentsUtils');
type ExtendsForProp = null | {
type: 'ReactNativeBuiltInType',
knownTypeName: 'ReactNativeCoreViewProps',
};
const schemaMock = {
modules: {
StringPropNativeComponentView: {
type: 'Component',
components: {
StringPropNativeComponentView: {
extendsProps: [],
events: [],
props: [],
commands: [],
},
},
},
},
};
export class MockedParser implements Parser {
typeParameterInstantiation: string = 'TypeParameterInstantiation';
typeAlias: string = 'TypeAlias';
enumDeclaration: string = 'EnumDeclaration';
interfaceDeclaration: string = 'InterfaceDeclaration';
nullLiteralTypeAnnotation: string = 'NullLiteralTypeAnnotation';
undefinedLiteralTypeAnnotation: string = 'VoidLiteralTypeAnnotation';
isProperty(property: $FlowFixMe): boolean {
return property.type === 'ObjectTypeProperty';
}
getKeyName(property: $FlowFixMe, hasteModuleName: string): string {
if (!this.isProperty(property)) {
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
hasteModuleName,
property,
property.type,
this.language(),
);
}
return property.key.name;
}
language(): ParserType {
return 'Flow';
}
getTypeAnnotationName(typeAnnotation: $FlowFixMe): string {
return typeAnnotation?.id?.name;
}
checkIfInvalidModule(typeArguments: $FlowFixMe): boolean {
return false;
}
remapUnionTypeAnnotationMemberNames(
membersTypes: $FlowFixMe[],
): UnionTypeAnnotationMemberType[] {
return [];
}
getStringLiteralUnionTypeAnnotationStringLiterals(
membersTypes: $FlowFixMe[],
): string[] {
return [];
}
parseFile(filename: string): SchemaType {
return schemaMock;
}
parseString(contents: string, filename: ?string): SchemaType {
return schemaMock;
}
parseModuleFixture(filename: string): SchemaType {
return schemaMock;
}
getAst(contents: string, filename?: ?string): $FlowFixMe {
return parseFlowAndThrowErrors(contents, {filename});
}
getFunctionTypeAnnotationParameters(
functionTypeAnnotation: $FlowFixMe,
): $ReadOnlyArray<$FlowFixMe> {
return functionTypeAnnotation.params;
}
getFunctionNameFromParameter(
parameter: NamedShape<Nullable<NativeModuleParamTypeAnnotation>>,
): $FlowFixMe {
return parameter.name;
}
getParameterName(parameter: $FlowFixMe): string {
return parameter.name.name;
}
getParameterTypeAnnotation(parameter: $FlowFixMe): $FlowFixMe {
return parameter.typeAnnotation;
}
getFunctionTypeAnnotationReturnType(
functionTypeAnnotation: $FlowFixMe,
): $FlowFixMe {
return functionTypeAnnotation.returnType;
}
parseEnumMembersType(typeAnnotation: $FlowFixMe): NativeModuleEnumMemberType {
return typeAnnotation.type;
}
validateEnumMembersSupported(
typeAnnotation: $FlowFixMe,
enumMembersType: NativeModuleEnumMemberType,
): void {
return;
}
parseEnumMembers(
typeAnnotation: $FlowFixMe,
): $ReadOnlyArray<NativeModuleEnumMember> {
return typeAnnotation.type === 'StringTypeAnnotation'
? [
{
name: 'Hello',
value: 'hello',
},
{
name: 'Goodbye',
value: 'goodbye',
},
]
: [
{
name: 'On',
value: '1',
},
{
name: 'Off',
value: '0',
},
];
}
isModuleInterface(node: $FlowFixMe): boolean {
return (
node.type === 'InterfaceDeclaration' &&
node.extends.length === 1 &&
node.extends[0].type === 'InterfaceExtends' &&
node.extends[0].id.name === 'TurboModule'
);
}
isGenericTypeAnnotation(type: $FlowFixMe): boolean {
return true;
}
extractAnnotatedElement(
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
): $FlowFixMe {
return types[typeAnnotation.typeParameters.params[0].id.name];
}
getTypes(ast: $FlowFixMe): TypeDeclarationMap {
return {};
}
callExpressionTypeParameters(callExpression: $FlowFixMe): $FlowFixMe | null {
return callExpression.typeArguments || null;
}
computePartialProperties(
properties: Array<$FlowFixMe>,
hasteModuleName: string,
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
enumMap: {...NativeModuleEnumMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
): Array<$FlowFixMe> {
return [
{
name: 'a',
optional: true,
typeAnnotation: {type: 'StringTypeAnnotation'},
},
{
name: 'b',
optional: true,
typeAnnotation: {type: 'BooleanTypeAnnotation'},
},
];
}
functionTypeAnnotation(propertyValueType: string): boolean {
return propertyValueType === 'FunctionTypeAnnotation';
}
getTypeArgumentParamsFromDeclaration(declaration: $FlowFixMe): $FlowFixMe {
return declaration.typeArguments.params;
}
getNativeComponentType(
typeArgumentParams: $FlowFixMe,
funcArgumentParams: $FlowFixMe,
): {[string]: string} {
return {
propsTypeName: typeArgumentParams[0].id.name,
componentName: funcArgumentParams[0].value,
};
}
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
return annotatedElement.right.properties;
}
bodyProperties(typeAlias: $FlowFixMe): $ReadOnlyArray<$FlowFixMe> {
return typeAlias.body.properties;
}
convertKeywordToTypeAnnotation(keyword: string): string {
return keyword;
}
argumentForProp(prop: PropAST): $FlowFixMe {
return prop.expression;
}
nameForArgument(prop: PropAST): $FlowFixMe {
return prop.expression.name;
}
isOptionalProperty(property: $FlowFixMe): boolean {
return property.optional || false;
}
getTypeAnnotationFromProperty(property: PropAST): $FlowFixMe {
return property.typeAnnotation.typeAnnotation;
}
getGetTypeAnnotationFN(): GetTypeAnnotationFN {
return () => {
return {};
};
}
getGetSchemaInfoFN(): GetSchemaInfoFN {
return () => {
return {
name: 'MockedSchema',
optional: false,
typeAnnotation: 'BooleanTypeAnnotation',
defaultValue: false,
withNullDefault: false,
};
};
}
getResolveTypeAnnotationFN(): ResolveTypeAnnotationFN {
return () => {
return {
nullable: false,
typeAnnotation: null,
typeResolutionStatus: {successful: false},
};
};
}
getResolvedTypeAnnotation(
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
): {
nullable: boolean,
typeAnnotation: $FlowFixMe,
typeResolutionStatus: TypeResolutionStatus,
} {
invariant(
typeAnnotation != null,
'resolveTypeAnnotation(): typeAnnotation cannot be null',
);
let node = typeAnnotation;
let nullable = false;
let typeResolutionStatus: TypeResolutionStatus = {
successful: false,
};
for (;;) {
if (node.type === 'NullableTypeAnnotation') {
nullable = true;
node = node.typeAnnotation;
continue;
}
if (node.type !== 'GenericTypeAnnotation') {
break;
}
const resolvedTypeAnnotation = types[node.id.name];
if (resolvedTypeAnnotation == null) {
break;
}
switch (resolvedTypeAnnotation.type) {
case 'TypeAlias': {
typeResolutionStatus = {
successful: true,
type: 'alias',
name: node.id.name,
};
node = resolvedTypeAnnotation.right;
break;
}
case 'EnumDeclaration': {
typeResolutionStatus = {
successful: true,
type: 'enum',
name: node.id.name,
};
node = resolvedTypeAnnotation.body;
break;
}
default: {
throw new TypeError(
`A non GenericTypeAnnotation must be a type declaration ('TypeAlias') or enum ('EnumDeclaration'). Instead, got the unsupported ${resolvedTypeAnnotation.type}.`,
);
}
}
}
return {
nullable: nullable,
typeAnnotation: node,
typeResolutionStatus,
};
}
getExtendsProps(
typeDefinition: $ReadOnlyArray<PropAST>,
types: TypeDeclarationMap,
): $ReadOnlyArray<ExtendsPropsShape> {
return typeDefinition
.filter(prop => prop.type === 'ObjectTypeSpreadProperty')
.map(prop => this.extendsForProp(prop, types, this))
.filter(Boolean);
}
extendsForProp(
prop: PropAST,
types: TypeDeclarationMap,
parser: Parser,
): ExtendsForProp {
const argument = this.argumentForProp(prop);
if (!argument) {
console.log('null', prop);
}
const name = parser.nameForArgument(prop);
if (types[name] != null) {
// This type is locally defined in the file
return null;
}
switch (name) {
case 'ViewProps':
return {
type: 'ReactNativeBuiltInType',
knownTypeName: 'ReactNativeCoreViewProps',
};
default: {
throw new Error(`Unable to handle prop spread: ${name}`);
}
}
}
removeKnownExtends(
typeDefinition: $ReadOnlyArray<PropAST>,
types: TypeDeclarationMap,
): $ReadOnlyArray<PropAST> {
return typeDefinition.filter(
prop =>
prop.type !== 'ObjectTypeSpreadProperty' ||
this.extendsForProp(prop, types, this) === null,
);
}
getProps(
typeDefinition: $ReadOnlyArray<PropAST>,
types: TypeDeclarationMap,
): {
props: $ReadOnlyArray<NamedShape<PropTypeAnnotation>>,
extendsProps: $ReadOnlyArray<ExtendsPropsShape>,
} {
const nonExtendsProps = this.removeKnownExtends(typeDefinition, types);
const props = flattenProperties(nonExtendsProps, types, this)
.map(property => buildPropSchema(property, types, this))
.filter(Boolean);
return {
props,
extendsProps: this.getExtendsProps(typeDefinition, types),
};
}
getProperties(typeName: string, types: TypeDeclarationMap): $FlowFixMe {
const typeAlias = types[typeName];
try {
return typeAlias.right.typeParameters.params[0].properties;
} catch (e) {
throw new Error(
`Failed to find type definition for "${typeName}", please check that you have a valid codegen flow file`,
);
}
}
nextNodeForTypeAlias(typeAnnotation: $FlowFixMe): $FlowFixMe {
return typeAnnotation.right;
}
nextNodeForEnum(typeAnnotation: $FlowFixMe): $FlowFixMe {
return typeAnnotation.body;
}
genericTypeAnnotationErrorMessage(typeAnnotation: $FlowFixMe): string {
return `A non GenericTypeAnnotation must be a type declaration ('${this.typeAlias}') or enum ('${this.enumDeclaration}'). Instead, got the unsupported ${typeAnnotation.type}.`;
}
extractTypeFromTypeAnnotation(typeAnnotation: $FlowFixMe): string {
return typeAnnotation.type === 'GenericTypeAnnotation'
? typeAnnotation.id.name
: typeAnnotation.type;
}
getObjectProperties(typeAnnotation: $FlowFixMe): $FlowFixMe {
return typeAnnotation.properties;
}
getLiteralValue(option: $FlowFixMe): $FlowFixMe {
return option.value;
}
getPaperTopLevelNameDeprecated(typeAnnotation: $FlowFixMe): $FlowFixMe {
return typeAnnotation.typeParameters.params.length > 1
? typeAnnotation.typeParameters.params[1].value
: null;
}
}