Add handling for ColorArray

Summary: This diff adds support for ColorArrayValue in the flow parser

Reviewed By: cpojer

Differential Revision: D15502923

fbshipit-source-id: 6a906b6d609168378fabeb49d0080de011a34d78
This commit is contained in:
Rick Hanlon
2019-06-03 07:21:20 -07:00
committed by Facebook Github Bot
parent d8fa1206c3
commit ebb8caa4df
8 changed files with 176 additions and 79 deletions
@@ -17,6 +17,7 @@ const insetsDiffer = require('../Utilities/differ/insetsDiffer');
const matricesDiffer = require('../Utilities/differ/matricesDiffer');
const pointsDiffer = require('../Utilities/differ/pointsDiffer');
const processColor = require('../StyleSheet/processColor');
const processColorArray = require('../StyleSheet/processColorArray');
const resolveAssetSource = require('../Image/resolveAssetSource');
const sizesDiffer = require('../Utilities/differ/sizesDiffer');
const invariant = require('invariant');
@@ -182,8 +183,4 @@ function getProcessorForType(typeName: string): ?(nextProp: any) => any {
return null;
}
function processColorArray(colors: ?Array<any>): ?Array<?number> {
return colors == null ? null : colors.map(processColor);
}
module.exports = getNativeComponentAttributes;
+1
View File
@@ -13,6 +13,7 @@
const AnimatedNode = require('../Animated/src/nodes/AnimatedNode');
export type ColorValue = null | string;
export type ColorArrayValue = null | $ReadOnlyArray<ColorValue>;
export type PointValue = {|
x: number,
y: number,
+19
View File
@@ -0,0 +1,19 @@
/**
* 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.
*
* @format
* @flow strict-local
*/
'use strict';
const processColor = require('./processColor');
function processColorArray(colors: ?Array<string>): ?Array<?number> {
return colors == null ? null : colors.map(processColor);
}
module.exports = processColorArray;
@@ -34,15 +34,12 @@ const template = `
::_COMPONENT_CONFIG_::
`;
function getReactDiffProcessValue(prop) {
const typeAnnotation = prop.typeAnnotation;
function getReactDiffProcessValue(typeAnnotation) {
switch (typeAnnotation.type) {
case 'BooleanTypeAnnotation':
case 'StringTypeAnnotation':
case 'Int32TypeAnnotation':
case 'FloatTypeAnnotation':
case 'ArrayTypeAnnotation':
case 'StringEnumTypeAnnotation':
return j.literal(true);
case 'NativePrimitiveTypeAnnotation':
@@ -60,6 +57,25 @@ function getReactDiffProcessValue(prop) {
`Received unknown native typeAnnotation: "${typeAnnotation.name}"`,
);
}
case 'ArrayTypeAnnotation':
if (typeAnnotation.elementType.type === 'NativePrimitiveTypeAnnotation') {
switch (typeAnnotation.elementType.name) {
case 'ColorPrimitive':
return j.template
.expression`{ process: require('processColorArray') }`;
case 'ImageSourcePrimitive':
return j.literal(true);
case 'PointPrimitive':
return j.literal(true);
default:
throw new Error(
`Received unknown array native typeAnnotation: "${
typeAnnotation.elementType.name
}"`,
);
}
}
return j.literal(true);
default:
(typeAnnotation: empty);
throw new Error(
@@ -194,7 +210,7 @@ function buildViewConfig(
return j.property(
'init',
j.identifier(schemaProp.name),
getReactDiffProcessValue(schemaProp),
getReactDiffProcessValue(schemaProp.typeAnnotation),
);
}),
...getValidAttributesForEvents(componentEvents),
@@ -253,76 +269,82 @@ function buildViewConfig(
module.exports = {
generate(libraryName: string, schema: SchemaType): FilesOutput {
const fileName = `${libraryName}NativeViewConfig.js`;
const imports: Set<string> = new Set();
try {
const fileName = `${libraryName}NativeViewConfig.js`;
const imports: Set<string> = new Set();
imports.add(
"const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry');",
);
imports.add(
"const verifyComponentAttributeEquivalence = require('verifyComponentAttributeEquivalence');",
);
const moduleResults = Object.keys(schema.modules)
.map(moduleName => {
const components = schema.modules[moduleName].components;
// No components in this module
if (components == null) {
return null;
}
return Object.keys(components)
.map(componentName => {
const component = components[componentName];
const compatabilityComponentName = `${
component.isDeprecatedPaperComponentNameRCT ? 'RCT' : ''
}${componentName}`;
const replacedTemplate = componentTemplate
.replace(/::_COMPONENT_NAME_::/g, componentName)
.replace(
/::_COMPONENT_NAME_WITH_COMPAT_SUPPORT_::/g,
compatabilityComponentName,
)
.replace(
/::_COMPAT_COMMENT_::/g,
component.isDeprecatedPaperComponentNameRCT
? ' // RCT prefix present for paper support'
: '',
);
const replacedSource: string = j
.withParser('flow')(replacedTemplate)
.find(j.Identifier, {
name: 'VIEW_CONFIG',
})
.replaceWith(
buildViewConfig(
schema,
compatabilityComponentName,
component,
imports,
),
)
.toSource({quote: 'single', trailingComma: true});
return replacedSource;
})
.join('\n\n');
})
.filter(Boolean)
.join('\n\n');
const replacedTemplate = template
.replace(/::_COMPONENT_CONFIG_::/g, moduleResults)
.replace(
'::_IMPORTS_::',
Array.from(imports)
.sort()
.join('\n'),
imports.add(
"const ReactNativeViewConfigRegistry = require('ReactNativeViewConfigRegistry');",
);
imports.add(
"const verifyComponentAttributeEquivalence = require('verifyComponentAttributeEquivalence');",
);
return new Map([[fileName, replacedTemplate]]);
const moduleResults = Object.keys(schema.modules)
.map(moduleName => {
const components = schema.modules[moduleName].components;
// No components in this module
if (components == null) {
return null;
}
return Object.keys(components)
.map(componentName => {
const component = components[componentName];
const compatabilityComponentName = `${
component.isDeprecatedPaperComponentNameRCT ? 'RCT' : ''
}${componentName}`;
const replacedTemplate = componentTemplate
.replace(/::_COMPONENT_NAME_::/g, componentName)
.replace(
/::_COMPONENT_NAME_WITH_COMPAT_SUPPORT_::/g,
compatabilityComponentName,
)
.replace(
/::_COMPAT_COMMENT_::/g,
component.isDeprecatedPaperComponentNameRCT
? ' // RCT prefix present for paper support'
: '',
);
const replacedSource: string = j
.withParser('flow')(replacedTemplate)
.find(j.Identifier, {
name: 'VIEW_CONFIG',
})
.replaceWith(
buildViewConfig(
schema,
compatabilityComponentName,
component,
imports,
),
)
.toSource({quote: 'single', trailingComma: true});
return replacedSource;
})
.join('\n\n');
})
.filter(Boolean)
.join('\n\n');
const replacedTemplate = template
.replace(/::_COMPONENT_CONFIG_::/g, moduleResults)
.replace(
'::_IMPORTS_::',
Array.from(imports)
.sort()
.join('\n'),
);
return new Map([[fileName, replacedTemplate]]);
} catch (error) {
console.error(`\nError parsing schema for ${libraryName}\n`);
console.error(JSON.stringify(schema));
throw error;
}
},
};
@@ -36,7 +36,7 @@ const ArrayPropsNativeComponentViewConfig = {
disableds: true,
progress: true,
radii: true,
colors: true,
colors: { process: require('processColorArray') },
srcs: true,
points: true,
},
@@ -122,7 +122,7 @@ import type {
CodegenNativeComponent,
} from 'CodegenFlowtypes';
import type {ColorValue, PointValue} from 'StyleSheetTypes';
import type {ColorValue, ColorArrayValue, PointValue} from 'StyleSheetTypes';
import type {ImageSource} from 'ImageSource';
import type {ViewProps} from 'ViewPropTypes';
@@ -171,6 +171,12 @@ type ModuleProps = $ReadOnly<{|
color_optional_value: ?ColorValue,
color_optional_both?: ?ColorValue,
// ColorArrayValue props
color_array_required: ColorArrayValue,
color_array_optional_key?: ColorArrayValue,
color_array_optional_value: ?ColorArrayValue,
color_array_optional_both?: ?ColorArrayValue,
// PointValue props
point_required: PointValue,
point_optional_key?: PointValue,
@@ -262,6 +262,50 @@ Object {
"type": "NativePrimitiveTypeAnnotation",
},
},
Object {
"name": "color_array_required",
"optional": false,
"typeAnnotation": Object {
"elementType": Object {
"name": "ColorPrimitive",
"type": "NativePrimitiveTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
},
Object {
"name": "color_array_optional_key",
"optional": true,
"typeAnnotation": Object {
"elementType": Object {
"name": "ColorPrimitive",
"type": "NativePrimitiveTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
},
Object {
"name": "color_array_optional_value",
"optional": true,
"typeAnnotation": Object {
"elementType": Object {
"name": "ColorPrimitive",
"type": "NativePrimitiveTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
},
Object {
"name": "color_array_optional_both",
"optional": true,
"typeAnnotation": Object {
"elementType": Object {
"name": "ColorPrimitive",
"type": "NativePrimitiveTypeAnnotation",
},
"type": "ArrayTypeAnnotation",
},
},
Object {
"name": "point_required",
"optional": false,
@@ -105,6 +105,14 @@ function getTypeAnnotation(name, typeAnnotation, defaultValue) {
type: 'NativePrimitiveTypeAnnotation',
name: 'ColorPrimitive',
};
case 'ColorArrayValue':
return {
type: 'ArrayTypeAnnotation',
elementType: {
type: 'NativePrimitiveTypeAnnotation',
name: 'ColorPrimitive',
},
};
case 'PointValue':
return {
type: 'NativePrimitiveTypeAnnotation',