0d4e7e15bb6aaee9ef391af222b36052da84573d
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / @typescript-eslint / typescript-estree / dist / node-utils.js
1 "use strict";
2 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3     if (k2 === undefined) k2 = k;
4     Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5 }) : (function(o, m, k, k2) {
6     if (k2 === undefined) k2 = k;
7     o[k2] = m[k];
8 }));
9 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10     Object.defineProperty(o, "default", { enumerable: true, value: v });
11 }) : function(o, v) {
12     o["default"] = v;
13 });
14 var __importStar = (this && this.__importStar) || function (mod) {
15     if (mod && mod.__esModule) return mod;
16     var result = {};
17     if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18     __setModuleDefault(result, mod);
19     return result;
20 };
21 var __importDefault = (this && this.__importDefault) || function (mod) {
22     return (mod && mod.__esModule) ? mod : { "default": mod };
23 };
24 Object.defineProperty(exports, "__esModule", { value: true });
25 exports.firstDefined = exports.nodeHasTokens = exports.createError = exports.convertTokens = exports.convertToken = exports.getTokenType = exports.isChildOptionalChain = exports.isOptionalChain = exports.isOptional = exports.isComputedProperty = exports.unescapeStringLiteralText = exports.hasJSXAncestor = exports.findFirstMatchingAncestor = exports.findNextToken = exports.getTSNodeAccessibility = exports.getDeclarationKind = exports.isJSXToken = exports.isToken = exports.getRange = exports.canContainDirective = exports.getLocFor = exports.getLineAndCharacterFor = exports.getBinaryExpressionType = exports.isJSDocComment = exports.isComment = exports.isComma = exports.getLastModifier = exports.hasModifier = exports.isESTreeClassMember = exports.getTextForTokenKind = exports.isLogicalOperator = exports.isAssignmentOperator = void 0;
26 const unescape_1 = __importDefault(require("lodash/unescape"));
27 const semver = __importStar(require("semver"));
28 const ts = __importStar(require("typescript"));
29 const ts_estree_1 = require("./ts-estree");
30 const SyntaxKind = ts.SyntaxKind;
31 const LOGICAL_OPERATORS = [
32     SyntaxKind.BarBarToken,
33     SyntaxKind.AmpersandAmpersandToken,
34     SyntaxKind.QuestionQuestionToken,
35 ];
36 /**
37  * Returns true if the given ts.Token is the assignment operator
38  * @param operator the operator token
39  * @returns is assignment
40  */
41 function isAssignmentOperator(operator) {
42     return (operator.kind >= SyntaxKind.FirstAssignment &&
43         operator.kind <= SyntaxKind.LastAssignment);
44 }
45 exports.isAssignmentOperator = isAssignmentOperator;
46 /**
47  * Returns true if the given ts.Token is a logical operator
48  * @param operator the operator token
49  * @returns is a logical operator
50  */
51 function isLogicalOperator(operator) {
52     return LOGICAL_OPERATORS.includes(operator.kind);
53 }
54 exports.isLogicalOperator = isLogicalOperator;
55 /**
56  * Returns the string form of the given TSToken SyntaxKind
57  * @param kind the token's SyntaxKind
58  * @returns the token applicable token as a string
59  */
60 function getTextForTokenKind(kind) {
61     return ts.tokenToString(kind);
62 }
63 exports.getTextForTokenKind = getTextForTokenKind;
64 /**
65  * Returns true if the given ts.Node is a valid ESTree class member
66  * @param node TypeScript AST node
67  * @returns is valid ESTree class member
68  */
69 function isESTreeClassMember(node) {
70     return node.kind !== SyntaxKind.SemicolonClassElement;
71 }
72 exports.isESTreeClassMember = isESTreeClassMember;
73 /**
74  * Checks if a ts.Node has a modifier
75  * @param modifierKind TypeScript SyntaxKind modifier
76  * @param node TypeScript AST node
77  * @returns has the modifier specified
78  */
79 function hasModifier(modifierKind, node) {
80     return (!!node.modifiers &&
81         !!node.modifiers.length &&
82         node.modifiers.some(modifier => modifier.kind === modifierKind));
83 }
84 exports.hasModifier = hasModifier;
85 /**
86  * Get last last modifier in ast
87  * @param node TypeScript AST node
88  * @returns returns last modifier if present or null
89  */
90 function getLastModifier(node) {
91     return ((!!node.modifiers &&
92         !!node.modifiers.length &&
93         node.modifiers[node.modifiers.length - 1]) ||
94         null);
95 }
96 exports.getLastModifier = getLastModifier;
97 /**
98  * Returns true if the given ts.Token is a comma
99  * @param token the TypeScript token
100  * @returns is comma
101  */
102 function isComma(token) {
103     return token.kind === SyntaxKind.CommaToken;
104 }
105 exports.isComma = isComma;
106 /**
107  * Returns true if the given ts.Node is a comment
108  * @param node the TypeScript node
109  * @returns is comment
110  */
111 function isComment(node) {
112     return (node.kind === SyntaxKind.SingleLineCommentTrivia ||
113         node.kind === SyntaxKind.MultiLineCommentTrivia);
114 }
115 exports.isComment = isComment;
116 /**
117  * Returns true if the given ts.Node is a JSDoc comment
118  * @param node the TypeScript node
119  * @returns is JSDoc comment
120  */
121 function isJSDocComment(node) {
122     return node.kind === SyntaxKind.JSDocComment;
123 }
124 exports.isJSDocComment = isJSDocComment;
125 /**
126  * Returns the binary expression type of the given ts.Token
127  * @param operator the operator token
128  * @returns the binary expression type
129  */
130 function getBinaryExpressionType(operator) {
131     if (isAssignmentOperator(operator)) {
132         return ts_estree_1.AST_NODE_TYPES.AssignmentExpression;
133     }
134     else if (isLogicalOperator(operator)) {
135         return ts_estree_1.AST_NODE_TYPES.LogicalExpression;
136     }
137     return ts_estree_1.AST_NODE_TYPES.BinaryExpression;
138 }
139 exports.getBinaryExpressionType = getBinaryExpressionType;
140 /**
141  * Returns line and column data for the given positions,
142  * @param pos position to check
143  * @param ast the AST object
144  * @returns line and column
145  */
146 function getLineAndCharacterFor(pos, ast) {
147     const loc = ast.getLineAndCharacterOfPosition(pos);
148     return {
149         line: loc.line + 1,
150         column: loc.character,
151     };
152 }
153 exports.getLineAndCharacterFor = getLineAndCharacterFor;
154 /**
155  * Returns line and column data for the given start and end positions,
156  * for the given AST
157  * @param start start data
158  * @param end   end data
159  * @param ast   the AST object
160  * @returns the loc data
161  */
162 function getLocFor(start, end, ast) {
163     return {
164         start: getLineAndCharacterFor(start, ast),
165         end: getLineAndCharacterFor(end, ast),
166     };
167 }
168 exports.getLocFor = getLocFor;
169 /**
170  * Check whatever node can contain directive
171  * @param node
172  * @returns returns true if node can contain directive
173  */
174 function canContainDirective(node) {
175     if (node.kind === ts.SyntaxKind.Block) {
176         switch (node.parent.kind) {
177             case ts.SyntaxKind.Constructor:
178             case ts.SyntaxKind.GetAccessor:
179             case ts.SyntaxKind.SetAccessor:
180             case ts.SyntaxKind.ArrowFunction:
181             case ts.SyntaxKind.FunctionExpression:
182             case ts.SyntaxKind.FunctionDeclaration:
183             case ts.SyntaxKind.MethodDeclaration:
184                 return true;
185             default:
186                 return false;
187         }
188     }
189     return true;
190 }
191 exports.canContainDirective = canContainDirective;
192 /**
193  * Returns range for the given ts.Node
194  * @param node the ts.Node or ts.Token
195  * @param ast the AST object
196  * @returns the range data
197  */
198 function getRange(node, ast) {
199     return [node.getStart(ast), node.getEnd()];
200 }
201 exports.getRange = getRange;
202 /**
203  * Returns true if a given ts.Node is a token
204  * @param node the ts.Node
205  * @returns is a token
206  */
207 function isToken(node) {
208     return (node.kind >= SyntaxKind.FirstToken && node.kind <= SyntaxKind.LastToken);
209 }
210 exports.isToken = isToken;
211 /**
212  * Returns true if a given ts.Node is a JSX token
213  * @param node ts.Node to be checked
214  * @returns is a JSX token
215  */
216 function isJSXToken(node) {
217     return (node.kind >= SyntaxKind.JsxElement && node.kind <= SyntaxKind.JsxAttribute);
218 }
219 exports.isJSXToken = isJSXToken;
220 /**
221  * Returns the declaration kind of the given ts.Node
222  * @param node TypeScript AST node
223  * @returns declaration kind
224  */
225 function getDeclarationKind(node) {
226     if (node.flags & ts.NodeFlags.Let) {
227         return 'let';
228     }
229     if (node.flags & ts.NodeFlags.Const) {
230         return 'const';
231     }
232     return 'var';
233 }
234 exports.getDeclarationKind = getDeclarationKind;
235 /**
236  * Gets a ts.Node's accessibility level
237  * @param node The ts.Node
238  * @returns accessibility "public", "protected", "private", or null
239  */
240 function getTSNodeAccessibility(node) {
241     const modifiers = node.modifiers;
242     if (!modifiers) {
243         return null;
244     }
245     for (let i = 0; i < modifiers.length; i++) {
246         const modifier = modifiers[i];
247         switch (modifier.kind) {
248             case SyntaxKind.PublicKeyword:
249                 return 'public';
250             case SyntaxKind.ProtectedKeyword:
251                 return 'protected';
252             case SyntaxKind.PrivateKeyword:
253                 return 'private';
254             default:
255                 break;
256         }
257     }
258     return null;
259 }
260 exports.getTSNodeAccessibility = getTSNodeAccessibility;
261 /**
262  * Finds the next token based on the previous one and its parent
263  * Had to copy this from TS instead of using TS's version because theirs doesn't pass the ast to getChildren
264  * @param previousToken The previous TSToken
265  * @param parent The parent TSNode
266  * @param ast The TS AST
267  * @returns the next TSToken
268  */
269 function findNextToken(previousToken, parent, ast) {
270     return find(parent);
271     function find(n) {
272         if (ts.isToken(n) && n.pos === previousToken.end) {
273             // this is token that starts at the end of previous token - return it
274             return n;
275         }
276         return firstDefined(n.getChildren(ast), (child) => {
277             const shouldDiveInChildNode = 
278             // previous token is enclosed somewhere in the child
279             (child.pos <= previousToken.pos && child.end > previousToken.end) ||
280                 // previous token ends exactly at the beginning of child
281                 child.pos === previousToken.end;
282             return shouldDiveInChildNode && nodeHasTokens(child, ast)
283                 ? find(child)
284                 : undefined;
285         });
286     }
287 }
288 exports.findNextToken = findNextToken;
289 /**
290  * Find the first matching ancestor based on the given predicate function.
291  * @param node The current ts.Node
292  * @param predicate The predicate function to apply to each checked ancestor
293  * @returns a matching parent ts.Node
294  */
295 function findFirstMatchingAncestor(node, predicate) {
296     while (node) {
297         if (predicate(node)) {
298             return node;
299         }
300         node = node.parent;
301     }
302     return undefined;
303 }
304 exports.findFirstMatchingAncestor = findFirstMatchingAncestor;
305 /**
306  * Returns true if a given ts.Node has a JSX token within its hierarchy
307  * @param node ts.Node to be checked
308  * @returns has JSX ancestor
309  */
310 function hasJSXAncestor(node) {
311     return !!findFirstMatchingAncestor(node, isJSXToken);
312 }
313 exports.hasJSXAncestor = hasJSXAncestor;
314 /**
315  * Unescape the text content of string literals, e.g. &amp; -> &
316  * @param text The escaped string literal text.
317  * @returns The unescaped string literal text.
318  */
319 function unescapeStringLiteralText(text) {
320     return unescape_1.default(text);
321 }
322 exports.unescapeStringLiteralText = unescapeStringLiteralText;
323 /**
324  * Returns true if a given ts.Node is a computed property
325  * @param node ts.Node to be checked
326  * @returns is Computed Property
327  */
328 function isComputedProperty(node) {
329     return node.kind === SyntaxKind.ComputedPropertyName;
330 }
331 exports.isComputedProperty = isComputedProperty;
332 /**
333  * Returns true if a given ts.Node is optional (has QuestionToken)
334  * @param node ts.Node to be checked
335  * @returns is Optional
336  */
337 function isOptional(node) {
338     return node.questionToken
339         ? node.questionToken.kind === SyntaxKind.QuestionToken
340         : false;
341 }
342 exports.isOptional = isOptional;
343 /**
344  * Returns true if the node is an optional chain node
345  */
346 function isOptionalChain(node) {
347     return (node.type === ts_estree_1.AST_NODE_TYPES.OptionalCallExpression ||
348         node.type == ts_estree_1.AST_NODE_TYPES.OptionalMemberExpression);
349 }
350 exports.isOptionalChain = isOptionalChain;
351 /**
352  * Returns true if the current TS version is TS 3.9
353  */
354 function isTSv3dot9() {
355     return !semver.satisfies(ts.version, '< 3.9.0 || < 3.9.1-rc || < 3.9.0-beta');
356 }
357 /**
358  * Returns true of the child of property access expression is an optional chain
359  */
360 function isChildOptionalChain(node, object) {
361     if (isOptionalChain(object) &&
362         // (x?.y).z is semantically different, and as such .z is no longer optional
363         node.expression.kind !== ts.SyntaxKind.ParenthesizedExpression) {
364         return true;
365     }
366     if (!isTSv3dot9()) {
367         return false;
368     }
369     // TS3.9 made a breaking change to how non-null works with optional chains.
370     // Pre-3.9,  `x?.y!.z` means `(x?.y).z` - i.e. it essentially scrubbed the optionality from the chain
371     // Post-3.9, `x?.y!.z` means `x?.y!.z`  - i.e. it just asserts that the property `y` is non-null, not the result of `x?.y`
372     if (object.type !== ts_estree_1.AST_NODE_TYPES.TSNonNullExpression ||
373         !isOptionalChain(object.expression)) {
374         return false;
375     }
376     if (
377     // make sure it's not (x.y)!.z
378     node.expression.kind === ts.SyntaxKind.NonNullExpression &&
379         node.expression.expression.kind !==
380             ts.SyntaxKind.ParenthesizedExpression) {
381         return true;
382     }
383     return false;
384 }
385 exports.isChildOptionalChain = isChildOptionalChain;
386 /**
387  * Returns the type of a given ts.Token
388  * @param token the ts.Token
389  * @returns the token type
390  */
391 function getTokenType(token) {
392     if ('originalKeywordKind' in token && token.originalKeywordKind) {
393         if (token.originalKeywordKind === SyntaxKind.NullKeyword) {
394             return ts_estree_1.AST_TOKEN_TYPES.Null;
395         }
396         else if (token.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord &&
397             token.originalKeywordKind <= SyntaxKind.LastKeyword) {
398             return ts_estree_1.AST_TOKEN_TYPES.Identifier;
399         }
400         return ts_estree_1.AST_TOKEN_TYPES.Keyword;
401     }
402     if (token.kind >= SyntaxKind.FirstKeyword &&
403         token.kind <= SyntaxKind.LastFutureReservedWord) {
404         if (token.kind === SyntaxKind.FalseKeyword ||
405             token.kind === SyntaxKind.TrueKeyword) {
406             return ts_estree_1.AST_TOKEN_TYPES.Boolean;
407         }
408         return ts_estree_1.AST_TOKEN_TYPES.Keyword;
409     }
410     if (token.kind >= SyntaxKind.FirstPunctuation &&
411         token.kind <= SyntaxKind.LastBinaryOperator) {
412         return ts_estree_1.AST_TOKEN_TYPES.Punctuator;
413     }
414     if (token.kind >= SyntaxKind.NoSubstitutionTemplateLiteral &&
415         token.kind <= SyntaxKind.TemplateTail) {
416         return ts_estree_1.AST_TOKEN_TYPES.Template;
417     }
418     switch (token.kind) {
419         case SyntaxKind.NumericLiteral:
420             return ts_estree_1.AST_TOKEN_TYPES.Numeric;
421         case SyntaxKind.JsxText:
422             return ts_estree_1.AST_TOKEN_TYPES.JSXText;
423         case SyntaxKind.StringLiteral:
424             // A TypeScript-StringLiteral token with a TypeScript-JsxAttribute or TypeScript-JsxElement parent,
425             // must actually be an ESTree-JSXText token
426             if (token.parent &&
427                 (token.parent.kind === SyntaxKind.JsxAttribute ||
428                     token.parent.kind === SyntaxKind.JsxElement)) {
429                 return ts_estree_1.AST_TOKEN_TYPES.JSXText;
430             }
431             return ts_estree_1.AST_TOKEN_TYPES.String;
432         case SyntaxKind.RegularExpressionLiteral:
433             return ts_estree_1.AST_TOKEN_TYPES.RegularExpression;
434         case SyntaxKind.Identifier:
435         case SyntaxKind.ConstructorKeyword:
436         case SyntaxKind.GetKeyword:
437         case SyntaxKind.SetKeyword:
438         // falls through
439         default:
440     }
441     // Some JSX tokens have to be determined based on their parent
442     if (token.parent && token.kind === SyntaxKind.Identifier) {
443         if (isJSXToken(token.parent)) {
444             return ts_estree_1.AST_TOKEN_TYPES.JSXIdentifier;
445         }
446         if (token.parent.kind === SyntaxKind.PropertyAccessExpression &&
447             hasJSXAncestor(token)) {
448             return ts_estree_1.AST_TOKEN_TYPES.JSXIdentifier;
449         }
450     }
451     return ts_estree_1.AST_TOKEN_TYPES.Identifier;
452 }
453 exports.getTokenType = getTokenType;
454 /**
455  * Extends and formats a given ts.Token, for a given AST
456  * @param token the ts.Token
457  * @param ast   the AST object
458  * @returns the converted Token
459  */
460 function convertToken(token, ast) {
461     const start = token.kind === SyntaxKind.JsxText
462         ? token.getFullStart()
463         : token.getStart(ast);
464     const end = token.getEnd();
465     const value = ast.text.slice(start, end);
466     const tokenType = getTokenType(token);
467     if (tokenType === ts_estree_1.AST_TOKEN_TYPES.RegularExpression) {
468         return {
469             type: tokenType,
470             value,
471             range: [start, end],
472             loc: getLocFor(start, end, ast),
473             regex: {
474                 pattern: value.slice(1, value.lastIndexOf('/')),
475                 flags: value.slice(value.lastIndexOf('/') + 1),
476             },
477         };
478     }
479     else {
480         return {
481             type: tokenType,
482             value,
483             range: [start, end],
484             loc: getLocFor(start, end, ast),
485         };
486     }
487 }
488 exports.convertToken = convertToken;
489 /**
490  * Converts all tokens for the given AST
491  * @param ast the AST object
492  * @returns the converted Tokens
493  */
494 function convertTokens(ast) {
495     const result = [];
496     /**
497      * @param node the ts.Node
498      */
499     function walk(node) {
500         // TypeScript generates tokens for types in JSDoc blocks. Comment tokens
501         // and their children should not be walked or added to the resulting tokens list.
502         if (isComment(node) || isJSDocComment(node)) {
503             return;
504         }
505         if (isToken(node) && node.kind !== SyntaxKind.EndOfFileToken) {
506             const converted = convertToken(node, ast);
507             if (converted) {
508                 result.push(converted);
509             }
510         }
511         else {
512             node.getChildren(ast).forEach(walk);
513         }
514     }
515     walk(ast);
516     return result;
517 }
518 exports.convertTokens = convertTokens;
519 /**
520  * @param ast     the AST object
521  * @param start      the index at which the error starts
522  * @param message the error message
523  * @returns converted error object
524  */
525 function createError(ast, start, message) {
526     const loc = ast.getLineAndCharacterOfPosition(start);
527     return {
528         index: start,
529         lineNumber: loc.line + 1,
530         column: loc.character,
531         message,
532     };
533 }
534 exports.createError = createError;
535 /**
536  * @param n the TSNode
537  * @param ast the TS AST
538  */
539 function nodeHasTokens(n, ast) {
540     // If we have a token or node that has a non-zero width, it must have tokens.
541     // Note: getWidth() does not take trivia into account.
542     return n.kind === SyntaxKind.EndOfFileToken
543         ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
544             !!n.jsDoc
545         : n.getWidth(ast) !== 0;
546 }
547 exports.nodeHasTokens = nodeHasTokens;
548 /**
549  * Like `forEach`, but suitable for use with numbers and strings (which may be falsy).
550  * @template T
551  * @template U
552  * @param array
553  * @param callback
554  */
555 function firstDefined(array, callback) {
556     if (array === undefined) {
557         return undefined;
558     }
559     for (let i = 0; i < array.length; i++) {
560         const result = callback(array[i], i);
561         if (result !== undefined) {
562             return result;
563         }
564     }
565     return undefined;
566 }
567 exports.firstDefined = firstDefined;
568 //# sourceMappingURL=node-utils.js.map