getMemberValuePath.js 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import getClassMemberValuePath from './getClassMemberValuePath.js';
  2. import getMemberExpressionValuePath from './getMemberExpressionValuePath.js';
  3. import getPropertyValuePath from './getPropertyValuePath.js';
  4. import resolveFunctionDefinitionToReturnValue from '../utils/resolveFunctionDefinitionToReturnValue.js';
  5. const postprocessPropTypes = (path) => path.isFunction() ? resolveFunctionDefinitionToReturnValue(path) : path;
  6. const POSTPROCESS_MEMBERS = new Map([['propTypes', postprocessPropTypes]]);
  7. const SUPPORTED_DEFINITION_TYPES = [
  8. // potential stateless function component
  9. 'ArrowFunctionExpression',
  10. /**
  11. * Adds support for libraries such as
  12. * [system-components]{@link https://jxnblk.com/styled-system/system-components} that use
  13. * CallExpressions to generate components.
  14. *
  15. * While react-docgen's built-in resolvers do not support resolving
  16. * CallExpressions definitions, third-party resolvers (such as
  17. * https://github.com/Jmeyering/react-docgen-annotation-resolver) could be
  18. * used to add these definitions.
  19. */
  20. 'CallExpression',
  21. 'ClassDeclaration',
  22. 'ClassExpression',
  23. // potential stateless function component
  24. 'FunctionDeclaration',
  25. // potential stateless function component
  26. 'FunctionExpression',
  27. 'ObjectExpression',
  28. // potential stateless function component
  29. 'ObjectMethod',
  30. /**
  31. * Adds support for libraries such as
  32. * [styled components]{@link https://github.com/styled-components} that use
  33. * TaggedTemplateExpression's to generate components.
  34. *
  35. * While react-docgen's built-in resolvers do not support resolving
  36. * TaggedTemplateExpression definitions, third-party resolvers (such as
  37. * https://github.com/Jmeyering/react-docgen-annotation-resolver) could be
  38. * used to add these definitions.
  39. */
  40. 'TaggedTemplateExpression',
  41. 'VariableDeclaration',
  42. ];
  43. export function isSupportedDefinitionType(path) {
  44. return SUPPORTED_DEFINITION_TYPES.includes(path.node.type);
  45. }
  46. /**
  47. * This is a helper method for handlers to make it easier to work either with
  48. * an ObjectExpression from `React.createClass` class or with a class
  49. * definition.
  50. *
  51. * Given a path and a name, this function will either return the path of the
  52. * property value if the path is an ObjectExpression, or the value of the
  53. * ClassProperty/MethodDefinition if it is a class definition (declaration or
  54. * expression).
  55. *
  56. * It also normalizes the names so that e.g. `defaultProps` and
  57. * `getDefaultProps` can be used interchangeably.
  58. */
  59. export default function getMemberValuePath(componentDefinition, memberName) {
  60. let result;
  61. if (componentDefinition.isObjectExpression()) {
  62. result = getPropertyValuePath(componentDefinition, memberName);
  63. if (!result && memberName === 'defaultProps') {
  64. result = getPropertyValuePath(componentDefinition, 'getDefaultProps');
  65. }
  66. }
  67. else if (componentDefinition.isClassDeclaration() ||
  68. componentDefinition.isClassExpression()) {
  69. result = getClassMemberValuePath(componentDefinition, memberName);
  70. if (!result && memberName === 'defaultProps') {
  71. result = getClassMemberValuePath(componentDefinition, 'getDefaultProps');
  72. }
  73. }
  74. else {
  75. result = getMemberExpressionValuePath(componentDefinition, memberName);
  76. if (!result && memberName === 'defaultProps') {
  77. result = getMemberExpressionValuePath(componentDefinition, 'getDefaultProps');
  78. }
  79. }
  80. const postprocessMethod = POSTPROCESS_MEMBERS.get(memberName);
  81. if (result && postprocessMethod) {
  82. result = postprocessMethod(result);
  83. }
  84. return result;
  85. }