Add command methods to GeneratePropsJavaInterface

Summary: These methods will be called when commands are dispatched.

Reviewed By: JoshuaGross

Differential Revision: D16388806

fbshipit-source-id: a09d257474aa3306b99f8dcdfdd23808f60eb4bd
This commit is contained in:
Eli White
2019-07-22 12:52:58 -07:00
committed by Facebook Github Bot
parent 7d15a6be2c
commit c7ee38149d
12 changed files with 394 additions and 6 deletions
@@ -11,6 +11,7 @@
'use strict';
import type {
CommandTypeShape,
ComponentShape,
PropTypeShape,
SchemaType,
@@ -26,7 +27,7 @@ package com.facebook.react.viewmanagers;
::_IMPORTS_::
public interface ::_CLASSNAME_::<T extends ::_EXTEND_CLASSES_::> {
::_PROP_SETTERS_::
::_METHODS_::
}
`;
@@ -70,7 +71,7 @@ function getJavaValueForProp(
function generatePropsString(component: ComponentShape, componentName: string) {
if (component.props.length === 0) {
return ' // No props';
return '// No props';
}
return component.props
@@ -82,6 +83,51 @@ function generatePropsString(component: ComponentShape, componentName: string) {
.join('\n' + ' ');
}
function getCommandArgJavaType(param) {
switch (param.typeAnnotation.type) {
case 'BooleanTypeAnnotation':
return 'boolean';
case 'Int32TypeAnnotation':
return 'int';
default:
(param.typeAnnotation.type: empty);
throw new Error('Receieved invalid typeAnnotation');
}
}
function getCommandArguments(
command: CommandTypeShape,
componentName: string,
): string {
const commandArgs = command.typeAnnotation.params
.map(param => {
const commandArgJavaType = getCommandArgJavaType(param);
return `${commandArgJavaType} ${param.name}`;
})
.join(', ');
return `T view, ${commandArgs}`;
}
function generateCommandsString(
component: ComponentShape,
componentName: string,
) {
return component.commands
.map(command => {
const safeJavaName = toSafeJavaString(command.name);
const lowerJavaName =
safeJavaName[0].toLowerCase() + safeJavaName.slice(1);
return `void ${lowerJavaName}(${getCommandArguments(
command,
componentName,
)});`;
})
.join('\n' + ' ');
}
function getClassExtendString(component): string {
const extendString = component.extendsProps
.map(extendProps => {
@@ -121,6 +167,7 @@ module.exports = {
const imports = getImports(component);
const propsString = generatePropsString(component, componentName);
const commandsString = generateCommandsString(component, componentName);
const extendString = getClassExtendString(component);
const replacedTemplate = template
@@ -132,7 +179,11 @@ module.exports = {
)
.replace(/::_CLASSNAME_::/g, className)
.replace('::_EXTEND_CLASSES_::', extendString)
.replace('::_PROP_SETTERS_::', propsString);
.replace(
'::_METHODS_::',
[propsString, commandsString].join('\n' + ' ').trimRight(),
)
.replace('::_COMMAND_HANDLERS_::', commandsString);
files.set(fileName, replacedTemplate);
});
@@ -970,6 +970,57 @@ const COMMANDS: SchemaType = {
},
};
const COMMANDS_AND_PROPS: SchemaType = {
modules: {
Switch: {
components: {
CommandNativeComponent: {
extendsProps: [
{
type: 'ReactNativeBuiltInType',
knownTypeName: 'ReactNativeCoreViewProps',
},
],
events: [],
props: [
{
name: 'accessibilityHint',
optional: true,
typeAnnotation: {
type: 'StringTypeAnnotation',
default: '',
},
},
],
commands: [
{
name: 'hotspotUpdate',
optional: false,
typeAnnotation: {
type: 'FunctionTypeAnnotation',
params: [
{
name: 'x',
typeAnnotation: {
type: 'Int32TypeAnnotation',
},
},
{
name: 'y',
typeAnnotation: {
type: 'Int32TypeAnnotation',
},
},
],
},
},
],
},
},
},
},
};
module.exports = {
NO_PROPS_NO_EVENTS,
INTERFACE_ONLY,
@@ -989,4 +1040,5 @@ module.exports = {
TWO_COMPONENTS_SAME_FILE,
TWO_COMPONENTS_DIFFERENT_FILES,
COMMANDS,
COMMANDS_AND_PROPS,
};
@@ -86,6 +86,29 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateEventEmitterCpp can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"EventEmitters.cpp" => "
/**
* 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.
*/
#include <react/components/COMMANDS_AND_PROPS/EventEmitters.h>
namespace facebook {
namespace react {
} // namespace react
} // namespace facebook
",
@@ -90,6 +90,30 @@ namespace react {
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateEventEmitterH can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"EventEmitters.h" => "
/**
* 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.
*/
#pragma once
#include <react/components/view/ViewEventEmitter.h>
namespace facebook {
namespace react {
} // namespace react
} // namespace facebook
",
@@ -124,6 +124,35 @@ CommandNativeComponentProps::CommandNativeComponentProps(
}
`;
exports[`GeneratePropsCpp can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"Props.cpp" => "
/**
* 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.
*/
#include <react/components/COMMANDS_AND_PROPS/Props.h>
#include <react/core/propsConversions.h>
namespace facebook {
namespace react {
CommandNativeComponentProps::CommandNativeComponentProps(
const CommandNativeComponentProps &sourceProps,
const RawProps &rawProps): ViewProps(sourceProps, rawProps),
accessibilityHint(convertRawProp(rawProps, \\"accessibilityHint\\", sourceProps.accessibilityHint, accessibilityHint))
{}
} // namespace react
} // namespace facebook
",
}
`;
exports[`GeneratePropsCpp can generate fixture ENUM_PROP 1`] = `
Map {
"Props.cpp" => "
@@ -197,6 +197,38 @@ class CommandNativeComponentProps final : public ViewProps {
}
`;
exports[`GeneratePropsH can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"Props.h" => "
/**
* 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.
*/
#pragma once
#include <react/components/view/ViewProps.h>
namespace facebook {
namespace react {
class CommandNativeComponentProps final : public ViewProps {
public:
CommandNativeComponentProps() = default;
CommandNativeComponentProps(const CommandNativeComponentProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
const std::string accessibilityHint{\\"\\"};
};
} // namespace react
} // namespace facebook
",
}
`;
exports[`GeneratePropsH can generate fixture ENUM_PROP 1`] = `
Map {
"Props.h" => "
@@ -100,6 +100,26 @@ public class CommandNativeComponentDelegate<T extends View> {
}
`;
exports[`GeneratePropsJavaDelegate can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"CommandNativeComponentDelegate.java" => "
package com.facebook.react.viewmanagers;
import android.view.View;
public class CommandNativeComponentDelegate<T extends View> {
public void setProperty(CommandNativeComponentInterface<T> viewManager, T view, String propName, Object value) {
switch (propName) {
case \\"accessibilityHint\\":
viewManager.setAccessibilityHint(view, (String) value);
break;
}
}
}
",
}
`;
exports[`GeneratePropsJavaDelegate can generate fixture ENUM_PROP 1`] = `
Map {
"EnumPropsNativeComponentDelegate.java" => "
@@ -58,7 +58,24 @@ package com.facebook.react.viewmanagers;
import android.view.View;
public interface CommandNativeComponentInterface<T extends View> {
// No props
// No props
void hotspotUpdate(T view, int x, int y);
void scrollTo(T view, int y, boolean animated);
}
",
}
`;
exports[`GeneratePropsJavaInterface can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"CommandNativeComponentInterface.java" => "
package com.facebook.react.viewmanagers;
import android.view.View;
public interface CommandNativeComponentInterface<T extends View> {
void setAccessibilityHint(T view, String value);
void hotspotUpdate(T view, int x, int y);
}
",
}
@@ -114,7 +131,7 @@ package com.facebook.react.viewmanagers;
import android.view.View;
public interface InterfaceOnlyComponentInterface<T extends View> {
// No props
// No props
}
",
}
@@ -210,7 +227,7 @@ package com.facebook.react.viewmanagers;
import android.view.View;
public interface NoPropsNoEventsComponentInterface<T extends View> {
// No props
// No props
}
",
}
@@ -92,6 +92,29 @@ extern const char CommandNativeComponentComponentName[] = \\"CommandNativeCompon
}
`;
exports[`GenerateShadowNodeCpp can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"ShadowNodes.cpp" => "
/**
* 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.
*/
#include <react/components/COMMANDS_AND_PROPS/ShadowNodes.h>
namespace facebook {
namespace react {
extern const char CommandNativeComponentComponentName[] = \\"CommandNativeComponent\\";
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateShadowNodeCpp can generate fixture ENUM_PROP 1`] = `
Map {
"ShadowNodes.cpp" => "
@@ -132,6 +132,39 @@ using CommandNativeComponentShadowNode = ConcreteViewShadowNode<
}
`;
exports[`GenerateShadowNodeH can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"ShadowNodes.h" => "
/**
* 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.
*/
#pragma once
#include <react/components/COMMANDS_AND_PROPS/Props.h>
#include <react/components/view/ConcreteViewShadowNode.h>
namespace facebook {
namespace react {
extern const char CommandNativeComponentComponentName[];
/*
* \`ShadowNode\` for <CommandNativeComponent> component.
*/
using CommandNativeComponentShadowNode = ConcreteViewShadowNode<
CommandNativeComponentComponentName,
CommandNativeComponentProps>;
} // namespace react
} // namespace facebook
",
}
`;
exports[`GenerateShadowNodeH can generate fixture ENUM_PROP 1`] = `
Map {
"ShadowNodes.h" => "
@@ -131,6 +131,43 @@ TEST(CommandNativeComponentProps_DoesNotDie, etc) {
}
`;
exports[`GenerateTests can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"Tests.cpp" => "/**
* 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.
*/
#include <gtest/gtest.h>
#include <react/components/COMMANDS_AND_PROPS/Props.h>
#include <react/core/RawProps.h>
#include <react/core/RawPropsParser.h>
#include <react/core/propsConversions.h>
using namespace facebook::react;
TEST(CommandNativeComponentProps_DoesNotDie, etc) {
auto propParser = RawPropsParser();
propParser.prepare<CommandNativeComponentProps>();
auto const &sourceProps = CommandNativeComponentProps();
auto const &rawProps = RawProps(folly::dynamic::object(\\"xx_invalid_xx\\", \\"xx_invalid_xx\\"));
rawProps.parse(propParser);
CommandNativeComponentProps(sourceProps, rawProps);
}
TEST(CommandNativeComponentProps_accessibilityHint, etc) {
auto propParser = RawPropsParser();
propParser.prepare<CommandNativeComponentProps>();
auto const &sourceProps = CommandNativeComponentProps();
auto const &rawProps = RawProps(folly::dynamic::object(\\"accessibilityHint\\", \\"foo\\"));
rawProps.parse(propParser);
CommandNativeComponentProps(sourceProps, rawProps);
}",
}
`;
exports[`GenerateTests can generate fixture ENUM_PROP 1`] = `
Map {
"Tests.cpp" => "/**
@@ -164,6 +164,53 @@ export const Commands = {
}
`;
exports[`GenerateViewConfigJs can generate fixture COMMANDS_AND_PROPS 1`] = `
Map {
"COMMANDS_AND_PROPSNativeViewConfig.js" => "
/**
* 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
*/
'use strict';
const registerGeneratedViewConfig = require('registerGeneratedViewConfig');
const {UIManager} = require(\\"react-native\\")
const {findNodeHandle} = require(\\"react-native\\")
const CommandNativeComponentViewConfig = {
uiViewClassName: 'CommandNativeComponent',
validAttributes: {
accessibilityHint: true,
},
};
let nativeComponentName = 'CommandNativeComponent';
registerGeneratedViewConfig(nativeComponentName, CommandNativeComponentViewConfig);
export const __INTERNAL_VIEW_CONFIG = CommandNativeComponentViewConfig;
export default nativeComponentName;
export const Commands = {
hotspotUpdate(ref, x, y) {
UIManager.dispatchViewCommand(
findNodeHandle(ref),
UIManager.getViewManagerConfig(\\"CommandNativeComponent\\").Commands.hotspotUpdate,
[x, y]
);
}
};
",
}
`;
exports[`GenerateViewConfigJs can generate fixture ENUM_PROP 1`] = `
Map {
"ENUM_PROPNativeViewConfig.js" => "