All files / src/handlers propTypeHandler.js

78.57% Statements 22/28
78.95% Branches 15/19
100% Functions 4/4
78.57% Lines 22/28
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 82 83 84                                                  2x     38x 38x 35x   3x       24x 1x     23x 38x   38x     38x 38x       38x 38x 38x     38x                                 30x 30x 6x   24x 24x     24x    
/*
 * 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 type Documentation from '../Documentation';
 
import getPropType from '../utils/getPropType';
import getPropertyName from '../utils/getPropertyName';
import getMemberValuePath from '../utils/getMemberValuePath';
import isReactModuleName from '../utils/isReactModuleName';
import isRequiredPropType from '../utils/isRequiredPropType';
import printValue from '../utils/printValue';
import recast from 'recast';
import resolveToModule from '../utils/resolveToModule';
import resolveToValue from '../utils/resolveToValue';
 
 
var {types: {namedTypes: types}} = recast;
 
function isPropTypesExpression(path) {
  var moduleName = resolveToModule(path);
  if (moduleName) {
    return isReactModuleName(moduleName) || moduleName === 'ReactPropTypes';
  }
  return false;
}
 
function amendPropTypes(documentation, path) {
  if (!types.ObjectExpression.check(path.node)) {
    return;
  }
 
  path.get('properties').each(function(propertyPath) {
    switch (propertyPath.node.type) {
      case types.Property.name:
        var propDescriptor = documentation.getPropDescriptor(
          getPropertyName(propertyPath)
        );
        var valuePath = propertyPath.get('value');
        var type = isPropTypesExpression(valuePath) ?
          getPropType(valuePath) :
          {name: 'custom', raw: printValue(valuePath)};
 
        Eif (type) {
          propDescriptor.type = type;
          propDescriptor.required =
            type.name !== 'custom' && isRequiredPropType(valuePath);
        }
        break;
      case types.SpreadProperty.name:
        var resolvedValuePath = resolveToValue(propertyPath.get('argument'));
        switch (resolvedValuePath.node.type) {
          case types.ObjectExpression.name: // normal object literal
            amendPropTypes(documentation, resolvedValuePath);
            break;
        }
        break;
    }
  });
}
 
export default function propTypeHandler(
  documentation: Documentation,
  path: NodePath
) {
  var propTypesPath = getMemberValuePath(path, 'propTypes');
  if (!propTypesPath) {
    return;
  }
  propTypesPath = resolveToValue(propTypesPath);
  Iif (!propTypesPath) {
    return;
  }
  amendPropTypes(documentation, propTypesPath);
}