.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tslint / lib / enableDisableRules.js
1 "use strict";
2 /**
3  * @license
4  * Copyright 2014 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 // tslint:disable object-literal-sort-keys
20 var utils = require("tsutils");
21 var ts = require("typescript");
22 /**
23  * regex is: start of string followed by any amount of whitespace
24  * followed by tslint and colon
25  * followed by either "enable" or "disable"
26  * followed optionally by -line or -next-line
27  * followed by either colon, whitespace or end of string
28  */
29 exports.ENABLE_DISABLE_REGEX = /^\s*tslint:(enable|disable)(?:-(line|next-line))?(:|\s|$)/;
30 function removeDisabledFailures(sourceFile, failures) {
31     if (failures.length === 0) {
32         // Usually there won't be failures anyway, so no need to look for "tslint:disable".
33         return failures;
34     }
35     var failingRules = new Set(failures.map(function (f) { return f.getRuleName(); }));
36     var map = getDisableMap(sourceFile, failingRules);
37     return failures.filter(function (failure) {
38         var disabledIntervals = map.get(failure.getRuleName());
39         return (disabledIntervals === undefined ||
40             !disabledIntervals.some(function (_a) {
41                 var pos = _a.pos, end = _a.end;
42                 var failPos = failure.getStartPosition().getPosition();
43                 var failEnd = failure.getEndPosition().getPosition();
44                 return failEnd >= pos && (end === -1 || failPos < end);
45             }));
46     });
47 }
48 exports.removeDisabledFailures = removeDisabledFailures;
49 /**
50  * The map will have an array of TextRange for each disable of a rule in a file.
51  * (It will have no entry if the rule is never disabled, meaning all arrays are non-empty.)
52  */
53 function getDisableMap(sourceFile, failingRules) {
54     var map = new Map();
55     utils.forEachComment(sourceFile, function (fullText, comment) {
56         var commentText = comment.kind === ts.SyntaxKind.SingleLineCommentTrivia
57             ? fullText.substring(comment.pos + 2, comment.end)
58             : fullText.substring(comment.pos + 2, comment.end - 2);
59         var parsed = parseComment(commentText);
60         if (parsed !== undefined) {
61             var rulesList = parsed.rulesList, isEnabled = parsed.isEnabled, modifier = parsed.modifier;
62             var switchRange = getSwitchRange(modifier, comment, sourceFile);
63             if (switchRange !== undefined) {
64                 var rulesToSwitch = rulesList === "all"
65                     ? Array.from(failingRules)
66                     : rulesList.filter(function (r) { return failingRules.has(r); });
67                 for (var _i = 0, rulesToSwitch_1 = rulesToSwitch; _i < rulesToSwitch_1.length; _i++) {
68                     var ruleToSwitch = rulesToSwitch_1[_i];
69                     switchRuleState(ruleToSwitch, isEnabled, switchRange.pos, switchRange.end);
70                 }
71             }
72         }
73     });
74     return map;
75     function switchRuleState(ruleName, isEnable, start, end) {
76         var disableRanges = map.get(ruleName);
77         if (isEnable) {
78             if (disableRanges !== undefined) {
79                 var lastDisable = disableRanges[disableRanges.length - 1];
80                 if (lastDisable.end === -1) {
81                     lastDisable.end = start;
82                     if (end !== -1) {
83                         // Disable it again after the enable range is over.
84                         disableRanges.push({ pos: end, end: -1 });
85                     }
86                 }
87             }
88         }
89         else {
90             // disable
91             if (disableRanges === undefined) {
92                 map.set(ruleName, [{ pos: start, end: end }]);
93             }
94             else if (disableRanges[disableRanges.length - 1].end !== -1) {
95                 disableRanges.push({ pos: start, end: end });
96             }
97         }
98     }
99 }
100 /** End will be -1 to indicate no end. */
101 function getSwitchRange(modifier, range, sourceFile) {
102     var lineStarts = sourceFile.getLineStarts();
103     switch (modifier) {
104         case "line":
105             return {
106                 // start at the beginning of the line where comment starts
107                 pos: getStartOfLinePosition(range.pos),
108                 // end at the beginning of the line following the comment
109                 end: getStartOfLinePosition(range.end, 1),
110             };
111         case "next-line":
112             // start at the beginning of the line following the comment
113             var pos = getStartOfLinePosition(range.end, 1);
114             if (pos === -1) {
115                 // no need to switch anything, there is no next line
116                 return undefined;
117             }
118             // end at the beginning of the line following the next line
119             return { pos: pos, end: getStartOfLinePosition(range.end, 2) };
120         default:
121             // switch rule for the rest of the file
122             // start at the current position, but skip end position
123             return { pos: range.pos, end: -1 };
124     }
125     /** Returns -1 for last line. */
126     function getStartOfLinePosition(position, lineOffset) {
127         if (lineOffset === void 0) { lineOffset = 0; }
128         var line = ts.getLineAndCharacterOfPosition(sourceFile, position).line + lineOffset;
129         return line >= lineStarts.length ? -1 : lineStarts[line];
130     }
131 }
132 function parseComment(commentText) {
133     var match = exports.ENABLE_DISABLE_REGEX.exec(commentText);
134     if (match === null) {
135         return undefined;
136     }
137     // remove everything matched by the previous regex to get only the specified rules
138     // split at whitespaces
139     // filter empty items coming from whitespaces at start, at end or empty list
140     var rulesList = splitOnSpaces(commentText.substr(match[0].length));
141     if (rulesList.length === 0 && match[3] === ":") {
142         // nothing to do here: an explicit separator was specified but no rules to switch
143         return undefined;
144     }
145     if (rulesList.length === 0 || rulesList.indexOf("all") !== -1) {
146         // if list is empty we default to all enabled rules
147         // if `all` is specified we ignore the other rules and take all enabled rules
148         rulesList = "all";
149     }
150     return { rulesList: rulesList, isEnabled: match[1] === "enable", modifier: match[2] };
151 }
152 function splitOnSpaces(str) {
153     return str.split(/\s+/).filter(function (s) { return s !== ""; });
154 }