All files / src/utils getMethodDocumentation.js

96.77% Statements 30/31
78.57% Branches 11/14
100% Functions 5/5
96.77% Lines 30/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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110                                    3x                                         14x 14x     14x 3x 3x 3x 3x 3x         3x           3x     14x         14x   14x 3x 3x 3x       11x       14x   14x 4x     14x 14x 1x   14x 2x     14x       14x 14x   14x                
/*
 * 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 {getDocblock} from './docblock';
import getFlowType from './getFlowType';
import getParameterName from './getParameterName';
import getPropertyName from './getPropertyName';
import getTypeAnnotation from './getTypeAnnotation';
import recast from 'recast';
 
const { types: { namedTypes: types } } = recast;
 
type MethodParameter = {
  name: string;
  type?: ?FlowTypeDescriptor;
  optional?: boolean;
};
 
type MethodReturn = {
  type: ?FlowTypeDescriptor;
};
 
type MethodDocumentation = {
  name: string;
  docblock: ?string;
  modifiers: Array<string>;
  params: Array<MethodParameter>;
  returns: ?MethodReturn;
};
 
function getMethodParamsDoc(methodPath) {
  const params = [];
  const functionExpression = methodPath.get('value');
 
  // Extract param flow types.
  functionExpression.get('params').each(paramPath => {
    let type = null;
    const typePath = getTypeAnnotation(paramPath);
    Eif (typePath) {
      type = getFlowType(typePath);
      Iif (types.GenericTypeAnnotation.check(typePath.node)) {
        type.alias = typePath.node.id.name;
      }
    }
 
    const param = {
      name: getParameterName(paramPath),
      optional: paramPath.node.optional,
      type,
    };
 
    params.push(param);
  });
 
  return params;
}
 
// Extract flow return type.
function getMethodReturnDoc(methodPath) {
  const functionExpression = methodPath.get('value');
 
  if (functionExpression.node.returnType) {
    const returnType = getTypeAnnotation(functionExpression.get('returnType'));
    Eif (returnType) {
      return {type: getFlowType(returnType)};
    }
  }
 
  return null;
}
 
function getMethodModifiers(methodPath) {
  const modifiers = [];
 
  if (methodPath.node.static) {
    modifiers.push('static');
  }
 
  const functionExpression = methodPath.get('value').node;
  if (functionExpression.generator) {
    modifiers.push('generator');
  }
  if (functionExpression.async) {
    modifiers.push('async');
  }
 
  return modifiers;
}
 
export default function getMethodDocumentation(methodPath: NodePath): MethodDocumentation {
  const name = getPropertyName(methodPath);
  const docblock = getDocblock(methodPath);
 
  return {
    name,
    docblock,
    modifiers: getMethodModifiers(methodPath),
    params: getMethodParamsDoc(methodPath),
    returns: getMethodReturnDoc(methodPath),
  };
}