Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export default function componentMethodsHandler(
documentation: Documentation,
path: NodePath,
) {
// Extract all methods from the class or object.
let methodPaths = [];
if (isReactComponentClass(path)) {
methodPaths = path.get('body', 'body').filter(isMethod);
} else if (t.ObjectExpression.check(path.node)) {
methodPaths = path.get('properties').filter(isMethod);
// Add the statics object properties.
const statics = getMemberValuePath(path, 'statics');
if (statics) {
statics.get('properties').each(p => {
if (isMethod(p)) {
p.node.static = true;
methodPaths.push(p);
}
});
}
}
documentation.set(
'methods',
function resolveDefinition(definition) {
if (isReactCreateClassCall(definition)) {
// return argument
const resolvedPath = resolveToValue(definition.get('arguments', 0));
if (t.ObjectExpression.check(resolvedPath.node)) {
return resolvedPath;
}
} else if (isReactComponentClass(definition)) {
normalizeClassDefinition(definition);
return definition;
} else if (
isStatelessComponent(definition) ||
isReactForwardRefCall(definition)
) {
return definition;
}
return null;
}
function isSupportedDefinitionType({ node }) {
return (
t.ObjectExpression.check(node) ||
t.ClassDeclaration.check(node) ||
t.ClassExpression.check(node) ||
/**
* Adds support for libraries such as
* [styled components]{@link https://github.com/styled-components} that use
* TaggedTemplateExpression's to generate components.
*
* While react-docgen's built-in resolvers do not support resolving
* TaggedTemplateExpression definitions, third-party resolvers (such as
* https://github.com/Jmeyering/react-docgen-annotation-resolver) could be
* used to add these definitions.
*/
t.TaggedTemplateExpression.check(node) ||
// potential stateless function component
t.VariableDeclaration.check(node) ||
t.ArrowFunctionExpression.check(node) ||
result.push('');
}
} else {
result.push(node.property.name);
}
continue;
} else if (t.Identifier.check(node)) {
result.push(node.name);
continue;
} else if (t.Literal.check(node)) {
result.push(node.raw);
continue;
} else if (t.ThisExpression.check(node)) {
result.push('this');
continue;
} else if (t.ObjectExpression.check(node)) {
const properties = path.get('properties').map(function(property) {
return (
toString(property.get('key')) + ': ' + toString(property.get('value'))
);
});
result.push('{' + properties.join(', ') + '}');
continue;
} else if (t.ArrayExpression.check(node)) {
result.push(
'[' +
path
.get('elements')
.map(toString)
.join(', ') +
']',
);
function handleKeysHelper(path: NodePath): ?FlowElementsType {
let value = path.get('typeParameters', 'params', 0);
if (t.TypeofTypeAnnotation.check(value.node)) {
value = value.get('argument', 'id');
} else if (!t.ObjectTypeAnnotation.check(value.node)) {
value = value.get('id');
}
const resolvedPath = resolveToValue(value);
if (
resolvedPath &&
(t.ObjectExpression.check(resolvedPath.node) ||
t.ObjectTypeAnnotation.check(resolvedPath.node))
) {
const keys = resolveObjectToNameArray(resolvedPath, true);
if (keys) {
return {
name: 'union',
raw: printValue(path),
elements: keys.map(key => ({ name: 'literal', value: key })),
};
}
}
return null;
}
};
const POSTPROCESS_MEMBERS = {
propTypes: path =>
t.Function.check(path.node)
? resolveFunctionDefinitionToReturnValue(path)
: path,
};
const LOOKUP_METHOD = {
[t.ArrowFunctionExpression.name]: getMemberExpressionValuePath,
[t.CallExpression.name]: getMemberExpressionValuePath,
[t.FunctionExpression.name]: getMemberExpressionValuePath,
[t.FunctionDeclaration.name]: getMemberExpressionValuePath,
[t.VariableDeclaration.name]: getMemberExpressionValuePath,
[t.ObjectExpression.name]: getPropertyValuePath,
[t.ClassDeclaration.name]: getClassMemberValuePath,
[t.ClassExpression.name]: getClassMemberValuePath,
};
function isSupportedDefinitionType({ node }) {
return (
t.ObjectExpression.check(node) ||
t.ClassDeclaration.check(node) ||
t.ClassExpression.check(node) ||
/**
* Adds support for libraries such as
* [styled components]{@link https://github.com/styled-components} that use
* TaggedTemplateExpression's to generate components.
*
* While react-docgen's built-in resolvers do not support resolving
* TaggedTemplateExpression definitions, third-party resolvers (such as
export function resolveObjectToNameArray(
object: NodePath,
raw: boolean = false,
): ?Array {
if (
(t.ObjectExpression.check(object.value) &&
object.value.properties.every(isWhitelistedObjectProperty)) ||
(t.ObjectTypeAnnotation.check(object.value) &&
object.value.properties.every(isWhiteListedObjectTypeProperty)) ||
(t.TSTypeLiteral.check(object.value) &&
object.value.members.every(isWhiteListedObjectTypeProperty))
) {
let values = [];
let error = false;
const properties = t.TSTypeLiteral.check(object.value)
? object.get('members')
: object.get('properties');
properties.each(propPath => {
if (error) return;
const prop = propPath.value;
if (
export default function resolveToValue(path: NodePath): NodePath {
const node = path.node;
if (t.VariableDeclarator.check(node)) {
if (node.init) {
return resolveToValue(path.get('init'));
}
} else if (t.MemberExpression.check(node)) {
const resolved = resolveToValue(getMemberExpressionRoot(path));
if (t.ObjectExpression.check(resolved.node)) {
let propertyPath = resolved;
for (const propertyName of toArray(path).slice(1)) {
if (propertyPath && t.ObjectExpression.check(propertyPath.node)) {
propertyPath = getPropertyValuePath(propertyPath, propertyName);
}
if (!propertyPath) {
return path;
}
propertyPath = resolveToValue(propertyPath);
}
return propertyPath;
}
} else if (
t.ImportDefaultSpecifier.check(node) ||
t.ImportNamespaceSpecifier.check(node) ||
t.ImportSpecifier.check(node)
export default function getPropertyValuePath(
path: NodePath,
propertyName: string,
): ?NodePath {
t.ObjectExpression.assert(path.node);
return path
.get('properties')
.filter(propertyPath => getPropertyName(propertyPath) === propertyName)
.map(propertyPath => propertyPath.get('value'))[0];
}
function resolveDocumentation(
documentation: Documentation,
path: NodePath,
): void {
if (!t.ObjectExpression.check(path.node)) {
return;
}
path.get('properties').each(propertyPath => {
if (t.Property.check(propertyPath.node)) {
setPropDescription(documentation, propertyPath);
} else if (t.SpreadElement.check(propertyPath.node)) {
const resolvedValuePath = resolveToValue(propertyPath.get('argument'));
resolveDocumentation(documentation, resolvedValuePath);
}
});
}