Add suport for array as a param and returning value

Summary: Now `Array<T>` is supported as a returning values or a param of function's definition. Also, Array of Array is allowed.

Reviewed By: TheSavior

Differential Revision: D16121246

fbshipit-source-id: 59c484120c4025a152e3ba8044eecf11dbbea1f7
This commit is contained in:
Michał Osadnik
2019-07-08 04:54:04 -07:00
committed by Facebook Github Bot
parent faf9130560
commit 690bcdf45e
5 changed files with 385 additions and 19 deletions
+26 -12
View File
@@ -130,20 +130,34 @@ export type PropTypeShape = $ReadOnly<{|
typeAnnotation: PropTypeTypeAnnotation,
|}>;
export type FunctionTypeAnnotationParamTypeAnnotation = $ReadOnly<{|
type:
| 'StringTypeAnnotation'
| 'NumberTypeAnnotation'
| 'BooleanTypeAnnotation',
export type PrimitiveTypeAnnotationType =
| 'StringTypeAnnotation'
| 'NumberTypeAnnotation'
| 'BooleanTypeAnnotation';
export type PrimitiveTypeAnnotation = $ReadOnly<{|
type: PrimitiveTypeAnnotationType,
|}>;
export type FunctionTypeAnnotationReturn = $ReadOnly<{|
type:
| 'StringTypeAnnotation'
| 'NumberTypeAnnotation'
| 'BooleanTypeAnnotation'
| 'VoidTypeAnnotation',
|}>;
export type FunctionTypeAnnotationParamTypeAnnotation =
| $ReadOnly<{|
type: 'AnyTypeAnnotation' | PrimitiveTypeAnnotationType,
|}>
| $ReadOnly<{|
type: 'ArrayTypeAnnotation',
elementType: FunctionTypeAnnotationParamTypeAnnotation,
|}>;
export type FunctionTypeAnnotationReturnArrayElementType = FunctionTypeAnnotationParamTypeAnnotation;
export type FunctionTypeAnnotationReturn =
| $ReadOnly<{|
type: PrimitiveTypeAnnotationType | 'VoidTypeAnnotation',
|}>
| $ReadOnly<{|
type: 'ArrayTypeAnnotation',
elementType: FunctionTypeAnnotationReturnArrayElementType,
|}>;
export type FunctionTypeAnnotationParam = $ReadOnly<{|
name: string,
@@ -34,6 +34,54 @@ export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT = `
/**
* 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';
export interface Spec extends TurboModule {
getString: (arg: string) => Array;
}
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT_AS_PARAM = `
/**
* 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';
export interface Spec extends TurboModule {
getString: (arg : Array) => string;
}
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULES_WITH_NOT_EXISTING_TYPE_AS_RETURN = `
/**
* Copyright (c) Facebook, Inc. and its affiliates.
@@ -276,6 +324,8 @@ export default codegenNativeComponent<ModuleProps>('Module');
`;
module.exports = {
NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT_AS_PARAM,
NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT,
TWO_NATIVE_MODULES_EXPORTED_WITH_DEFAULT,
NATIVE_MODULES_WITH_NOT_EXISTING_TYPE_AS_PARAM,
NATIVE_MODULES_WITH_NOT_EXISTING_TYPE_AS_RETURN,
@@ -91,6 +91,80 @@ export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULE_WITH_BASIC_ARRAY = `
/**
* 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';
export interface Spec extends TurboModule {
+getArray: (arg: Array<string>) => Array<string>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULE_WITH_ARRAY_WITH_ALIAS = `
/**
* 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';
export type SomeString = string;
export interface Spec extends TurboModule {
+getArray: (arg: Array<SomeString>) => Array<string>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULE_WITH_COMPLEX_ARRAY = `
/**
* 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';
export interface Spec extends TurboModule {
+getArray: (arg: Array<Array<Array<Array<Array<any>>>>>) => Array<Array<Array<string>>>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const EVENT_DEFINITION = `
boolean_required: boolean,
boolean_optional_key?: boolean,
@@ -632,6 +706,9 @@ export default codegenNativeComponent<ModuleProps>('Module');
module.exports = {
NATIVE_MODULE_WITH_WITH_ALIASES,
NATIVE_MODULE_WITH_BASIC_ARRAY,
NATIVE_MODULE_WITH_COMPLEX_ARRAY,
NATIVE_MODULE_WITH_ARRAY_WITH_ALIAS,
NATIVE_MODULE_WITH_BASIC_PARAM_TYPES,
EMPTY_NATIVE_MODULE,
ALL_PROP_TYPES_NO_EVENTS,
@@ -8,6 +8,10 @@ exports[`RN Codegen Flow Parser Fails with error message COMMANDS_DEFINED_WITHOU
exports[`RN Codegen Flow Parser Fails with error message INCORRECT_NATIVE_MODULES 1`] = `"Interface properties for \\"SpecWithTypo has been specified incorrectly.\\""`;
exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT 1`] = `"Unsupported return type for getString: expected to find annotation for type of array contents"`;
exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT_AS_PARAM 1`] = `"Unsupported type for getString, param: \\"arg\\": expected to find annotation for type of array contents"`;
exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_NOT_EXISTING_TYPE_AS_PARAM 1`] = `"Unsupported param type for method \\"getString\\", param \\"arg\\". Found GenericTypeAnnotation"`;
exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_NOT_EXISTING_TYPE_AS_RETURN 1`] = `"Unsupported param type for method \\"getString\\", param \\"arg\\". Found GenericTypeAnnotation"`;
@@ -3320,6 +3324,82 @@ Object {
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_ARRAY_WITH_ALIAS 1`] = `
Object {
"modules": Object {
"SampleTurboModule": Object {
"nativeModules": Object {
"SampleTurboModule": Object {
"properties": Array [
Object {
"name": "getArray",
"typeAnnotation": Object {
"params": Array [
Object {
"name": "arg",
"typeAnnotation": Object {
"elementType": Object {
"type": "StringTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
},
],
"returnTypeAnnotation": Object {
"elementType": Object {
"type": "StringTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "FunctionTypeAnnotation",
},
},
],
},
},
},
},
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_BASIC_ARRAY 1`] = `
Object {
"modules": Object {
"SampleTurboModule": Object {
"nativeModules": Object {
"SampleTurboModule": Object {
"properties": Array [
Object {
"name": "getArray",
"typeAnnotation": Object {
"params": Array [
Object {
"name": "arg",
"typeAnnotation": Object {
"elementType": Object {
"type": "StringTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
},
],
"returnTypeAnnotation": Object {
"elementType": Object {
"type": "StringTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "FunctionTypeAnnotation",
},
},
],
},
},
},
},
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_BASIC_PARAM_TYPES 1`] = `
Object {
"modules": Object {
@@ -3386,6 +3466,62 @@ Object {
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_COMPLEX_ARRAY 1`] = `
Object {
"modules": Object {
"SampleTurboModule": Object {
"nativeModules": Object {
"SampleTurboModule": Object {
"properties": Array [
Object {
"name": "getArray",
"typeAnnotation": Object {
"params": Array [
Object {
"name": "arg",
"typeAnnotation": Object {
"elementType": Object {
"elementType": Object {
"elementType": Object {
"elementType": Object {
"elementType": Object {
"type": "AnyTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
},
],
"returnTypeAnnotation": Object {
"elementType": Object {
"elementType": Object {
"elementType": Object {
"type": "StringTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
"type": "FunctionTypeAnnotation",
},
},
],
},
},
},
},
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_WITH_ALIASES 1`] = `
Object {
"modules": Object {
+96 -7
View File
@@ -13,8 +13,9 @@
import type {
MethodTypeShape,
FunctionTypeAnnotationParam,
FunctionTypeAnnotationParamTypeAnnotation,
FunctionTypeAnnotationReturn,
PrimitiveTypeAnnotation,
FunctionTypeAnnotationParamTypeAnnotation,
} from '../../CodegenSchema.js';
function getValueFromTypes(value, types) {
@@ -31,7 +32,7 @@ function wrapPrimitiveIntoTypeAnnotation(
| 'NumberTypeAnnotation'
| 'StringTypeAnnotation',
paramName: string,
): FunctionTypeAnnotationParamTypeAnnotation {
): PrimitiveTypeAnnotation {
switch (type) {
case 'BooleanTypeAnnotation':
case 'NumberTypeAnnotation':
@@ -47,23 +48,110 @@ function wrapPrimitiveIntoTypeAnnotation(
}
}
function getElementTypeForArray(
name,
arrayParam,
paramName,
types: $ReadOnlyArray<TypesAST>,
): FunctionTypeAnnotationParamTypeAnnotation {
const typeAnnotation = getValueFromTypes(arrayParam, types);
if (
typeAnnotation.type === 'GenericTypeAnnotation' &&
typeAnnotation.id.name === 'Array'
) {
if (
typeAnnotation.typeParameters &&
typeAnnotation.typeParameters.params[0]
) {
return {
type: 'ArrayTypeAnnotation',
elementType: getElementTypeForArray(
name,
typeAnnotation.typeParameters.params[0],
'returning value',
types,
),
};
} else {
throw new Error(
`Unsupported type for ${name}, param: "${paramName}": expected to find annotation for type of nested array contents`,
);
}
}
const type = typeAnnotation.type;
if (type === 'AnyTypeAnnotation') {
return {
type,
};
}
return wrapPrimitiveIntoTypeAnnotation(name, type, paramName);
}
function getTypeAnnotationForParam(
name: string,
param,
types: $ReadOnlyArray<TypesAST>,
): FunctionTypeAnnotationParam {
const type = getValueFromTypes(param.typeAnnotation, types).type;
const typeAnnotation = getValueFromTypes(param.typeAnnotation, types);
const paramName = param.name.name;
const typeAnnotation = wrapPrimitiveIntoTypeAnnotation(name, type, paramName);
if (
typeAnnotation.type === 'GenericTypeAnnotation' &&
typeAnnotation.id.name === 'Array'
) {
if (
typeAnnotation.typeParameters &&
typeAnnotation.typeParameters.params[0]
) {
return {
name: paramName,
typeAnnotation: {
type: 'ArrayTypeAnnotation',
elementType: getElementTypeForArray(
name,
typeAnnotation.typeParameters.params[0],
paramName,
types,
),
},
};
} else {
throw new Error(
`Unsupported type for ${name}, param: "${paramName}": expected to find annotation for type of array contents`,
);
}
}
const type = typeAnnotation.type;
return {
name: paramName,
typeAnnotation,
typeAnnotation: wrapPrimitiveIntoTypeAnnotation(name, type, paramName),
};
}
function getReturnTypeAnnotation(
methodName: string,
type,
returnType,
types: $ReadOnlyArray<TypesAST>,
): FunctionTypeAnnotationReturn {
if (
returnType.type === 'GenericTypeAnnotation' &&
returnType.id.name === 'Array'
) {
if (returnType.typeParameters && returnType.typeParameters.params[0]) {
return {
type: 'ArrayTypeAnnotation',
elementType: getElementTypeForArray(
methodName,
returnType.typeParameters.params[0],
'returning value',
types,
),
};
} else {
throw new Error(
`Unsupported return type for ${methodName}: expected to find annotation for type of array contents`,
);
}
}
const type = returnType.type;
switch (type) {
case 'BooleanTypeAnnotation':
case 'NumberTypeAnnotation':
@@ -99,7 +187,8 @@ function buildMethodSchema(
const returnTypeAnnotation = getReturnTypeAnnotation(
name,
getValueFromTypes(value.returnType, types).type,
getValueFromTypes(value.returnType, types),
types,
);
return {
name,