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]; } |