UNPKG

3.92 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _lodash = require('lodash');
8
9var _lodash2 = _interopRequireDefault(_lodash);
10
11var _utilities = require('./../utilities');
12
13function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
15exports.default = function (context) {
16 var checkThisFile = !_lodash2.default.get(context, 'settings.flowtype.onlyFilesWithFlowAnnotation') || (0, _utilities.isFlowFile)(context);
17
18 if (!checkThisFile) {
19 return function () {};
20 }
21
22 var annotateReturn = (_lodash2.default.get(context, 'options[0]') || 'always') === 'always';
23 var annotateUndefined = (_lodash2.default.get(context, 'options[1].annotateUndefined') || 'never') === 'always';
24 var skipArrows = _lodash2.default.get(context, 'options[1].excludeArrowFunctions') || false;
25
26 var targetNodes = [];
27
28 var registerFunction = function registerFunction(functionNode) {
29 targetNodes.push({
30 functionNode: functionNode
31 });
32 };
33
34 var isUndefinedReturnType = function isUndefinedReturnType(returnNode) {
35 return returnNode.argument === null || returnNode.argument.name === 'undefined' || returnNode.argument.operator === 'void';
36 };
37
38 var getIsReturnTypeAnnotationUndefined = function getIsReturnTypeAnnotationUndefined(targetNode) {
39 var isReturnTypeAnnotationLiteralUndefined = _lodash2.default.get(targetNode, 'functionNode.returnType.typeAnnotation.id.name') === 'undefined' && _lodash2.default.get(targetNode, 'functionNode.returnType.typeAnnotation.type') === 'GenericTypeAnnotation';
40 var isReturnTypeAnnotationVoid = _lodash2.default.get(targetNode, 'functionNode.returnType.typeAnnotation.type') === 'VoidTypeAnnotation';
41
42 return isReturnTypeAnnotationLiteralUndefined || isReturnTypeAnnotationVoid;
43 };
44
45 var evaluateFunction = function evaluateFunction(functionNode) {
46 var targetNode = targetNodes.pop();
47
48 if (functionNode !== targetNode.functionNode) {
49 throw new Error('Mismatch.');
50 }
51
52 var isArrow = functionNode.type === 'ArrowFunctionExpression';
53 var isArrowFunctionExpression = functionNode.expression;
54 var hasImplicitReturnType = functionNode.async || functionNode.generator;
55 var isFunctionReturnUndefined = !isArrowFunctionExpression && !hasImplicitReturnType && (!targetNode.returnStatementNode || isUndefinedReturnType(targetNode.returnStatementNode));
56 var isReturnTypeAnnotationUndefined = getIsReturnTypeAnnotationUndefined(targetNode);
57
58 if (skipArrows === 'expressionsOnly' && isArrowFunctionExpression || skipArrows === true && isArrow) {
59 return;
60 }
61
62 if (isFunctionReturnUndefined && isReturnTypeAnnotationUndefined && !annotateUndefined) {
63 context.report(functionNode, 'Must not annotate undefined return type.');
64 } else if (isFunctionReturnUndefined && !isReturnTypeAnnotationUndefined && annotateUndefined) {
65 context.report(functionNode, 'Must annotate undefined return type.');
66 } else if (!isFunctionReturnUndefined && !isReturnTypeAnnotationUndefined) {
67 if (annotateReturn && !functionNode.returnType) {
68 context.report(functionNode, 'Missing return type annotation.');
69 }
70 }
71 };
72
73 var evaluateNoise = function evaluateNoise() {
74 targetNodes.pop();
75 };
76
77 return {
78 ArrowFunctionExpression: registerFunction,
79 'ArrowFunctionExpression:exit': evaluateFunction,
80 ClassDeclaration: registerFunction,
81 'ClassDeclaration:exit': evaluateNoise,
82 ClassExpression: registerFunction,
83 'ClassExpression:exit': evaluateNoise,
84 FunctionDeclaration: registerFunction,
85 'FunctionDeclaration:exit': evaluateFunction,
86 FunctionExpression: registerFunction,
87 'FunctionExpression:exit': evaluateFunction,
88 ReturnStatement: function ReturnStatement(node) {
89 targetNodes[targetNodes.length - 1].returnStatementNode = node;
90 }
91 };
92};
93
94module.exports = exports['default'];
\No newline at end of file