.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tslint / lib / rules / trailingCommaRule.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 tsutils_1 = require("tsutils");
21 var ts = require("typescript");
22 var Lint = require("../index");
23 var defaultOptions = fillOptions("ignore");
24 function fillOptions(value) {
25     return {
26         arrays: value,
27         exports: value,
28         functions: value,
29         imports: value,
30         objects: value,
31         typeLiterals: value,
32     };
33 }
34 function normalizeOptions(options) {
35     return {
36         multiline: normalize(options.multiline),
37         singleline: normalize(options.singleline),
38         specCompliant: !!options.esSpecCompliant,
39     };
40 }
41 function normalize(value) {
42     return typeof value === "string" ? fillOptions(value) : tslib_1.__assign({}, defaultOptions, value);
43 }
44 /* tslint:disable:object-literal-sort-keys */
45 var metadataOptionShape = {
46     anyOf: [
47         {
48             type: "string",
49             enum: ["always", "never"],
50         },
51         {
52             type: "object",
53             properties: fillOptions({
54                 type: "string",
55                 enum: ["always", "never", "ignore"],
56             }),
57         },
58     ],
59 };
60 /* tslint:enable:object-literal-sort-keys */
61 var Rule = /** @class */ (function (_super) {
62     tslib_1.__extends(Rule, _super);
63     function Rule() {
64         return _super !== null && _super.apply(this, arguments) || this;
65     }
66     Rule.prototype.apply = function (sourceFile) {
67         var options = normalizeOptions(this.ruleArguments[0]);
68         return this.applyWithWalker(new TrailingCommaWalker(sourceFile, this.ruleName, options));
69     };
70     Rule.prototype.isEnabled = function () {
71         return _super.prototype.isEnabled.call(this) && this.ruleArguments.length !== 0;
72     };
73     /* tslint:disable:object-literal-sort-keys */
74     Rule.metadata = {
75         ruleName: "trailing-comma",
76         description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n            Requires or disallows trailing commas in array and object literals, destructuring assignments, function typings,\n            named imports and exports and function parameters."], ["\n            Requires or disallows trailing commas in array and object literals, destructuring assignments, function typings,\n            named imports and exports and function parameters."]))),
77         hasFix: true,
78         optionsDescription: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n            One argument which is an object with the keys `multiline` and `singleline`.\n            Both can be set to a string (`\"always\"` or `\"never\"`) or an object.\n\n            The object can contain any of the following keys: `\"arrays\"`, `\"objects\"`, `\"functions\"`,\n            `\"imports\"`, `\"exports\"`, and `\"typeLiterals\"`; each key can have one of the following\n            values: `\"always\"`, `\"never\"`, and `\"ignore\"`. Any missing keys will default to `\"ignore\"`.\n\n            * `\"multiline\"` checks multi-line object literals.\n            * `\"singleline\"` checks single-line object literals.\n\n            An array is considered \"multiline\" if its closing bracket is on a line\n            after the last array element. The same general logic is followed for\n            object literals, function typings, named import statements\n            and function parameters.\n\n            To align this rule with the ECMAScript specification that is implemented in modern JavaScript VMs,\n            there is a third option `esSpecCompliant`. Set this option to `true` to disallow trailing comma on\n            object and array rest and rest parameters.\n        "], ["\n            One argument which is an object with the keys \\`multiline\\` and \\`singleline\\`.\n            Both can be set to a string (\\`\"always\"\\` or \\`\"never\"\\`) or an object.\n\n            The object can contain any of the following keys: \\`\"arrays\"\\`, \\`\"objects\"\\`, \\`\"functions\"\\`,\n            \\`\"imports\"\\`, \\`\"exports\"\\`, and \\`\"typeLiterals\"\\`; each key can have one of the following\n            values: \\`\"always\"\\`, \\`\"never\"\\`, and \\`\"ignore\"\\`. Any missing keys will default to \\`\"ignore\"\\`.\n\n            * \\`\"multiline\"\\` checks multi-line object literals.\n            * \\`\"singleline\"\\` checks single-line object literals.\n\n            An array is considered \"multiline\" if its closing bracket is on a line\n            after the last array element. The same general logic is followed for\n            object literals, function typings, named import statements\n            and function parameters.\n\n            To align this rule with the ECMAScript specification that is implemented in modern JavaScript VMs,\n            there is a third option \\`esSpecCompliant\\`. Set this option to \\`true\\` to disallow trailing comma on\n            object and array rest and rest parameters.\n        "]))),
79         options: {
80             type: "object",
81             properties: {
82                 multiline: metadataOptionShape,
83                 singleline: metadataOptionShape,
84                 esSpecCompliant: { type: "boolean" },
85             },
86             additionalProperties: false,
87         },
88         optionExamples: [
89             [true, { multiline: "always", singleline: "never" }],
90             [
91                 true,
92                 {
93                     multiline: {
94                         objects: "always",
95                         arrays: "always",
96                         functions: "never",
97                         typeLiterals: "ignore",
98                     },
99                     esSpecCompliant: true,
100                 },
101             ],
102         ],
103         type: "formatting",
104         typescriptOnly: false,
105     };
106     /* tslint:enable:object-literal-sort-keys */
107     Rule.FAILURE_STRING_NEVER = "Unnecessary trailing comma";
108     Rule.FAILURE_STRING_FORBIDDEN = "Forbidden trailing comma";
109     Rule.FAILURE_STRING_ALWAYS = "Missing trailing comma";
110     return Rule;
111 }(Lint.Rules.AbstractRule));
112 exports.Rule = Rule;
113 var TrailingCommaWalker = /** @class */ (function (_super) {
114     tslib_1.__extends(TrailingCommaWalker, _super);
115     function TrailingCommaWalker() {
116         return _super !== null && _super.apply(this, arguments) || this;
117     }
118     TrailingCommaWalker.prototype.walk = function (sourceFile) {
119         var _this = this;
120         var cb = function (node) {
121             switch (node.kind) {
122                 case ts.SyntaxKind.ArrayLiteralExpression:
123                     _this.checkList(node.elements, node.end, "arrays", isArrayRest);
124                     break;
125                 case ts.SyntaxKind.ArrayBindingPattern:
126                     _this.checkList(node.elements, node.end, "arrays", isDestructuringRest);
127                     break;
128                 case ts.SyntaxKind.ObjectBindingPattern:
129                     _this.checkList(node.elements, node.end, "objects", isDestructuringRest);
130                     break;
131                 case ts.SyntaxKind.NamedImports:
132                     _this.checkList(node.elements, node.end, "imports", noRest);
133                     break;
134                 case ts.SyntaxKind.NamedExports:
135                     _this.checkList(node.elements, node.end, "exports", noRest);
136                     break;
137                 case ts.SyntaxKind.ObjectLiteralExpression:
138                     _this.checkList(node.properties, node.end, "objects", isObjectRest);
139                     break;
140                 case ts.SyntaxKind.EnumDeclaration:
141                     _this.checkList(node.members, node.end, "objects", noRest);
142                     break;
143                 case ts.SyntaxKind.NewExpression:
144                     if (node.arguments === undefined) {
145                         break;
146                     }
147                 // falls through
148                 case ts.SyntaxKind.CallExpression:
149                     _this.checkList(node.arguments, node.end, "functions", noRest);
150                     break;
151                 case ts.SyntaxKind.ArrowFunction:
152                     // don't check arrow functions without parens around the parameter
153                     if (tsutils_1.getChildOfKind(node, ts.SyntaxKind.OpenParenToken, _this.sourceFile) ===
154                         undefined) {
155                         break;
156                     }
157                 // falls through
158                 case ts.SyntaxKind.Constructor:
159                 case ts.SyntaxKind.FunctionDeclaration:
160                 case ts.SyntaxKind.FunctionExpression:
161                 case ts.SyntaxKind.MethodDeclaration:
162                 case ts.SyntaxKind.SetAccessor:
163                 case ts.SyntaxKind.MethodSignature:
164                 case ts.SyntaxKind.ConstructSignature:
165                 case ts.SyntaxKind.ConstructorType:
166                 case ts.SyntaxKind.FunctionType:
167                 case ts.SyntaxKind.CallSignature:
168                     var closingParen = tsutils_1.getChildOfKind(node, ts.SyntaxKind.CloseParenToken, _this.sourceFile);
169                     if (closingParen !== undefined) {
170                         _this.checkList(node.parameters, closingParen.end, "functions", isRestParameter);
171                     }
172                     break;
173                 case ts.SyntaxKind.TypeLiteral:
174                     _this.checkTypeLiteral(node);
175                     break;
176                 default:
177             }
178             return ts.forEachChild(node, cb);
179         };
180         return ts.forEachChild(sourceFile, cb);
181     };
182     TrailingCommaWalker.prototype.checkTypeLiteral = function (node) {
183         var members = node.members;
184         if (members.length === 0) {
185             return;
186         }
187         var sourceText = this.sourceFile.text;
188         for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
189             var member = members_1[_i];
190             // PropertySignature in TypeLiteral can end with semicolon or comma. If one ends with a semicolon don't check for trailing comma
191             if (sourceText[member.end - 1] === ";") {
192                 return;
193             }
194         }
195         // The trailing comma is part of the last member and therefore not present as hasTrailingComma on the NodeArray
196         var hasTrailingComma = sourceText[members.end - 1] === ",";
197         return this.checkComma(hasTrailingComma, members, node.end, "typeLiterals", noRest);
198     };
199     TrailingCommaWalker.prototype.checkList = function (list, closeElementPos, optionKey, isRest) {
200         if (list.length === 0) {
201             return;
202         }
203         return this.checkComma(list.hasTrailingComma, list, closeElementPos, optionKey, isRest);
204     };
205     /* Expects `list.length !== 0` */
206     TrailingCommaWalker.prototype.checkComma = function (hasTrailingComma, list, closeTokenPos, optionKey, isRest) {
207         var last = list[list.length - 1];
208         if (this.options.specCompliant && isRest(last)) {
209             if (hasTrailingComma) {
210                 this.addFailureAt(list.end - 1, 1, Rule.FAILURE_STRING_FORBIDDEN, Lint.Replacement.deleteText(list.end - 1, 1));
211             }
212             return;
213         }
214         var options = tsutils_1.isSameLine(this.sourceFile, last.end, closeTokenPos)
215             ? this.options.singleline
216             : this.options.multiline;
217         var option = options[optionKey];
218         if (option === "always" && !hasTrailingComma) {
219             this.addFailureAt(list.end, 0, Rule.FAILURE_STRING_ALWAYS, Lint.Replacement.appendText(list.end, ","));
220         }
221         else if (option === "never" && hasTrailingComma) {
222             this.addFailureAt(list.end - 1, 1, Rule.FAILURE_STRING_NEVER, Lint.Replacement.deleteText(list.end - 1, 1));
223         }
224     };
225     return TrailingCommaWalker;
226 }(Lint.AbstractWalker));
227 function isRestParameter(node) {
228     return node.dotDotDotToken !== undefined;
229 }
230 function isDestructuringRest(node) {
231     return node.kind === ts.SyntaxKind.BindingElement && node.dotDotDotToken !== undefined;
232 }
233 function isObjectRest(node) {
234     return node.kind === ts.SyntaxKind.SpreadAssignment && tsutils_1.isReassignmentTarget(node.expression);
235 }
236 function isArrayRest(node) {
237     return node.kind === ts.SyntaxKind.SpreadElement && tsutils_1.isReassignmentTarget(node);
238 }
239 function noRest() {
240     return false;
241 }
242 var templateObject_1, templateObject_2;