From 688caa0bdc5cffe83e2e7b715eb28d45de82fd1b Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Thu, 5 Nov 2020 17:43:23 -0800 Subject: [PATCH] Introduce ObjectTypeAnnotation utility type Summary: All throughout the Codegen schema, we re-declare the following shape: ``` { type: 'ObjectTypeAnnotation', properties: $ReadOnlyArray<{ name: string, optional: boolean, typeAnnotation: ... }> } ``` This diff introduces an `ObjectTypeAnnotation` utility type and replaces those re-declarations with instantiations of this type. **Motivation:** To reduce noise in the CodegenSchema. This should be a pure refactor, and shouldn't actually change any behaviour. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D24707963 fbshipit-source-id: 6b4eb711ddd041f3a041109ade5ad5644fb16924 --- .../react-native-codegen/src/CodegenSchema.js | 59 +++++++------------ .../src/generators/components/CppHelpers.js | 8 ++- .../components/GenerateComponentHObjCpp.js | 5 +- .../components/GenerateEventEmitterCpp.js | 5 +- .../components/GenerateEventEmitterH.js | 7 ++- .../generators/components/GeneratePropsH.js | 11 ++-- .../components/GeneratePropsJavaDelegate.js | 11 ++-- .../components/GeneratePropsJavaInterface.js | 12 ++-- .../src/parsers/flow/components/commands.js | 7 ++- .../src/parsers/flow/components/events.js | 7 ++- .../src/parsers/flow/components/props.js | 9 ++- .../src/parsers/flow/components/schema.js | 9 +-- 12 files changed, 78 insertions(+), 72 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index a496f777e15..2d22324f82b 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -48,7 +48,12 @@ export type StringEnumTypeAnnotation = $ReadOnly<{| |}>, |}>; -type NamedShape<+T> = $ReadOnly<{ +type ObjectTypeAnnotation<+T> = $ReadOnly<{| + type: 'ObjectTypeAnnotation', + properties: $ReadOnlyArray>, +|}>; + +export type NamedShape<+T> = $ReadOnly<{ name: string, optional: boolean, typeAnnotation: T, @@ -65,8 +70,8 @@ export type ComponentShape = $ReadOnly<{| ...OptionsShape, extendsProps: $ReadOnlyArray, events: $ReadOnlyArray, - props: $ReadOnlyArray, - commands: $ReadOnlyArray, + props: $ReadOnlyArray>, + commands: $ReadOnlyArray>, |}>; export type OptionsShape = $ReadOnly<{| @@ -96,29 +101,20 @@ export type EventTypeShape = $ReadOnly<{| paperTopLevelNameDeprecated?: string, typeAnnotation: $ReadOnly<{| type: 'EventTypeAnnotation', - argument?: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, + argument?: ObjectTypeAnnotation, |}>, |}>; -export type EventObjectPropertyType = NamedShape< +export type EventTypeAnnotation = | BooleanTypeAnnotation | StringTypeAnnotation | DoubleTypeAnnotation | FloatTypeAnnotation | Int32TypeAnnotation | StringEnumTypeAnnotation - | $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, ->; + | ObjectTypeAnnotation; -export type PropTypeShape = NamedShape; - -type PropTypeTypeAnnotation = +export type PropTypeAnnotation = | $ReadOnly<{| type: 'BooleanTypeAnnotation', default: boolean | null, @@ -161,10 +157,7 @@ type PropTypeTypeAnnotation = | 'PointPrimitive' | 'EdgeInsetsPrimitive', |}> - | $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}> + | ObjectTypeAnnotation | $ReadOnly<{| type: 'ArrayTypeAnnotation', elementType: @@ -180,10 +173,7 @@ type PropTypeTypeAnnotation = name: string, |}>, |}> - | $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}> + | ObjectTypeAnnotation | $ReadOnly<{| type: 'ReservedPropTypeAnnotation', name: @@ -194,26 +184,22 @@ type PropTypeTypeAnnotation = |}> | $ReadOnly<{| type: 'ArrayTypeAnnotation', - elementType: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, + elementType: ObjectTypeAnnotation, |}>, |}>; -export type CommandTypeShape = NamedShape; - -export type CommandsFunctionTypeAnnotation = $ReadOnly<{| +// TODO: Unify this function type annotation with NativeModule schema +export type CommandsTypeAnnotation = $ReadOnly<{| type: 'FunctionTypeAnnotation', params: $ReadOnlyArray, |}>; export type CommandsFunctionTypeParamAnnotation = $ReadOnly<{| name: string, - typeAnnotation: CommandsTypeAnnotation, + typeAnnotation: CommandsParamTypeAnnotation, |}>; -export type CommandsTypeAnnotation = +type CommandsParamTypeAnnotation = | ReservedTypeAnnotation | BooleanTypeAnnotation | Int32TypeAnnotation @@ -273,10 +259,9 @@ export type NativeModuleMethodParamSchema = NamedShape< Nullable, >; -export type NativeModuleObjectTypeAnnotation = $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, -|}>; +export type NativeModuleObjectTypeAnnotation = ObjectTypeAnnotation< + Nullable, +>; export type NativeModuleObjectTypeAnnotationPropertySchema = NamedShape< Nullable, diff --git a/packages/react-native-codegen/src/generators/components/CppHelpers.js b/packages/react-native-codegen/src/generators/components/CppHelpers.js index f6e7077a416..1f816df8fd7 100644 --- a/packages/react-native-codegen/src/generators/components/CppHelpers.js +++ b/packages/react-native-codegen/src/generators/components/CppHelpers.js @@ -9,7 +9,7 @@ */ 'use strict'; -import type {PropTypeShape} from '../../CodegenSchema'; +import type {NamedShape, PropTypeAnnotation} from '../../CodegenSchema'; function upperCaseFirst(inString: string): string { if (inString.length === 0) { @@ -55,7 +55,9 @@ function getCppTypeForAnnotation( } } -function getImports(properties: $ReadOnlyArray): Set { +function getImports( + properties: $ReadOnlyArray>, +): Set { const imports: Set = new Set(); function addImportsForNativeName(name) { @@ -122,7 +124,7 @@ function getEnumMaskName(enumName: string): string { function convertDefaultTypeToString( componentName: string, - prop: PropTypeShape, + prop: NamedShape, ): string { const typeAnnotation = prop.typeAnnotation; switch (typeAnnotation.type) { diff --git a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js index 467d02bcdae..9ede5b15eb7 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js @@ -11,7 +11,8 @@ 'use strict'; import type { - CommandTypeShape, + NamedShape, + CommandsTypeAnnotation, ComponentShape, SchemaType, CommandsFunctionTypeParamAnnotation, @@ -273,7 +274,7 @@ function generateConvertAndValidateParam( } function generateCommandIfCase( - command: CommandTypeShape, + command: NamedShape, componentName: string, ) { const params = command.typeAnnotation.params; diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js index cde931ae98d..62201df8f36 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js @@ -14,7 +14,8 @@ const {generateEventStructName} = require('./CppHelpers.js'); import type { ComponentShape, - EventObjectPropertyType, + NamedShape, + EventTypeAnnotation, SchemaType, } from '../../CodegenSchema'; @@ -81,7 +82,7 @@ function generateEnumSetter(variableName, propertyName, propertyParts) { function generateSetters( parentPropertyName: string, - properties: $ReadOnlyArray, + properties: $ReadOnlyArray>, propertyParts: $ReadOnlyArray, ): string { const propSetters = properties diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js index 0415b7af9b4..acb4346173f 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js @@ -21,7 +21,8 @@ const { import type { ComponentShape, EventTypeShape, - EventObjectPropertyType, + NamedShape, + EventTypeAnnotation, SchemaType, } from '../../CodegenSchema'; @@ -99,7 +100,7 @@ function indent(nice: string, spaces: number) { function getNativeTypeFromAnnotation( componentName: string, - eventProperty: EventObjectPropertyType, + eventProperty: NamedShape, nameParts: $ReadOnlyArray, ): string { const {type} = eventProperty.typeAnnotation; @@ -148,7 +149,7 @@ function generateStruct( structs: StructsMap, componentName: string, nameParts: $ReadOnlyArray, - properties: $ReadOnlyArray, + properties: $ReadOnlyArray>, ): void { const structNameParts = nameParts; const structName = generateEventStructName(structNameParts); diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js index b84793ca440..b498c04c0d9 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js @@ -23,7 +23,8 @@ const { import type { ExtendsPropsShape, - PropTypeShape, + NamedShape, + PropTypeAnnotation, SchemaType, } from '../../CodegenSchema'; @@ -447,7 +448,7 @@ function generateEnumString(componentName: string, component): string { function generatePropsString( componentName: string, - props: $ReadOnlyArray, + props: $ReadOnlyArray>, ) { return props .map(prop => { @@ -487,7 +488,7 @@ function getExtendsImports( } function getLocalImports( - properties: $ReadOnlyArray, + properties: $ReadOnlyArray>, ): Set { const imports: Set = new Set(); @@ -677,7 +678,7 @@ function generateStruct( structs: StructsMap, componentName: string, nameParts: $ReadOnlyArray, - properties: $ReadOnlyArray, + properties: $ReadOnlyArray>, ): void { const structNameParts = nameParts; const structName = generateStructName(componentName, structNameParts); @@ -692,7 +693,7 @@ function generateStruct( }) .join('\n' + ' '); - properties.forEach((property: PropTypeShape) => { + properties.forEach((property: NamedShape) => { const name = property.name; switch (property.typeAnnotation.type) { case 'BooleanTypeAnnotation': diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js index c963d8b61e2..528d0fb628c 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js @@ -11,9 +11,10 @@ 'use strict'; import type { - CommandTypeShape, + NamedShape, + CommandsTypeAnnotation, ComponentShape, - PropTypeShape, + PropTypeAnnotation, SchemaType, } from '../../CodegenSchema'; const { @@ -64,7 +65,7 @@ const commandsTemplate = ` `; function getJavaValueForProp( - prop: PropTypeShape, + prop: NamedShape, componentName: string, ): string { const typeAnnotation = prop.typeAnnotation; @@ -181,7 +182,9 @@ function getCommandArgJavaType(param, index) { } } -function getCommandArguments(command: CommandTypeShape): string { +function getCommandArguments( + command: NamedShape, +): string { return [ 'view', ...command.typeAnnotation.params.map(getCommandArgJavaType), diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js index d5e26c745a8..27c0f3de25e 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js @@ -11,9 +11,10 @@ 'use strict'; import type { - CommandTypeShape, + NamedShape, + CommandsTypeAnnotation, ComponentShape, - PropTypeShape, + PropTypeAnnotation, SchemaType, } from '../../CodegenSchema'; const { @@ -47,7 +48,10 @@ function addNullable(imports) { imports.add('import androidx.annotation.Nullable;'); } -function getJavaValueForProp(prop: PropTypeShape, imports): string { +function getJavaValueForProp( + prop: NamedShape, + imports, +): string { const typeAnnotation = prop.typeAnnotation; switch (typeAnnotation.type) { @@ -153,7 +157,7 @@ function getCommandArgJavaType(param) { } function getCommandArguments( - command: CommandTypeShape, + command: NamedShape, componentName: string, ): string { return [ diff --git a/packages/react-native-codegen/src/parsers/flow/components/commands.js b/packages/react-native-codegen/src/parsers/flow/components/commands.js index b6b2ce39b95..c79c8e84090 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/commands.js +++ b/packages/react-native-codegen/src/parsers/flow/components/commands.js @@ -10,7 +10,10 @@ 'use strict'; -import type {CommandTypeShape} from '../../../CodegenSchema.js'; +import type { + NamedShape, + CommandsTypeAnnotation, +} from '../../../CodegenSchema.js'; import type {TypeDeclarationMap} from '../utils.js'; const {getValueFromTypes} = require('../utils.js'); @@ -99,7 +102,7 @@ function buildCommandSchema(property, types: TypeDeclarationMap) { function getCommands( commandTypeAST: $ReadOnlyArray, types: TypeDeclarationMap, -): $ReadOnlyArray { +): $ReadOnlyArray> { return commandTypeAST .filter(property => property.type === 'ObjectTypeProperty') .map(property => buildCommandSchema(property, types)) diff --git a/packages/react-native-codegen/src/parsers/flow/components/events.js b/packages/react-native-codegen/src/parsers/flow/components/events.js index 6f6105bbfd0..868f6feefee 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/events.js +++ b/packages/react-native-codegen/src/parsers/flow/components/events.js @@ -12,14 +12,15 @@ import type { EventTypeShape, - EventObjectPropertyType, + NamedShape, + EventTypeAnnotation, } from '../../../CodegenSchema.js'; function getPropertyType( name, optional, typeAnnotation, -): EventObjectPropertyType { +): NamedShape { const type = typeAnnotation.type === 'GenericTypeAnnotation' ? typeAnnotation.id.name @@ -150,7 +151,7 @@ function findEventArgumentsAndType( } } -function buildPropertiesForEvent(property): EventObjectPropertyType { +function buildPropertiesForEvent(property): NamedShape { const name = property.key.name; const optional = property.value.type === 'NullableTypeAnnotation' || property.optional; diff --git a/packages/react-native-codegen/src/parsers/flow/components/props.js b/packages/react-native-codegen/src/parsers/flow/components/props.js index 50e887bcd93..757e238d38f 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/props.js +++ b/packages/react-native-codegen/src/parsers/flow/components/props.js @@ -12,7 +12,7 @@ const {getValueFromTypes} = require('../utils.js'); -import type {PropTypeShape} from '../../../CodegenSchema.js'; +import type {NamedShape, PropTypeAnnotation} from '../../../CodegenSchema.js'; import type {TypeDeclarationMap} from '../utils.js'; function getPropProperties( @@ -324,7 +324,10 @@ function getTypeAnnotation( } } -function buildPropSchema(property, types: TypeDeclarationMap): ?PropTypeShape { +function buildPropSchema( + property, + types: TypeDeclarationMap, +): ?NamedShape { const name = property.key.name; const value = getValueFromTypes(property.value, types); @@ -460,7 +463,7 @@ function flattenProperties( function getProps( typeDefinition: $ReadOnlyArray, types: TypeDeclarationMap, -): $ReadOnlyArray { +): $ReadOnlyArray> { return flattenProperties(typeDefinition, types) .map(property => buildPropSchema(property, types)) .filter(Boolean); diff --git a/packages/react-native-codegen/src/parsers/flow/components/schema.js b/packages/react-native-codegen/src/parsers/flow/components/schema.js index 9ca89ebc12e..dda92acb990 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/schema.js +++ b/packages/react-native-codegen/src/parsers/flow/components/schema.js @@ -12,8 +12,9 @@ import type { EventTypeShape, - PropTypeShape, - CommandTypeShape, + NamedShape, + CommandsTypeAnnotation, + PropTypeAnnotation, ExtendsPropsShape, SchemaType, OptionsShape, @@ -24,8 +25,8 @@ export type ComponentSchemaBuilderConfig = $ReadOnly<{| componentName: string, extendsProps: $ReadOnlyArray, events: $ReadOnlyArray, - props: $ReadOnlyArray, - commands: $ReadOnlyArray, + props: $ReadOnlyArray>, + commands: $ReadOnlyArray>, options?: ?OptionsShape, |}>;