All files / src/utils getMemberValuePath.js

90.91% Statements 10/11
92.31% Branches 12/13
100% Functions 2/2
90.91% Lines 10/11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81                                  10x   10x         10x                     112x                                                       112x                   112x 112x 112x 7x   105x    
/*
 * 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.
 *
 * @flow
 *
 */
 
import getMemberExpressionValuePath from './getMemberExpressionValuePath';
import getClassMemberValuePath from './getClassMemberValuePath';
import getPropertyValuePath from './getPropertyValuePath';
import recast from 'recast';
 
var {types: {namedTypes: types}} = recast;
 
var SYNONYMS = {
  getDefaultProps: 'defaultProps',
  defaultProps: 'getDefaultProps',
};
 
var LOOKUP_METHOD = {
  [types.ArrowFunctionExpression.name]: getMemberExpressionValuePath,
  [types.FunctionExpression.name]: getMemberExpressionValuePath,
  [types.FunctionDeclaration.name]: getMemberExpressionValuePath,
  [types.VariableDeclaration.name]: getMemberExpressionValuePath,
  [types.ObjectExpression.name]: getPropertyValuePath,
  [types.ClassDeclaration.name]: getClassMemberValuePath,
  [types.ClassExpression.name]: getClassMemberValuePath,
};
 
function isSupportedDefinitionType({node}) {
  return types.ObjectExpression.check(node) ||
    types.ClassDeclaration.check(node) ||
    types.ClassExpression.check(node) ||
 
    // potential stateless function component
    types.VariableDeclaration.check(node) ||
    types.ArrowFunctionExpression.check(node) ||
    types.FunctionDeclaration.check(node) ||
    types.FunctionExpression.check(node);
}
 
/**
 * This is a helper method for handlers to make it easier to work either with
 * an ObjectExpression from `React.createClass` class or with a class
 * definition.
 *
 * Given a path and a name, this function will either return the path of the
 * property value if the path is an ObjectExpression, or the value of the
 * ClassProperty/MethodDefinition if it is a class definition (declaration or
 * expression).
 *
 * It also normalizes the names so that e.g. `defaultProps` and
 * `getDefaultProps` can be used interchangeably.
 */
export default function getMemberValuePath(
  componentDefinition: NodePath,
  memberName: string
): ?NodePath {
  Iif (!isSupportedDefinitionType(componentDefinition)) {
    throw new TypeError(
      'Got unsupported definition type. Definition must be one of ' +
      'ObjectExpression, ClassDeclaration, ClassExpression,' +
      'VariableDeclaration, ArrowFunctionExpression, FunctionExpression, or ' +
      'FunctionDeclaration. Got "' + componentDefinition.node.type + '"' +
      'instead.'
    );
  }
 
  var lookupMethod = LOOKUP_METHOD[componentDefinition.node.type];
  var result = lookupMethod(componentDefinition, memberName);
  if (!result && SYNONYMS[memberName]) {
    return lookupMethod(componentDefinition, SYNONYMS[memberName]);
  }
  return result;
}