.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tslint / lib / rules / promiseFunctionAsyncRule.js
1 "use strict";
2 /**
3  * @license
4  * Copyright 2018 Palantir Technologies, Inc.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 Object.defineProperty(exports, "__esModule", { value: true });
19 var tslib_1 = require("tslib");
20 var _a;
21 var tsutils = require("tsutils");
22 var ts = require("typescript");
23 var Lint = require("../index");
24 var OPTION_FUNCTION_DECLARATION = "check-function-declaration";
25 var OPTION_FUNCTION_EXPRESSION = "check-function-expression";
26 var OPTION_ARROW_FUNCTION = "check-arrow-function";
27 var OPTION_METHOD_DECLARATION = "check-method-declaration";
28 var KIND_FOR_OPTION = (_a = {},
29     _a[OPTION_FUNCTION_DECLARATION] = ts.SyntaxKind.FunctionDeclaration,
30     _a[OPTION_FUNCTION_EXPRESSION] = ts.SyntaxKind.FunctionExpression,
31     _a[OPTION_ARROW_FUNCTION] = ts.SyntaxKind.ArrowFunction,
32     _a[OPTION_METHOD_DECLARATION] = ts.SyntaxKind.MethodDeclaration,
33     _a);
34 function parseOptions(ruleArguments) {
35     if (ruleArguments.length === 0) {
36         ruleArguments = Object.keys(KIND_FOR_OPTION);
37     }
38     var enabledKinds = new Set();
39     for (var _i = 0, ruleArguments_1 = ruleArguments; _i < ruleArguments_1.length; _i++) {
40         var arg = ruleArguments_1[_i];
41         enabledKinds.add(KIND_FOR_OPTION[arg]);
42     }
43     return enabledKinds;
44 }
45 var Rule = /** @class */ (function (_super) {
46     tslib_1.__extends(Rule, _super);
47     function Rule() {
48         return _super !== null && _super.apply(this, arguments) || this;
49     }
50     Rule.prototype.applyWithProgram = function (sourceFile, program) {
51         return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments), program.getTypeChecker());
52     };
53     /* tslint:disable:object-literal-sort-keys */
54     Rule.metadata = {
55         ruleName: "promise-function-async",
56         description: "Requires any function or method that returns a promise to be marked async.",
57         rationale: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n            Ensures that each function is only capable of 1) returning a rejected promise, or 2)\n            throwing an Error object. In contrast, non-`async` `Promise`-returning functions\n            are technically capable of either. This practice removes a requirement for consuming\n            code to handle both cases.\n\n            If no optional arguments are provided then all function types are checked,\n            otherwise the specific function types are checked:\n\n            * `\"", "\"` check function declarations.\n            * `\"", "\"` check function expressions.\n            * `\"", "\"` check arrow functions.\n            * `\"", "\"` check method declarations.\n        "], ["\n            Ensures that each function is only capable of 1) returning a rejected promise, or 2)\n            throwing an Error object. In contrast, non-\\`async\\` \\`Promise\\`-returning functions\n            are technically capable of either. This practice removes a requirement for consuming\n            code to handle both cases.\n\n            If no optional arguments are provided then all function types are checked,\n            otherwise the specific function types are checked:\n\n            * \\`\"", "\"\\` check function declarations.\n            * \\`\"", "\"\\` check function expressions.\n            * \\`\"", "\"\\` check arrow functions.\n            * \\`\"", "\"\\` check method declarations.\n        "])), OPTION_FUNCTION_DECLARATION, OPTION_FUNCTION_EXPRESSION, OPTION_ARROW_FUNCTION, OPTION_METHOD_DECLARATION),
58         optionsDescription: "Not configurable.",
59         options: {
60             type: "array",
61             items: {
62                 type: "string",
63                 enum: [
64                     OPTION_FUNCTION_DECLARATION,
65                     OPTION_FUNCTION_EXPRESSION,
66                     OPTION_ARROW_FUNCTION,
67                     OPTION_METHOD_DECLARATION,
68                 ],
69             },
70             minLength: 0,
71             maxLength: 4,
72         },
73         optionExamples: [true, [true, OPTION_FUNCTION_DECLARATION, OPTION_METHOD_DECLARATION]],
74         type: "typescript",
75         typescriptOnly: false,
76         requiresTypeInfo: true,
77     };
78     /* tslint:enable:object-literal-sort-keys */
79     Rule.FAILURE_STRING = "functions that return promises must be async";
80     return Rule;
81 }(Lint.Rules.TypedRule));
82 exports.Rule = Rule;
83 function walk(ctx, tc) {
84     var sourceFile = ctx.sourceFile, options = ctx.options;
85     return ts.forEachChild(sourceFile, function cb(node) {
86         if (options.has(node.kind) && isFunctionLikeWithBody(node)) {
87             if (!tsutils.hasModifier(node.modifiers, ts.SyntaxKind.AsyncKeyword) &&
88                 !isCallExpressionBody(node.body) &&
89                 returnsPromise(node, tc)) {
90                 ctx.addFailure(node.getStart(sourceFile), node.body.pos, Rule.FAILURE_STRING);
91             }
92         }
93         return ts.forEachChild(node, cb);
94     });
95 }
96 function isFunctionLikeWithBody(node) {
97     switch (node.kind) {
98         case ts.SyntaxKind.MethodDeclaration:
99         case ts.SyntaxKind.FunctionDeclaration:
100         case ts.SyntaxKind.FunctionExpression:
101         case ts.SyntaxKind.ArrowFunction:
102             return node.body !== undefined;
103     }
104     return false;
105 }
106 function isCallExpressionBody(body) {
107     while (tsutils.isParenthesizedExpression(body)) {
108         body = body.expression;
109     }
110     return tsutils.isCallExpression(body);
111 }
112 function returnsPromise(node, tc) {
113     var type = tc.getReturnTypeOfSignature(tc.getTypeAtLocation(node).getCallSignatures()[0]);
114     return type.symbol !== undefined && type.symbol.name === "Promise";
115 }
116 var templateObject_1;