mirror of
https://github.com/status-im/react-native.git
synced 2025-01-09 17:15:54 +00:00
1c6e837504
Summary: To allow smoother API changes for users we often deprecate props and keep them around for a while before removing them. Right now it is all done manually, this adds a consistent way to show a warning when using a deprecated prop. This also adds a deprecation warning of the website generated from the deprecatedPropType. <img width="643" alt="screen shot 2016-01-26 at 7 43 08 pm" src="https://cloud.githubusercontent.com/assets/2677334/12600172/7af28fb0-c465-11e5-85e5-3786852bf522.png"> It also changes places where we added the warnings manually to use deprecatedPropType instead. Closes https://github.com/facebook/react-native/pull/5566 Reviewed By: svcscm Differential Revision: D2874629 Pulled By: nicklockwood fb-gh-sync-id: c3c63bae7bbec26cc146029abd9aa5efbe73f795
130 lines
4.1 KiB
JavaScript
130 lines
4.1 KiB
JavaScript
"use strict";
|
|
var docgen = require('react-docgen');
|
|
|
|
function stylePropTypeHandler(documentation, path) {
|
|
var propTypesPath = docgen.utils.getMemberValuePath(path, 'propTypes');
|
|
if (!propTypesPath) {
|
|
return;
|
|
}
|
|
|
|
propTypesPath = docgen.utils.resolveToValue(propTypesPath);
|
|
if (!propTypesPath || propTypesPath.node.type !== 'ObjectExpression') {
|
|
return;
|
|
}
|
|
|
|
// Check if the there is a style prop
|
|
propTypesPath.get('properties').each(function(propertyPath) {
|
|
if (propertyPath.node.type !== 'Property' ||
|
|
docgen.utils.getPropertyName(propertyPath) !== 'style') {
|
|
return;
|
|
}
|
|
var valuePath = docgen.utils.resolveToValue(propertyPath.get('value'));
|
|
// If it's a call to StyleSheetPropType, do stuff
|
|
if (valuePath.node.type !== 'CallExpression' ||
|
|
valuePath.node.callee.name !== 'StyleSheetPropType') {
|
|
return;
|
|
}
|
|
// Get type of style sheet
|
|
var styleSheetModule = docgen.utils.resolveToModule(
|
|
valuePath.get('arguments', 0)
|
|
);
|
|
if (styleSheetModule) {
|
|
var propDescriptor = documentation.getPropDescriptor('style');
|
|
propDescriptor.type = {name: 'stylesheet', value: styleSheetModule};
|
|
}
|
|
});
|
|
}
|
|
|
|
function deprecatedPropTypeHandler(documentation, path) {
|
|
var propTypesPath = docgen.utils.getMemberValuePath(path, 'propTypes');
|
|
if (!propTypesPath) {
|
|
return;
|
|
}
|
|
|
|
propTypesPath = docgen.utils.resolveToValue(propTypesPath);
|
|
if (!propTypesPath || propTypesPath.node.type !== 'ObjectExpression') {
|
|
return;
|
|
}
|
|
|
|
// Checks for deprecatedPropType function and add deprecation info.
|
|
propTypesPath.get('properties').each(function(propertyPath) {
|
|
var valuePath = docgen.utils.resolveToValue(propertyPath.get('value'));
|
|
// If it's a call to deprecatedPropType, do stuff
|
|
if (valuePath.node.type !== 'CallExpression' ||
|
|
valuePath.node.callee.name !== 'deprecatedPropType') {
|
|
return;
|
|
}
|
|
var propDescriptor = documentation.getPropDescriptor(
|
|
docgen.utils.getPropertyName(propertyPath)
|
|
);
|
|
// The 2nd argument of deprecatedPropType is the deprecation message.
|
|
// Used printValue to get the string otherwise there was issues with template
|
|
// strings.
|
|
propDescriptor.deprecationMessage = docgen.utils
|
|
.printValue(valuePath.get('arguments', 1))
|
|
// Remove the quotes printValue adds.
|
|
.slice(1, -1);
|
|
|
|
// Get the actual prop type.
|
|
propDescriptor.type = docgen.utils.getPropType(
|
|
valuePath.get('arguments', 0)
|
|
);
|
|
});
|
|
}
|
|
|
|
function findExportedOrFirst(node, recast) {
|
|
return docgen.resolver.findExportedComponentDefinition(node, recast) ||
|
|
docgen.resolver.findAllComponentDefinitions(node, recast)[0];
|
|
}
|
|
|
|
function findExportedObject(ast, recast) {
|
|
var objPath;
|
|
recast.visit(ast, {
|
|
visitAssignmentExpression: function(path) {
|
|
if (!objPath && docgen.utils.isExportsOrModuleAssignment(path)) {
|
|
objPath = docgen.utils.resolveToValue(path.get('right'));
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
|
|
if (objPath) {
|
|
// Hack: This is easier than replicating the default propType
|
|
// handler.
|
|
// This converts any expression, e.g. `foo` to an object expression of
|
|
// the form `{propTypes: foo}`
|
|
var b = recast.types.builders;
|
|
var nt = recast.types.namedTypes;
|
|
var obj = objPath.node;
|
|
|
|
// Hack: This is converting calls like
|
|
//
|
|
// Object.apply(Object.create(foo), { bar: 42 })
|
|
//
|
|
// to an AST representing an object literal:
|
|
//
|
|
// { ...foo, bar: 42 }
|
|
if (nt.CallExpression.check(obj) &&
|
|
recast.print(obj.callee).code === 'Object.assign') {
|
|
obj = objPath.node.arguments[1];
|
|
var firstArg = objPath.node.arguments[0];
|
|
if (recast.print(firstArg.callee).code === 'Object.create') {
|
|
firstArg = firstArg.arguments[0];
|
|
}
|
|
obj.properties.unshift(
|
|
b.spreadProperty(firstArg)
|
|
);
|
|
}
|
|
|
|
objPath.replace(b.objectExpression([
|
|
b.property('init', b.literal('propTypes'), obj)
|
|
]));
|
|
}
|
|
return objPath;
|
|
}
|
|
|
|
exports.stylePropTypeHandler = stylePropTypeHandler;
|
|
exports.deprecatedPropTypeHandler = deprecatedPropTypeHandler;
|
|
exports.findExportedOrFirst = findExportedOrFirst;
|
|
exports.findExportedObject = findExportedObject;
|