.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tslint / lib / rules / semicolonRule.js
1 "use strict";
2 /**
3  * @license
4  * Copyright 2013 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 utils = require("tsutils");
21 var ts = require("typescript");
22 var Lint = require("../index");
23 var OPTION_ALWAYS = "always";
24 var OPTION_NEVER = "never";
25 var OPTION_IGNORE_BOUND_CLASS_METHODS = "ignore-bound-class-methods";
26 var OPTION_STRICT_BOUND_CLASS_METHODS = "strict-bound-class-methods";
27 var OPTION_IGNORE_INTERFACES = "ignore-interfaces";
28 var Rule = /** @class */ (function (_super) {
29     tslib_1.__extends(Rule, _super);
30     function Rule() {
31         return _super !== null && _super.apply(this, arguments) || this;
32     }
33     Rule.prototype.apply = function (sourceFile) {
34         var options = {
35             boundClassMethods: this.ruleArguments.indexOf(OPTION_STRICT_BOUND_CLASS_METHODS) !== -1
36                 ? 2 /* Strict */
37                 : this.ruleArguments.indexOf(OPTION_IGNORE_BOUND_CLASS_METHODS) !== -1
38                     ? 1 /* Ignore */
39                     : 0 /* Default */,
40             interfaces: this.ruleArguments.indexOf(OPTION_IGNORE_INTERFACES) === -1,
41         };
42         var Walker = this.ruleArguments.indexOf(OPTION_NEVER) === -1
43             ? SemicolonAlwaysWalker
44             : SemicolonNeverWalker;
45         return this.applyWithWalker(new Walker(sourceFile, this.ruleName, options));
46     };
47     /* tslint:disable:object-literal-sort-keys */
48     Rule.metadata = {
49         ruleName: "semicolon",
50         description: "Enforces consistent semicolon usage at the end of every statement.",
51         hasFix: true,
52         optionsDescription: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n            One of the following arguments must be provided:\n\n            * `\"", "\"` enforces semicolons at the end of every statement.\n            * `\"", "\"` disallows semicolons at the end of every statement except for when they are necessary.\n\n            The following arguments may be optionally provided:\n\n            * `\"", "\"` skips checking semicolons at the end of interface members.\n            * `\"", "\"` skips checking semicolons at the end of bound class methods.\n            * `\"", "\"` disables any special handling of bound class methods and treats them as any\n            other assignment. This option overrides `\"", "\"`.\n        "], ["\n            One of the following arguments must be provided:\n\n            * \\`\"", "\"\\` enforces semicolons at the end of every statement.\n            * \\`\"", "\"\\` disallows semicolons at the end of every statement except for when they are necessary.\n\n            The following arguments may be optionally provided:\n\n            * \\`\"", "\"\\` skips checking semicolons at the end of interface members.\n            * \\`\"", "\"\\` skips checking semicolons at the end of bound class methods.\n            * \\`\"", "\"\\` disables any special handling of bound class methods and treats them as any\n            other assignment. This option overrides \\`\"", "\"\\`.\n        "])), OPTION_ALWAYS, OPTION_NEVER, OPTION_IGNORE_INTERFACES, OPTION_IGNORE_BOUND_CLASS_METHODS, OPTION_STRICT_BOUND_CLASS_METHODS, OPTION_IGNORE_BOUND_CLASS_METHODS),
53         options: {
54             type: "array",
55             items: [
56                 {
57                     type: "string",
58                     enum: [OPTION_ALWAYS, OPTION_NEVER],
59                 },
60                 {
61                     type: "string",
62                     enum: [OPTION_IGNORE_INTERFACES],
63                 },
64             ],
65             additionalItems: false,
66         },
67         optionExamples: [
68             [true, OPTION_ALWAYS],
69             [true, OPTION_NEVER],
70             [true, OPTION_ALWAYS, OPTION_IGNORE_INTERFACES],
71             [true, OPTION_ALWAYS, OPTION_IGNORE_BOUND_CLASS_METHODS],
72         ],
73         type: "formatting",
74         typescriptOnly: false,
75     };
76     /* tslint:enable:object-literal-sort-keys */
77     Rule.FAILURE_STRING_MISSING = "Missing semicolon";
78     Rule.FAILURE_STRING_COMMA = "Properties should be separated by semicolons";
79     Rule.FAILURE_STRING_UNNECESSARY = "Unnecessary semicolon";
80     return Rule;
81 }(Lint.Rules.AbstractRule));
82 exports.Rule = Rule;
83 var SemicolonWalker = /** @class */ (function (_super) {
84     tslib_1.__extends(SemicolonWalker, _super);
85     function SemicolonWalker() {
86         return _super !== null && _super.apply(this, arguments) || this;
87     }
88     SemicolonWalker.prototype.walk = function (sourceFile) {
89         var _this = this;
90         var cb = function (node) {
91             _this.visitNode(node);
92             return ts.forEachChild(node, cb);
93         };
94         return ts.forEachChild(sourceFile, cb);
95     };
96     SemicolonWalker.prototype.visitNode = function (node) {
97         switch (node.kind) {
98             case ts.SyntaxKind.SemicolonClassElement:
99                 return this.reportUnnecessary(node.end);
100             case ts.SyntaxKind.EmptyStatement:
101                 return this.checkEmptyStatement(node);
102             case ts.SyntaxKind.PropertyDeclaration:
103                 return this.visitPropertyDeclaration(node);
104         }
105     };
106     SemicolonWalker.prototype.reportUnnecessary = function (pos, noFix) {
107         this.addFailure(pos - 1, pos, Rule.FAILURE_STRING_UNNECESSARY, noFix ? undefined : Lint.Replacement.deleteText(pos - 1, 1));
108     };
109     SemicolonWalker.prototype.checkSemicolonOrLineBreak = function (node) {
110         if (this.sourceFile.text[node.end - 1] !== ";") {
111             return;
112         }
113         var nextToken = utils.getNextToken(node, this.sourceFile);
114         switch (nextToken.kind) {
115             case ts.SyntaxKind.EndOfFileToken:
116             case ts.SyntaxKind.CloseBraceToken:
117                 return this.reportUnnecessary(node.end);
118             default:
119                 if (!utils.isSameLine(this.sourceFile, node.end, nextToken.end)) {
120                     this.reportUnnecessary(node.end);
121                 }
122         }
123     };
124     SemicolonWalker.prototype.checkUnnecessary = function (node) {
125         if (this.sourceFile.text[node.end - 1] !== ";") {
126             return;
127         }
128         var lastToken = utils.getPreviousToken(node.getLastToken(this.sourceFile), this.sourceFile);
129         // yield does not continue on the next line if there is no yielded expression
130         if ((lastToken.kind === ts.SyntaxKind.YieldKeyword &&
131             lastToken.parent.kind === ts.SyntaxKind.YieldExpression) ||
132             // arrow functions with block as body don't continue on the next line
133             (lastToken.kind === ts.SyntaxKind.CloseBraceToken &&
134                 lastToken.parent.kind === ts.SyntaxKind.Block &&
135                 lastToken.parent.parent.kind === ts.SyntaxKind.ArrowFunction)) {
136             return this.checkSemicolonOrLineBreak(node);
137         }
138         var nextToken = utils.getNextToken(node, this.sourceFile);
139         switch (nextToken.kind) {
140             case ts.SyntaxKind.OpenParenToken:
141             case ts.SyntaxKind.OpenBracketToken:
142             case ts.SyntaxKind.PlusToken:
143             case ts.SyntaxKind.MinusToken:
144             case ts.SyntaxKind.RegularExpressionLiteral:
145             case ts.SyntaxKind.LessThanToken:
146             case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
147             case ts.SyntaxKind.TemplateHead:
148                 break;
149             case ts.SyntaxKind.CloseBraceToken:
150             case ts.SyntaxKind.EndOfFileToken:
151                 return this.reportUnnecessary(node.end);
152             default:
153                 if (!utils.isSameLine(this.sourceFile, node.end, nextToken.end)) {
154                     this.reportUnnecessary(node.end);
155                 }
156         }
157     };
158     SemicolonWalker.prototype.checkEmptyStatement = function (node) {
159         // An empty statement is only ever useful when it is the only statement inside a loop
160         if (!utils.isIterationStatement(node.parent)) {
161             var parentKind = node.parent.kind;
162             // don't remove empty statement if it is a direct child of if, with or a LabeledStatement
163             // otherwise this would unintentionally change control flow
164             var noFix = parentKind === ts.SyntaxKind.IfStatement ||
165                 parentKind === ts.SyntaxKind.LabeledStatement ||
166                 parentKind === ts.SyntaxKind.WithStatement;
167             this.reportUnnecessary(node.end, noFix);
168         }
169     };
170     SemicolonWalker.prototype.visitPropertyDeclaration = function (node) {
171         // check if this is a multi-line arrow function
172         if (this.options.boundClassMethods !== 2 /* Strict */ &&
173             node.initializer !== undefined &&
174             node.initializer.kind === ts.SyntaxKind.ArrowFunction &&
175             !utils.isSameLine(this.sourceFile, node.getStart(this.sourceFile), node.end)) {
176             if (this.options.boundClassMethods === 0 /* Default */) {
177                 this.checkUnnecessary(node);
178             }
179         }
180         else {
181             this.checkPropertyDeclaration(node);
182         }
183     };
184     return SemicolonWalker;
185 }(Lint.AbstractWalker));
186 var SemicolonAlwaysWalker = /** @class */ (function (_super) {
187     tslib_1.__extends(SemicolonAlwaysWalker, _super);
188     function SemicolonAlwaysWalker() {
189         return _super !== null && _super.apply(this, arguments) || this;
190     }
191     SemicolonAlwaysWalker.prototype.visitNode = function (node) {
192         switch (node.kind) {
193             case ts.SyntaxKind.VariableStatement:
194             case ts.SyntaxKind.ExpressionStatement:
195             case ts.SyntaxKind.ReturnStatement:
196             case ts.SyntaxKind.BreakStatement:
197             case ts.SyntaxKind.ContinueStatement:
198             case ts.SyntaxKind.ThrowStatement:
199             case ts.SyntaxKind.ImportEqualsDeclaration:
200             case ts.SyntaxKind.DoStatement:
201             case ts.SyntaxKind.ExportAssignment:
202             case ts.SyntaxKind.TypeAliasDeclaration:
203             case ts.SyntaxKind.ImportDeclaration:
204             case ts.SyntaxKind.ExportDeclaration:
205             case ts.SyntaxKind.DebuggerStatement:
206                 return this.checkMissing(node);
207             case ts.SyntaxKind.ModuleDeclaration:
208             case ts.SyntaxKind.MethodDeclaration:
209             case ts.SyntaxKind.FunctionDeclaration:
210                 // check shorthand module declarations and method / function signatures
211                 if (node.body === undefined) {
212                     this.checkMissing(node);
213                 }
214                 break;
215             case ts.SyntaxKind.InterfaceDeclaration:
216                 if (this.options.interfaces) {
217                     this.checkInterface(node);
218                 }
219                 break;
220             default:
221                 return _super.prototype.visitNode.call(this, node);
222         }
223     };
224     SemicolonAlwaysWalker.prototype.checkPropertyDeclaration = function (node) {
225         return this.checkMissing(node);
226     };
227     SemicolonAlwaysWalker.prototype.checkMissing = function (node) {
228         if (this.sourceFile.text[node.end - 1] !== ";") {
229             this.reportMissing(node.end);
230         }
231     };
232     SemicolonAlwaysWalker.prototype.reportMissing = function (pos) {
233         this.addFailureAt(pos, 0, Rule.FAILURE_STRING_MISSING, Lint.Replacement.appendText(pos, ";"));
234     };
235     SemicolonAlwaysWalker.prototype.checkInterface = function (node) {
236         for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
237             var member = _a[_i];
238             switch (this.sourceFile.text[member.end - 1]) {
239                 case ";":
240                     break;
241                 case ",":
242                     this.addFailureAt(member.end - 1, 1, Rule.FAILURE_STRING_COMMA, new Lint.Replacement(member.end - 1, 1, ";"));
243                     break;
244                 default:
245                     this.reportMissing(member.end);
246             }
247         }
248     };
249     return SemicolonAlwaysWalker;
250 }(SemicolonWalker));
251 var SemicolonNeverWalker = /** @class */ (function (_super) {
252     tslib_1.__extends(SemicolonNeverWalker, _super);
253     function SemicolonNeverWalker() {
254         return _super !== null && _super.apply(this, arguments) || this;
255     }
256     SemicolonNeverWalker.prototype.visitNode = function (node) {
257         switch (node.kind) {
258             case ts.SyntaxKind.ExpressionStatement:
259             case ts.SyntaxKind.ThrowStatement:
260             case ts.SyntaxKind.ExportAssignment:
261                 return this.checkUnnecessary(node);
262             case ts.SyntaxKind.VariableStatement:
263                 return this.checkVariableStatement(node);
264             case ts.SyntaxKind.ReturnStatement:
265                 if (node.expression === undefined) {
266                     // return does not continue on the next line if the is no returned expression
267                     return this.checkSemicolonOrLineBreak(node);
268                 }
269                 return this.checkUnnecessary(node);
270             case ts.SyntaxKind.TypeAliasDeclaration:
271             case ts.SyntaxKind.ImportEqualsDeclaration:
272             case ts.SyntaxKind.ImportDeclaration:
273             case ts.SyntaxKind.ExportDeclaration:
274             case ts.SyntaxKind.DebuggerStatement:
275             case ts.SyntaxKind.BreakStatement:
276             case ts.SyntaxKind.ContinueStatement:
277             case ts.SyntaxKind.DoStatement:
278                 return this.checkSemicolonOrLineBreak(node);
279             case ts.SyntaxKind.ModuleDeclaration:
280                 // shorthand module declaration
281                 if (node.body === undefined) {
282                     this.checkShorthandModuleDeclaration(node);
283                 }
284                 break;
285             case ts.SyntaxKind.MethodDeclaration:
286                 // check method signature
287                 if (node.body === undefined) {
288                     this.checkSemicolonOrLineBreak(node);
289                 }
290                 break;
291             case ts.SyntaxKind.FunctionDeclaration:
292                 // check function signature
293                 if (node.body === undefined) {
294                     this.checkSemicolonOrLineBreak(node);
295                 }
296                 break;
297             case ts.SyntaxKind.InterfaceDeclaration:
298                 if (this.options.interfaces) {
299                     this.checkInterface(node);
300                 }
301                 break;
302             default:
303                 return _super.prototype.visitNode.call(this, node);
304         }
305     };
306     SemicolonNeverWalker.prototype.checkPropertyDeclaration = function (node) {
307         if (node.initializer === undefined) {
308             return this.checkSemicolonOrLineBreak(node);
309         }
310         return this.checkUnnecessary(node);
311     };
312     SemicolonNeverWalker.prototype.checkVariableStatement = function (node) {
313         var declarations = node.declarationList.declarations;
314         if (declarations.length !== 0 &&
315             declarations[declarations.length - 1].initializer === undefined) {
316             // variable declaration does not continue on the next line if it has no initializer
317             return this.checkSemicolonOrLineBreak(node);
318         }
319         return this.checkUnnecessary(node);
320     };
321     SemicolonNeverWalker.prototype.checkShorthandModuleDeclaration = function (node) {
322         var nextStatement = utils.getNextStatement(node);
323         if (nextStatement === undefined || nextStatement.kind !== ts.SyntaxKind.Block) {
324             this.checkSemicolonOrLineBreak(node);
325         }
326     };
327     SemicolonNeverWalker.prototype.checkInterface = function (node) {
328         for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
329             var member = _a[_i];
330             this.checkSemicolonOrLineBreak(member);
331         }
332     };
333     return SemicolonNeverWalker;
334 }(SemicolonWalker));
335 var templateObject_1;