Back out "Back out D16434402, D16434634"

Summary: Reverting the revert and fixing the snapshot tests

Reviewed By: JoshuaGross

Differential Revision: D16467242

fbshipit-source-id: 23ed4122da226ea815d3766098da4400e7ad9442
This commit is contained in:
Eli White
2019-07-24 16:50:13 -07:00
committed by Facebook Github Bot
parent 76ff31616e
commit a24a9b9946
7 changed files with 145 additions and 19 deletions
@@ -11,6 +11,7 @@
'use strict';
import type {
CommandTypeShape,
ComponentShape,
PropTypeShape,
SchemaType,
@@ -26,10 +27,20 @@ package com.facebook.react.viewmanagers;
::_IMPORTS_::
public class ::_CLASSNAME_::<T extends ::_EXTEND_CLASSES_::> {
::_METHODS_::
}
`;
const propSetterTemplate = `
public void setProperty(::_INTERFACE_CLASSNAME_::<T> viewManager, T view, String propName, Object value) {
::_PROP_CASES_::
}
}
`;
const commandsTemplate = `
public void receiveCommand(::_INTERFACE_CLASSNAME_::<T> viewManager, T view, String commandName, ReadableArray args) {
::_COMMAND_CASES_::
}
`;
function getJavaValueForProp(
@@ -105,6 +116,51 @@ function generatePropCasesString(
}`;
}
function getCommandArgJavaType(param) {
switch (param.typeAnnotation.type) {
case 'BooleanTypeAnnotation':
return 'getBoolean';
case 'Int32TypeAnnotation':
return 'getInt';
default:
(param.typeAnnotation.type: empty);
throw new Error('Receieved invalid typeAnnotation');
}
}
function getCommandArguments(command: CommandTypeShape): string {
return [
'view',
...command.typeAnnotation.params.map((param, index) => {
const commandArgJavaType = getCommandArgJavaType(param);
return `args.${commandArgJavaType}(${index})`;
}),
].join(', ');
}
function generateCommandCasesString(
component: ComponentShape,
componentName: string,
) {
if (component.commands.length === 0) {
return null;
}
const commandMethods = component.commands
.map(command => {
return `case "${command.name}":
viewManager.${toSafeJavaString(
command.name,
false,
)}(${getCommandArguments(command)});
break;`;
})
.join('\n' + ' ');
return commandMethods;
}
function getClassExtendString(component): string {
const extendString = component.extendsProps
.map(extendProps => {
@@ -127,6 +183,28 @@ function getClassExtendString(component): string {
return extendString;
}
function getDelegateImports(component) {
const imports = getImports(component);
// The delegate needs ReadableArray for commands always.
// The interface doesn't always need it
if (component.commands.length > 0) {
imports.add('import com.facebook.react.bridge.ReadableArray;');
}
return imports;
}
function generateMethods(propsString, commandsString): string {
return [
propSetterTemplate.trim().replace('::_PROP_CASES_::', propsString),
commandsString != null
? commandsTemplate.trim().replace('::_COMMAND_CASES_::', commandsString)
: '',
]
.join('\n\n ')
.trimRight();
}
module.exports = {
generate(libraryName: string, schema: SchemaType): FilesOutput {
const files = new Map();
@@ -143,8 +221,12 @@ module.exports = {
const interfaceClassName = `${componentName}ViewManagerInterface`;
const fileName = `${className}.java`;
const imports = getImports(component);
const imports = getDelegateImports(component);
const propsString = generatePropCasesString(component, componentName);
const commandsString = generateCommandCasesString(
component,
componentName,
);
const extendString = getClassExtendString(component);
const replacedTemplate = template
@@ -155,9 +237,13 @@ module.exports = {
.join('\n'),
)
.replace(/::_CLASSNAME_::/g, className)
.replace(/::_INTERFACE_CLASSNAME_::/g, interfaceClassName)
.replace('::_EXTEND_CLASSES_::', extendString)
.replace('::_PROP_CASES_::', propsString);
.replace('::_PROP_CASES_::', propsString)
.replace(
'::_METHODS_::',
generateMethods(propsString, commandsString),
)
.replace(/::_INTERFACE_CLASSNAME_::/g, interfaceClassName);
files.set(fileName, replacedTemplate);
});
@@ -107,15 +107,14 @@ function getCommandArguments(
command: CommandTypeShape,
componentName: string,
): string {
const commandArgs = command.typeAnnotation.params
.map(param => {
return [
'T view',
...command.typeAnnotation.params.map(param => {
const commandArgJavaType = getCommandArgJavaType(param);
return `${commandArgJavaType} ${param.name}`;
})
.join(', ');
return `T view, ${commandArgs}`;
}),
].join(', ');
}
function generateCommandsString(
@@ -124,11 +123,9 @@ function generateCommandsString(
) {
return component.commands
.map(command => {
const safeJavaName = toSafeJavaString(command.name);
const lowerJavaName =
safeJavaName[0].toLowerCase() + safeJavaName.slice(1);
const safeJavaName = toSafeJavaString(command.name, false);
return `void ${lowerJavaName}(${getCommandArguments(
return `void ${safeJavaName}(${getCommandArguments(
command,
componentName,
)});`;
@@ -16,11 +16,17 @@ function upperCaseFirst(inString: string): string {
return inString[0].toUpperCase() + inString.slice(1);
}
function toSafeJavaString(input: string): string {
return input
.split('-')
.map(upperCaseFirst)
.join('');
function toSafeJavaString(
input: string,
shouldUpperCaseFirst?: boolean,
): string {
const parts = input.split('-');
if (shouldUpperCaseFirst === false) {
return parts.join('');
}
return parts.map(upperCaseFirst).join('');
}
function getImports(component: ComponentShape): Set<string> {
@@ -921,6 +921,14 @@ const COMMANDS: SchemaType = {
events: [],
props: [],
commands: [
{
name: 'flashScrollIndicators',
optional: false,
typeAnnotation: {
type: 'FunctionTypeAnnotation',
params: [],
},
},
{
name: 'hotspotUpdate',
optional: false,
@@ -88,11 +88,24 @@ Map {
package com.facebook.react.viewmanagers;
import android.view.View;
import com.facebook.react.bridge.ReadableArray;
public class CommandNativeComponentViewManagerDelegate<T extends View> {
public void setProperty(CommandNativeComponentViewManagerInterface<T> viewManager, T view, String propName, Object value) {
// No props
}
public void receiveCommand(CommandNativeComponentViewManagerInterface<T> viewManager, T view, String commandName, ReadableArray args) {
case \\"flashScrollIndicators\\":
viewManager.flashScrollIndicators(view);
break;
case \\"hotspotUpdate\\":
viewManager.hotspotUpdate(view, args.getInt(0), args.getInt(1));
break;
case \\"scrollTo\\":
viewManager.scrollTo(view, args.getInt(0), args.getBoolean(1));
break;
}
}
",
}
@@ -104,6 +117,7 @@ Map {
package com.facebook.react.viewmanagers;
import android.view.View;
import com.facebook.react.bridge.ReadableArray;
public class CommandNativeComponentViewManagerDelegate<T extends View> {
public void setProperty(CommandNativeComponentViewManagerInterface<T> viewManager, T view, String propName, Object value) {
@@ -113,6 +127,12 @@ public class CommandNativeComponentViewManagerDelegate<T extends View> {
break;
}
}
public void receiveCommand(CommandNativeComponentViewManagerInterface<T> viewManager, T view, String commandName, ReadableArray args) {
case \\"hotspotUpdate\\":
viewManager.hotspotUpdate(view, args.getInt(0), args.getInt(1));
break;
}
}
",
}
@@ -61,6 +61,7 @@ import android.view.View;
public interface CommandNativeComponentViewManagerInterface<T extends View> {
// No props
void flashScrollIndicators(T view);
void hotspotUpdate(T view, int x, int y);
void scrollTo(T view, int y, boolean animated);
}
@@ -144,6 +144,14 @@ export const __INTERNAL_VIEW_CONFIG = CommandNativeComponentViewConfig;
export default nativeComponentName;
export const Commands = {
flashScrollIndicators(ref) {
UIManager.dispatchViewCommand(
findNodeHandle(ref),
UIManager.getViewManagerConfig(\\"CommandNativeComponent\\").Commands.flashScrollIndicators,
[]
);
},
hotspotUpdate(ref, x, y) {
UIManager.dispatchViewCommand(
findNodeHandle(ref),