mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Rewrite GenerateViewConfigJs with @babel/core
This commit is contained in:
+99
-135
@@ -16,7 +16,8 @@ import type {
|
||||
} from '../../CodegenSchema';
|
||||
import type {SchemaType} from '../../CodegenSchema';
|
||||
|
||||
const j = require('jscodeshift');
|
||||
const core = require('@babel/core');
|
||||
const t = core.types;
|
||||
|
||||
// File path -> contents
|
||||
type FilesOutput = Map<string, string>;
|
||||
@@ -50,6 +51,10 @@ ${componentConfig}
|
||||
// this multiple times.
|
||||
const UIMANAGER_IMPORT = 'const {UIManager} = require("react-native")';
|
||||
|
||||
function expression(input: string) {
|
||||
return core.template.expression(input)();
|
||||
}
|
||||
|
||||
function getReactDiffProcessValue(typeAnnotation: PropTypeAnnotation) {
|
||||
switch (typeAnnotation.type) {
|
||||
case 'BooleanTypeAnnotation':
|
||||
@@ -61,25 +66,21 @@ function getReactDiffProcessValue(typeAnnotation: PropTypeAnnotation) {
|
||||
case 'StringEnumTypeAnnotation':
|
||||
case 'Int32EnumTypeAnnotation':
|
||||
case 'MixedTypeAnnotation':
|
||||
return j.literal(true);
|
||||
return t.booleanLiteral(true);
|
||||
case 'ReservedPropTypeAnnotation':
|
||||
switch (typeAnnotation.name) {
|
||||
case 'ColorPrimitive':
|
||||
return j.template
|
||||
.expression`{ process: require('react-native/Libraries/StyleSheet/processColor').default }`;
|
||||
return expression(`{ process: require('react-native/Libraries/StyleSheet/processColor').default }`);
|
||||
case 'ImageSourcePrimitive':
|
||||
return j.template
|
||||
.expression`{ process: require('react-native/Libraries/Image/resolveAssetSource') }`;
|
||||
return expression(`{ process: require('react-native/Libraries/Image/resolveAssetSource') }`);
|
||||
case 'ImageRequestPrimitive':
|
||||
throw new Error('ImageRequest should not be used in props');
|
||||
case 'PointPrimitive':
|
||||
return j.template
|
||||
.expression`{ diff: ((req) => 'default' in req ? req.default : req)(require('react-native/Libraries/Utilities/differ/pointsDiffer')) }`;
|
||||
return expression(`{ diff: ((req) => 'default' in req ? req.default : req)(require('react-native/Libraries/Utilities/differ/pointsDiffer')) }`);
|
||||
case 'EdgeInsetsPrimitive':
|
||||
return j.template
|
||||
.expression`{ diff: ((req) => 'default' in req ? req.default : req)(require('react-native/Libraries/Utilities/differ/insetsDiffer')) }`;
|
||||
return expression(`{ diff: ((req) => 'default' in req ? req.default : req)(require('react-native/Libraries/Utilities/differ/insetsDiffer')) }`);
|
||||
case 'DimensionPrimitive':
|
||||
return j.literal(true);
|
||||
return t.booleanLiteral(true);
|
||||
default:
|
||||
(typeAnnotation.name: empty);
|
||||
throw new Error(
|
||||
@@ -90,20 +91,19 @@ function getReactDiffProcessValue(typeAnnotation: PropTypeAnnotation) {
|
||||
if (typeAnnotation.elementType.type === 'ReservedPropTypeAnnotation') {
|
||||
switch (typeAnnotation.elementType.name) {
|
||||
case 'ColorPrimitive':
|
||||
return j.template
|
||||
.expression`{ process: ((req) => 'default' in req ? req.default : req)(require('react-native/Libraries/StyleSheet/processColorArray')) }`;
|
||||
return expression(`{ process: ((req) => 'default' in req ? req.default : req)(require('react-native/Libraries/StyleSheet/processColorArray')) }`);
|
||||
case 'ImageSourcePrimitive':
|
||||
case 'PointPrimitive':
|
||||
case 'EdgeInsetsPrimitive':
|
||||
case 'DimensionPrimitive':
|
||||
return j.literal(true);
|
||||
return t.booleanLiteral(true);
|
||||
default:
|
||||
throw new Error(
|
||||
`Received unknown array native typeAnnotation: "${typeAnnotation.elementType.name}"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
return j.literal(true);
|
||||
return t.booleanLiteral(true);
|
||||
default:
|
||||
(typeAnnotation: empty);
|
||||
throw new Error(
|
||||
@@ -134,7 +134,7 @@ ${
|
||||
: ''
|
||||
}
|
||||
|
||||
export const __INTERNAL_VIEW_CONFIG = VIEW_CONFIG;
|
||||
export const __INTERNAL_VIEW_CONFIG = %%VIEW_CONFIG%%;
|
||||
|
||||
export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);
|
||||
`.trim();
|
||||
@@ -180,36 +180,40 @@ function getValidAttributesForEvents(
|
||||
"const {ConditionallyIgnoredEventHandlers} = require('react-native/Libraries/NativeComponent/ViewConfigIgnore');",
|
||||
);
|
||||
|
||||
const validAttributes = j.objectExpression(
|
||||
const validAttributes = t.objectExpression(
|
||||
events.map(eventType => {
|
||||
return j.property('init', j.identifier(eventType.name), j.literal(true));
|
||||
return t.objectProperty(
|
||||
t.identifier(eventType.name),
|
||||
t.booleanLiteral(true),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
return j.callExpression(j.identifier('ConditionallyIgnoredEventHandlers'), [
|
||||
validAttributes,
|
||||
]);
|
||||
return t.callExpression(
|
||||
t.identifier('ConditionallyIgnoredEventHandlers'),
|
||||
[validAttributes]
|
||||
);
|
||||
}
|
||||
|
||||
function generateBubblingEventInfo(
|
||||
event: EventTypeShape,
|
||||
nameOveride: void | string,
|
||||
) {
|
||||
return j.property(
|
||||
'init',
|
||||
j.identifier(normalizeInputEventName(nameOveride || event.name)),
|
||||
j.objectExpression([
|
||||
j.property(
|
||||
'init',
|
||||
j.identifier('phasedRegistrationNames'),
|
||||
j.objectExpression([
|
||||
j.property(
|
||||
'init',
|
||||
j.identifier('captured'),
|
||||
j.literal(`${event.name}Capture`),
|
||||
return t.objectProperty(
|
||||
t.identifier(normalizeInputEventName(nameOveride || event.name)),
|
||||
t.objectExpression([
|
||||
t.objectProperty(
|
||||
t.identifier('phasedRegistrationNames'),
|
||||
t.objectExpression([
|
||||
t.objectProperty(
|
||||
t.identifier('captured'),
|
||||
t.identifier(`${event.name}Capture`),
|
||||
),
|
||||
j.property('init', j.identifier('bubbled'), j.literal(event.name)),
|
||||
]),
|
||||
t.objectProperty(
|
||||
t.identifier('bubbled'),
|
||||
t.identifier(event.name),
|
||||
),
|
||||
])
|
||||
),
|
||||
]),
|
||||
);
|
||||
@@ -219,14 +223,12 @@ function generateDirectEventInfo(
|
||||
event: EventTypeShape,
|
||||
nameOveride: void | string,
|
||||
) {
|
||||
return j.property(
|
||||
'init',
|
||||
j.identifier(normalizeInputEventName(nameOveride || event.name)),
|
||||
j.objectExpression([
|
||||
j.property(
|
||||
'init',
|
||||
j.identifier('registrationName'),
|
||||
j.literal(event.name),
|
||||
return t.objectProperty(
|
||||
t.identifier(normalizeInputEventName(nameOveride || event.name)),
|
||||
t.objectExpression([
|
||||
t.objectProperty(
|
||||
t.identifier('registrationName'),
|
||||
t.identifier(event.name),
|
||||
),
|
||||
]),
|
||||
);
|
||||
@@ -261,17 +263,16 @@ function buildViewConfig(
|
||||
}
|
||||
});
|
||||
|
||||
const validAttributes = j.objectExpression([
|
||||
const validAttributes = t.objectExpression([
|
||||
...componentProps.map(schemaProp => {
|
||||
return j.property(
|
||||
'init',
|
||||
j.identifier(schemaProp.name),
|
||||
return t.objectProperty(
|
||||
t.identifier(schemaProp.name),
|
||||
getReactDiffProcessValue(schemaProp.typeAnnotation),
|
||||
);
|
||||
}),
|
||||
...(componentEvents.length > 0
|
||||
? [
|
||||
j.spreadProperty(
|
||||
t.spreadElement(
|
||||
getValidAttributesForEvents(componentEvents, imports),
|
||||
),
|
||||
]
|
||||
@@ -294,15 +295,6 @@ function buildViewConfig(
|
||||
return bubblingEvents;
|
||||
}, []);
|
||||
|
||||
const bubblingEvents =
|
||||
bubblingEventNames.length > 0
|
||||
? j.property(
|
||||
'init',
|
||||
j.identifier('bubblingEventTypes'),
|
||||
j.objectExpression(bubblingEventNames),
|
||||
)
|
||||
: null;
|
||||
|
||||
const directEventNames = component.events
|
||||
.filter(event => event.bubblingType === 'direct')
|
||||
.reduce((directEvents: Array<any>, event) => {
|
||||
@@ -319,27 +311,28 @@ function buildViewConfig(
|
||||
return directEvents;
|
||||
}, []);
|
||||
|
||||
const directEvents =
|
||||
directEventNames.length > 0
|
||||
? j.property(
|
||||
'init',
|
||||
j.identifier('directEventTypes'),
|
||||
j.objectExpression(directEventNames),
|
||||
)
|
||||
: null;
|
||||
|
||||
const properties = [
|
||||
j.property(
|
||||
'init',
|
||||
j.identifier('uiViewClassName'),
|
||||
j.literal(componentName),
|
||||
t.objectProperty(
|
||||
t.identifier('uiViewClassName'),
|
||||
t.stringLiteral(componentName),
|
||||
),
|
||||
bubblingEvents,
|
||||
directEvents,
|
||||
j.property('init', j.identifier('validAttributes'), validAttributes),
|
||||
].filter(Boolean);
|
||||
];
|
||||
|
||||
return j.objectExpression(properties);
|
||||
if (bubblingEventNames.length > 0) {
|
||||
properties.push(t.objectProperty(
|
||||
t.identifier('bubblingEventTypes'),
|
||||
t.objectExpression(bubblingEventNames),
|
||||
));
|
||||
}
|
||||
if (directEventNames.length > 0) {
|
||||
properties.push(t.objectProperty(
|
||||
t.identifier('directEventTypes'),
|
||||
t.objectExpression(directEventNames),
|
||||
));
|
||||
}
|
||||
|
||||
properties.push(t.objectProperty(t.identifier('validAttributes'), validAttributes));
|
||||
return t.objectExpression(properties);
|
||||
}
|
||||
|
||||
function buildCommands(
|
||||
@@ -358,44 +351,32 @@ function buildCommands(
|
||||
'const {dispatchCommand} = require("react-native/Libraries/ReactNative/RendererProxy");',
|
||||
);
|
||||
|
||||
const properties = commands.map(command => {
|
||||
const commandName = command.name;
|
||||
const params = command.typeAnnotation.params;
|
||||
const commandsObject = t.objectExpression(
|
||||
commands.map(command => {
|
||||
const commandName = command.name;
|
||||
const params = command.typeAnnotation.params;
|
||||
|
||||
const commandNameLiteral = j.literal(commandName);
|
||||
const commandNameIdentifier = j.identifier(commandName);
|
||||
const arrayParams = j.arrayExpression(
|
||||
params.map(param => {
|
||||
return j.identifier(param.name);
|
||||
}),
|
||||
);
|
||||
const dispatchCommandCall = t.callExpression(t.identifier('dispatchCommand'), [
|
||||
t.identifier(commandName),
|
||||
t.arrayExpression(params.map(param => t.identifier(param.name))),
|
||||
]);
|
||||
|
||||
const expression = j.template
|
||||
.expression`dispatchCommand(ref, ${commandNameLiteral}, ${arrayParams})`;
|
||||
return t.objectMethod(
|
||||
'method',
|
||||
t.identifier(commandName),
|
||||
[t.identifier('ref'), ...params.map(param => t.identifier(param.name))],
|
||||
t.blockStatement([
|
||||
t.expressionStatement(dispatchCommandCall),
|
||||
]),
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
const functionParams = params.map(param => {
|
||||
return j.identifier(param.name);
|
||||
});
|
||||
|
||||
const property = j.property(
|
||||
'init',
|
||||
commandNameIdentifier,
|
||||
j.functionExpression(
|
||||
null,
|
||||
[j.identifier('ref'), ...functionParams],
|
||||
j.blockStatement([j.expressionStatement(expression)]),
|
||||
),
|
||||
);
|
||||
property.method = true;
|
||||
|
||||
return property;
|
||||
});
|
||||
|
||||
return j.exportNamedDeclaration(
|
||||
j.variableDeclaration('const', [
|
||||
j.variableDeclarator(
|
||||
j.identifier('Commands'),
|
||||
j.objectExpression(properties),
|
||||
return t.exportNamedDeclaration(
|
||||
t.variableDeclaration('const', [
|
||||
t.variableDeclarator(
|
||||
t.identifier('Commands'),
|
||||
commandsObject,
|
||||
),
|
||||
]),
|
||||
);
|
||||
@@ -431,42 +412,25 @@ module.exports = {
|
||||
component.paperComponentNameDeprecated,
|
||||
});
|
||||
|
||||
const replacedSourceRoot = j.withParser('flow')(replacedTemplate);
|
||||
|
||||
const paperComponentName =
|
||||
component.paperComponentName ?? componentName;
|
||||
|
||||
replacedSourceRoot
|
||||
.find(j.Identifier, {
|
||||
name: 'VIEW_CONFIG',
|
||||
})
|
||||
.replaceWith(
|
||||
buildViewConfig(
|
||||
schema,
|
||||
paperComponentName,
|
||||
component,
|
||||
imports,
|
||||
),
|
||||
);
|
||||
const replacedSourceRoot = core.template.program(replacedTemplate)({
|
||||
VIEW_CONFIG: buildViewConfig(schema, paperComponentName, component, imports),
|
||||
});
|
||||
|
||||
const commands = buildCommands(
|
||||
const commandsExport = buildCommands(
|
||||
schema,
|
||||
paperComponentName,
|
||||
component,
|
||||
imports,
|
||||
);
|
||||
if (commands) {
|
||||
replacedSourceRoot
|
||||
.find(j.ExportDefaultDeclaration)
|
||||
.insertAfter(j(commands).toSource());
|
||||
if (commandsExport) {
|
||||
replacedSourceRoot.body.push(commandsExport);
|
||||
}
|
||||
|
||||
const replacedSource: string = replacedSourceRoot.toSource({
|
||||
quote: 'single',
|
||||
trailingComma: true,
|
||||
});
|
||||
|
||||
return replacedSource;
|
||||
const replacedSource = core.transformFromAstSync(replacedSourceRoot);
|
||||
return replacedSource.code;
|
||||
})
|
||||
.join('\n\n');
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user