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