All files convertTypeToPropTypes.js

96.61% Statements 57/59
50% Branches 3/6
100% Functions 16/16
96.49% Lines 55/57
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 111 112 113 114 115 116 117                  1x 39x     3x 3x     10x 14x     1x   1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1x 24x     1x 26x   26x 20x     23x   23x     1x 20x 20x   20x   20x   17x 17x     17x     1x 1x         1x 3x     1x 3x 3x     3x     1x 1x     1x 1x     1x 1x         1x 97x   97x       97x             24x    
// @flow
import type {Path, Node} from './types';
import * as t from 'babel-types';
import {log} from 'babel-log';
 
type Options = {
  propTypesRef: Node,
};
 
let refPropTypes = (property: Node, opts: Options): Node => {
  return t.memberExpression(opts.propTypesRef, property);
};
 
let createThrows = message => (path: Path, opts: Options) => {
  throw path.buildCodeFrameError(message);
};
 
let createConversion = name => (path: Path, opts: Options): Node => {
  return refPropTypes(t.identifier(name), opts);
};
 
let converters = {};
 
converters.AnyTypeAnnotation = createConversion('any');
converters.MixedTypeAnnotation = createConversion('any');
converters.NumberTypeAnnotation = createConversion('number');
converters.NumericLiteralTypeAnnotation = createConversion('number');
converters.BooleanTypeAnnotation = createConversion('bool');
converters.BooleanLiteralTypeAnnotation = createConversion('bool');
converters.StringTypeAnnotation = createConversion('string');
converters.StringLiteralTypeAnnotation = createConversion('string');
converters.NullLiteralTypeAnnotation = createThrows('null types unsupported');
converters.VoidTypeAnnotation = createThrows('void types unsupported');
converters.FunctionTypeAnnotation = createConversion('func');
converters.NullableTypeAnnotation = createThrows('maybe types unsupported');
converters.TupleTypeAnnotation = createConversion('array');
 
converters.TypeAnnotation = (path: Path, opts: Options) => {
  return convert(path.get('typeAnnotation'), opts);
};
 
converters.ObjectTypeAnnotation = (path: Path, opts: Options) => {
  let properties = [];
 
  for (let property of path.get('properties')) {
    properties.push(convert(property, opts));
  }
 
  let object = t.objectExpression(properties);
 
  return t.callExpression(refPropTypes(t.identifier('shape'), opts), [object]);
};
 
converters.ObjectTypeProperty = (path: Path, opts: Options) => {
  let key = path.get('key');
  let value = path.get('value');
 
  let id = t.inheritsComments(t.identifier(key.node.name), key.node);
 
  let converted = convert(value, opts);
 
  Eif (!path.node.optional) {
    converted = t.memberExpression(converted, t.identifier('isRequired'));
  }
 
  return t.objectProperty(id, converted);
};
 
converters.ArrayTypeAnnotation = (path: Path, opts: Options) => {
  return t.callExpression(refPropTypes(t.identifier('arrayOf'), opts), [
    convert(path.get('elementType'), opts),
  ]);
};
 
converters.GenericTypeAnnotation = (path: Path, opts: Options) => {
  return convert(path.get('id'), opts);
};
 
converters.Identifier = (path: Path, opts: Options) => {
  let binding = path.scope.getBinding(path.node.name);
  Iif (!binding) {
    throw path.buildCodeFrameError('Missing reference');
  }
  return convert(binding.path, opts);
};
 
converters.TypeAlias = (path: Path, opts: Options) => {
  return convert(path.get('right'), opts);
};
 
converters.InterfaceDeclaration = (path: Path, opts: Options) => {
  return convert(path.get('body'), opts);
};
 
converters.ClassDeclaration = (path: Path, opts: Options) => {
  return t.callExpression(refPropTypes(t.identifier('instanceOf'), opts), [
    t.identifier(path.node.id.name),
  ]);
};
 
let convert = (path: Path, opts: {propTypesRef: Node}): Node => {
  let converter = converters[path.type];
 
  Iif (!converter) {
    throw path.buildCodeFrameError(`No converter for node type: ${path.type}`);
  }
 
  return t.inheritsComments(converter(path, opts), path.node);
};
 
export default function convertTypeToPropTypes(
  typeAnnotation: Path,
  propTypesRef: Node,
): Node {
  return convert(typeAnnotation, {propTypesRef}).arguments[0];
}