.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tslint / lib / language / utils.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 path = require("path");
20 var tsutils_1 = require("tsutils");
21 var ts = require("typescript");
22 function getSourceFile(fileName, source) {
23     var normalizedName = path.normalize(fileName).replace(/\\/g, "/");
24     return ts.createSourceFile(normalizedName, source, ts.ScriptTarget.ES5, 
25     /*setParentNodes*/ true);
26 }
27 exports.getSourceFile = getSourceFile;
28 /** @deprecated See IDisabledInterval. */
29 function doesIntersect(failure, 
30 // tslint:disable-next-line:deprecation
31 disabledIntervals) {
32     return disabledIntervals.some(function (interval) {
33         var maxStart = Math.max(interval.startPosition, failure.getStartPosition().getPosition());
34         var minEnd = Math.min(interval.endPosition, failure.getEndPosition().getPosition());
35         return maxStart <= minEnd;
36     });
37 }
38 exports.doesIntersect = doesIntersect;
39 /**
40  * @returns true if any modifier kinds passed along exist in the given modifiers array
41  *
42  * @deprecated use `hasModifier` from `tsutils`
43  */
44 function hasModifier(modifiers) {
45     var modifierKinds = [];
46     for (var _i = 1; _i < arguments.length; _i++) {
47         modifierKinds[_i - 1] = arguments[_i];
48     }
49     if (modifiers === undefined || modifierKinds.length === 0) {
50         return false;
51     }
52     return modifiers.some(function (m) { return modifierKinds.some(function (k) { return m.kind === k; }); });
53 }
54 exports.hasModifier = hasModifier;
55 /**
56  * Determines if the appropriate bit in the parent (VariableDeclarationList) is set,
57  * which indicates this is a "let" or "const".
58  *
59  * @deprecated use `isBlockScopedVariableDeclarationList` from `tsutils`
60  */
61 function isBlockScopedVariable(node) {
62     if (node.kind === ts.SyntaxKind.VariableDeclaration) {
63         var parent = node.parent;
64         return (parent.kind === ts.SyntaxKind.CatchClause ||
65             tsutils_1.isBlockScopedVariableDeclarationList(parent));
66     }
67     else {
68         return tsutils_1.isBlockScopedVariableDeclarationList(node.declarationList);
69     }
70 }
71 exports.isBlockScopedVariable = isBlockScopedVariable;
72 /** @deprecated use `isBlockScopedVariableDeclarationList` and `getDeclarationOfBindingElement` from `tsutils` */
73 function isBlockScopedBindingElement(node) {
74     var variableDeclaration = getBindingElementVariableDeclaration(node); // tslint:disable-line:deprecation
75     // if no variable declaration, it must be a function param, which is block scoped
76     return variableDeclaration === null || isBlockScopedVariable(variableDeclaration); // tslint:disable-line:deprecation
77 }
78 exports.isBlockScopedBindingElement = isBlockScopedBindingElement;
79 /** @deprecated use `getDeclarationOfBindingElement` from `tsutils` */
80 function getBindingElementVariableDeclaration(node) {
81     var currentParent = node.parent;
82     while (currentParent.kind !== ts.SyntaxKind.VariableDeclaration) {
83         if (currentParent.parent === undefined) {
84             return null; // function parameter, no variable declaration
85         }
86         else {
87             currentParent = currentParent.parent;
88         }
89     }
90     return currentParent;
91 }
92 exports.getBindingElementVariableDeclaration = getBindingElementVariableDeclaration;
93 /**
94  * Finds a child of a given node with a given kind.
95  * Note: This uses `node.getChildren()`, which does extra parsing work to include tokens.
96  *
97  * @deprecated use `getChildOfKind` from `tsutils`
98  */
99 function childOfKind(node, kind) {
100     return node.getChildren().find(function (child) { return child.kind === kind; });
101 }
102 exports.childOfKind = childOfKind;
103 /**
104  * @returns true if some ancestor of `node` satisfies `predicate`, including `node` itself.
105  *
106  * @deprecated no longer used, use a `while` loop instead
107  */
108 function someAncestor(node, predicate) {
109     return predicate(node) || (node.parent !== undefined && someAncestor(node.parent, predicate)); // tslint:disable-line:deprecation
110 }
111 exports.someAncestor = someAncestor;
112 function ancestorWhere(node, predicate) {
113     var cur = node;
114     do {
115         if (predicate(cur)) {
116             return cur;
117         }
118         cur = cur.parent;
119     } while (cur !== undefined);
120     return undefined;
121 }
122 exports.ancestorWhere = ancestorWhere;
123 /** @deprecated use `isBinaryExpression(node) && isAssignmentKind(node.operatorToken.kind)` with functions from `tsutils` */
124 function isAssignment(node) {
125     if (node.kind === ts.SyntaxKind.BinaryExpression) {
126         var binaryExpression = node;
127         return (binaryExpression.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
128             binaryExpression.operatorToken.kind <= ts.SyntaxKind.LastAssignment);
129     }
130     else {
131         return false;
132     }
133 }
134 exports.isAssignment = isAssignment;
135 /**
136  * Bitwise check for node flags.
137  *
138  * @deprecated use `isNodeFlagSet` from `tsutils`
139  */
140 function isNodeFlagSet(node, flagToCheck) {
141     // tslint:disable-next-line:no-bitwise
142     return (node.flags & flagToCheck) !== 0;
143 }
144 exports.isNodeFlagSet = isNodeFlagSet;
145 /**
146  * Bitwise check for combined node flags.
147  *
148  * @deprecated no longer used
149  */
150 function isCombinedNodeFlagSet(node, flagToCheck) {
151     // tslint:disable-next-line:no-bitwise
152     return (ts.getCombinedNodeFlags(node) & flagToCheck) !== 0;
153 }
154 exports.isCombinedNodeFlagSet = isCombinedNodeFlagSet;
155 /**
156  * Bitwise check for combined modifier flags.
157  *
158  * @deprecated no longer used
159  */
160 function isCombinedModifierFlagSet(node, flagToCheck) {
161     // tslint:disable-next-line:no-bitwise
162     return (ts.getCombinedModifierFlags(node) & flagToCheck) !== 0;
163 }
164 exports.isCombinedModifierFlagSet = isCombinedModifierFlagSet;
165 /**
166  * Bitwise check for type flags.
167  *
168  * @deprecated use `isTypeFlagSet` from `tsutils`
169  */
170 function isTypeFlagSet(type, flagToCheck) {
171     // tslint:disable-next-line:no-bitwise
172     return (type.flags & flagToCheck) !== 0;
173 }
174 exports.isTypeFlagSet = isTypeFlagSet;
175 /**
176  * Bitwise check for symbol flags.
177  *
178  * @deprecated use `isSymbolFlagSet` from `tsutils`
179  */
180 function isSymbolFlagSet(symbol, flagToCheck) {
181     // tslint:disable-next-line:no-bitwise
182     return (symbol.flags & flagToCheck) !== 0;
183 }
184 exports.isSymbolFlagSet = isSymbolFlagSet;
185 /**
186  * Bitwise check for object flags.
187  * Does not work with TypeScript 2.0.x
188  *
189  * @deprecated use `isObjectFlagSet` from `tsutils`
190  */
191 function isObjectFlagSet(objectType, flagToCheck) {
192     // tslint:disable-next-line:no-bitwise
193     return (objectType.objectFlags & flagToCheck) !== 0;
194 }
195 exports.isObjectFlagSet = isObjectFlagSet;
196 /**
197  * @returns true if decl is a nested module declaration, i.e. represents a segment of a dotted module path.
198  *
199  * @deprecated use `decl.parent!.kind === ts.SyntaxKind.ModuleDeclaration`
200  */
201 function isNestedModuleDeclaration(decl) {
202     // in a declaration expression like 'module a.b.c' - 'a' is the top level module declaration node and 'b' and 'c'
203     // are nested therefore we can depend that a node's position will only match with its name's position for nested
204     // nodes
205     return decl.name.pos === decl.pos;
206 }
207 exports.isNestedModuleDeclaration = isNestedModuleDeclaration;
208 function unwrapParentheses(node) {
209     while (node.kind === ts.SyntaxKind.ParenthesizedExpression) {
210         node = node.expression;
211     }
212     return node;
213 }
214 exports.unwrapParentheses = unwrapParentheses;
215 /** @deprecated use `isFunctionScopeBoundary` from `tsutils` */
216 function isScopeBoundary(node) {
217     return (node.kind === ts.SyntaxKind.FunctionDeclaration ||
218         node.kind === ts.SyntaxKind.FunctionExpression ||
219         node.kind === ts.SyntaxKind.PropertyAssignment ||
220         node.kind === ts.SyntaxKind.ShorthandPropertyAssignment ||
221         node.kind === ts.SyntaxKind.MethodDeclaration ||
222         node.kind === ts.SyntaxKind.Constructor ||
223         node.kind === ts.SyntaxKind.ModuleDeclaration ||
224         node.kind === ts.SyntaxKind.ArrowFunction ||
225         node.kind === ts.SyntaxKind.ParenthesizedExpression ||
226         node.kind === ts.SyntaxKind.ClassDeclaration ||
227         node.kind === ts.SyntaxKind.ClassExpression ||
228         node.kind === ts.SyntaxKind.InterfaceDeclaration ||
229         node.kind === ts.SyntaxKind.GetAccessor ||
230         node.kind === ts.SyntaxKind.SetAccessor ||
231         (node.kind === ts.SyntaxKind.SourceFile && ts.isExternalModule(node)));
232 }
233 exports.isScopeBoundary = isScopeBoundary;
234 /** @deprecated use `isBlockScopeBoundary` from `tsutils` */
235 function isBlockScopeBoundary(node) {
236     return (isScopeBoundary(node) || // tslint:disable-line:deprecation
237         node.kind === ts.SyntaxKind.Block ||
238         isLoop(node) || // tslint:disable-line:deprecation
239         node.kind === ts.SyntaxKind.WithStatement ||
240         node.kind === ts.SyntaxKind.SwitchStatement ||
241         (node.parent !== undefined &&
242             (node.parent.kind === ts.SyntaxKind.TryStatement ||
243                 node.parent.kind === ts.SyntaxKind.IfStatement)));
244 }
245 exports.isBlockScopeBoundary = isBlockScopeBoundary;
246 /** @deprecated use `isIterationStatement` from `tsutils` or `typescript` */
247 function isLoop(node) {
248     return (node.kind === ts.SyntaxKind.DoStatement ||
249         node.kind === ts.SyntaxKind.WhileStatement ||
250         node.kind === ts.SyntaxKind.ForStatement ||
251         node.kind === ts.SyntaxKind.ForInStatement ||
252         node.kind === ts.SyntaxKind.ForOfStatement);
253 }
254 exports.isLoop = isLoop;
255 /**
256  * @returns Whether node is a numeric expression.
257  */
258 function isNumeric(node) {
259     while (tsutils_1.isPrefixUnaryExpression(node) &&
260         (node.operator === ts.SyntaxKind.PlusToken || node.operator === ts.SyntaxKind.MinusToken)) {
261         node = node.operand;
262     }
263     return (node.kind === ts.SyntaxKind.NumericLiteral ||
264         (tsutils_1.isIdentifier(node) && (node.text === "NaN" || node.text === "Infinity")));
265 }
266 exports.isNumeric = isNumeric;
267 /**
268  * Iterate over all tokens of `node`
269  *
270  * @description JsDoc comments are treated like regular comments and only visited if `skipTrivia` === false.
271  *
272  * @param node The node whose tokens should be visited
273  * @param skipTrivia If set to false all trivia preceeding `node` or any of its children is included
274  * @param cb Is called for every token of `node`. It gets the full text of the SourceFile and the position of the token within that text.
275  * @param filter If provided, will be called for every Node and Token found. If it returns false `cb` will not be called for this subtree.
276  *
277  * @deprecated use `forEachToken` or `forEachTokenWithTrivia` from `tsutils`
278  */
279 function forEachToken(node, skipTrivia, cb, filter) {
280     // this function will most likely be called with SourceFile anyways, so there is no need for an additional parameter
281     var sourceFile = node.getSourceFile();
282     var fullText = sourceFile.text;
283     var iterateFn = filter === undefined ? iterateChildren : iterateWithFilter;
284     var handleTrivia = skipTrivia ? undefined : createTriviaHandler(sourceFile, cb);
285     iterateFn(node);
286     // this function is used to save the if condition for the common case where no filter is provided
287     function iterateWithFilter(child) {
288         if (filter(child)) {
289             return iterateChildren(child);
290         }
291     }
292     function iterateChildren(child) {
293         if (child.kind < ts.SyntaxKind.FirstNode ||
294             // for backwards compatibility to typescript 2.0.10
295             // JsxText was no Token, but a Node in that version
296             child.kind === ts.SyntaxKind.JsxText) {
297             // we found a token, tokens have no children, stop recursing here
298             return callback(child);
299         }
300         /* Exclude everything contained in JsDoc, it will be handled with the other trivia anyway.
301          * When we would handle JsDoc tokens like regular ones, we would scan some trivia multiple times.
302          * Even worse, we would scan for trivia inside the JsDoc comment, which yields unexpected results.*/
303         if (child.kind !== ts.SyntaxKind.JSDocComment) {
304             // recurse into Node's children to find tokens
305             return child.getChildren(sourceFile).forEach(iterateFn);
306         }
307     }
308     function callback(token) {
309         var tokenStart = token.getStart(sourceFile);
310         if (!skipTrivia && tokenStart !== token.pos) {
311             // we only have to handle trivia before each token, because there is nothing after EndOfFileToken
312             handleTrivia(token.pos, tokenStart, token);
313         }
314         return cb(fullText, token.kind, { tokenStart: tokenStart, fullStart: token.pos, end: token.end }, token.parent);
315     }
316 }
317 exports.forEachToken = forEachToken;
318 function createTriviaHandler(sourceFile, cb) {
319     var fullText = sourceFile.text;
320     var scanner = ts.createScanner(sourceFile.languageVersion, false, sourceFile.languageVariant, fullText);
321     /**
322      * Scan the specified range to get all trivia tokens.
323      * This includes trailing trivia of the last token and the leading trivia of the current token
324      */
325     function handleTrivia(start, end, token) {
326         var parent = token.parent;
327         // prevent false positives by not scanning inside JsxText
328         if (!canHaveLeadingTrivia(token.kind, parent)) {
329             return;
330         }
331         scanner.setTextPos(start);
332         var position;
333         // we only get here if start !== end, so we can scan at least one time
334         do {
335             var kind = scanner.scan();
336             position = scanner.getTextPos();
337             cb(fullText, kind, { tokenStart: scanner.getTokenPos(), end: position, fullStart: start }, parent);
338         } while (position < end);
339     }
340     return handleTrivia;
341 }
342 /**
343  * Iterate over all comments owned by `node` or its children
344  *
345  * @deprecated use `forEachComment` from `tsutils`
346  */
347 function forEachComment(node, cb) {
348     /* Visit all tokens and skip trivia.
349        Comment ranges between tokens are parsed without the need of a scanner.
350        forEachToken also does intentionally not pay attention to the correct comment ownership of nodes as it always
351        scans all trivia before each token, which could include trailing comments of the previous token.
352        Comment onwership is done right in this function*/
353     // tslint:disable-next-line:deprecation
354     return forEachToken(node, true, function (fullText, tokenKind, pos, parent) {
355         // don't search for comments inside JsxText
356         if (canHaveLeadingTrivia(tokenKind, parent)) {
357             // Comments before the first token (pos.fullStart === 0) are all considered leading comments, so no need for special treatment
358             var comments = ts.getLeadingCommentRanges(fullText, pos.fullStart);
359             if (comments !== undefined) {
360                 for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
361                     var comment = comments_1[_i];
362                     cb(fullText, comment.kind, {
363                         end: comment.end,
364                         fullStart: pos.fullStart,
365                         tokenStart: comment.pos,
366                     });
367                 }
368             }
369         }
370         if (canHaveTrailingTrivia(tokenKind, parent)) {
371             var comments = ts.getTrailingCommentRanges(fullText, pos.end);
372             if (comments !== undefined) {
373                 for (var _a = 0, comments_2 = comments; _a < comments_2.length; _a++) {
374                     var comment = comments_2[_a];
375                     cb(fullText, comment.kind, {
376                         end: comment.end,
377                         fullStart: pos.fullStart,
378                         tokenStart: comment.pos,
379                     });
380                 }
381             }
382         }
383     });
384 }
385 exports.forEachComment = forEachComment;
386 /** Exclude leading positions that would lead to scanning for trivia inside JsxText */
387 function canHaveLeadingTrivia(tokenKind, parent) {
388     switch (tokenKind) {
389         case ts.SyntaxKind.JsxText:
390             return false; // there is no trivia before JsxText
391         case ts.SyntaxKind.OpenBraceToken:
392             // before a JsxExpression inside a JsxElement's body can only be other JsxChild, but no trivia
393             return (parent.kind !== ts.SyntaxKind.JsxExpression ||
394                 parent.parent.kind !== ts.SyntaxKind.JsxElement);
395         case ts.SyntaxKind.LessThanToken:
396             switch (parent.kind) {
397                 case ts.SyntaxKind.JsxClosingElement:
398                     return false; // would be inside the element body
399                 case ts.SyntaxKind.JsxOpeningElement:
400                 case ts.SyntaxKind.JsxSelfClosingElement:
401                     // there can only be leading trivia if we are at the end of the top level element
402                     return parent.parent.parent.kind !== ts.SyntaxKind.JsxElement;
403                 default:
404                     return true;
405             }
406         default:
407             return true;
408     }
409 }
410 /** Exclude trailing positions that would lead to scanning for trivia inside JsxText */
411 function canHaveTrailingTrivia(tokenKind, parent) {
412     switch (tokenKind) {
413         case ts.SyntaxKind.JsxText:
414             // there is no trivia after JsxText
415             return false;
416         case ts.SyntaxKind.CloseBraceToken:
417             // after a JsxExpression inside a JsxElement's body can only be other JsxChild, but no trivia
418             return (parent.kind !== ts.SyntaxKind.JsxExpression ||
419                 parent.parent.kind !== ts.SyntaxKind.JsxElement);
420         case ts.SyntaxKind.GreaterThanToken:
421             switch (parent.kind) {
422                 case ts.SyntaxKind.JsxOpeningElement:
423                     return false; // would be inside the element
424                 case ts.SyntaxKind.JsxClosingElement:
425                 case ts.SyntaxKind.JsxSelfClosingElement:
426                     // there can only be trailing trivia if we are at the end of the top level element
427                     return parent.parent.parent.kind !== ts.SyntaxKind.JsxElement;
428                 default:
429                     return true;
430             }
431         default:
432             return true;
433     }
434 }
435 /**
436  * Checks if there are any comments between `position` and the next non-trivia token
437  *
438  * @param text The text to scan
439  * @param position The position inside `text` where to start scanning. Make sure that this is a valid start position.
440  *                 This value is typically obtained from `node.getFullStart()` or `node.getEnd()`
441  */
442 function hasCommentAfterPosition(text, position) {
443     return (ts.getTrailingCommentRanges(text, position) !== undefined ||
444         ts.getLeadingCommentRanges(text, position) !== undefined);
445 }
446 exports.hasCommentAfterPosition = hasCommentAfterPosition;
447 function getEqualsKind(node) {
448     switch (node.kind) {
449         case ts.SyntaxKind.EqualsEqualsToken:
450             return { isPositive: true, isStrict: false };
451         case ts.SyntaxKind.EqualsEqualsEqualsToken:
452             return { isPositive: true, isStrict: true };
453         case ts.SyntaxKind.ExclamationEqualsToken:
454             return { isPositive: false, isStrict: false };
455         case ts.SyntaxKind.ExclamationEqualsEqualsToken:
456             return { isPositive: false, isStrict: true };
457         default:
458             return undefined;
459     }
460 }
461 exports.getEqualsKind = getEqualsKind;
462 function isStrictNullChecksEnabled(options) {
463     return (options.strictNullChecks === true ||
464         (options.strict === true && options.strictNullChecks !== false));
465 }
466 exports.isStrictNullChecksEnabled = isStrictNullChecksEnabled;
467 function isNegativeNumberLiteral(node) {
468     return (tsutils_1.isPrefixUnaryExpression(node) &&
469         node.operator === ts.SyntaxKind.MinusToken &&
470         node.operand.kind === ts.SyntaxKind.NumericLiteral);
471 }
472 exports.isNegativeNumberLiteral = isNegativeNumberLiteral;
473 /** Wrapper for compatibility with typescript@<2.3.1 */
474 function isWhiteSpace(ch) {
475     // tslint:disable-next-line
476     return (ts.isWhiteSpaceLike || ts.isWhiteSpace)(ch);
477 }
478 exports.isWhiteSpace = isWhiteSpace;