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