All files / src/handlers defaultPropsHandler.js

93.55% Statements 29/31
76.19% Branches 16/21
83.33% Functions 5/6
93.55% Lines 29/31
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 85 86 87 88 89 90 91 92 93                                        2x     19x   19x 12x   7x 7x 1x   6x 6x     19x 19x                         12x       12x 2x     10x 10x       10x     3x     3x 3x 3x   3x         10x 10x 20x   19x     19x 19x 19x          
/*
 * 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 getPropertyName from '../utils/getPropertyName';
import getMemberValuePath from '../utils/getMemberValuePath';
import printValue from '../utils/printValue';
import recast from 'recast';
import resolveToValue from '../utils/resolveToValue';
 
var {types: {namedTypes: types, visit}} = recast;
 
function getDefaultValue(path) {
  var node = path.node;
  var defaultValue;
  if (types.Literal.check(node)) {
    defaultValue = node.raw;
  } else {
    path = resolveToValue(path);
    if (types.ImportDeclaration.check(path.node)) {
      defaultValue = node.name;
    } else {
      node = path.node;
      defaultValue = printValue(path);
    }
  }
  Eif (typeof defaultValue !== 'undefined') {
    return {
      value: defaultValue,
      computed: types.CallExpression.check(node) ||
                types.MemberExpression.check(node) ||
                types.Identifier.check(node),
    };
  }
}
 
export default function defaultPropsHandler(
  documentation: Documentation,
  componentDefinition: NodePath
) {
  var defaultPropsPath = getMemberValuePath(
    componentDefinition,
    'defaultProps'
  );
  if (!defaultPropsPath) {
    return;
  }
 
  defaultPropsPath = resolveToValue(defaultPropsPath);
  Iif (!defaultPropsPath) {
    return;
  }
 
  if (types.FunctionExpression.check(defaultPropsPath.node)) {
    // Find the value that is returned from the function and process it if it is
    // an object literal.
    visit(defaultPropsPath.get('body'), {
      visitFunction: () => false,
      visitReturnStatement: function(path) {
        var resolvedPath = resolveToValue(path.get('argument'));
        Eif (types.ObjectExpression.check(resolvedPath.node)) {
          defaultPropsPath = resolvedPath;
        }
        return false;
      },
    });
  }
 
  Eif (types.ObjectExpression.check(defaultPropsPath.node)) {
    defaultPropsPath.get('properties')
      .filter(propertyPath => types.Property.check(propertyPath.node))
      .forEach(function(propertyPath) {
        var propDescriptor = documentation.getPropDescriptor(
          getPropertyName(propertyPath)
        );
        var defaultValue = getDefaultValue(propertyPath.get('value'));
        Eif (defaultValue) {
          propDescriptor.defaultValue = defaultValue;
        }
      });
  }
}