.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tslint / lib / rules / unnecessaryBindRule.js
1 "use strict";
2 /**
3  * @license
4  * Copyright 2017 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 tsutils = require("tsutils");
21 var ts = require("typescript");
22 var Lint = require("../index");
23 var Rule = /** @class */ (function (_super) {
24     tslib_1.__extends(Rule, _super);
25     function Rule() {
26         return _super !== null && _super.apply(this, arguments) || this;
27     }
28     Rule.prototype.apply = function (sourceFile) {
29         return this.applyWithFunction(sourceFile, walk);
30     };
31     Rule.prototype.applyWithProgram = function (sourceFile, program) {
32         return this.applyWithFunction(sourceFile, walk, undefined, program.getTypeChecker());
33     };
34     Rule.metadata = {
35         description: "Prevents unnecessary and/or misleading scope bindings on functions.",
36         optionExamples: [true],
37         options: null,
38         optionsDescription: "Not configurable.",
39         rationale: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n            `function` expressions that are immediately bound to `this` are equivalent to `() =>` arrow lambdas.\n            Additionally, there's no use in binding a scope to an arrow lambda, as it already has one.\n        "], ["\n            \\`function\\` expressions that are immediately bound to \\`this\\` are equivalent to \\`() =>\\` arrow lambdas.\n            Additionally, there's no use in binding a scope to an arrow lambda, as it already has one.\n        "]))),
40         requiresTypeInfo: true,
41         ruleName: "unnecessary-bind",
42         type: "style",
43         typescriptOnly: false,
44     };
45     Rule.FAILURE_STRING_FUNCTION = "Don't bind `this` without arguments as a scope to a function. Use an arrow lambda instead.";
46     Rule.FAILURE_STRING_ARROW = "Don't bind scopes to arrow lambdas, as they already have a bound scope.";
47     return Rule;
48 }(Lint.Rules.OptionallyTypedRule));
49 exports.Rule = Rule;
50 function walk(context, typeChecker) {
51     var variableUsage = tsutils.collectVariableUsage(context.sourceFile);
52     function checkArrowFunction(node) {
53         if (node.arguments.length !== 1) {
54             return;
55         }
56         context.addFailureAtNode(node, Rule.FAILURE_STRING_ARROW);
57     }
58     function canFunctionExpressionBeFixed(callExpression, valueDeclaration) {
59         if (callExpression.arguments.length !== 1 ||
60             callExpression.arguments[0].kind !== ts.SyntaxKind.ThisKeyword ||
61             valueDeclaration.asteriskToken !== undefined ||
62             valueDeclaration.decorators !== undefined) {
63             return false;
64         }
65         var name = valueDeclaration.name;
66         if (name === undefined) {
67             return true;
68         }
69         var nameInfo = variableUsage.get(name);
70         return nameInfo === undefined || nameInfo.uses.length === 0;
71     }
72     function checkFunctionExpression(callExpression, valueDeclaration) {
73         if (!canFunctionExpressionBeFixed(callExpression, valueDeclaration)) {
74             return;
75         }
76         context.addFailureAtNode(callExpression, Rule.FAILURE_STRING_FUNCTION);
77     }
78     function getArrowFunctionDeclaration(node) {
79         if (typeChecker === undefined) {
80             return undefined;
81         }
82         var symbol = typeChecker.getTypeAtLocation(node).symbol;
83         if (symbol === undefined) {
84             return undefined;
85         }
86         var valueDeclaration = symbol.valueDeclaration;
87         if (valueDeclaration === undefined) {
88             return undefined;
89         }
90         if (!tsutils.isArrowFunction(valueDeclaration)) {
91             return undefined;
92         }
93         return valueDeclaration;
94     }
95     function isDecoratedPropertyMember(node) {
96         return (node.parent !== undefined &&
97             tsutils.isPropertyDeclaration(node.parent) &&
98             node.parent.decorators !== undefined);
99     }
100     function checkCallExpression(node) {
101         if (isDecoratedPropertyMember(node)) {
102             return;
103         }
104         var bindExpression = node.expression;
105         if (!isBindPropertyAccess(bindExpression)) {
106             return;
107         }
108         var boundExpression = Lint.unwrapParentheses(bindExpression.expression);
109         if (tsutils.isFunctionExpression(boundExpression)) {
110             checkFunctionExpression(node, boundExpression);
111             return;
112         }
113         var valueDeclaration = getArrowFunctionDeclaration(boundExpression);
114         if (valueDeclaration !== undefined) {
115             checkArrowFunction(node);
116         }
117     }
118     return ts.forEachChild(context.sourceFile, function callback(node) {
119         if (ts.isCallExpression(node)) {
120             checkCallExpression(node);
121         }
122         return ts.forEachChild(node, callback);
123     });
124 }
125 function isBindPropertyAccess(node) {
126     return ts.isPropertyAccessExpression(node) && node.name.text === "bind";
127 }
128 var templateObject_1;