From 4d9fa4b08ef624291a803ddc4631268600bcd67e Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Thu, 23 Apr 2020 12:38:35 -0700 Subject: [PATCH] RN: Add `RootTag` to New Commands Codegen Summary: Adds support for `RootTag` in the new codegen for Native Component Commands. Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D21169371 fbshipit-source-id: 3b25433f3328e9c04cfe45bb176fc06d63559f14 --- .../react-native-codegen/src/CodegenSchema.js | 6 ++ .../components/GenerateComponentHObjCpp.js | 56 ++++++++++++++++--- .../components/GeneratePropsJavaDelegate.js | 16 +++++- .../components/GeneratePropsJavaInterface.js | 14 ++++- .../components/__test_fixtures__/fixtures.js | 16 ++++++ .../GenerateComponentHObjCpp-test.js.snap | 23 +++++++- .../GeneratePropsJavaDelegate-test.js.snap | 3 + .../GeneratePropsJavaInterface-test.js.snap | 1 + .../GenerateViewConfigJs-test.js.snap | 4 ++ .../components/__test_fixtures__/fixtures.js | 4 +- .../component-parser-test.js.snap | 16 ++++++ .../src/parsers/flow/components/commands.js | 6 ++ 12 files changed, 150 insertions(+), 15 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 0352c48948b..51d96416ff7 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -21,12 +21,18 @@ export type CommandsFunctionTypeParamAnnotation = $ReadOnly<{| |}>; export type CommandsTypeAnnotation = + | ReservedFunctionValueTypeAnnotation | BooleanTypeAnnotation | Int32TypeAnnotation | DoubleTypeAnnotation | FloatTypeAnnotation | StringTypeAnnotation; +type ReservedFunctionValueTypeAnnotation = $ReadOnly<{| + type: 'ReservedFunctionValueTypeAnnotation', + name: ReservedFunctionValueTypeName, +|}>; + export type DoubleTypeAnnotation = $ReadOnly<{| type: 'DoubleTypeAnnotation', |}>; diff --git a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js index db66bacc553..6ecc358b381 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js @@ -102,7 +102,17 @@ NS_ASSUME_NONNULL_END `.trim(); function getObjCParamType(param: CommandsFunctionTypeParamAnnotation): string { - switch (param.typeAnnotation.type) { + const {typeAnnotation} = param; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return 'double'; + default: + (typeAnnotation.name: empty); + throw new Error(`Receieved invalid type: ${typeAnnotation.name}`); + } case 'BooleanTypeAnnotation': return 'BOOL'; case 'DoubleTypeAnnotation': @@ -114,7 +124,7 @@ function getObjCParamType(param: CommandsFunctionTypeParamAnnotation): string { case 'StringTypeAnnotation': return 'NSString *'; default: - (param.typeAnnotation.type: empty); + (typeAnnotation.type: empty); throw new Error('Received invalid param type annotation'); } } @@ -122,7 +132,17 @@ function getObjCParamType(param: CommandsFunctionTypeParamAnnotation): string { function getObjCExpectedKindParamType( param: CommandsFunctionTypeParamAnnotation, ): string { - switch (param.typeAnnotation.type) { + const {typeAnnotation} = param; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return '[NSNumber class]'; + default: + (typeAnnotation.name: empty); + throw new Error(`Receieved invalid type: ${typeAnnotation.name}`); + } case 'BooleanTypeAnnotation': return '[NSNumber class]'; case 'DoubleTypeAnnotation': @@ -134,7 +154,7 @@ function getObjCExpectedKindParamType( case 'StringTypeAnnotation': return '[NSString class]'; default: - (param.typeAnnotation.type: empty); + (typeAnnotation.type: empty); throw new Error('Received invalid param type annotation'); } } @@ -142,7 +162,17 @@ function getObjCExpectedKindParamType( function getReadableExpectedKindParamType( param: CommandsFunctionTypeParamAnnotation, ): string { - switch (param.typeAnnotation.type) { + const {typeAnnotation} = param; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return 'double'; + default: + (typeAnnotation.name: empty); + throw new Error(`Receieved invalid type: ${typeAnnotation.name}`); + } case 'BooleanTypeAnnotation': return 'boolean'; case 'DoubleTypeAnnotation': @@ -154,7 +184,7 @@ function getReadableExpectedKindParamType( case 'StringTypeAnnotation': return 'string'; default: - (param.typeAnnotation.type: empty); + (typeAnnotation.type: empty); throw new Error('Received invalid param type annotation'); } } @@ -163,7 +193,17 @@ function getObjCRightHandAssignmentParamType( param: CommandsFunctionTypeParamAnnotation, index: number, ): string { - switch (param.typeAnnotation.type) { + const {typeAnnotation} = param; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return `[(NSNumber *)arg${index} doubleValue]`; + default: + (typeAnnotation.name: empty); + throw new Error(`Receieved invalid type: ${typeAnnotation.name}`); + } case 'BooleanTypeAnnotation': return `[(NSNumber *)arg${index} boolValue]`; case 'DoubleTypeAnnotation': @@ -175,7 +215,7 @@ function getObjCRightHandAssignmentParamType( case 'StringTypeAnnotation': return `(NSString *)arg${index}`; default: - (param.typeAnnotation.type: empty); + (typeAnnotation.type: empty); throw new Error('Received invalid param type annotation'); } } diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js index afddadb9107..17f587b0145 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js @@ -153,7 +153,17 @@ function generatePropCasesString( } function getCommandArgJavaType(param, index) { - switch (param.typeAnnotation.type) { + const {typeAnnotation} = param; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return `args.getDouble(${index})`; + default: + (typeAnnotation.name: empty); + throw new Error(`Receieved invalid type: ${typeAnnotation.name}`); + } case 'BooleanTypeAnnotation': return `args.getBoolean(${index})`; case 'DoubleTypeAnnotation': @@ -165,8 +175,8 @@ function getCommandArgJavaType(param, index) { case 'StringTypeAnnotation': return `args.getString(${index})`; default: - (param.typeAnnotation.type: empty); - throw new Error('Receieved invalid typeAnnotation'); + (typeAnnotation.type: empty); + throw new Error(`Receieved invalid type: ${typeAnnotation.type}`); } } diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js index ea8e4262b9d..bf4f42bbfc8 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js @@ -125,7 +125,17 @@ function generatePropsString(component: ComponentShape, imports) { } function getCommandArgJavaType(param) { - switch (param.typeAnnotation.type) { + const {typeAnnotation} = param; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return 'double'; + default: + (typeAnnotation.name: empty); + throw new Error(`Receieved invalid type: ${typeAnnotation.name}`); + } case 'BooleanTypeAnnotation': return 'boolean'; case 'DoubleTypeAnnotation': @@ -137,7 +147,7 @@ function getCommandArgJavaType(param) { case 'StringTypeAnnotation': return 'String'; default: - (param.typeAnnotation.type: empty); + (typeAnnotation.type: empty); throw new Error('Receieved invalid typeAnnotation'); } } diff --git a/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js index 9461acd92fd..6f3bf1becb8 100644 --- a/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js @@ -1475,6 +1475,22 @@ const COMMANDS_AND_PROPS: SchemaType = { }, ], commands: [ + { + name: 'handleRootTag', + optional: false, + typeAnnotation: { + type: 'FunctionTypeAnnotation', + params: [ + { + name: 'rootTag', + typeAnnotation: { + type: 'ReservedFunctionValueTypeAnnotation', + name: 'RootTag', + }, + }, + ], + }, + }, { name: 'hotspotUpdate', optional: false, diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap index 70dd19d5b9e..93b0a8b7f0f 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap @@ -208,6 +208,7 @@ Map { NS_ASSUME_NONNULL_BEGIN @protocol RCTCommandNativeComponentViewProtocol +- (void)handleRootTag:(double)rootTag; - (void)hotspotUpdate:(NSInteger)x y:(NSInteger)y; @end @@ -216,7 +217,27 @@ RCT_EXTERN inline void RCTCommandNativeComponentHandleCommand( NSString const *commandName, NSArray const *args) { - if ([commandName isEqualToString:@\\"hotspotUpdate\\"]) { + if ([commandName isEqualToString:@\\"handleRootTag\\"]) { +#if RCT_DEBUG + if ([args count] != 1) { + RCTLogError(@\\"%@ command %@ received %d arguments, expected %d.\\", @\\"CommandNativeComponent\\", commandName, (int)[args count], 1); + return; + } +#endif + + NSObject *arg0 = args[0]; +#if RCT_DEBUG + if (!RCTValidateTypeOfViewCommandArgument(arg0, [NSNumber class], @\\"double\\", @\\"CommandNativeComponent\\", commandName, @\\"1st\\")) { + return; + } +#endif + double rootTag = [(NSNumber *)arg0 doubleValue]; + + [componentView handleRootTag:rootTag]; + return; +} + +if ([commandName isEqualToString:@\\"hotspotUpdate\\"]) { #if RCT_DEBUG if ([args count] != 2) { RCTLogError(@\\"%@ command %@ received %d arguments, expected %d.\\", @\\"CommandNativeComponent\\", commandName, (int)[args count], 2); diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap index 27e4baf9895..6ae0cd6f4f2 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap @@ -266,6 +266,9 @@ public class CommandNativeComponentManagerDelegate viewManager, T view, String commandName, ReadableArray args) { switch (commandName) { + case \\"handleRootTag\\": + viewManager.handleRootTag(view, args.getDouble(0)); + break; case \\"hotspotUpdate\\": viewManager.hotspotUpdate(view, args.getInt(0), args.getInt(1)); break; diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap index 1f52c9c59a8..45873d75b22 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap @@ -145,6 +145,7 @@ import androidx.annotation.Nullable; public interface CommandNativeComponentManagerInterface { void setAccessibilityHint(T view, @Nullable String value); + void handleRootTag(T view, double rootTag); void hotspotUpdate(T view, int x, int y); } ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap index 6a1892f0aa7..f7e1722e545 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap @@ -227,6 +227,10 @@ export const __INTERNAL_VIEW_CONFIG = CommandNativeComponentViewConfig; export default nativeComponentName; export const Commands = { + handleRootTag(ref, rootTag) { + dispatchCommand(ref, \\"handleRootTag\\", [rootTag]); + }, + hotspotUpdate(ref, x, y) { dispatchCommand(ref, \\"hotspotUpdate\\", [x, y]); } diff --git a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js index 5a6e24d43dc..13e51319533 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js @@ -837,6 +837,7 @@ const codegenNativeCommands = require('codegenNativeCommands'); const codegenNativeComponent = require('codegenNativeComponent'); import type {Int32, Double, Float} from 'CodegenTypes'; +import type {RootTag} from 'RCTExport'; import type {ViewProps} from 'ViewPropTypes'; import type {HostComponent} from 'react-native'; @@ -849,6 +850,7 @@ export type ModuleProps = $ReadOnly<{| type NativeType = HostComponent; interface NativeCommands { + +handleRootTag: (viewRef: React.ElementRef, rootTag: RootTag) => void; +hotspotUpdate: (viewRef: React.ElementRef, x: Int32, y: Int32) => void; +scrollTo: ( viewRef: React.ElementRef, @@ -860,7 +862,7 @@ interface NativeCommands { } export const Commands = codegenNativeCommands({ - supportedCommands: ['hotspotUpdate', 'scrollTo'], + supportedCommands: ['handleRootTag', 'hotspotUpdate', 'scrollTo'], }); export default (codegenNativeComponent( diff --git a/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap index bd0b3629a6f..8192bb77cdf 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap @@ -2336,6 +2336,22 @@ Object { "components": Object { "Module": Object { "commands": Array [ + Object { + "name": "handleRootTag", + "optional": false, + "typeAnnotation": Object { + "params": Array [ + Object { + "name": "rootTag", + "typeAnnotation": Object { + "name": "RootTag", + "type": "ReservedFunctionValueTypeAnnotation", + }, + }, + ], + "type": "FunctionTypeAnnotation", + }, + }, Object { "name": "hotspotUpdate", "optional": false, 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 0232a82d1f4..769039be7a0 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/commands.js +++ b/packages/react-native-codegen/src/parsers/flow/components/commands.js @@ -47,6 +47,12 @@ function buildCommandSchema(property, types: TypeMap) { let returnType; switch (type) { + case 'RootTag': + returnType = { + type: 'ReservedFunctionValueTypeAnnotation', + name: 'RootTag', + }; + break; case 'BooleanTypeAnnotation': returnType = { type: 'BooleanTypeAnnotation',