Prepare generic mechanism for extracting types from external type definitions

Summary: This diff a adds generic mechansm for extracting types from types' difinitions defined in other part of the file.

Reviewed By: TheSavior

Differential Revision: D16131742

fbshipit-source-id: 006b6980fa9f6a064d5bb8734ba2740b802b6989
This commit is contained in:
Michał Osadnik 2019-07-08 03:14:42 -07:00 коммит произвёл Facebook Github Bot
Родитель 06ce568155
Коммит 59b8ee86c8
4 изменённых файлов: 96 добавлений и 10 удалений

Просмотреть файл

@ -60,6 +60,37 @@ export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULE_WITH_WITH_ALIASES = `
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
'use strict';
import type {TurboModule} from '../RCTExport';
import * as TurboModuleRegistry from '../TurboModuleRegistry';
type NumNum = number;
export type Num = (arg: NumNum) => void;
type Num2 = Num;
export type Void = void
export interface Spec extends TurboModule {
// Exported methods.
+getNumber: Num2;
+getVoid: () => Void;
}
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const EVENT_DEFINITION = `
boolean_required: boolean,
boolean_optional_key?: boolean,
@ -600,6 +631,7 @@ export default codegenNativeComponent<ModuleProps>('Module');
`;
module.exports = {
NATIVE_MODULE_WITH_WITH_ALIASES,
NATIVE_MODULE_WITH_BASIC_PARAM_TYPES,
EMPTY_NATIVE_MODULE,
ALL_PROP_TYPES_NO_EVENTS,

Просмотреть файл

@ -3386,6 +3386,48 @@ Object {
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_WITH_ALIASES 1`] = `
Object {
"modules": Object {
"SampleTurboModule": Object {
"nativeModules": Object {
"SampleTurboModule": Object {
"properties": Array [
Object {
"name": "getNumber",
"typeAnnotation": Object {
"params": Array [
Object {
"name": "arg",
"typeAnnotation": Object {
"type": "NumberTypeAnnotation",
},
},
],
"returnTypeAnnotation": Object {
"type": "VoidTypeAnnotation",
},
"type": "FunctionTypeAnnotation",
},
},
Object {
"name": "getVoid",
"typeAnnotation": Object {
"params": Array [],
"returnTypeAnnotation": Object {
"type": "VoidTypeAnnotation",
},
"type": "FunctionTypeAnnotation",
},
},
],
},
},
},
},
}
`;
exports[`RN Codegen Flow Parser can generate fixture NO_PROPS_EVENTS_ONLY_DEPRECATED_VIEW_CONFIG_NAME_OPTION 1`] = `
Object {
"modules": Object {

Просмотреть файл

@ -240,7 +240,7 @@ function processString(contents: string): SchemaBuilderConfig {
const {interfaceName, moduleName} = findModuleConfig(ast);
const moduleProperties = getModuleProperties(types, interfaceName);
const properties = getMethods(moduleProperties);
const properties = getMethods(moduleProperties, types);
return {configType, properties, filename: moduleName, moduleName};
}
}

Просмотреть файл

@ -17,6 +17,13 @@ import type {
FunctionTypeAnnotationReturn,
} from '../../CodegenSchema.js';
function getValueFromTypes(value, types) {
if (value.type === 'GenericTypeAnnotation' && types[value.id.name]) {
return getValueFromTypes(types[value.id.name].right, types);
}
return value;
}
function wrapPrimitiveIntoTypeAnnotation(
methodName: string,
type:
@ -43,17 +50,16 @@ function wrapPrimitiveIntoTypeAnnotation(
function getTypeAnnotationForParam(
name: string,
param,
types: $ReadOnlyArray<TypesAST>,
): FunctionTypeAnnotationParam {
const type = param.typeAnnotation.type;
const type = getValueFromTypes(param.typeAnnotation, types).type;
const paramName = param.name.name;
// TODO handle more types
const typeAnnotation = wrapPrimitiveIntoTypeAnnotation(name, type, paramName);
return {
name: paramName,
typeAnnotation,
};
}
function getReturnTypeAnnotation(
methodName: string,
type,
@ -73,9 +79,13 @@ function getReturnTypeAnnotation(
);
}
}
function buildMethodSchema(property: MethodAST): MethodTypeShape {
function buildMethodSchema(
property: MethodAST,
types: $ReadOnlyArray<TypesAST>,
): MethodTypeShape {
const name: string = property.key.name;
const value = property.value;
const value = getValueFromTypes(property.value, types);
if (value.type !== 'FunctionTypeAnnotation') {
throw new Error(
`Only methods are supported as module properties. Found ${
@ -83,14 +93,13 @@ function buildMethodSchema(property: MethodAST): MethodTypeShape {
} in ${property.key.name}`,
);
}
const params = value.params.map(param =>
getTypeAnnotationForParam(name, param),
getTypeAnnotationForParam(name, param, types),
);
const returnTypeAnnotation = getReturnTypeAnnotation(
name,
value.returnType.type,
getValueFromTypes(value.returnType, types).type,
);
return {
name,
@ -104,13 +113,16 @@ function buildMethodSchema(property: MethodAST): MethodTypeShape {
// $FlowFixMe there's no flowtype for ASTs
type MethodAST = Object;
// $FlowFixMe there's no flowtype for ASTs
type TypesAST = Object;
function getMethods(
typeDefinition: $ReadOnlyArray<MethodAST>,
types: $ReadOnlyArray<TypesAST>,
): $ReadOnlyArray<MethodTypeShape> {
return typeDefinition
.filter(property => property.type === 'ObjectTypeProperty')
.map(buildMethodSchema)
.map(property => buildMethodSchema(property, types))
.filter(Boolean);
}