Allow key of objects to be nullable

Summary: In this diff I handle the case where the key of an object may be nullable. To do that, I added a nullable param to the schema.

Reviewed By: rickhanlonii

Differential Revision: D16282081

fbshipit-source-id: cb7668d754e2ff30aef22df582351a512c988016
This commit is contained in:
Michał Osadnik 2019-07-17 06:13:28 -07:00 коммит произвёл Facebook Github Bot
Родитель 6e73304401
Коммит b4ac9ddcd5
5 изменённых файлов: 257 добавлений и 11 удалений

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

@ -163,6 +163,7 @@ export type FunctionTypeAnnotationParamTypeAnnotation =
export type FunctionTypeAnnotationReturnArrayElementType = FunctionTypeAnnotationParamTypeAnnotation;
export type ObjectParamTypeAnnotation = $ReadOnly<{|
optional: boolean,
name: string,
typeAnnotation: FunctionTypeAnnotationParamTypeAnnotation,
|}>;

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

@ -38,18 +38,21 @@ const SIMPLE_NATIVE_MODULES: SchemaType = {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'const1',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
{
optional: false,
name: 'const2',
typeAnnotation: {
type: 'NumberTypeAnnotation',
},
},
{
optional: false,
name: 'const3',
typeAnnotation: {
type: 'StringTypeAnnotation',

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

@ -66,6 +66,42 @@ export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULE_WITH_COMPLEX_OBJECTS_WITH_NULLABLE_KEY = `
/**
* 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 {
+getConstants: () => {|
isTesting: boolean,
reactNativeVersion: {|
major: number,
minor: number,
patch: number,
prerelease: ?number,
|},
forceTouchAvailable: boolean,
osVersion: string,
systemName: string,
interfaceIdiom: string,
|};
}
export default TurboModuleRegistry.getEnforcing<Spec>('PlatformConstants');
`;
const NATIVE_MODULE_WITH_BASIC_PARAM_TYPES = `
/**
* Copyright (c) Facebook, Inc. and its affiliates.
@ -224,6 +260,38 @@ export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEIFNED_IN_FILE_AS_PROPERTY = `
/**
* 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 DisplayMetricsAndroid = {|
width: number,
|};
export interface Spec extends TurboModule {
+getConstants: () => {|
+Dimensions: {
windowPhysicalPixels: DisplayMetricsAndroid,
},
|};
}
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
const NATIVE_MODULE_WITH_ARRAY_WITH_ALIAS = `
/**
* Copyright (c) Facebook, Inc. and its affiliates.
@ -328,10 +396,12 @@ export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
`;
module.exports = {
NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEIFNED_IN_FILE_AS_PROPERTY,
NATIVE_MODULE_WITH_WITH_FLOAT_AND_INT32,
NATIVE_MODULE_WITH_WITH_ALIASES,
NATIVE_MODULE_WITH_PROMISE,
NATIVE_MODULE_WITH_COMPLEX_OBJECTS,
NATIVE_MODULE_WITH_COMPLEX_OBJECTS_WITH_NULLABLE_KEY,
NATIVE_MODULE_WITH_SIMPLE_OBJECT,
NATIVE_MODULE_WITH_NULLABLE_PARAM,
NATIVE_MODULE_WITH_BASIC_ARRAY,

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

@ -325,10 +325,12 @@ Object {
"properties": Array [
Object {
"name": "const1",
"optional": false,
"typeAnnotation": Object {
"properties": Array [
Object {
"name": "const1",
"optional": false,
"typeAnnotation": Object {
"type": "BooleanTypeAnnotation",
},
@ -346,10 +348,12 @@ Object {
"properties": Array [
Object {
"name": "const1",
"optional": false,
"typeAnnotation": Object {
"properties": Array [
Object {
"name": "const1",
"optional": false,
"typeAnnotation": Object {
"type": "BooleanTypeAnnotation",
},
@ -376,6 +380,7 @@ Object {
"properties": Array [
Object {
"name": "a",
"optional": false,
"typeAnnotation": Object {
"type": "StringTypeAnnotation",
},
@ -403,10 +408,12 @@ Object {
"properties": Array [
Object {
"name": "const1",
"optional": false,
"typeAnnotation": Object {
"properties": Array [
Object {
"name": "const1",
"optional": false,
"typeAnnotation": Object {
"type": "BooleanTypeAnnotation",
},
@ -425,10 +432,12 @@ Object {
"properties": Array [
Object {
"name": "const1",
"optional": false,
"typeAnnotation": Object {
"properties": Array [
Object {
"name": "const1",
"optional": false,
"typeAnnotation": Object {
"type": "BooleanTypeAnnotation",
},
@ -453,6 +462,106 @@ Object {
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_COMPLEX_OBJECTS_WITH_NULLABLE_KEY 1`] = `
Object {
"modules": Object {
"NativeSampleTurboModule": Object {
"nativeModules": Object {
"SampleTurboModule": Object {
"properties": Array [
Object {
"name": "getConstants",
"typeAnnotation": Object {
"optional": false,
"params": Array [],
"returnTypeAnnotation": Object {
"properties": Array [
Object {
"name": "isTesting",
"optional": false,
"typeAnnotation": Object {
"type": "BooleanTypeAnnotation",
},
},
Object {
"name": "reactNativeVersion",
"optional": false,
"typeAnnotation": Object {
"properties": Array [
Object {
"name": "major",
"optional": false,
"typeAnnotation": Object {
"type": "NumberTypeAnnotation",
},
},
Object {
"name": "minor",
"optional": false,
"typeAnnotation": Object {
"type": "NumberTypeAnnotation",
},
},
Object {
"name": "patch",
"optional": false,
"typeAnnotation": Object {
"type": "NumberTypeAnnotation",
},
},
Object {
"name": "prerelease",
"optional": true,
"typeAnnotation": Object {
"type": "NumberTypeAnnotation",
},
},
],
"type": "ObjectTypeAnnotation",
},
},
Object {
"name": "forceTouchAvailable",
"optional": false,
"typeAnnotation": Object {
"type": "BooleanTypeAnnotation",
},
},
Object {
"name": "osVersion",
"optional": false,
"typeAnnotation": Object {
"type": "StringTypeAnnotation",
},
},
Object {
"name": "systemName",
"optional": false,
"typeAnnotation": Object {
"type": "StringTypeAnnotation",
},
},
Object {
"name": "interfaceIdiom",
"optional": false,
"typeAnnotation": Object {
"type": "StringTypeAnnotation",
},
},
],
"type": "ObjectTypeAnnotation",
},
"type": "FunctionTypeAnnotation",
},
},
],
},
},
},
},
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_NULLABLE_PARAM 1`] = `
Object {
"modules": Object {
@ -487,6 +596,59 @@ Object {
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEIFNED_IN_FILE_AS_PROPERTY 1`] = `
Object {
"modules": Object {
"NativeSampleTurboModule": Object {
"nativeModules": Object {
"SampleTurboModule": Object {
"properties": Array [
Object {
"name": "getConstants",
"typeAnnotation": Object {
"optional": false,
"params": Array [],
"returnTypeAnnotation": Object {
"properties": Array [
Object {
"name": "Dimensions",
"optional": false,
"typeAnnotation": Object {
"properties": Array [
Object {
"name": "windowPhysicalPixels",
"optional": false,
"typeAnnotation": Object {
"properties": Array [
Object {
"name": "width",
"optional": false,
"typeAnnotation": Object {
"type": "NumberTypeAnnotation",
},
},
],
"type": "ObjectTypeAnnotation",
},
},
],
"type": "ObjectTypeAnnotation",
},
},
],
"type": "ObjectTypeAnnotation",
},
"type": "FunctionTypeAnnotation",
},
},
],
},
},
},
},
}
`;
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PROMISE 1`] = `
Object {
"modules": Object {
@ -621,6 +783,7 @@ Object {
"properties": Array [
Object {
"name": "a",
"optional": false,
"typeAnnotation": Object {
"type": "NumberTypeAnnotation",
},

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

@ -30,15 +30,24 @@ function getObjectProperties(
paramName: string,
types: TypeMap,
): $ReadOnlyArray<ObjectParamTypeAnnotation> {
return objectParam.properties.map(objectTypeProperty => ({
name: objectTypeProperty.key.name,
typeAnnotation: getElementTypeForArrayOrObject(
name,
objectTypeProperty.value,
paramName,
types,
),
}));
return objectParam.properties.map(objectTypeProperty => {
let optional = false;
let value = objectTypeProperty.value;
if (value.type === 'NullableTypeAnnotation') {
optional = true;
value = objectTypeProperty.value.typeAnnotation;
}
return {
optional,
name: objectTypeProperty.key.name,
typeAnnotation: getElementTypeForArrayOrObject(
name,
value,
paramName,
types,
),
};
});
}
function getElementTypeForArrayOrObject(
@ -80,7 +89,7 @@ function getElementTypeForArrayOrObject(
case 'ObjectTypeAnnotation':
return {
type: 'ObjectTypeAnnotation',
properties: getObjectProperties(name, arrayParam, paramName, types),
properties: getObjectProperties(name, typeAnnotation, paramName, types),
};
case 'AnyTypeAnnotation':
return {
@ -166,7 +175,7 @@ function getTypeAnnotationForParam(
type: 'ObjectTypeAnnotation',
properties: getObjectProperties(
name,
param.typeAnnotation,
typeAnnotation,
paramName,
types,
),