UNPKG

108 kBJavaScriptView Raw
1'use strict';
2
3var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; })();
4
5/**
6 * # Typecheck Transformer
7 */
8
9Object.defineProperty(exports, "__esModule", {
10 value: true
11});
12
13exports.default = function (_ref) {
14 var t = _ref.types;
15 var template = _ref.template;
16
17 /**
18 * Binary Operators that can only produce boolean results.
19 */
20 var BOOLEAN_BINARY_OPERATORS = ['==', '===', '>=', '<=', '>', '<', 'instanceof'];
21
22 var checks = createChecks();
23 var staticChecks = createStaticChecks();
24
25 var checkIsArray = expression('Array.isArray(input)');
26 var checkIsMap = expression('input instanceof Map');
27 var checkIsSet = expression('input instanceof Set');
28 var checkIsClass = expression('typeof input === \'function\' && input.prototype && input.prototype.constructor === input');
29 var checkIsGenerator = expression('typeof input === \'function\' && input.generator');
30 var checkIsIterable = expression('input && typeof input[Symbol.iterator] === \'function\'');
31 var checkIsObject = expression('input != null && typeof input === \'object\'');
32 var checkNotNull = expression('input != null');
33 var checkEquals = expression('input === expected');
34
35 var declareTypeChecker = template('\n const id = function id (input) {\n return check;\n };\n ');
36
37 var guard = template('\n if (!check) {\n throw new TypeError(message);\n }\n ');
38
39 var thrower = template('\n if (check) {\n ret;\n }\n else {\n throw new TypeError(message);\n }\n ');
40
41 var guardInline = expression('\n (id => {\n if (!check) {\n throw new TypeError(message);\n }\n return id;\n })(input)\n ');
42
43 var guardFn = expression('\n function name (id) {\n if (!check) {\n throw new TypeError(message);\n }\n return id;\n }\n ');
44
45 var readableName = expression('\n input === null ? \'null\' : typeof input === \'object\' && input.constructor ? input.constructor.name || \'[Unknown Object]\' : typeof input\n ');
46
47 var checkMapKeys = expression('\n input instanceof Map && Array.from(input.keys()).every(key => keyCheck)\n ');
48
49 var checkMapValues = expression('\n input instanceof Map && Array.from(input.values()).every(value => valueCheck)\n ');
50
51 var checkMapEntries = expression('\n input instanceof Map && Array.from(input).every(([key, value]) => keyCheck && valueCheck)\n ');
52
53 var checkSetEntries = expression('\n input instanceof Set && Array.from(input).every(value => valueCheck)\n ');
54
55 var checkObjectIndexers = expression('\n Object.keys(input).every(key => {\n const value = input[key];\n if (~fixedKeys.indexOf(key)) {\n return true;\n }\n else {\n return check;\n }\n });\n ');
56
57 var checkObjectIndexersNoFixed = expression('\n Object.keys(input).every(key => {\n const value = input[key];\n return check;\n });\n ');
58
59 var PRAGMA_IGNORE_STATEMENT = /typecheck:\s*ignore\s+statement/i;
60 var PRAGMA_IGNORE_FILE = /typecheck:\s*ignore\s+file/i;
61
62 var visitors = {
63 Statement: function Statement(path) {
64 maybeSkip(path);
65 },
66 TypeAlias: function TypeAlias(path) {
67 if (maybeSkip(path)) {
68 return;
69 }
70 path.replaceWith(createTypeAliasChecks(path));
71 },
72 InterfaceDeclaration: function InterfaceDeclaration(path) {
73 if (maybeSkip(path)) {
74 return;
75 }
76 path.replaceWith(createInterfaceChecks(path));
77 },
78 ExportNamedDeclaration: function ExportNamedDeclaration(path) {
79 if (maybeSkip(path)) {
80 return;
81 }
82 var node = path.node;
83 var scope = path.scope;
84
85 if (node.declaration && node.declaration.type === 'TypeAlias') {
86 path.replaceWith(t.exportNamedDeclaration(createTypeAliasChecks(path.get('declaration')), [], null));
87 }
88 },
89 ImportDeclaration: function ImportDeclaration(path) {
90 if (maybeSkip(path)) {
91 return;
92 }
93 if (path.node.importKind !== 'type') {
94 return;
95 }
96
97 var _path$get$map$reduce = path.get('specifiers').map(function (specifier) {
98 var local = specifier.get('local');
99 var tmpId = path.scope.generateUidIdentifierBasedOnNode(local.node);
100 var replacement = t.importSpecifier(tmpId, specifier.node.imported);
101 var id = t.identifier(local.node.name);
102
103 id.isTypeChecker = true;
104 var declarator = t.variableDeclarator(id, tmpId);
105 declarator.isTypeChecker = true;
106 return [declarator, replacement];
107 }).reduce(function (_ref2, _ref3) {
108 var _ref5 = _slicedToArray(_ref2, 2);
109
110 var declarators = _ref5[0];
111 var specifiers = _ref5[1];
112
113 var _ref4 = _slicedToArray(_ref3, 2);
114
115 var declarator = _ref4[0];
116 var specifier = _ref4[1];
117
118 declarators.push(declarator);
119 specifiers.push(specifier);
120 return [declarators, specifiers];
121 }, [[], []]);
122
123 var _path$get$map$reduce2 = _slicedToArray(_path$get$map$reduce, 2);
124
125 var declarators = _path$get$map$reduce2[0];
126 var specifiers = _path$get$map$reduce2[1];
127
128 var declaration = t.variableDeclaration('var', declarators);
129 declaration.isTypeChecker = true;
130
131 path.replaceWithMultiple([t.importDeclaration(specifiers, path.node.source), declaration]);
132 },
133
134 Function: {
135 enter: function enter(path) {
136 var _node$body$body;
137
138 if (maybeSkip(path)) {
139 return;
140 }
141
142 var node = path.node;
143 var scope = path.scope;
144
145 var paramChecks = collectParamChecks(path);
146 if (node.type === "ArrowFunctionExpression" && node.expression) {
147 node.expression = false;
148 node.body = t.blockStatement([t.returnStatement(node.body)]);
149 }
150 if (node.returnType) {
151 createFunctionReturnGuard(path);
152 createFunctionYieldGuards(path);
153 }
154 (_node$body$body = node.body.body).unshift.apply(_node$body$body, _toConsumableArray(paramChecks));
155 node.savedTypeAnnotation = node.returnType;
156 node.returnCount = 0;
157 node.yieldCount = 0;
158 },
159 exit: function exit(path) {
160 var node = path.node;
161 var scope = path.scope;
162
163 var isVoid = node.savedTypeAnnotation ? maybeNullableAnnotation(node.savedTypeAnnotation) : null;
164 if (!node.returnCount && isVoid === false) {
165 var annotation = node.savedTypeAnnotation;
166 if (annotation.type === 'TypeAnnotation') {
167 annotation = annotation.typeAnnotation;
168 }
169 if (node.generator && isGeneratorAnnotation(annotation) && annotation.typeParameters && annotation.typeParameters.params.length > 1) {
170 annotation = annotation.typeParameters.params[1];
171 }
172 throw path.buildCodeFrameError('Function ' + (node.id ? '"' + node.id.name + '" ' : '') + 'did not return a value, expected ' + humanReadableType(annotation));
173 }
174 if (node.nextGuardCount) {
175 path.get('body').get('body')[0].insertBefore(node.nextGuard);
176 }
177 if (node.yieldGuardCount) {
178 path.get('body').get('body')[0].insertBefore(node.yieldGuard);
179 }
180 if (node.returnGuardCount) {
181 path.get('body').get('body')[0].insertBefore(node.returnGuard);
182 }
183 }
184 },
185
186 YieldExpression: function YieldExpression(path) {
187 var fn = path.getFunctionParent();
188 if (!fn) {
189 return;
190 }
191 fn.node.yieldCount++;
192 if (!isGeneratorAnnotation(fn.node.returnType) || maybeSkip(path)) {
193 return;
194 }
195 var node = path.node;
196 var parent = path.parent;
197 var scope = path.scope;
198
199 var annotation = fn.node.returnType;
200 if (annotation.type === 'NullableTypeAnnotation' || annotation.type === 'TypeAnnotation') {
201 annotation = annotation.typeAnnotation;
202 }
203 if (!annotation.typeParameters || annotation.typeParameters.params.length === 0) {
204 return;
205 }
206
207 var yieldType = annotation.typeParameters.params[0];
208 var nextType = annotation.typeParameters.params[2];
209 var ok = staticCheckAnnotation(path.get("argument"), yieldType);
210 if (ok === true && !nextType) {
211 return;
212 } else if (ok === false) {
213 throw path.buildCodeFrameError('Function ' + (fn.node.id ? '"' + fn.node.id.name + '" ' : '') + 'yielded an invalid type, expected ' + humanReadableType(yieldType) + ' got ' + humanReadableType(getAnnotation(path.get('argument'))));
214 }
215 fn.node.yieldGuardCount++;
216 if (fn.node.yieldGuard) {
217 var _yielder = t.yieldExpression(t.callExpression(fn.node.yieldGuardName, [node.argument || t.identifier('undefined')]));
218 _yielder.hasBeenTypeChecked = true;
219
220 if (fn.node.nextGuard) {
221 fn.node.nextGuardCount++;
222 path.replaceWith(t.callExpression(fn.node.nextGuardName, [_yielder]));
223 } else {
224 path.replaceWith(_yielder);
225 }
226 } else if (fn.node.nextGuard) {
227 fn.node.nextGuardCount++;
228 path.replaceWith(t.callExpression(fn.node.nextGuardName, [yielder]));
229 }
230 },
231 ReturnStatement: function ReturnStatement(path) {
232 var fn = path.getFunctionParent();
233 if (!fn) {
234 return;
235 }
236 fn.node.returnCount++;
237 if (maybeSkip(path)) {
238 return;
239 }
240 var node = path.node;
241 var parent = path.parent;
242 var scope = path.scope;
243 var _fn$node = fn.node;
244 var returnType = _fn$node.returnType;
245 var returnGuardName = _fn$node.returnGuardName;
246
247 if (!returnType || !returnGuardName) {
248 return;
249 }
250 if (!node.argument) {
251 if (maybeNullableAnnotation(returnType) === false) {
252 throw path.buildCodeFrameError('Function ' + (fn.node.id ? '"' + fn.node.id.name + '" ' : '') + 'did not return a value, expected ' + humanReadableType(returnType));
253 }
254 return;
255 }
256 var annotation = returnType;
257 if (annotation.type === 'TypeAnnotation') {
258 annotation = annotation.typeAnnotation;
259 }
260 if (isGeneratorAnnotation(annotation)) {
261 annotation = annotation.typeParameters && annotation.typeParameters.params.length > 1 ? annotation.typeParameters.params[1] : t.anyTypeAnnotation();
262 }
263 var ok = staticCheckAnnotation(path.get("argument"), annotation);
264 if (ok === true) {
265 return;
266 } else if (ok === false) {
267 throw path.buildCodeFrameError('Function ' + (fn.node.id ? '"' + fn.node.id.name + '" ' : '') + 'returned an invalid type, expected ' + humanReadableType(annotation) + ' got ' + humanReadableType(getAnnotation(path.get('argument'))));
268 }
269 fn.node.returnGuardCount++;
270 var returner = t.returnStatement(t.callExpression(fn.node.returnGuardName, [node.argument]));
271 returner.hasBeenTypeChecked = true;
272 path.replaceWith(returner);
273 },
274 VariableDeclaration: function VariableDeclaration(path) {
275 if (maybeSkip(path)) {
276 return;
277 }
278 var node = path.node;
279 var scope = path.scope;
280
281 var collected = [];
282 var declarations = path.get("declarations");
283 for (var i = 0; i < node.declarations.length; i++) {
284 var declaration = node.declarations[i];
285 var _id = declaration.id;
286 var init = declaration.init;
287
288 if (!_id.typeAnnotation || _id.hasBeenTypeChecked) {
289 continue;
290 }
291 _id.savedTypeAnnotation = _id.typeAnnotation;
292 _id.hasBeenTypeChecked = true;
293 var ok = staticCheckAnnotation(declarations[i], _id.typeAnnotation);
294 if (ok === true) {
295 continue;
296 } else if (ok === false) {
297 throw path.buildCodeFrameError('Invalid assignment value, expected ' + humanReadableType(_id.typeAnnotation) + ' got ' + humanReadableType(getAnnotation(declarations[i])));
298 }
299 var check = checkAnnotation(_id, _id.typeAnnotation, scope);
300 if (check) {
301 collected.push(guard({
302 check: check,
303 message: varTypeErrorMessage(_id, scope)
304 }));
305 }
306 }
307 if (collected.length > 0) {
308 var check = collected.reduce(function (check, branch) {
309 branch.alternate = check;
310 return branch;
311 });
312 if (path.parent.type === 'Program' || path.parent.type === 'BlockStatement') {
313 path.insertAfter(check);
314 } else if (path.parentPath.isForXStatement() || path.parentPath.isForStatement() || path.parentPath.isForInStatement()) {
315 var body = path.parentPath.get('body');
316 if (body.type !== 'BlockStatement') {
317 var block = t.blockStatement([body.node]);
318 body.replaceWith(block);
319 body = path.parentPath.get('body');
320 }
321 var children = body.get('body');
322 if (children.length === 0) {
323 body.replaceWith(check);
324 } else {
325 children[0].insertBefore(check);
326 }
327 } else if (path.parent.type === 'ExportNamedDeclaration' || path.parent.type === 'ExportDefaultDeclaration' || path.parent.type === 'ExportAllDeclaration') {
328 path.parentPath.insertAfter(check);
329 } else {
330 path.replaceWith(t.blockStatement([node, check]));
331 }
332 }
333 },
334 AssignmentExpression: function AssignmentExpression(path) {
335 if (maybeSkip(path)) {
336 return;
337 }
338 var node = path.node;
339 var scope = path.scope;
340
341 var left = path.get('left');
342 var annotation = undefined;
343 if (node.hasBeenTypeChecked || node.left.hasBeenTypeChecked) {
344 return;
345 } else if (left.isMemberExpression()) {
346 annotation = getAnnotation(left);
347 } else if (t.isIdentifier(node.left)) {
348 var binding = scope.getBinding(node.left.name);
349 if (!binding) {
350 return;
351 } else if (binding.path.type !== 'VariableDeclarator') {
352 return;
353 }
354 annotation = left.getTypeAnnotation();
355 if (annotation.type === 'AnyTypeAnnotation') {
356 var item = binding.path.get('id');
357 annotation = item.node.savedTypeAnnotation || item.getTypeAnnotation();
358 }
359 } else {
360 return;
361 }
362
363 node.hasBeenTypeChecked = true;
364 node.left.hasBeenTypeChecked = true;
365 var id = node.left;
366 var right = path.get('right');
367 if (annotation.type === 'AnyTypeAnnotation') {
368 return;
369 }
370 var ok = staticCheckAnnotation(right, annotation);
371 if (ok === true) {
372 return;
373 } else if (ok === false) {
374 throw path.buildCodeFrameError('Invalid assignment value, expected ' + humanReadableType(annotation) + ' got ' + humanReadableType(getAnnotation(right)));
375 }
376 var check = checkAnnotation(id, annotation, scope);
377 if (!id.typeAnnotation) {
378 id.typeAnnotation = annotation;
379 }
380 id.hasBeenTypeChecked = true;
381 if (check) {
382 var parent = path.getStatementParent();
383 parent.insertAfter(guard({
384 check: check,
385 message: varTypeErrorMessage(id, scope)
386 }));
387 }
388 },
389 TypeCastExpression: function TypeCastExpression(path) {
390 var node = path.node;
391
392 var target = undefined;
393 switch (node.expression.type) {
394 case 'Identifier':
395 target = node.expression;
396 break;
397 case 'AssignmentExpression':
398 target = node.expression.left;
399 break;
400 default:
401 // unsupported.
402 return;
403 }
404 var id = path.scope.getBindingIdentifier(target.name);
405 if (!id) {
406 return;
407 }
408 id.savedTypeAnnotation = path.getTypeAnnotation();
409 },
410 ForOfStatement: function ForOfStatement(path) {
411 if (maybeSkip(path)) {
412 return;
413 }
414 var left = path.get('left');
415 var right = path.get('right');
416 var rightAnnotation = getAnnotation(right);
417 var leftAnnotation = left.isVariableDeclaration() ? getAnnotation(left.get('declarations')[0].get('id')) : getAnnotation(left);
418 if (rightAnnotation.type !== 'VoidTypeAnnotation') {
419 var ok = maybeIterableAnnotation(rightAnnotation);
420 if (ok === false) {
421 throw path.buildCodeFrameError('Cannot iterate ' + humanReadableType(rightAnnotation));
422 }
423 }
424 var id = undefined;
425 if (right.isIdentifier()) {
426 id = right.node;
427 } else {
428 id = path.scope.generateUidIdentifierBasedOnNode(right.node);
429 path.scope.push({ id: id });
430 var replacement = t.expressionStatement(t.assignmentExpression('=', id, right.node));
431 path.insertBefore(replacement);
432 right.replaceWith(id);
433 }
434 path.insertBefore(guard({
435 check: checks.iterable({ input: id }),
436 message: t.binaryExpression('+', t.stringLiteral('Expected ' + (0, _babelGenerator2.default)(right.node).code + ' to be iterable, got '), readableName({ input: id }))
437 }));
438
439 if (rightAnnotation.type !== 'GenericTypeAnnotation' || rightAnnotation.id.name !== 'Iterable' || !rightAnnotation.typeParameters || !rightAnnotation.typeParameters.params.length) {
440 return;
441 }
442
443 var annotation = rightAnnotation.typeParameters.params[0];
444 if (compareAnnotations(annotation, leftAnnotation) === false) {
445 throw path.buildCodeFrameError('Invalid iterator type, expected ' + humanReadableType(annotation) + ' got ' + humanReadableType(leftAnnotation));
446 }
447 }
448 };
449
450 return {
451 visitor: {
452 Program: function Program(path, _ref6) {
453 var opts = _ref6.opts;
454
455 if (opts && opts.disable && opts.disable[process.env.NODE_ENV]) {
456 return;
457 }
458 var _iteratorNormalCompletion = true;
459 var _didIteratorError = false;
460 var _iteratorError = undefined;
461
462 try {
463 for (var _iterator = path.get('body')[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
464 var child = _step.value;
465
466 if (maybeSkipFile(child)) {
467 return;
468 }
469 }
470 } catch (err) {
471 _didIteratorError = true;
472 _iteratorError = err;
473 } finally {
474 try {
475 if (!_iteratorNormalCompletion && _iterator.return) {
476 _iterator.return();
477 }
478 } finally {
479 if (_didIteratorError) {
480 throw _iteratorError;
481 }
482 }
483 }
484
485 path.traverse(visitors);
486 }
487 }
488 };
489
490 /**
491 * Create a function which can verify the return type for a function.
492 */
493 function createFunctionReturnGuard(path) {
494 var node = path.node;
495 var scope = path.scope;
496
497 var annotation = node.returnType;
498 if (annotation.type === 'TypeAnnotation') {
499 annotation = annotation.typeAnnotation;
500 }
501 if (isGeneratorAnnotation(annotation)) {
502 annotation = annotation.typeParameters && annotation.typeParameters.params.length > 1 ? annotation.typeParameters.params[1] : t.anyTypeAnnotation();
503 }
504 var name = scope.generateUidIdentifierBasedOnNode(node);
505 var id = scope.generateUidIdentifier('id');
506 var check = checkAnnotation(id, annotation, scope);
507 if (check) {
508 node.returnGuard = guardFn({
509 id: id,
510 name: name,
511 check: check,
512 message: returnTypeErrorMessage(path, path.node, id)
513 });
514 node.returnGuard.hasBeenTypeChecked = true;
515 node.returnGuardName = name;
516 node.returnGuardCount = 0;
517 }
518 }
519
520 function createFunctionYieldGuards(path) {
521 var node = path.node;
522 var scope = path.scope;
523
524 var annotation = node.returnType;
525 if (annotation.type === 'NullableTypeAnnotation' || annotation.type === 'TypeAnnotation') {
526 annotation = annotation.typeAnnotation;
527 }
528 if (!annotation.typeParameters || annotation.typeParameters.params.length === 0) {
529 return;
530 }
531 if (annotation.type === 'TypeAnnotation') {
532 annotation = annotation.typeAnnotation;
533 }
534 if (!isGeneratorAnnotation(annotation)) {
535 return;
536 }
537
538 var yieldType = annotation.typeParameters.params[0];
539 var nextType = annotation.typeParameters.params[2];
540
541 if (yieldType) {
542 var _name = scope.generateUidIdentifier('check' + (node.id ? node.id.name.slice(0, 1).toUpperCase() + node.id.name.slice(1) : '') + 'Yield');
543 var _id2 = scope.generateUidIdentifier('id');
544 var check = checkAnnotation(_id2, yieldType, scope);
545 if (check) {
546 node.yieldGuard = guardFn({
547 id: _id2,
548 name: _name,
549 check: check,
550 message: yieldTypeErrorMessage(node, yieldType, _id2)
551 });
552 node.yieldGuardName = _name;
553 node.yieldGuardCount = 0;
554 }
555 }
556
557 if (nextType) {
558 var _name2 = scope.generateUidIdentifier('check' + (node.id ? node.id.name.slice(0, 1).toUpperCase() + node.id.name.slice(1) : '') + 'Next');
559 var _id3 = scope.generateUidIdentifier('id');
560 var check = checkAnnotation(_id3, nextType, scope);
561 if (check) {
562 node.nextGuard = guardFn({
563 id: _id3,
564 name: _name2,
565 check: check,
566 message: yieldNextTypeErrorMessage(node, nextType, _id3)
567 });
568 node.nextGuardName = _name2;
569 node.nextGuardCount = 0;
570 }
571 }
572 }
573
574 function isThisMemberExpression(path) {
575 var node = path.node;
576
577 if (node.type === 'ThisExpression') {
578 return true;
579 } else if (node.type === 'MemberExpression') {
580 return isThisMemberExpression(path.get('object'));
581 } else {
582 return false;
583 }
584 }
585
586 function isGeneratorAnnotation(annotation) {
587 if (!annotation) {
588 return false;
589 }
590 if (annotation.type === 'TypeAnnotation' || annotation.type === 'NullableTypeAnnotation') {
591 annotation = annotation.typeAnnotation;
592 }
593 return annotation.type === 'GenericTypeAnnotation' && annotation.id.name === 'Generator';
594 }
595
596 function createChecks() {
597 return {
598 number: expression('typeof input === \'number\''),
599 numericLiteral: checkNumericLiteral,
600 boolean: expression('typeof input === \'boolean\''),
601 booleanLiteral: checkBooleanLiteral,
602 class: checkClass,
603 function: expression('typeof input === \'function\''),
604 string: expression('typeof input === \'string\''),
605 stringLiteral: checkStringLiteral,
606 symbol: expression('typeof input === \'symbol\''),
607 undefined: expression('input === undefined'),
608 null: expression('input === null'),
609 void: expression('input == null'),
610 instanceof: expression('input instanceof type'),
611 type: expression('type(input)'),
612 mixed: function mixed() {
613 return null;
614 },
615 any: function any() {
616 return null;
617 },
618 union: checkUnion,
619 intersection: checkIntersection,
620 array: checkArray,
621 map: checkMap,
622 set: checkSet,
623 generator: checkGenerator,
624 iterable: checkIterable,
625 tuple: checkTuple,
626 object: checkObject,
627 nullable: checkNullable,
628 typeof: checkTypeof,
629 int8: expression('typeof input === \'number\' && !isNaN(input) && input >= -128 && input <= 127 && input === Math.floor(input)'),
630 uint8: expression('typeof input === \'number\' && !isNaN(input) && input >= 0 && input <= 255 && input === Math.floor(input)'),
631 int16: expression('typeof input === \'number\' && !isNaN(input) && input >= -32768 && input <= 32767 && input === Math.floor(input)'),
632 uint16: expression('typeof input === \'number\' && !isNaN(input) && input >= 0 && input <= 65535 && input === Math.floor(input)'),
633 int32: expression('typeof input === \'number\' && !isNaN(input) && input >= -2147483648 && input <= 2147483647 && input === Math.floor(input)'),
634 uint32: expression('typeof input === \'number\' && !isNaN(input) && input >= 0 && input <= 4294967295 && input === Math.floor(input)'),
635 float32: expression('typeof input === \'number\' && !isNaN(input) && input >= -3.40282347e+38 && input <= 3.40282347e+38'),
636 float64: expression('typeof input === \'number\' && !isNaN(input)')
637
638 };
639 }
640
641 function createStaticChecks() {
642 return {
643 symbol: function symbol(path) {
644 return maybeSymbolAnnotation(getAnnotation(path));
645 },
646 instanceof: function _instanceof(_ref7) {
647 var path = _ref7.path;
648 var annotation = _ref7.annotation;
649
650 var type = createTypeExpression(annotation.id);
651
652 var node = path.node;
653 var scope = path.scope;
654
655 if (type.name === 'Object' && node.type === 'ObjectExpression' && !scope.hasBinding('Object')) {
656 return true;
657 } else if (type.name === 'Map' && !scope.hasBinding('Map')) {
658 return null;
659 } else if (type.name === 'Set' && !scope.hasBinding('Set')) {
660 return null;
661 } else if (type.name === 'Class' && !scope.hasBinding('Class')) {
662 return null;
663 } else if (type.name === 'int8' && !scope.hasBinding('int8')) {
664 return null;
665 } else if (type.name === 'uint8' && !scope.hasBinding('uint8')) {
666 return null;
667 } else if (type.name === 'int16' && !scope.hasBinding('int16')) {
668 return null;
669 } else if (type.name === 'uint16' && !scope.hasBinding('uint16')) {
670 return null;
671 } else if (type.name === 'int32' && !scope.hasBinding('int32')) {
672 return null;
673 } else if (type.name === 'uint32' && !scope.hasBinding('uint32')) {
674 return null;
675 } else if (type.name === 'float32' && !scope.hasBinding('float32')) {
676 return null;
677 } else if (type.name === 'float64' && !scope.hasBinding('float64')) {
678 return null;
679 }
680 return maybeInstanceOfAnnotation(getAnnotation(path), type, annotation.typeParameters ? annotation.typeParameters.params : []);
681 },
682 type: (function (_type) {
683 function type(_x) {
684 return _type.apply(this, arguments);
685 }
686
687 type.toString = function () {
688 return _type.toString();
689 };
690
691 return type;
692 })(function (_ref8) {
693 var path = _ref8.path;
694 var type = _ref8.type;
695
696 return null;
697 })
698 };
699 }
700
701 function compareAnnotations(a, b) {
702 if (a.type === 'TypeAnnotation') {
703 a = a.typeAnnotation;
704 }
705 if (b.type === 'TypeAnnotation') {
706 b = b.typeAnnotation;
707 }
708 switch (a.type) {
709 case 'StringTypeAnnotation':
710 return maybeStringAnnotation(b);
711 case 'StringLiteralTypeAnnotation':
712 return compareStringLiteralAnnotations(a, b);
713 case 'NumberTypeAnnotation':
714 return maybeNumberAnnotation(b);
715 case 'NumericLiteralTypeAnnotation':
716 return compareNumericLiteralAnnotations(a, b);
717 case 'BooleanTypeAnnotation':
718 return maybeBooleanAnnotation(b);
719 case 'BooleanLiteralTypeAnnotation':
720 return compareBooleanLiteralAnnotations(a, b);
721 case 'FunctionTypeAnnotation':
722 return maybeFunctionAnnotation(b);
723 case 'AnyTypeAnnotation':
724 return null;
725 case 'MixedTypeAnnotation':
726 return null;
727 case 'ObjectTypeAnnotation':
728 return compareObjectAnnotation(a, b);
729 case 'ArrayTypeAnnotation':
730 return compareArrayAnnotation(a, b);
731 case 'GenericTypeAnnotation':
732 return compareGenericAnnotation(a, b);
733 case 'TupleTypeAnnotation':
734 return compareTupleAnnotation(a, b);
735 case 'UnionTypeAnnotation':
736 return compareUnionAnnotation(a, b);
737 case 'IntersectionTypeAnnotation':
738 return compareIntersectionAnnotation(a, b);
739 case 'NullableTypeAnnotation':
740 return compareNullableAnnotation(a, b);
741 default:
742 return null;
743 }
744 }
745
746 function compareStringLiteralAnnotations(a, b) {
747 if (b.type === 'StringLiteralTypeAnnotation') {
748 return a.value === b.value;
749 } else {
750 return maybeStringAnnotation(b) === false ? false : null;
751 }
752 }
753
754 function compareBooleanLiteralAnnotations(a, b) {
755 if (b.type === 'BooleanLiteralTypeAnnotation') {
756 return a.value === b.value;
757 } else {
758 return maybeBooleanAnnotation(b) === false ? false : null;
759 }
760 }
761
762 function compareNumericLiteralAnnotations(a, b) {
763 if (b.type === 'NumericLiteralTypeAnnotation') {
764 return a.value === b.value;
765 } else {
766 return maybeNumberAnnotation(b) === false ? false : null;
767 }
768 }
769
770 function unionComparer(a, b, comparator) {
771 if (!a.types || a.types.length === 0) {
772 return null;
773 }
774 var falseCount = 0;
775 var trueCount = 0;
776 if (!a.types) {
777 return null;
778 }
779 var _iteratorNormalCompletion2 = true;
780 var _didIteratorError2 = false;
781 var _iteratorError2 = undefined;
782
783 try {
784 for (var _iterator2 = a.types[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
785 var _type2 = _step2.value;
786
787 var result = comparator(_type2, b);
788 if (result === true) {
789 if (b.type !== 'UnionTypeAnnotation') {
790 return true;
791 }
792 trueCount++;
793 } else if (result === false) {
794 if (b.type === 'UnionTypeAnnotation') {
795 return false;
796 }
797 falseCount++;
798 }
799 }
800 } catch (err) {
801 _didIteratorError2 = true;
802 _iteratorError2 = err;
803 } finally {
804 try {
805 if (!_iteratorNormalCompletion2 && _iterator2.return) {
806 _iterator2.return();
807 }
808 } finally {
809 if (_didIteratorError2) {
810 throw _iteratorError2;
811 }
812 }
813 }
814
815 if (falseCount === a.types.length) {
816 return false;
817 } else if (trueCount === a.types.length) {
818 return true;
819 } else {
820 return null;
821 }
822 }
823
824 function intersectionComparer(a, b, comparator) {
825 var falseCount = 0;
826 var trueCount = 0;
827 if (!a.types) {
828 return null;
829 }
830 var _iteratorNormalCompletion3 = true;
831 var _didIteratorError3 = false;
832 var _iteratorError3 = undefined;
833
834 try {
835 for (var _iterator3 = a.types[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
836 var _type3 = _step3.value;
837
838 var result = comparator(_type3, b);
839 if (result === true) {
840 trueCount++;
841 } else if (result === false) {
842 return false;
843 }
844 }
845 } catch (err) {
846 _didIteratorError3 = true;
847 _iteratorError3 = err;
848 } finally {
849 try {
850 if (!_iteratorNormalCompletion3 && _iterator3.return) {
851 _iterator3.return();
852 }
853 } finally {
854 if (_didIteratorError3) {
855 throw _iteratorError3;
856 }
857 }
858 }
859
860 if (trueCount === a.types.length) {
861 return true;
862 } else {
863 return null;
864 }
865 }
866
867 function compareObjectAnnotation(a, b) {
868 switch (b.type) {
869 case 'ObjectTypeAnnotation':
870 break;
871 case 'TypeAnnotation':
872 case 'FunctionTypeParam':
873 case 'NullableTypeAnnotation':
874 return compareObjectAnnotation(a, b.typeAnnotation);
875 case 'UnionTypeAnnotation':
876 return unionComparer(a, b, compareObjectAnnotation);
877 case 'IntersectionTypeAnnotation':
878 return intersectionComparer(a, b, compareObjectAnnotation);
879 case 'VoidTypeAnnotation':
880 case 'BooleanTypeAnnotation':
881 case 'BooleanLiteralTypeAnnotation':
882 case 'StringTypeAnnotation':
883 case 'StringLiteralTypeAnnotation':
884 case 'NumberTypeAnnotation':
885 case 'NumericLiteralTypeAnnotation':
886 case 'FunctionTypeAnnotation':
887 return false;
888 default:
889 return null;
890 }
891
892 // We're comparing two object annotations.
893 var allTrue = true;
894 var _iteratorNormalCompletion4 = true;
895 var _didIteratorError4 = false;
896 var _iteratorError4 = undefined;
897
898 try {
899 for (var _iterator4 = a.properties[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
900 var aprop = _step4.value;
901
902 var found = false;
903 var _iteratorNormalCompletion5 = true;
904 var _didIteratorError5 = false;
905 var _iteratorError5 = undefined;
906
907 try {
908 for (var _iterator5 = b.properties[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
909 var bprop = _step5.value;
910
911 if (bprop.key.name === aprop.key.name) {
912 var result = compareAnnotations(aprop.value, bprop.value);
913 if (result === false && !(aprop.optional && (bprop.optional || maybeNullableAnnotation(bprop.value) === true))) {
914 return false;
915 } else {
916 found = result;
917 }
918 break;
919 }
920 }
921 } catch (err) {
922 _didIteratorError5 = true;
923 _iteratorError5 = err;
924 } finally {
925 try {
926 if (!_iteratorNormalCompletion5 && _iterator5.return) {
927 _iterator5.return();
928 }
929 } finally {
930 if (_didIteratorError5) {
931 throw _iteratorError5;
932 }
933 }
934 }
935
936 if (found === false && !aprop.optional) {
937 return false;
938 }
939 allTrue = allTrue && found === true;
940 }
941 } catch (err) {
942 _didIteratorError4 = true;
943 _iteratorError4 = err;
944 } finally {
945 try {
946 if (!_iteratorNormalCompletion4 && _iterator4.return) {
947 _iterator4.return();
948 }
949 } finally {
950 if (_didIteratorError4) {
951 throw _iteratorError4;
952 }
953 }
954 }
955
956 return allTrue ? true : null;
957 }
958
959 function compareArrayAnnotation(a, b) {
960 switch (b.type) {
961 case 'TypeAnnotation':
962 case 'FunctionTypeParam':
963 case 'NullableTypeAnnotation':
964 return compareArrayAnnotation(a, b.typeAnnotation);
965 case 'UnionTypeAnnotation':
966 return unionComparer(a, b, compareArrayAnnotation);
967 case 'IntersectionTypeAnnotation':
968 return intersectionComparer(a, b, compareArrayAnnotation);
969 case 'VoidTypeAnnotation':
970 case 'BooleanTypeAnnotation':
971 case 'BooleanLiteralTypeAnnotation':
972 case 'StringTypeAnnotation':
973 case 'StringLiteralTypeAnnotation':
974 case 'NumberTypeAnnotation':
975 case 'NumericLiteralTypeAnnotation':
976 case 'FunctionTypeAnnotation':
977 return false;
978 default:
979 return null;
980 }
981 }
982
983 function compareGenericAnnotation(a, b) {
984 switch (b.type) {
985 case 'TypeAnnotation':
986 case 'FunctionTypeParam':
987 case 'NullableTypeAnnotation':
988 return compareGenericAnnotation(a, b.typeAnnotation);
989 case 'GenericTypeAnnotation':
990 if (b.id.name === a.id.name) {
991 return true;
992 } else {
993 return null;
994 }
995 case 'UnionTypeAnnotation':
996 return unionComparer(a, b, compareGenericAnnotation);
997 case 'IntersectionTypeAnnotation':
998 return intersectionComparer(a, b, compareGenericAnnotation);
999 default:
1000 return null;
1001 }
1002 }
1003
1004 function compareTupleAnnotation(a, b) {
1005 if (b.type === 'TupleTypeAnnotation') {
1006 if (b.types.length === 0) {
1007 return null;
1008 } else if (b.types.length < a.types.length) {
1009 return false;
1010 }
1011 return a.types.every(function (type, index) {
1012 return compareAnnotations(type, b.types[index]);
1013 });
1014 }
1015 switch (b.type) {
1016 case 'TypeAnnotation':
1017 case 'FunctionTypeParam':
1018 case 'NullableTypeAnnotation':
1019 return compareTupleAnnotation(a, b.typeAnnotation);
1020 case 'UnionTypeAnnotation':
1021 return unionComparer(a, b, compareTupleAnnotation);
1022 case 'IntersectionTypeAnnotation':
1023 return intersectionComparer(a, b, compareTupleAnnotation);
1024 case 'VoidTypeAnnotation':
1025 case 'BooleanTypeAnnotation':
1026 case 'BooleanLiteralTypeAnnotation':
1027 case 'StringTypeAnnotation':
1028 case 'StringLiteralTypeAnnotation':
1029 case 'NumberTypeAnnotation':
1030 case 'NumericLiteralTypeAnnotation':
1031 case 'FunctionTypeAnnotation':
1032 return false;
1033 default:
1034 return null;
1035 }
1036 }
1037
1038 function compareUnionAnnotation(a, b) {
1039 switch (b.type) {
1040 case 'NullableTypeAnnotation':
1041 return compareUnionAnnotation(a, b.typeAnnotation);
1042 case 'AnyTypeAnnotation':
1043 case 'MixedTypeAnnotation':
1044 return null;
1045 default:
1046 return unionComparer(a, b, compareAnnotations);
1047 }
1048 }
1049
1050 function compareNullableAnnotation(a, b) {
1051 switch (b.type) {
1052 case 'TypeAnnotation':
1053 case 'FunctionTypeParam':
1054 return compareNullableAnnotation(a, b.typeAnnotation);
1055 case 'NullableTypeAnnotation':
1056 case 'VoidTypeAnnotation':
1057 return null;
1058 }
1059 if (compareAnnotations(a.typeAnnotation, b) === true) {
1060 return true;
1061 } else {
1062 return null;
1063 }
1064 }
1065
1066 function arrayExpressionToTupleAnnotation(path) {
1067 var elements = path.get('elements');
1068 return t.tupleTypeAnnotation(elements.map(function (element) {
1069 return getAnnotation(element);
1070 }));
1071 }
1072
1073 function checkNullable(_ref9) {
1074 var input = _ref9.input;
1075 var type = _ref9.type;
1076 var scope = _ref9.scope;
1077
1078 var check = checkAnnotation(input, type, scope);
1079 if (!check) {
1080 return;
1081 }
1082 return t.logicalExpression("||", checks.void({ input: input }), check);
1083 }
1084
1085 function checkTypeof(_ref10) {
1086 var input = _ref10.input;
1087 var annotation = _ref10.annotation;
1088 var scope = _ref10.scope;
1089
1090 switch (annotation.type) {
1091 case 'GenericTypeAnnotation':
1092 var id = annotation.id;
1093
1094 var path = Object.assign({}, input, { type: id.type, node: id, scope: scope });
1095 return checkAnnotation(input, getAnnotation(path), scope);
1096 default:
1097 return checkAnnotation(input, annotation, scope);
1098 }
1099 }
1100
1101 function checkStringLiteral(_ref11) {
1102 var input = _ref11.input;
1103 var annotation = _ref11.annotation;
1104
1105 return checkEquals({ input: input, expected: t.stringLiteral(annotation.value) });
1106 }
1107
1108 function checkNumericLiteral(_ref12) {
1109 var input = _ref12.input;
1110 var annotation = _ref12.annotation;
1111
1112 return checkEquals({ input: input, expected: t.numericLiteral(annotation.value) });
1113 }
1114
1115 function checkBooleanLiteral(_ref13) {
1116 var input = _ref13.input;
1117 var annotation = _ref13.annotation;
1118
1119 return checkEquals({ input: input, expected: t.booleanLiteral(annotation.value) });
1120 }
1121
1122 function checkUnion(_ref14) {
1123 var input = _ref14.input;
1124 var types = _ref14.types;
1125 var scope = _ref14.scope;
1126
1127 var checks = types.map(function (type) {
1128 return checkAnnotation(input, type, scope);
1129 }).filter(identity);
1130 return checks.reduce(function (last, check, index) {
1131 if (last == null) {
1132 return check;
1133 }
1134 return t.logicalExpression("||", last, check);
1135 }, null);
1136 }
1137
1138 function checkIntersection(_ref15) {
1139 var input = _ref15.input;
1140 var types = _ref15.types;
1141 var scope = _ref15.scope;
1142
1143 var checks = types.map(function (type) {
1144 return checkAnnotation(input, type, scope);
1145 }).filter(identity);
1146 return checks.reduce(function (last, check, index) {
1147 if (last == null) {
1148 return check;
1149 }
1150 return t.logicalExpression("&&", last, check);
1151 }, null);
1152 }
1153
1154 function checkMap(_ref16) {
1155 var input = _ref16.input;
1156 var types = _ref16.types;
1157 var scope = _ref16.scope;
1158
1159 var _types = _slicedToArray(types, 2);
1160
1161 var keyType = _types[0];
1162 var valueType = _types[1];
1163
1164 var key = t.identifier('key');
1165 var value = t.identifier('value');
1166 var keyCheck = keyType ? checkAnnotation(key, keyType, scope) : null;
1167 var valueCheck = valueType ? checkAnnotation(value, valueType, scope) : null;
1168 if (!keyCheck) {
1169 if (!valueCheck) {
1170 return checkIsMap({ input: input });
1171 } else {
1172 return checkMapValues({ input: input, value: value, valueCheck: valueCheck });
1173 }
1174 } else {
1175 if (!valueCheck) {
1176 return checkMapKeys({ input: input, key: key, keyCheck: keyCheck });
1177 } else {
1178 return checkMapEntries({ input: input, key: key, value: value, keyCheck: keyCheck, valueCheck: valueCheck });
1179 }
1180 }
1181 }
1182
1183 function checkSet(_ref17) {
1184 var input = _ref17.input;
1185 var types = _ref17.types;
1186 var scope = _ref17.scope;
1187
1188 var _types2 = _slicedToArray(types, 1);
1189
1190 var valueType = _types2[0];
1191
1192 var value = t.identifier('value');
1193 var valueCheck = valueType ? checkAnnotation(value, valueType, scope) : null;
1194 if (!valueCheck) {
1195 return checkIsSet({ input: input });
1196 } else {
1197 return checkSetEntries({ input: input, value: value, valueCheck: valueCheck });
1198 }
1199 }
1200
1201 function checkGenerator(_ref18) {
1202 var input = _ref18.input;
1203 var types = _ref18.types;
1204 var scope = _ref18.scope;
1205
1206 return checkIsGenerator({ input: input });
1207 }
1208
1209 function checkIterable(_ref19) {
1210 var input = _ref19.input;
1211 var types = _ref19.types;
1212 var scope = _ref19.scope;
1213
1214 return checkIsIterable({ input: input });
1215 }
1216
1217 function checkClass(_ref20) {
1218 var input = _ref20.input;
1219 var types = _ref20.types;
1220 var scope = _ref20.scope;
1221
1222 return checkIsClass({ input: input });
1223 }
1224
1225 function checkArray(_ref21) {
1226 var input = _ref21.input;
1227 var types = _ref21.types;
1228 var scope = _ref21.scope;
1229
1230 if (!types || types.length === 0) {
1231 return checkIsArray({ input: input });
1232 } else if (types.length === 1) {
1233 var item = t.identifier('item');
1234 var _type4 = types[0];
1235 var check = checkAnnotation(item, _type4, scope);
1236 if (!check) {
1237 return checkIsArray({ input: input });
1238 }
1239 return t.logicalExpression('&&', checkIsArray({ input: input }), t.callExpression(t.memberExpression(input, t.identifier('every')), [t.functionExpression(null, [item], t.blockStatement([t.returnStatement(check)]))]));
1240 } else {
1241 // This is a tuple
1242 var _checks = types.map(function (type, index) {
1243 return checkAnnotation(t.memberExpression(input, t.numericLiteral(index), true), type, scope);
1244 }).filter(identity);
1245
1246 var checkLength = t.binaryExpression('>=', t.memberExpression(input, t.identifier('length')), t.numericLiteral(types.length));
1247
1248 return _checks.reduce(function (last, check, index) {
1249 return t.logicalExpression("&&", last, check);
1250 }, t.logicalExpression('&&', checkIsArray({ input: input }), checkLength));
1251 }
1252 }
1253
1254 function checkTuple(_ref22) {
1255 var input = _ref22.input;
1256 var types = _ref22.types;
1257 var scope = _ref22.scope;
1258
1259 if (types.length === 0) {
1260 return checkIsArray({ input: input });
1261 }
1262
1263 // This is a tuple
1264 var checks = types.map(function (type, index) {
1265 return checkAnnotation(t.memberExpression(input, t.numericLiteral(index), true), type, scope);
1266 }).filter(identity);
1267
1268 var checkLength = t.binaryExpression('>=', t.memberExpression(input, t.identifier('length')), t.numericLiteral(types.length));
1269
1270 return checks.reduce(function (last, check, index) {
1271 return t.logicalExpression("&&", last, check);
1272 }, t.logicalExpression('&&', checkIsArray({ input: input }), checkLength));
1273 }
1274
1275 function checkObject(_ref23) {
1276 var input = _ref23.input;
1277 var properties = _ref23.properties;
1278 var indexers = _ref23.indexers;
1279 var scope = _ref23.scope;
1280
1281 if (input.type === 'ObjectPattern') {
1282 return checkObjectPattern({ input: input, properties: properties, scope: scope });
1283 }
1284 var propNames = [];
1285 var check = properties.reduce(function (expr, prop, index) {
1286 var target = prop.key.type === 'Identifier' ? t.memberExpression(input, prop.key) : t.memberExpression(input, prop.key, true);
1287 propNames.push(prop.key.type === 'Identifier' ? t.stringLiteral(prop.key.name) : prop.key);
1288 var check = checkAnnotation(target, prop.value, scope);
1289 if (check) {
1290 if (prop.optional) {
1291 check = t.logicalExpression('||', checks.undefined({ input: target }), check);
1292 }
1293 return t.logicalExpression("&&", expr, check);
1294 } else {
1295 return expr;
1296 }
1297 }, checkIsObject({ input: input }));
1298
1299 if (indexers.length) {
1300 return indexers.reduceRight(function (expr, indexer) {
1301 if (indexer.value.type === 'AnyTypeAnnotation') {
1302 return expr;
1303 }
1304 var value = scope.generateUidIdentifier(indexer.id.name);
1305 var check = checkAnnotation(value, indexer.value, scope);
1306 var fixedKeys = t.arrayExpression(propNames);
1307
1308 if (check) {
1309 if (propNames.length) {
1310 return t.logicalExpression('&&', expr, checkObjectIndexers({ input: input, value: value, check: check, fixedKeys: fixedKeys }));
1311 } else {
1312 return t.logicalExpression('&&', expr, checkObjectIndexersNoFixed({ input: input, value: value, check: check, fixedKeys: fixedKeys }));
1313 }
1314 } else {
1315 return expr;
1316 }
1317 }, check);
1318 }
1319
1320 return check;
1321 }
1322
1323 function checkObjectPattern(_ref24) {
1324 var input = _ref24.input;
1325 var properties = _ref24.properties;
1326 var scope = _ref24.scope;
1327
1328 var propNames = properties.reduce(function (names, prop) {
1329 names[prop.key.name] = prop;
1330 return names;
1331 }, {});
1332 var propChecks = {};
1333 var _iteratorNormalCompletion6 = true;
1334 var _didIteratorError6 = false;
1335 var _iteratorError6 = undefined;
1336
1337 try {
1338 for (var _iterator6 = input.properties[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
1339 var item = _step6.value;
1340 var key = item.key;
1341 var _id4 = item.value;
1342
1343 var prop = propNames[key.name];
1344 if (!prop) {
1345 continue;
1346 }
1347 var check = checkAnnotation(_id4, prop.value, scope);
1348 if (check) {
1349 propChecks[key.name] = check;
1350 }
1351 }
1352 } catch (err) {
1353 _didIteratorError6 = true;
1354 _iteratorError6 = err;
1355 } finally {
1356 try {
1357 if (!_iteratorNormalCompletion6 && _iterator6.return) {
1358 _iterator6.return();
1359 }
1360 } finally {
1361 if (_didIteratorError6) {
1362 throw _iteratorError6;
1363 }
1364 }
1365 }
1366
1367 return Object.keys(propChecks).reduce(function (last, name) {
1368 var check = propChecks[name];
1369 if (last === null) {
1370 return check;
1371 } else {
1372 return t.logicalExpression('&&', last, check);
1373 }
1374 }, null);
1375 }
1376
1377 function createTypeAliasChecks(path) {
1378 var node = path.node;
1379 var scope = path.scope;
1380 var id = node.id;
1381 var annotation = node.right;
1382
1383 var input = t.identifier('input');
1384 var check = checkAnnotation(input, annotation, scope) || t.booleanLiteral(true);
1385 var declaration = declareTypeChecker({ id: id, check: check });
1386 declaration.isTypeChecker = true;
1387 declaration.savedTypeAnnotation = annotation;
1388 declaration.declarations[0].savedTypeAnnotation = annotation;
1389 return declaration;
1390 }
1391
1392 function createInterfaceChecks(path) {
1393 var node = path.node;
1394 var scope = path.scope;
1395 var id = node.id;
1396 var annotation = node.body;
1397
1398 var input = t.identifier('input');
1399 var check = node.extends.reduce(function (check, extender) {
1400 return t.logicalExpression('&&', check, checkAnnotation(input, t.genericTypeAnnotation(extender.id), path.scope));
1401 return check;
1402 }, checkAnnotation(input, annotation, scope) || t.booleanLiteral(true));
1403
1404 var declaration = declareTypeChecker({ id: id, check: check });
1405 declaration.isTypeChecker = true;
1406 return declaration;
1407 }
1408
1409 function checkAnnotation(input, annotation, scope) {
1410 switch (annotation.type) {
1411 case 'TypeAnnotation':
1412 case 'FunctionTypeParam':
1413 return checkAnnotation(input, annotation.typeAnnotation, scope);
1414 case 'TypeofTypeAnnotation':
1415 return checks.typeof({ input: input, annotation: annotation.argument, scope: scope });
1416 case 'GenericTypeAnnotation':
1417 if (annotation.id.name === 'Array') {
1418 return checks.array({ input: input, types: annotation.typeParameters ? annotation.typeParameters.params : [], scope: scope });
1419 } else if (annotation.id.name === 'Generator' && !scope.hasBinding('Generator')) {
1420 return checks.generator({ input: input, types: annotation.typeParameters ? annotation.typeParameters.params : [], scope: scope });
1421 } else if (annotation.id.name === 'Iterable' && !scope.hasBinding('Iterable')) {
1422 return checks.iterable({ input: input, types: annotation.typeParameters ? annotation.typeParameters.params : [], scope: scope });
1423 } else if (annotation.id.name === 'Map' && !scope.hasBinding('Map')) {
1424 return checks.map({ input: input, types: annotation.typeParameters ? annotation.typeParameters.params : [], scope: scope });
1425 } else if (annotation.id.name === 'Set' && !scope.hasBinding('Set')) {
1426 return checks.set({ input: input, types: annotation.typeParameters ? annotation.typeParameters.params : [], scope: scope });
1427 } else if (annotation.id.name === 'Function') {
1428 return checks.function({ input: input });
1429 } else if (annotation.id.name === 'Class' && !scope.hasBinding('Class')) {
1430 return checks.class({ input: input, types: annotation.typeParameters ? annotation.typeParameters.params : [], scope: scope });
1431 } else if (annotation.id.name === 'int8' && !scope.hasBinding('int8')) {
1432 return checks.int8({ input: input });
1433 } else if (annotation.id.name === 'uint8' && !scope.hasBinding('uint8')) {
1434 return checks.uint8({ input: input });
1435 } else if (annotation.id.name === 'int16' && !scope.hasBinding('int16')) {
1436 return checks.int16({ input: input });
1437 } else if (annotation.id.name === 'uint16' && !scope.hasBinding('uint16')) {
1438 return checks.uint16({ input: input });
1439 } else if (annotation.id.name === 'int32' && !scope.hasBinding('int32')) {
1440 return checks.int32({ input: input });
1441 } else if (annotation.id.name === 'uint32' && !scope.hasBinding('uint32')) {
1442 return checks.uint32({ input: input });
1443 } else if (annotation.id.name === 'float32' && !scope.hasBinding('float32')) {
1444 return checks.float32({ input: input });
1445 } else if (annotation.id.name === 'float64' && !scope.hasBinding('float64')) {
1446 return checks.float64({ input: input });
1447 } else if (annotation.id.name === 'Symbol' && !scope.hasBinding('Symbol')) {
1448 return checks.symbol({ input: input });
1449 } else if (isTypeChecker(annotation.id, scope)) {
1450 return checks.type({ input: input, type: annotation.id });
1451 } else if (isPolymorphicType(annotation.id, scope)) {
1452 return;
1453 } else {
1454 return checks.instanceof({ input: input, type: createTypeExpression(annotation.id) });
1455 }
1456 case 'TupleTypeAnnotation':
1457 return checks.tuple({ input: input, types: annotation.types, scope: scope });
1458 case 'NumberTypeAnnotation':
1459 return checks.number({ input: input });
1460 case 'NumericLiteralTypeAnnotation':
1461 return checks.numericLiteral({ input: input, annotation: annotation });
1462 case 'BooleanTypeAnnotation':
1463 return checks.boolean({ input: input });
1464 case 'BooleanLiteralTypeAnnotation':
1465 return checks.booleanLiteral({ input: input, annotation: annotation });
1466 case 'StringTypeAnnotation':
1467 return checks.string({ input: input });
1468 case 'StringLiteralTypeAnnotation':
1469 return checks.stringLiteral({ input: input, annotation: annotation });
1470 case 'UnionTypeAnnotation':
1471 return checks.union({ input: input, types: annotation.types, scope: scope });
1472 case 'IntersectionTypeAnnotation':
1473 return checks.intersection({ input: input, types: annotation.types, scope: scope });
1474 case 'ObjectTypeAnnotation':
1475 return checks.object({ input: input, properties: annotation.properties || [], indexers: annotation.indexers, scope: scope });
1476 case 'ArrayTypeAnnotation':
1477 return checks.array({ input: input, types: [annotation.elementType || t.anyTypeAnnotation()], scope: scope });
1478 case 'FunctionTypeAnnotation':
1479 return checks.function({ input: input, params: annotation.params, returnType: annotation.returnType });
1480 case 'MixedTypeAnnotation':
1481 return checks.mixed({ input: input });
1482 case 'AnyTypeAnnotation':
1483 case 'ExistentialTypeParam':
1484 return checks.any({ input: input });
1485 case 'NullableTypeAnnotation':
1486 return checks.nullable({ input: input, type: annotation.typeAnnotation, scope: scope });
1487 case 'VoidTypeAnnotation':
1488 return checks.void({ input: input });
1489 }
1490 }
1491
1492 function staticCheckAnnotation(path, annotation) {
1493 var other = getAnnotation(path);
1494 switch (annotation.type) {
1495 case 'TypeAnnotation':
1496 case 'FunctionTypeParam':
1497 return staticCheckAnnotation(path, annotation.typeAnnotation);
1498 case 'GenericTypeAnnotation':
1499 if (isTypeChecker(annotation.id, path.scope)) {
1500 return staticChecks.type({ path: path, type: annotation.id });
1501 } else if (isPolymorphicType(annotation.id, path.scope)) {
1502 return;
1503 } else if (annotation.id.name === 'Symbol') {
1504 return staticChecks.symbol(path);
1505 } else {
1506 return staticChecks.instanceof({ path: path, annotation: annotation });
1507 }
1508 }
1509 return compareAnnotations(annotation, other);
1510 }
1511
1512 /**
1513 * Get the type annotation for a given node.
1514 */
1515 function getAnnotation(path) {
1516 var annotation = undefined;
1517 try {
1518 annotation = getAnnotationShallow(path);
1519 } catch (e) {
1520 if (e instanceof SyntaxError) {
1521 throw e;
1522 }
1523 if (process.env.TYPECHECK_DEBUG) {
1524 console.error(e.stack);
1525 }
1526 }
1527 while (annotation && annotation.type === 'TypeAnnotation') {
1528 annotation = annotation.typeAnnotation;
1529 }
1530 return annotation || t.anyTypeAnnotation();
1531 }
1532
1533 function getAnnotationShallow(path) {
1534 if (!path || !path.node) {
1535 return t.voidTypeAnnotation();
1536 }
1537 var node = path.node;
1538 var scope = path.scope;
1539
1540 if (node.type === 'TypeAlias') {
1541 return node.right;
1542 } else if (node.type === 'ClassProperty' && node.typeAnnotation) {
1543 return getClassPropertyAnnotation(path);
1544 } else if (node.type === 'ClassMethod' && node.returnType) {
1545 return getClassMethodAnnotation(path);
1546 } else if (node.type === 'ObjectProperty' && node.typeAnnotation) {
1547 return getObjectPropertyAnnotation(path);
1548 } else if (node.type === 'SpreadProperty' && node.typeAnnotation) {
1549 return getSpreadPropertyAnnotation(path);
1550 } else if (node.type === 'ObjectMethod' && node.returnType) {
1551 return getObjectMethodAnnotation(path);
1552 } else if (!node.typeAnnotation && !node.savedTypeAnnotation && !node.returnType) {
1553 switch (path.type) {
1554 case 'Identifier':
1555 var binding = scope.getBinding(node.name);
1556 if (!binding || !binding.identifier) {
1557 return path.getTypeAnnotation();
1558 }
1559 var id = binding.identifier;
1560 if (binding.path.type === 'ObjectPattern') {
1561 return getObjectPatternAnnotation(binding.path, node.name);
1562 }
1563 if (id.savedTypeAnnotation) {
1564 return id.savedTypeAnnotation;
1565 } else if (id.returnType) {
1566 return id.returnType;
1567 } else if (id.typeAnnotation) {
1568 return id.typeAnnotation;
1569 } else if (isPolymorphicType(id, scope)) {
1570 return t.anyTypeAnnotation();
1571 }
1572 return binding.constant ? binding.path.getTypeAnnotation() : path.getTypeAnnotation();
1573 case 'StringLiteral':
1574 case 'NumericLiteral':
1575 case 'BooleanLiteral':
1576 return createLiteralTypeAnnotation(path);
1577 case 'CallExpression':
1578 var callee = path.get('callee');
1579 if (callee.type === 'Identifier') {
1580 if (callee.name === 'Symbol') {
1581 return t.genericTypeAnnotation('Symbol');
1582 }
1583 var fn = getFunctionForIdentifier(callee);
1584 if (fn) {
1585 return getAnnotation(fn);
1586 }
1587 }
1588 break;
1589 case 'ThisExpression':
1590 return getThisExpressionAnnotation(path);
1591 case 'AssignmentExpression':
1592 return getAssignmentExpressionAnnotation(path);
1593 case 'MemberExpression':
1594 return getMemberExpressionAnnotation(path);
1595 case 'ArrayExpression':
1596 return getArrayExpressionAnnotation(path);
1597 case 'ObjectExpression':
1598 return getObjectExpressionAnnotation(path);
1599 case 'BinaryExpression':
1600 return getBinaryExpressionAnnotation(path);
1601 case 'BinaryExpression':
1602 return getBinaryExpressionAnnotation(path);
1603 case 'LogicalExpression':
1604 return getLogicalExpressionAnnotation(path);
1605 case 'ConditionalExpression':
1606 return getConditionalExpressionAnnotation(path);
1607 case 'ObjectMethod':
1608 return getObjectMethodAnnotation(path);
1609 case 'SpreadProperty':
1610 return getSpreadPropertyAnnotation(path);
1611 case 'ObjectProperty':
1612 return getObjectPropertyAnnotation(path);
1613 case 'ClassDeclaration':
1614 return getClassDeclarationAnnotation(path);
1615 case 'ClassMethod':
1616 return getClassMethodAnnotation(path);
1617 case 'ClassProperty':
1618 return getClassPropertyAnnotation(path);
1619 default:
1620 return path.getTypeAnnotation();
1621
1622 }
1623 }
1624 return node.savedTypeAnnotation || node.returnType || node.typeAnnotation || path.getTypeAnnotation();
1625 }
1626
1627 function createLiteralTypeAnnotation(path) {
1628 var annotation = undefined;
1629 if (path.isStringLiteral()) {
1630 annotation = t.stringLiteralTypeAnnotation();
1631 } else if (path.isNumericLiteral()) {
1632 annotation = t.numericLiteralTypeAnnotation();
1633 } else if (path.isBooleanLiteral()) {
1634 annotation = t.booleanLiteralTypeAnnotation();
1635 } else {
1636 return path.getTypeAnnotation();
1637 }
1638 annotation.value = path.node.value;
1639 return annotation;
1640 }
1641
1642 function getObjectPatternAnnotation(path, name) {
1643 var annotation = keyByName(getAnnotation(path), name);
1644 var found = undefined;
1645 if (!path.node.properties) {
1646 return;
1647 }
1648 var _iteratorNormalCompletion7 = true;
1649 var _didIteratorError7 = false;
1650 var _iteratorError7 = undefined;
1651
1652 try {
1653 for (var _iterator7 = path.get('properties')[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
1654 var prop = _step7.value;
1655
1656 if (prop.node.value && prop.node.value.name === name) {
1657 found = prop.get('key');
1658 break;
1659 } else if (prop.node.key.type === 'Identifier' && prop.node.key.name === name) {
1660 found = prop.get('key');
1661 break;
1662 }
1663 }
1664 } catch (err) {
1665 _didIteratorError7 = true;
1666 _iteratorError7 = err;
1667 } finally {
1668 try {
1669 if (!_iteratorNormalCompletion7 && _iterator7.return) {
1670 _iterator7.return();
1671 }
1672 } finally {
1673 if (_didIteratorError7) {
1674 throw _iteratorError7;
1675 }
1676 }
1677 }
1678
1679 if (!annotation || !found) {
1680 return;
1681 }
1682 if (found.type === 'Identifier') {
1683 annotation.value.authoritative = false;
1684 return annotation.value;
1685 }
1686 }
1687
1688 function keyByName(node, name) {
1689 if (!node.properties) {
1690 return;
1691 }
1692 var _iteratorNormalCompletion8 = true;
1693 var _didIteratorError8 = false;
1694 var _iteratorError8 = undefined;
1695
1696 try {
1697 for (var _iterator8 = node.properties[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
1698 var prop = _step8.value;
1699
1700 if (prop.key && prop.key.name === name) {
1701 return prop;
1702 }
1703 }
1704 } catch (err) {
1705 _didIteratorError8 = true;
1706 _iteratorError8 = err;
1707 } finally {
1708 try {
1709 if (!_iteratorNormalCompletion8 && _iterator8.return) {
1710 _iterator8.return();
1711 }
1712 } finally {
1713 if (_didIteratorError8) {
1714 throw _iteratorError8;
1715 }
1716 }
1717 }
1718 }
1719
1720 function valueByName(node, name) {
1721 if (!node.properties) {
1722 return;
1723 }
1724 var _iteratorNormalCompletion9 = true;
1725 var _didIteratorError9 = false;
1726 var _iteratorError9 = undefined;
1727
1728 try {
1729 for (var _iterator9 = node.properties[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
1730 var prop = _step9.value;
1731
1732 if (prop.value && prop.value.name === name) {
1733 return prop;
1734 }
1735 }
1736 } catch (err) {
1737 _didIteratorError9 = true;
1738 _iteratorError9 = err;
1739 } finally {
1740 try {
1741 if (!_iteratorNormalCompletion9 && _iterator9.return) {
1742 _iterator9.return();
1743 }
1744 } finally {
1745 if (_didIteratorError9) {
1746 throw _iteratorError9;
1747 }
1748 }
1749 }
1750 }
1751
1752 function getSpreadPropertyAnnotation(path) {
1753 var node = path.node;
1754
1755 var annotation = node.typeAnnotation || node.savedTypeAnnotation;
1756 if (!annotation) {
1757 annotation = getAnnotation(path.get('argument'));
1758 }
1759 return annotation;
1760 }
1761
1762 function getObjectPropertyAnnotation(path) {
1763 var node = path.node;
1764
1765 var annotation = node.typeAnnotation || node.savedTypeAnnotation;
1766 if (!annotation) {
1767 if (node.value) {
1768 annotation = node.value.typeAnnotation || node.value.savedTypeAnnotation || t.anyTypeAnnotation();
1769 } else {
1770 annotation = t.anyTypeAnnotation();
1771 }
1772 }
1773 return t.objectTypeProperty(node.key, annotation);
1774 }
1775
1776 function getObjectMethodAnnotation(path) {
1777 var node = path.node;
1778
1779 return t.objectTypeProperty(t.identifier(node.key.name), t.functionTypeAnnotation(null, node.params.map(function (param) {
1780 return param.savedTypeAnnotation || param.typeAnnotation;
1781 }), null, node.savedTypeAnnotation || node.returnType || node.typeAnnotation || t.anyTypeAnnotation()));
1782 }
1783
1784 function getThisExpressionAnnotation(path) {
1785 var parent = path.parentPath;
1786 loop: while (parent) {
1787 switch (parent.type) {
1788 case 'ClassDeclaration':
1789 return getAnnotation(parent);
1790 case 'ClassBody':
1791 return getAnnotation(parent.parentPath);
1792 case 'ClassMethod':
1793 case 'ClassProperty':
1794 return getAnnotation(parent.parentPath.parentPath);
1795 case 'ObjectProperty':
1796 return getAnnotation(parent.parentPath);
1797 case 'ObjectMethod':
1798 return getAnnotation(parent.parentPath);
1799 case 'FunctionExpression':
1800 if (parent.parentPath.type === 'ObjectProperty') {
1801 return getAnnotation(parent.parentPath.parentPath);
1802 }
1803 break loop;
1804 case 'ArrowFunctionExpression':
1805 parent = parent.parentPath;
1806 continue;
1807 }
1808 if (parent.isFunction()) {
1809 break;
1810 }
1811 parent = parent.parentPath;
1812 }
1813 return t.objectTypeAnnotation([]);
1814 }
1815
1816 function getClassDeclarationAnnotation(path) {
1817 var body = path.get('body').get('body').map(getAnnotation).filter(function (annotation) {
1818 return annotation && annotation.type !== 'AnyTypeAnnotation';
1819 });
1820 return t.objectTypeAnnotation(body);
1821 }
1822
1823 function getAssignmentExpressionAnnotation(path) {
1824 if (path.node.operator === '=') {
1825 return getAnnotation(path.get('right'));
1826 }
1827 }
1828
1829 function getClassPropertyAnnotation(path) {
1830 var node = path.node;
1831
1832 if (node.computed) {
1833 return;
1834 }
1835 var annotation = node.typeAnnotation || (node.value ? node.value.savedTypeAnnotation || node.value.typeAnnotation : t.anyTypeAnnotation());
1836 return t.objectTypeProperty(node.key, annotation || t.anyTypeAnnotation());
1837 }
1838
1839 function getClassMethodAnnotation(path) {
1840 var node = path.node;
1841
1842 if (node.computed) {
1843 return;
1844 }
1845 if (node.kind === 'get') {
1846 return t.objectTypeProperty(node.key, node.savedTypeAnnotation || node.returnType || node.typeAnnotation || t.anyTypeAnnotation());
1847 } else if (node.kind === 'set') {
1848 return t.objectTypeProperty(node.key, node.params.map(function (param) {
1849 return param.savedTypeAnnotation || param.typeAnnotation;
1850 }).shift() || t.anyTypeAnnotation());
1851 } else {
1852 return t.objectTypeProperty(node.key, t.functionTypeAnnotation(null, node.params.map(function (param) {
1853 return param.savedTypeAnnotation || param.typeAnnotation || t.anyTypeAnnotation();
1854 }), null, node.savedTypeAnnotation || node.returnType || node.typeAnnotation || t.anyTypeAnnotation()));
1855 }
1856 }
1857
1858 function getBinaryExpressionAnnotation(path) {
1859 var node = path.node;
1860
1861 if (isBooleanExpression(node)) {
1862 return t.booleanTypeAnnotation();
1863 } else {
1864 return t.anyTypeAnnotation();
1865 }
1866 }
1867
1868 function getLogicalExpressionAnnotation(path) {
1869 var node = path.node;
1870
1871 if (isBooleanExpression(node)) {
1872 return t.booleanTypeAnnotation();
1873 } else {
1874 var left = path.get('left');
1875 var right = path.get('right');
1876 switch (node.operator) {
1877 case '&&':
1878 case '||':
1879 var _ref25 = [getAnnotation(left), getAnnotation(right)];
1880 left = _ref25[0];
1881 right = _ref25[1];
1882
1883 if (t.isUnionTypeAnnotation(left)) {
1884 if (t.isUnionTypeAnnotation(right)) {
1885 return t.unionTypeAnnotation(left.types.concat(right.types));
1886 } else {
1887 return t.unionTypeAnnotation(left.types.concat(right));
1888 }
1889 } else {
1890 return t.unionTypeAnnotation([left, right]);
1891 }
1892 }
1893 return t.anyTypeAnnotation();
1894 }
1895 }
1896
1897 function getConditionalExpressionAnnotation(path) {
1898 var node = path.node;
1899
1900 var consequent = getAnnotation(path.get('consequent'));
1901 var alternate = getAnnotation(path.get('alternate'));
1902 if (t.isUnionTypeAnnotation(consequent)) {
1903 if (t.isUnionTypeAnnotation(alternate)) {
1904 return t.unionTypeAnnotation(consequent.types.concat(alternate.types));
1905 } else {
1906 return t.unionTypeAnnotation(consequent.types.concat(alternate));
1907 }
1908 } else {
1909 return t.unionTypeAnnotation([consequent, alternate]);
1910 }
1911 }
1912
1913 function getArrayExpressionAnnotation(path) {
1914 return t.genericTypeAnnotation(t.identifier('Array'), t.typeParameterDeclaration(path.get('elements').map(getAnnotation)));
1915 }
1916
1917 function getObjectExpressionAnnotation(path) {
1918 var annotation = t.objectTypeAnnotation(path.get('properties').filter(function (prop) {
1919 return !prop.node.computed;
1920 }).map(getAnnotation).reduce(function (properties, prop) {
1921 if (t.isObjectTypeProperty(prop)) {
1922 properties.push(prop);
1923 } else if (t.isObjectTypeAnnotation(prop)) {
1924 properties.push.apply(properties, _toConsumableArray(prop.properties));
1925 }
1926 return properties;
1927 }, []).filter(function (annotation) {
1928 return !t.isAnyTypeAnnotation(annotation.value);
1929 }));
1930 return annotation;
1931 }
1932
1933 function getMemberExpressionAnnotation(path) {
1934 if (path.node.computed) {
1935 return getComputedMemberExpressionAnnotation(path);
1936 }
1937 var stack = [];
1938 var target = path;
1939 while (target.isMemberExpression()) {
1940 stack.push(target);
1941 if (target.node.computed) {
1942 break;
1943 }
1944 target = target.get('object');
1945 }
1946 var objectAnnotation = stack.reduceRight(function (last, target) {
1947 var annotation = last;
1948 if (annotation == null) {
1949 if (stack.length === 1) {
1950 annotation = getAnnotation(target.get('object'));
1951 } else {
1952 return getAnnotation(target);
1953 }
1954 }
1955
1956 switch (annotation.type) {
1957 case 'AnyTypeAnnotation':
1958 return annotation;
1959 case 'NullableTypeAnnotation':
1960 case 'TypeAnnotation':
1961 annotation = annotation.typeAnnotation;
1962 }
1963
1964 if (annotation.type === 'GenericTypeAnnotation') {
1965 var typeChecker = getTypeChecker(annotation.id, path.scope);
1966 if (typeChecker) {
1967 annotation = getAnnotation(typeChecker);
1968 } else {
1969 var binding = path.scope.getBinding(annotation.id.name);
1970 if (binding) {
1971 annotation = getAnnotation(binding.path);
1972 }
1973 }
1974 }
1975 switch (annotation.type) {
1976 case 'AnyTypeAnnotation':
1977 return annotation;
1978 case 'ObjectTypeAnnotation':
1979 var id = target.get('property').node;
1980 var _iteratorNormalCompletion10 = true;
1981 var _didIteratorError10 = false;
1982 var _iteratorError10 = undefined;
1983
1984 try {
1985 for (var _iterator10 = (annotation.properties || [])[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
1986 var _step10$value = _step10.value;
1987 var key = _step10$value.key;
1988 var value = _step10$value.value;
1989
1990 if (key.name === id.name) {
1991 return value.type === 'VoidTypeAnnotation' ? t.anyTypeAnnotation() : value;
1992 }
1993 }
1994 } catch (err) {
1995 _didIteratorError10 = true;
1996 _iteratorError10 = err;
1997 } finally {
1998 try {
1999 if (!_iteratorNormalCompletion10 && _iterator10.return) {
2000 _iterator10.return();
2001 }
2002 } finally {
2003 if (_didIteratorError10) {
2004 throw _iteratorError10;
2005 }
2006 }
2007 }
2008
2009 }
2010 return t.anyTypeAnnotation();
2011 }, null);
2012
2013 return objectAnnotation || path.getTypeAnnotation();
2014 }
2015
2016 function getComputedMemberExpressionAnnotation(path) {
2017 var object = path.get('object');
2018 var property = path.get('property');
2019 var objectAnnotation = getAnnotation(object);
2020 if (objectAnnotation.type === 'TypeAnnotation' || objectAnnotation.type === 'NullableTypeAnnotation') {
2021 objectAnnotation = objectAnnotation.typeAnnotation;
2022 }
2023 var propertyAnnotation = getAnnotation(property);
2024 if (propertyAnnotation.type === 'TypeAnnotation' || propertyAnnotation.type === 'NullableTypeAnnotation') {
2025 propertyAnnotation = propertyAnnotation.typeAnnotation;
2026 }
2027
2028 var _property$evaluate = property.evaluate();
2029
2030 var confident = _property$evaluate.confident;
2031 var value = _property$evaluate.value;
2032
2033 if (!confident) {
2034 return path.getTypeAnnotation();
2035 }
2036 switch (objectAnnotation.type) {
2037 case 'TupleTypeAnnotation':
2038 if (objectAnnotation.types.length === 0) {
2039 break;
2040 } else if (typeof value === 'number') {
2041 if (!objectAnnotation.types[value]) {
2042 throw path.buildCodeFrameError('Invalid computed member expression for tuple: ' + humanReadableType(objectAnnotation));
2043 }
2044 return objectAnnotation.types[value];
2045 } else {
2046 throw path.buildCodeFrameError('Invalid computed member expression for tuple: ' + humanReadableType(objectAnnotation));
2047 }
2048 break;
2049 }
2050 return path.getTypeAnnotation();
2051 }
2052
2053 function getFunctionForIdentifier(path) {
2054 if (path.type !== 'Identifier') {
2055 return false;
2056 }
2057 var ref = path.scope.getBinding(path.node.name);
2058 if (!ref) {
2059 return false;
2060 }
2061 return t.isFunction(ref.path.parent) && ref.path.parentPath;
2062 }
2063
2064 /**
2065 * Returns `true` if the annotation is definitely for an array,
2066 * otherwise `false`.
2067 */
2068 function isStrictlyArrayAnnotation(annotation) {
2069 switch (annotation.type) {
2070 case 'TypeAnnotation':
2071 case 'FunctionTypeParam':
2072 return isStrictlyArrayAnnotation(annotation.typeAnnotation);
2073 case 'GenericTypeAnnotation':
2074 return annotation.id.name === 'Array';
2075 case 'UnionTypeAnnotation':
2076 return annotation.types.every(isStrictlyArrayAnnotation);
2077 default:
2078 return false;
2079 }
2080 }
2081
2082 function compareMaybeUnion(annotation, comparator) {
2083 var falseCount = 0;
2084 var _iteratorNormalCompletion11 = true;
2085 var _didIteratorError11 = false;
2086 var _iteratorError11 = undefined;
2087
2088 try {
2089 for (var _iterator11 = annotation.types[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
2090 var _type5 = _step11.value;
2091
2092 var result = comparator(_type5);
2093 if (result === true) {
2094 return true;
2095 } else if (result === false) {
2096 falseCount++;
2097 }
2098 }
2099 } catch (err) {
2100 _didIteratorError11 = true;
2101 _iteratorError11 = err;
2102 } finally {
2103 try {
2104 if (!_iteratorNormalCompletion11 && _iterator11.return) {
2105 _iterator11.return();
2106 }
2107 } finally {
2108 if (_didIteratorError11) {
2109 throw _iteratorError11;
2110 }
2111 }
2112 }
2113
2114 if (falseCount === annotation.types.length) {
2115 return false;
2116 } else {
2117 return null;
2118 }
2119 }
2120
2121 /**
2122 * Returns `true` if the annotation is compatible with a number,
2123 * `false` if it definitely isn't, or `null` if we're not sure.
2124 */
2125 function maybeNumberAnnotation(annotation) {
2126 switch (annotation.type) {
2127 case 'TypeAnnotation':
2128 case 'FunctionTypeParam':
2129 case 'NullableTypeAnnotation':
2130 return maybeNumberAnnotation(annotation.typeAnnotation);
2131 case 'NumberTypeAnnotation':
2132 case 'NumericLiteralTypeAnnotation':
2133 return true;
2134 case 'GenericTypeAnnotation':
2135 switch (annotation.id.name) {
2136 case 'Array':
2137 case 'Function':
2138 case 'Object':
2139 case 'String':
2140 case 'Boolean':
2141 case 'Date':
2142 case 'RegExp':
2143 return false;
2144 default:
2145 return null;
2146 }
2147 case 'UnionTypeAnnotation':
2148 return compareMaybeUnion(annotation, maybeNumberAnnotation);
2149 case 'AnyTypeAnnotation':
2150 case 'MixedTypeAnnotation':
2151 case 'IntersectionTypeAnnotation':
2152 return null;
2153 default:
2154 return false;
2155 }
2156 }
2157
2158 /**
2159 * Returns `true` if the annotation is compatible with a string,
2160 * `false` if it definitely isn't, or `null` if we're not sure.
2161 */
2162 function maybeStringAnnotation(annotation) {
2163 switch (annotation.type) {
2164 case 'TypeAnnotation':
2165 case 'FunctionTypeParam':
2166 case 'NullableTypeAnnotation':
2167 return maybeStringAnnotation(annotation.typeAnnotation);
2168 case 'StringTypeAnnotation':
2169 return true;
2170 case 'StringLiteralTypeAnnotation':
2171 return null;
2172 case 'GenericTypeAnnotation':
2173 switch (annotation.id.name) {
2174 case 'Array':
2175 case 'Function':
2176 case 'Object':
2177 case 'Number':
2178 case 'Boolean':
2179 case 'Date':
2180 case 'RegExp':
2181 return false;
2182 default:
2183 return null;
2184 }
2185 case 'UnionTypeAnnotation':
2186 var falseCount = 0;
2187 var _iteratorNormalCompletion12 = true;
2188 var _didIteratorError12 = false;
2189 var _iteratorError12 = undefined;
2190
2191 try {
2192 for (var _iterator12 = annotation.types[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
2193 var _type6 = _step12.value;
2194
2195 var result = maybeStringAnnotation(_type6);
2196 if (result === true) {
2197 return true;
2198 } else if (result === false) {
2199 falseCount++;
2200 }
2201 }
2202 } catch (err) {
2203 _didIteratorError12 = true;
2204 _iteratorError12 = err;
2205 } finally {
2206 try {
2207 if (!_iteratorNormalCompletion12 && _iterator12.return) {
2208 _iterator12.return();
2209 }
2210 } finally {
2211 if (_didIteratorError12) {
2212 throw _iteratorError12;
2213 }
2214 }
2215 }
2216
2217 if (falseCount === annotation.types.length) {
2218 return false;
2219 } else {
2220 return null;
2221 }
2222 case 'AnyTypeAnnotation':
2223 case 'MixedTypeAnnotation':
2224 case 'IntersectionTypeAnnotation':
2225 return null;
2226 default:
2227 return false;
2228 }
2229 }
2230
2231 /**
2232 * Returns `true` if the annotation is compatible with a symbol,
2233 * `false` if it definitely isn't, or `null` if we're not sure.
2234 */
2235 function maybeSymbolAnnotation(annotation) {
2236 switch (annotation.type) {
2237 case 'TypeAnnotation':
2238 case 'FunctionTypeParam':
2239 case 'NullableTypeAnnotation':
2240 return maybeSymbolAnnotation(annotation.typeAnnotation);
2241 case 'GenericTypeAnnotation':
2242 switch (annotation.id.name) {
2243 case 'Array':
2244 case 'Function':
2245 case 'Object':
2246 case 'Number':
2247 case 'Boolean':
2248 case 'Date':
2249 case 'RegExp':
2250 return false;
2251 case 'Symbol':
2252 return true;
2253 default:
2254 return null;
2255 }
2256 case 'UnionTypeAnnotation':
2257 var falseCount = 0;
2258 var _iteratorNormalCompletion13 = true;
2259 var _didIteratorError13 = false;
2260 var _iteratorError13 = undefined;
2261
2262 try {
2263 for (var _iterator13 = annotation.types[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
2264 var _type7 = _step13.value;
2265
2266 var result = maybeSymbolAnnotation(_type7);
2267 if (result === true) {
2268 return true;
2269 } else if (result === false) {
2270 falseCount++;
2271 }
2272 }
2273 } catch (err) {
2274 _didIteratorError13 = true;
2275 _iteratorError13 = err;
2276 } finally {
2277 try {
2278 if (!_iteratorNormalCompletion13 && _iterator13.return) {
2279 _iterator13.return();
2280 }
2281 } finally {
2282 if (_didIteratorError13) {
2283 throw _iteratorError13;
2284 }
2285 }
2286 }
2287
2288 if (falseCount === annotation.types.length) {
2289 return false;
2290 } else {
2291 return null;
2292 }
2293 case 'AnyTypeAnnotation':
2294 case 'MixedTypeAnnotation':
2295 case 'IntersectionTypeAnnotation':
2296 return null;
2297 default:
2298 return false;
2299 }
2300 }
2301
2302 /**
2303 * Returns `true` if the annotation is compatible with a boolean,
2304 * `false` if it definitely isn't, or `null` if we're not sure.
2305 */
2306 function maybeBooleanAnnotation(annotation) {
2307 switch (annotation.type) {
2308 case 'TypeAnnotation':
2309 case 'FunctionTypeParam':
2310 case 'NullableTypeAnnotation':
2311 return maybeBooleanAnnotation(annotation.typeAnnotation);
2312 case 'BooleanTypeAnnotation':
2313 case 'BooleanLiteralTypeAnnotation':
2314 return true;
2315 case 'GenericTypeAnnotation':
2316 switch (annotation.id.name) {
2317 case 'Array':
2318 case 'Function':
2319 case 'Object':
2320 case 'String':
2321 case 'Number':
2322 case 'Date':
2323 case 'RegExp':
2324 return false;
2325 default:
2326 return null;
2327 }
2328 case 'UnionTypeAnnotation':
2329 var falseCount = 0;
2330 var _iteratorNormalCompletion14 = true;
2331 var _didIteratorError14 = false;
2332 var _iteratorError14 = undefined;
2333
2334 try {
2335 for (var _iterator14 = annotation.types[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
2336 var _type8 = _step14.value;
2337
2338 var result = maybeBooleanAnnotation(_type8);
2339 if (result === true) {
2340 return true;
2341 } else if (result === false) {
2342 falseCount++;
2343 }
2344 }
2345 } catch (err) {
2346 _didIteratorError14 = true;
2347 _iteratorError14 = err;
2348 } finally {
2349 try {
2350 if (!_iteratorNormalCompletion14 && _iterator14.return) {
2351 _iterator14.return();
2352 }
2353 } finally {
2354 if (_didIteratorError14) {
2355 throw _iteratorError14;
2356 }
2357 }
2358 }
2359
2360 if (falseCount === annotation.types.length) {
2361 return false;
2362 } else {
2363 return null;
2364 }
2365 case 'AnyTypeAnnotation':
2366 case 'MixedTypeAnnotation':
2367 case 'IntersectionTypeAnnotation':
2368 return null;
2369 default:
2370 return false;
2371 }
2372 }
2373
2374 /**
2375 * Returns `true` if the annotation is compatible with a function,
2376 * `false` if it definitely isn't, or `null` if we're not sure.
2377 */
2378 function maybeFunctionAnnotation(annotation) {
2379 switch (annotation.type) {
2380 case 'TypeAnnotation':
2381 case 'FunctionTypeParam':
2382 case 'NullableTypeAnnotation':
2383 return maybeFunctionAnnotation(annotation.typeAnnotation);
2384 case 'FunctionTypeAnnotation':
2385 return true;
2386 case 'GenericTypeAnnotation':
2387 switch (annotation.id.name) {
2388 case 'Array':
2389 case 'Number':
2390 case 'Object':
2391 case 'String':
2392 case 'Boolean':
2393 case 'Date':
2394 case 'RegExp':
2395 return false;
2396 default:
2397 return null;
2398 }
2399 case 'UnionTypeAnnotation':
2400 var falseCount = 0;
2401 var _iteratorNormalCompletion15 = true;
2402 var _didIteratorError15 = false;
2403 var _iteratorError15 = undefined;
2404
2405 try {
2406 for (var _iterator15 = annotation.types[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
2407 var _type9 = _step15.value;
2408
2409 var result = maybeFunctionAnnotation(_type9);
2410 if (result === true) {
2411 return true;
2412 } else if (result === false) {
2413 falseCount++;
2414 }
2415 }
2416 } catch (err) {
2417 _didIteratorError15 = true;
2418 _iteratorError15 = err;
2419 } finally {
2420 try {
2421 if (!_iteratorNormalCompletion15 && _iterator15.return) {
2422 _iterator15.return();
2423 }
2424 } finally {
2425 if (_didIteratorError15) {
2426 throw _iteratorError15;
2427 }
2428 }
2429 }
2430
2431 if (falseCount === annotation.types.length) {
2432 return false;
2433 } else {
2434 return null;
2435 }
2436 case 'AnyTypeAnnotation':
2437 case 'MixedTypeAnnotation':
2438 case 'IntersectionTypeAnnotation':
2439 return null;
2440 default:
2441 return false;
2442 }
2443 }
2444
2445 /**
2446 * Returns `true` if the annotation is compatible with an undefined or null type,
2447 * `false` if it definitely isn't, or `null` if we're not sure.
2448 */
2449 function maybeNullableAnnotation(annotation) {
2450 switch (annotation.type) {
2451 case 'NullableTypeAnnotation':
2452 case 'VoidTypeAnnotation':
2453 case 'MixedTypeAnnotation':
2454 return true;
2455 case 'TypeAnnotation':
2456 case 'FunctionTypeParam':
2457 return maybeNullableAnnotation(annotation.typeAnnotation);
2458 case 'GenericTypeAnnotation':
2459 switch (annotation.id.name) {
2460 case 'Array':
2461 case 'Number':
2462 case 'Object':
2463 case 'String':
2464 case 'Boolean':
2465 case 'Date':
2466 case 'RegExp':
2467 return false;
2468 case 'Generator':
2469 if (annotation.typeParameters && annotation.typeParameters.params.length > 1) {
2470 return maybeNullableAnnotation(annotation.typeParameters.params[1]);
2471 } else {
2472 return null;
2473 }
2474 default:
2475 return null;
2476 }
2477 case 'UnionTypeAnnotation':
2478 var falseCount = 0;
2479 var _iteratorNormalCompletion16 = true;
2480 var _didIteratorError16 = false;
2481 var _iteratorError16 = undefined;
2482
2483 try {
2484 for (var _iterator16 = annotation.types[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) {
2485 var _type10 = _step16.value;
2486
2487 var result = maybeNullableAnnotation(_type10);
2488 if (result === true) {
2489 return true;
2490 } else if (result === false) {
2491 falseCount++;
2492 }
2493 }
2494 } catch (err) {
2495 _didIteratorError16 = true;
2496 _iteratorError16 = err;
2497 } finally {
2498 try {
2499 if (!_iteratorNormalCompletion16 && _iterator16.return) {
2500 _iterator16.return();
2501 }
2502 } finally {
2503 if (_didIteratorError16) {
2504 throw _iteratorError16;
2505 }
2506 }
2507 }
2508
2509 if (falseCount === annotation.types.length) {
2510 return false;
2511 } else {
2512 return null;
2513 }
2514 default:
2515 return false;
2516 }
2517 }
2518
2519 /**
2520 * Returns `true` if the annotation is compatible with an object type,
2521 * `false` if it definitely isn't, or `null` if we're not sure.
2522 */
2523 function maybeInstanceOfAnnotation(annotation, expected, typeParameters) {
2524 switch (annotation.type) {
2525 case 'TypeAnnotation':
2526 case 'FunctionTypeParam':
2527 case 'NullableTypeAnnotation':
2528 return maybeInstanceOfAnnotation(annotation.typeAnnotation, expected, typeParameters);
2529 case 'GenericTypeAnnotation':
2530 if (annotation.id.name === expected.name) {
2531 if (typeParameters.length === 0) {
2532 return true;
2533 }
2534 if (annotation.typeParameters && annotation.typeParameters.params.length) {
2535 var trueCount = 0;
2536 var nullCount = 0;
2537 for (var i = 0; i < typeParameters.length && i < annotation.typeParameters.params.length; i++) {
2538 var result = compareAnnotations(typeParameters[i], annotation.typeParameters.params[i]);
2539 if (result === false) {
2540 return false;
2541 } else if (result === true) {
2542 trueCount++;
2543 } else {
2544 nullCount++;
2545 }
2546 }
2547 return trueCount > 0 && nullCount === 0 ? true : null;
2548 }
2549 }
2550 return null;
2551 case 'UnionTypeAnnotation':
2552 var falseCount = 0;
2553 var _iteratorNormalCompletion17 = true;
2554 var _didIteratorError17 = false;
2555 var _iteratorError17 = undefined;
2556
2557 try {
2558 for (var _iterator17 = annotation.types[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) {
2559 var _type11 = _step17.value;
2560
2561 var result = maybeInstanceOfAnnotation(_type11, expected, typeParameters);
2562 if (result === true) {
2563 return true;
2564 } else if (result === false) {
2565 falseCount++;
2566 }
2567 }
2568 } catch (err) {
2569 _didIteratorError17 = true;
2570 _iteratorError17 = err;
2571 } finally {
2572 try {
2573 if (!_iteratorNormalCompletion17 && _iterator17.return) {
2574 _iterator17.return();
2575 }
2576 } finally {
2577 if (_didIteratorError17) {
2578 throw _iteratorError17;
2579 }
2580 }
2581 }
2582
2583 if (falseCount === annotation.types.length) {
2584 return false;
2585 } else {
2586 return null;
2587 }
2588 case 'VoidTypeAnnotation':
2589 case 'BooleanTypeAnnotation':
2590 case 'BooleanLiteralTypeAnnotation':
2591 case 'StringTypeAnnotation':
2592 case 'StringLiteralTypeAnnotation':
2593 case 'NumberTypeAnnotation':
2594 case 'NumericLiteralTypeAnnotation':
2595 case 'FunctionTypeAnnotation':
2596 return false;
2597 default:
2598 return null;
2599 }
2600 }
2601
2602 /**
2603 * Returns `true` if the annotation is compatible with an array,
2604 * `false` if it definitely isn't, or `null` if we're not sure.
2605 */
2606 function maybeArrayAnnotation(annotation) {
2607 switch (annotation.type) {
2608 case 'TypeAnnotation':
2609 case 'FunctionTypeParam':
2610 case 'NullableTypeAnnotation':
2611 return maybeArrayAnnotation(annotation.typeAnnotation);
2612 case 'TupleTypeAnnotation':
2613 case 'ArrayTypeAnnotation':
2614 return true;
2615 case 'GenericTypeAnnotation':
2616 return annotation.id.name === 'Array' ? true : null;
2617 case 'UnionTypeAnnotation':
2618 var falseCount = 0;
2619 var _iteratorNormalCompletion18 = true;
2620 var _didIteratorError18 = false;
2621 var _iteratorError18 = undefined;
2622
2623 try {
2624 for (var _iterator18 = annotation.types[Symbol.iterator](), _step18; !(_iteratorNormalCompletion18 = (_step18 = _iterator18.next()).done); _iteratorNormalCompletion18 = true) {
2625 var _type12 = _step18.value;
2626
2627 var result = maybeArrayAnnotation(_type12);
2628 if (result === true) {
2629 return true;
2630 } else if (result === false) {
2631 falseCount++;
2632 }
2633 }
2634 } catch (err) {
2635 _didIteratorError18 = true;
2636 _iteratorError18 = err;
2637 } finally {
2638 try {
2639 if (!_iteratorNormalCompletion18 && _iterator18.return) {
2640 _iterator18.return();
2641 }
2642 } finally {
2643 if (_didIteratorError18) {
2644 throw _iteratorError18;
2645 }
2646 }
2647 }
2648
2649 if (falseCount === annotation.types.length) {
2650 return false;
2651 } else {
2652 return null;
2653 }
2654 case 'AnyTypeAnnotation':
2655 case 'MixedTypeAnnotation':
2656 case 'IntersectionTypeAnnotation':
2657 return null;
2658 default:
2659 return false;
2660 }
2661 }
2662
2663 /**
2664 * Returns `true` if the annotation is compatible with an iterable,
2665 * `false` if it definitely isn't, or `null` if we're not sure.
2666 */
2667 function maybeIterableAnnotation(annotation) {
2668 switch (annotation.type) {
2669 case 'TypeAnnotation':
2670 case 'FunctionTypeParam':
2671 case 'NullableTypeAnnotation':
2672 return maybeIterableAnnotation(annotation.typeAnnotation);
2673 case 'TupleTypeAnnotation':
2674 case 'ArrayTypeAnnotation':
2675 return true;
2676 case 'GenericTypeAnnotation':
2677 return annotation.id.name === 'Iterable' ? true : null;
2678 case 'UnionTypeAnnotation':
2679 var falseCount = 0;
2680 var _iteratorNormalCompletion19 = true;
2681 var _didIteratorError19 = false;
2682 var _iteratorError19 = undefined;
2683
2684 try {
2685 for (var _iterator19 = annotation.types[Symbol.iterator](), _step19; !(_iteratorNormalCompletion19 = (_step19 = _iterator19.next()).done); _iteratorNormalCompletion19 = true) {
2686 var _type13 = _step19.value;
2687
2688 var result = maybeIterableAnnotation(_type13);
2689 if (result === true) {
2690 return true;
2691 } else if (result === false) {
2692 falseCount++;
2693 }
2694 }
2695 } catch (err) {
2696 _didIteratorError19 = true;
2697 _iteratorError19 = err;
2698 } finally {
2699 try {
2700 if (!_iteratorNormalCompletion19 && _iterator19.return) {
2701 _iterator19.return();
2702 }
2703 } finally {
2704 if (_didIteratorError19) {
2705 throw _iteratorError19;
2706 }
2707 }
2708 }
2709
2710 if (falseCount === annotation.types.length) {
2711 return false;
2712 } else {
2713 return null;
2714 }
2715 case 'BooleanTypeAnnotation':
2716 case 'BooleanLiteralTypeAnnotation':
2717 case 'NumericLiteralTypeAnnotation':
2718 case 'NumberTypeAnnotation':
2719 case 'VoidTypeAnnotation':
2720 return false;
2721 default:
2722 return null;
2723 }
2724 }
2725
2726 /**
2727 * Returns `true` if the annotation is compatible with a tuple,
2728 * `false` if it definitely isn't, or `null` if we're not sure.
2729 */
2730 function maybeTupleAnnotation(annotation) {
2731 switch (annotation.type) {
2732 case 'TypeAnnotation':
2733 case 'FunctionTypeParam':
2734 case 'NullableTypeAnnotation':
2735 return maybeTupleAnnotation(annotation.typeAnnotation);
2736 case 'TupleTypeAnnotation':
2737 return true;
2738 case 'UnionTypeAnnotation':
2739 var falseCount = 0;
2740 var _iteratorNormalCompletion20 = true;
2741 var _didIteratorError20 = false;
2742 var _iteratorError20 = undefined;
2743
2744 try {
2745 for (var _iterator20 = annotation.types[Symbol.iterator](), _step20; !(_iteratorNormalCompletion20 = (_step20 = _iterator20.next()).done); _iteratorNormalCompletion20 = true) {
2746 var _type14 = _step20.value;
2747
2748 var result = maybeTupleAnnotation(_type14);
2749 if (result === true) {
2750 return true;
2751 } else if (result === false) {
2752 falseCount++;
2753 }
2754 }
2755 } catch (err) {
2756 _didIteratorError20 = true;
2757 _iteratorError20 = err;
2758 } finally {
2759 try {
2760 if (!_iteratorNormalCompletion20 && _iterator20.return) {
2761 _iterator20.return();
2762 }
2763 } finally {
2764 if (_didIteratorError20) {
2765 throw _iteratorError20;
2766 }
2767 }
2768 }
2769
2770 if (falseCount === annotation.types.length) {
2771 return false;
2772 } else {
2773 return null;
2774 }
2775 case 'GenericTypeAnnotation':
2776 case 'AnyTypeAnnotation':
2777 case 'ArrayTypeAnnotation':
2778 case 'MixedTypeAnnotation':
2779 case 'IntersectionTypeAnnotation':
2780 return null;
2781 default:
2782 return false;
2783 }
2784 }
2785
2786 function humanReadableType(annotation) {
2787 switch (annotation.type) {
2788 case 'TypeAnnotation':
2789 case 'FunctionTypeParam':
2790 return humanReadableType(annotation.typeAnnotation);
2791
2792 case 'FunctionTypeAnnotation':
2793 // @fixme babel doesn't seem to like generating FunctionTypeAnnotations yet
2794 return '(' + annotation.params.map(humanReadableType).join(', ') + ') => ' + humanReadableType(annotation.returnType);
2795 default:
2796 return (0, _babelGenerator2.default)(annotation).code;
2797 }
2798 }
2799
2800 function getTypeChecker(id, scope) {
2801 var binding = scope.getBinding(id.name);
2802 if (binding === undefined) {
2803 return false;
2804 }
2805 var path = binding.path;
2806
2807 if (path == null) {
2808 return false;
2809 } else if (path.type === 'TypeAlias') {
2810 return path;
2811 } else if (path.type === 'VariableDeclaration' && path.node.isTypeChecker) {
2812 return path.get('declarations')[0];
2813 } else if (path.isImportSpecifier() && path.parent.importKind === 'type') {
2814 return path;
2815 }
2816 return false;
2817 }
2818
2819 function isTypeChecker(id, scope) {
2820 var binding = scope.getBinding(id.name);
2821 if (binding === undefined) {
2822 return false;
2823 }
2824 var path = binding.path;
2825
2826 if (path == null) {
2827 return false;
2828 } else if (path.type === 'TypeAlias' || path.type === 'VariableDeclaration' && path.node.isTypeChecker) {
2829 return true;
2830 } else if (path.isImportSpecifier() && path.parent.importKind === 'type') {
2831 return true;
2832 }
2833 return false;
2834 }
2835
2836 function isPolymorphicType(id, scope) {
2837 var binding = scope.getBinding(id.name);
2838 if (binding !== undefined) {
2839 return false;
2840 }
2841 var path = scope.path;
2842
2843 while (path && path.type !== 'Program') {
2844 var _path = path;
2845 var _node = _path.node;
2846
2847 if ((t.isFunction(_node) || t.isClass(_node)) && _node.typeParameters) {
2848 var _iteratorNormalCompletion21 = true;
2849 var _didIteratorError21 = false;
2850 var _iteratorError21 = undefined;
2851
2852 try {
2853 for (var _iterator21 = _node.typeParameters.params[Symbol.iterator](), _step21; !(_iteratorNormalCompletion21 = (_step21 = _iterator21.next()).done); _iteratorNormalCompletion21 = true) {
2854 var param = _step21.value;
2855
2856 param.isPolymorphicType = true;
2857 if (param.name === id.name) {
2858 return true;
2859 }
2860 }
2861 } catch (err) {
2862 _didIteratorError21 = true;
2863 _iteratorError21 = err;
2864 } finally {
2865 try {
2866 if (!_iteratorNormalCompletion21 && _iterator21.return) {
2867 _iterator21.return();
2868 }
2869 } finally {
2870 if (_didIteratorError21) {
2871 throw _iteratorError21;
2872 }
2873 }
2874 }
2875 }
2876 path = path.parentPath;
2877 }
2878 return false;
2879 }
2880
2881 function getPolymorphicType(id, scope) {
2882 var binding = scope.getBinding(id.name);
2883 if (binding !== undefined) {
2884 return false;
2885 }
2886 var path = scope.path;
2887
2888 while (path && path.type !== 'Program') {
2889 var _path2 = path;
2890 var _node2 = _path2.node;
2891
2892 if (t.isFunction(_node2) && _node2.typeParameters) {
2893 var _iteratorNormalCompletion22 = true;
2894 var _didIteratorError22 = false;
2895 var _iteratorError22 = undefined;
2896
2897 try {
2898 for (var _iterator22 = _node2.typeParameters.params[Symbol.iterator](), _step22; !(_iteratorNormalCompletion22 = (_step22 = _iterator22.next()).done); _iteratorNormalCompletion22 = true) {
2899 var param = _step22.value;
2900
2901 param.isPolymorphicType = true;
2902 if (param.name === id.name) {
2903 return param;
2904 }
2905 }
2906 } catch (err) {
2907 _didIteratorError22 = true;
2908 _iteratorError22 = err;
2909 } finally {
2910 try {
2911 if (!_iteratorNormalCompletion22 && _iterator22.return) {
2912 _iterator22.return();
2913 }
2914 } finally {
2915 if (_didIteratorError22) {
2916 throw _iteratorError22;
2917 }
2918 }
2919 }
2920 }
2921 path = path.parent;
2922 }
2923 return null;
2924 }
2925
2926 function collectParamChecks(path) {
2927 return path.get('params').map(function (param) {
2928 var node = param.node;
2929
2930 if (node.type === 'AssignmentPattern') {
2931 if (node.left.typeAnnotation) {
2932 return createDefaultParamGuard(param);
2933 }
2934 } else if (node.type === 'RestElement') {
2935 if (node.typeAnnotation) {
2936 return createRestParamGuard(param);
2937 }
2938 } else if (node.typeAnnotation) {
2939 return createParamGuard(param);
2940 }
2941 }).filter(identity);
2942 }
2943
2944 function createParamGuard(path) {
2945 var node = path.node;
2946 var scope = path.scope;
2947
2948 node.hasBeenTypeChecked = true;
2949 node.savedTypeAnnotation = node.typeAnnotation;
2950 if (node.type === 'ObjectPattern') {
2951 return;
2952 }
2953 var check = checkAnnotation(node, node.typeAnnotation, scope);
2954 if (!check) {
2955 return;
2956 }
2957 if (node.optional) {
2958 check = t.logicalExpression('||', checks.undefined({ input: node }), check);
2959 }
2960 var message = paramTypeErrorMessage(node, scope);
2961 return guard({
2962 check: check,
2963 message: message
2964 });
2965 }
2966
2967 function createDefaultParamGuard(path) {
2968 var node = path.node;
2969 var scope = path.scope;
2970 var id = node.left;
2971 var value = node.right;
2972
2973 var ok = staticCheckAnnotation(path.get('right'), id.typeAnnotation);
2974 if (ok === false) {
2975 throw path.buildCodeFrameError('Invalid default value for argument "' + id.name + '", expected ' + humanReadableType(id.typeAnnotation) + '.');
2976 }
2977 return createParamGuard(path.get('left'));
2978 }
2979
2980 function createRestParamGuard(path) {
2981 var node = path.node;
2982 var scope = path.scope;
2983 var id = node.argument;
2984
2985 id.hasBeenTypeChecked = true;
2986 node.savedTypeAnnotation = node.typeAnnotation;
2987 if (!isStrictlyArrayAnnotation(node.typeAnnotation)) {
2988 throw path.buildCodeFrameError('Invalid type annotation for rest argument "' + id.name + '", expected an Array, got: ' + humanReadableType(node.typeAnnotation) + '.');
2989 }
2990 var check = checkAnnotation(id, node.typeAnnotation, scope);
2991 if (!check) {
2992 return;
2993 }
2994 if (node.optional) {
2995 check = t.logicalExpression('||', checks.undefined({ input: id }), check);
2996 }
2997 var message = paramTypeErrorMessage(id, scope, node.typeAnnotation);
2998 return guard({
2999 check: check,
3000 message: message
3001 });
3002 }
3003
3004 function returnTypeErrorMessage(path, fn, id) {
3005 var node = path.node;
3006 var scope = path.scope;
3007
3008 var name = fn.id ? fn.id.name : '';
3009 var annotation = fn.returnType;
3010 if (annotation.type === 'TypeAnnotation') {
3011 annotation = annotation.typeAnnotation;
3012 }
3013 if (fn.generator && isGeneratorAnnotation(annotation) && annotation.typeParameters && annotation.typeParameters.params.length > 1) {
3014 annotation = annotation.typeParameters.params[1];
3015 }
3016 var message = 'Function ' + (name ? '"' + name + '" ' : '') + 'return value violates contract, expected ' + humanReadableType(annotation) + ' got ';
3017
3018 return t.binaryExpression('+', t.stringLiteral(message), id ? readableName({ input: id }) : node.argument ? readableName({ input: node.argument }) : t.stringLiteral('undefined'));
3019 }
3020
3021 function yieldTypeErrorMessage(fn, annotation, id) {
3022 var name = fn.id ? fn.id.name : '';
3023 var message = 'Function ' + (name ? '"' + name + '" ' : '') + ' yielded an invalid value, expected ' + humanReadableType(annotation) + ' got ';
3024
3025 return t.binaryExpression('+', t.stringLiteral(message), readableName({ input: id }));
3026 }
3027 function yieldNextTypeErrorMessage(fn, annotation, id) {
3028 var name = fn.id ? fn.id.name : '';
3029 var message = 'Generator ' + (name ? '"' + name + '" ' : '') + 'received an invalid next value, expected ' + humanReadableType(annotation) + ' got ';
3030
3031 return t.binaryExpression('+', t.stringLiteral(message), readableName({ input: id }));
3032 }
3033
3034 function paramTypeErrorMessage(node, scope) {
3035 var typeAnnotation = arguments.length <= 2 || arguments[2] === undefined ? node.typeAnnotation : arguments[2];
3036
3037 var name = node.name;
3038 var message = 'Value of ' + (node.optional ? 'optional ' : '') + 'argument "' + name + '" violates contract, expected ' + humanReadableType(typeAnnotation) + ' got ';
3039
3040 return t.binaryExpression('+', t.stringLiteral(message), readableName({ input: node }));
3041 }
3042
3043 function varTypeErrorMessage(node, scope) {
3044 var annotation = arguments.length <= 2 || arguments[2] === undefined ? node.typeAnnotation : arguments[2];
3045
3046 if (node.type === 'Identifier') {
3047 var _name3 = node.name;
3048 var message = 'Value of variable "' + _name3 + '" violates contract, expected ' + humanReadableType(annotation) + ' got ';
3049 return t.binaryExpression('+', t.stringLiteral(message), readableName({ input: node }));
3050 } else {
3051 var message = 'Value of "' + (0, _babelGenerator2.default)(node).code + '" violates contract, expected ' + humanReadableType(annotation) + ' got ';
3052 return t.binaryExpression('+', t.stringLiteral(message), readableName({ input: node }));
3053 }
3054 }
3055
3056 /**
3057 * Determine whether the given node can produce purely boolean results.
3058 */
3059 function isBooleanExpression(node) {
3060 if (node.type === 'BinaryExpression' && BOOLEAN_BINARY_OPERATORS.indexOf(node.operator) > -1) {
3061 return true;
3062 } else if (node.type === 'LogicalExpression') {
3063 return isBooleanExpression(node.left) && isBooleanExpression(node.right);
3064 } else {
3065 return false;
3066 }
3067 }
3068
3069 /**
3070 * Convert type specifier to expression.
3071 */
3072 function createTypeExpression(node) {
3073 if (node.type == 'Identifier') {
3074 return node;
3075 } else if (node.type == 'QualifiedTypeIdentifier') {
3076 return t.memberExpression(createTypeExpression(node.qualification), createTypeExpression(node.id));
3077 }
3078
3079 throw this.errorWithNode('Unsupported type: ' + node.type);
3080 }
3081
3082 /**
3083 * Get name of a type as a string.
3084 */
3085 function getTypeName(node) {
3086 if (node.type == 'Identifier') {
3087 return node.name;
3088 } else if (node.type == 'QualifiedTypeIdentifier') {
3089 return getTypeName(node.qualification) + '.' + getTypeName(node.id);
3090 }
3091
3092 throw this.errorWithNode('Unsupported type: ' + node.type);
3093 }
3094
3095 /**
3096 * Union two arrays.
3097 */
3098 function union(arr1, arr2) {
3099 for (var i = 0; i < arr2.length; i++) {
3100 var item = arr2[i];
3101 if (arr1.indexOf(item) === -1) {
3102 arr1.push(item);
3103 }
3104 }
3105 return arr1;
3106 }
3107
3108 /**
3109 * Determine whether the given annotation allows any value.
3110 */
3111 function allowsAny(annotation) {
3112 if (annotation.type === 'TypeAnnotation' || annotation.type === 'NullableTypeAnnotation') {
3113 return allowsAny(annotation.typeAnnotation);
3114 } else if (annotation.type === 'AnyTypeAnnotation' || annotation.type === 'MixedTypeAnnotation') {
3115 return true;
3116 } else if (annotation.type === 'UnionTypeAnnotation') {
3117 return annotation.types.some(allowsAny);
3118 } else {
3119 return false;
3120 }
3121 }
3122
3123 /**
3124 * Determine whether a given node is nully (null or undefined).
3125 */
3126 function isNodeNully(node) {
3127 if (node == null) {
3128 return true;
3129 } else if (node.type === 'Identifier' && node.name === 'undefined') {
3130 return true;
3131 } else if (node.type === 'Literal' && node.value === null) {
3132 return true;
3133 } else if (node.type === 'UnaryExpression' && node.operator === 'void') {
3134 return true;
3135 } else {
3136 return false;
3137 }
3138 }
3139
3140 /**
3141 * Determine whether the file should be skipped, based on the comments attached to the given node.
3142 */
3143 function maybeSkipFile(path) {
3144 if (path.node.leadingComments && path.node.leadingComments.length) {
3145 return path.node.leadingComments.some(function (comment) {
3146 return PRAGMA_IGNORE_FILE.test(comment.value);
3147 });
3148 }
3149 return false;
3150 }
3151
3152 /**
3153 * Maybe skip the given path if it has a relevant pragma.
3154 */
3155 function maybeSkip(path) {
3156 var node = path.node;
3157
3158 if (node.hasBeenTypeChecked) {
3159 return true;
3160 }
3161 if (node.leadingComments && node.leadingComments.length) {
3162 var comment = node.leadingComments[node.leadingComments.length - 1];
3163 if (PRAGMA_IGNORE_STATEMENT.test(comment.value)) {
3164 path.skip();
3165 return true;
3166 }
3167 }
3168 return false;
3169 }
3170
3171 /**
3172 * A function that returns its first argument, useful when filtering.
3173 */
3174 function identity(input) {
3175 return input;
3176 }
3177
3178 function getExpression(node) {
3179 return t.isExpressionStatement(node) ? node.expression : node;
3180 }
3181
3182 function expression(input) {
3183 var fn = template(input);
3184 return function () {
3185 var node = fn.apply(undefined, arguments);
3186 return getExpression(node);
3187 };
3188 }
3189};
3190
3191var _babelGenerator = require('babel-generator');
3192
3193var _babelGenerator2 = _interopRequireDefault(_babelGenerator);
3194
3195function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
3196
3197function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
\No newline at end of file