react-docgen
Version:
A CLI and toolkit to extract information from React components for documentation generation.
106 lines (81 loc) • 3.47 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyToFlowTypeProperties = applyToFlowTypeProperties;
exports.default = void 0;
var _getTypeAnnotation = _interopRequireDefault(require("../utils/getTypeAnnotation"));
var _getMemberValuePath = _interopRequireDefault(require("../utils/getMemberValuePath"));
var _isReactComponentClass = _interopRequireDefault(require("../utils/isReactComponentClass"));
var _isStatelessComponent = _interopRequireDefault(require("../utils/isStatelessComponent"));
var _isUnreachableFlowType = _interopRequireDefault(require("../utils/isUnreachableFlowType"));
var _recast = _interopRequireDefault(require("recast"));
var _resolveToValue = _interopRequireDefault(require("../utils/resolveToValue"));
var _flowUtilityTypes = require("../utils/flowUtilityTypes");
var _resolveGenericTypeAnnotation = _interopRequireDefault(require("../utils/resolveGenericTypeAnnotation"));
/*
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*
*/
const types = _recast.default.types.namedTypes;
/**
* Given an React component (stateless or class) tries to find the
* flow type for the props. If not found or not one of the supported
* component types returns null.
*/
var _default = path => {
let typePath;
if ((0, _isReactComponentClass.default)(path)) {
const superTypes = path.get('superTypeParameters');
if (superTypes.value) {
const params = superTypes.get('params');
if (params.value.length === 3) {
typePath = params.get(1);
} else {
typePath = params.get(0);
}
} else {
const propsMemberPath = (0, _getMemberValuePath.default)(path, 'props');
if (!propsMemberPath) {
return null;
}
typePath = (0, _getTypeAnnotation.default)(propsMemberPath.parentPath);
}
} else if ((0, _isStatelessComponent.default)(path)) {
const param = path.get('params').get(0);
typePath = (0, _getTypeAnnotation.default)(param);
}
if (typePath && (0, _flowUtilityTypes.isSupportedUtilityType)(typePath)) {
typePath = (0, _flowUtilityTypes.unwrapUtilityType)(typePath);
} else if (typePath && types.GenericTypeAnnotation.check(typePath.node)) {
typePath = (0, _resolveToValue.default)(typePath.get('id'));
if (!typePath || types.Identifier.check(typePath.node) || (0, _isUnreachableFlowType.default)(typePath)) {
return;
}
typePath = typePath.get('right');
}
return typePath;
};
exports.default = _default;
function applyToFlowTypeProperties(path, callback) {
if (path.node.properties) {
path.get('properties').each(propertyPath => callback(propertyPath));
} else if (path.node.type === 'IntersectionTypeAnnotation') {
path.get('types').each(typesPath => applyToFlowTypeProperties(typesPath, callback));
} else if (path.node.type !== 'UnionTypeAnnotation') {
// The react-docgen output format does not currently allow
// for the expression of union types
const typePath = (0, _resolveGenericTypeAnnotation.default)(path);
if (typePath) {
applyToFlowTypeProperties(typePath, callback);
}
}
}