.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tsutils / util / util.js
1 "use strict";\r
2 Object.defineProperty(exports, "__esModule", { value: true });\r
3 exports.isValidIdentifier = exports.getLineBreakStyle = exports.getLineRanges = exports.forEachComment = exports.forEachTokenWithTrivia = exports.forEachToken = exports.isFunctionWithBody = exports.hasOwnThisReference = exports.isBlockScopeBoundary = exports.isFunctionScopeBoundary = exports.isTypeScopeBoundary = exports.isScopeBoundary = exports.ScopeBoundarySelector = exports.ScopeBoundary = exports.isInSingleStatementContext = exports.isBlockScopedDeclarationStatement = exports.isBlockScopedVariableDeclaration = exports.isBlockScopedVariableDeclarationList = exports.getVariableDeclarationKind = exports.VariableDeclarationKind = exports.forEachDeclaredVariable = exports.forEachDestructuringIdentifier = exports.getPropertyName = exports.getWrappedNodeAtPosition = exports.getAstNodeAtPosition = exports.commentText = exports.isPositionInComment = exports.getCommentAtPosition = exports.getTokenAtPosition = exports.getNextToken = exports.getPreviousToken = exports.getNextStatement = exports.getPreviousStatement = exports.isModifierFlagSet = exports.isObjectFlagSet = exports.isSymbolFlagSet = exports.isTypeFlagSet = exports.isNodeFlagSet = exports.hasAccessModifier = exports.isParameterProperty = exports.hasModifier = exports.getModifier = exports.isThisParameter = exports.isKeywordKind = exports.isJsDocKind = exports.isTypeNodeKind = exports.isAssignmentKind = exports.isNodeKind = exports.isTokenKind = exports.getChildOfKind = void 0;\r
4 exports.getBaseOfClassLikeExpression = exports.hasExhaustiveCaseClauses = exports.formatPseudoBigInt = exports.unwrapParentheses = exports.getSingleLateBoundPropertyNameOfPropertyName = exports.getLateBoundPropertyNamesOfPropertyName = exports.getLateBoundPropertyNames = exports.getPropertyNameOfWellKnownSymbol = exports.isWellKnownSymbolLiterally = exports.isBindableObjectDefinePropertyCall = exports.isReadonlyAssignmentDeclaration = exports.isInConstContext = exports.isConstAssertion = exports.getTsCheckDirective = exports.getCheckJsDirective = exports.isAmbientModule = exports.isCompilerOptionEnabled = exports.isStrictCompilerOptionEnabled = exports.getIIFE = exports.isAmbientModuleBlock = exports.isStatementInAmbientContext = exports.findImportLikeNodes = exports.findImports = exports.ImportKind = exports.parseJsDocOfNode = exports.getJsDoc = exports.canHaveJsDoc = exports.isReassignmentTarget = exports.getAccessKind = exports.AccessKind = exports.isExpressionValueUsed = exports.getDeclarationOfBindingElement = exports.hasSideEffects = exports.SideEffectOptions = exports.isSameLine = exports.isNumericPropertyName = exports.isValidJsxIdentifier = exports.isValidNumericLiteral = exports.isValidPropertyName = exports.isValidPropertyAccess = void 0;\r
5 const ts = require("typescript");\r
6 const node_1 = require("../typeguard/node");\r
7 const _3_2_1 = require("../typeguard/3.2");\r
8 const type_1 = require("./type");\r
9 function getChildOfKind(node, kind, sourceFile) {\r
10     for (const child of node.getChildren(sourceFile))\r
11         if (child.kind === kind)\r
12             return child;\r
13 }\r
14 exports.getChildOfKind = getChildOfKind;\r
15 function isTokenKind(kind) {\r
16     return kind >= ts.SyntaxKind.FirstToken && kind <= ts.SyntaxKind.LastToken;\r
17 }\r
18 exports.isTokenKind = isTokenKind;\r
19 function isNodeKind(kind) {\r
20     return kind >= ts.SyntaxKind.FirstNode;\r
21 }\r
22 exports.isNodeKind = isNodeKind;\r
23 function isAssignmentKind(kind) {\r
24     return kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;\r
25 }\r
26 exports.isAssignmentKind = isAssignmentKind;\r
27 function isTypeNodeKind(kind) {\r
28     return kind >= ts.SyntaxKind.FirstTypeNode && kind <= ts.SyntaxKind.LastTypeNode;\r
29 }\r
30 exports.isTypeNodeKind = isTypeNodeKind;\r
31 function isJsDocKind(kind) {\r
32     return kind >= ts.SyntaxKind.FirstJSDocNode && kind <= ts.SyntaxKind.LastJSDocNode;\r
33 }\r
34 exports.isJsDocKind = isJsDocKind;\r
35 function isKeywordKind(kind) {\r
36     return kind >= ts.SyntaxKind.FirstKeyword && kind <= ts.SyntaxKind.LastKeyword;\r
37 }\r
38 exports.isKeywordKind = isKeywordKind;\r
39 function isThisParameter(parameter) {\r
40     return parameter.name.kind === ts.SyntaxKind.Identifier && parameter.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword;\r
41 }\r
42 exports.isThisParameter = isThisParameter;\r
43 function getModifier(node, kind) {\r
44     if (node.modifiers !== undefined)\r
45         for (const modifier of node.modifiers)\r
46             if (modifier.kind === kind)\r
47                 return modifier;\r
48 }\r
49 exports.getModifier = getModifier;\r
50 function hasModifier(modifiers, ...kinds) {\r
51     if (modifiers === undefined)\r
52         return false;\r
53     for (const modifier of modifiers)\r
54         if (kinds.includes(modifier.kind))\r
55             return true;\r
56     return false;\r
57 }\r
58 exports.hasModifier = hasModifier;\r
59 function isParameterProperty(node) {\r
60     return hasModifier(node.modifiers, ts.SyntaxKind.PublicKeyword, ts.SyntaxKind.ProtectedKeyword, ts.SyntaxKind.PrivateKeyword, ts.SyntaxKind.ReadonlyKeyword);\r
61 }\r
62 exports.isParameterProperty = isParameterProperty;\r
63 function hasAccessModifier(node) {\r
64     return isModifierFlagSet(node, ts.ModifierFlags.AccessibilityModifier);\r
65 }\r
66 exports.hasAccessModifier = hasAccessModifier;\r
67 function isFlagSet(obj, flag) {\r
68     return (obj.flags & flag) !== 0;\r
69 }\r
70 exports.isNodeFlagSet = isFlagSet;\r
71 exports.isTypeFlagSet = isFlagSet;\r
72 exports.isSymbolFlagSet = isFlagSet;\r
73 function isObjectFlagSet(objectType, flag) {\r
74     return (objectType.objectFlags & flag) !== 0;\r
75 }\r
76 exports.isObjectFlagSet = isObjectFlagSet;\r
77 function isModifierFlagSet(node, flag) {\r
78     return (ts.getCombinedModifierFlags(node) & flag) !== 0;\r
79 }\r
80 exports.isModifierFlagSet = isModifierFlagSet;\r
81 function getPreviousStatement(statement) {\r
82     const parent = statement.parent;\r
83     if (node_1.isBlockLike(parent)) {\r
84         const index = parent.statements.indexOf(statement);\r
85         if (index > 0)\r
86             return parent.statements[index - 1];\r
87     }\r
88 }\r
89 exports.getPreviousStatement = getPreviousStatement;\r
90 function getNextStatement(statement) {\r
91     const parent = statement.parent;\r
92     if (node_1.isBlockLike(parent)) {\r
93         const index = parent.statements.indexOf(statement);\r
94         if (index < parent.statements.length)\r
95             return parent.statements[index + 1];\r
96     }\r
97 }\r
98 exports.getNextStatement = getNextStatement;\r
99 /** Returns the token before the start of `node` or `undefined` if there is none. */\r
100 function getPreviousToken(node, sourceFile) {\r
101     const { pos } = node;\r
102     if (pos === 0)\r
103         return;\r
104     do\r
105         node = node.parent;\r
106     while (node.pos === pos);\r
107     return getTokenAtPositionWorker(node, pos - 1, sourceFile !== null && sourceFile !== void 0 ? sourceFile : node.getSourceFile(), false);\r
108 }\r
109 exports.getPreviousToken = getPreviousToken;\r
110 /** Returns the next token that begins after the end of `node`. Returns `undefined` for SourceFile and EndOfFileToken */\r
111 function getNextToken(node, sourceFile) {\r
112     if (node.kind === ts.SyntaxKind.SourceFile || node.kind === ts.SyntaxKind.EndOfFileToken)\r
113         return;\r
114     const end = node.end;\r
115     node = node.parent;\r
116     while (node.end === end) {\r
117         if (node.parent === undefined)\r
118             return node.endOfFileToken;\r
119         node = node.parent;\r
120     }\r
121     return getTokenAtPositionWorker(node, end, sourceFile !== null && sourceFile !== void 0 ? sourceFile : node.getSourceFile(), false);\r
122 }\r
123 exports.getNextToken = getNextToken;\r
124 /** Returns the token at or following the specified position or undefined if none is found inside `parent`. */\r
125 function getTokenAtPosition(parent, pos, sourceFile, allowJsDoc) {\r
126     if (pos < parent.pos || pos >= parent.end)\r
127         return;\r
128     if (isTokenKind(parent.kind))\r
129         return parent;\r
130     return getTokenAtPositionWorker(parent, pos, sourceFile !== null && sourceFile !== void 0 ? sourceFile : parent.getSourceFile(), allowJsDoc === true);\r
131 }\r
132 exports.getTokenAtPosition = getTokenAtPosition;\r
133 function getTokenAtPositionWorker(node, pos, sourceFile, allowJsDoc) {\r
134     if (!allowJsDoc) {\r
135         // if we are not interested in JSDoc, we can skip to the deepest AST node at the given position\r
136         node = getAstNodeAtPosition(node, pos);\r
137         if (isTokenKind(node.kind))\r
138             return node;\r
139     }\r
140     outer: while (true) {\r
141         for (const child of node.getChildren(sourceFile)) {\r
142             if (child.end > pos && (allowJsDoc || child.kind !== ts.SyntaxKind.JSDocComment)) {\r
143                 if (isTokenKind(child.kind))\r
144                     return child;\r
145                 // next token is nested in another node\r
146                 node = child;\r
147                 continue outer;\r
148             }\r
149         }\r
150         return;\r
151     }\r
152 }\r
153 /**\r
154  * Return the comment at the specified position.\r
155  * You can pass an optional `parent` to avoid some work finding the corresponding token starting at `sourceFile`.\r
156  * If the `parent` parameter is passed, `pos` must be between `parent.pos` and `parent.end`.\r
157 */\r
158 function getCommentAtPosition(sourceFile, pos, parent = sourceFile) {\r
159     const token = getTokenAtPosition(parent, pos, sourceFile);\r
160     if (token === undefined || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || '').length)\r
161         return;\r
162     const startPos = token.pos === 0\r
163         ? (ts.getShebang(sourceFile.text) || '').length\r
164         : token.pos;\r
165     return startPos !== 0 && ts.forEachTrailingCommentRange(sourceFile.text, startPos, commentAtPositionCallback, pos) ||\r
166         ts.forEachLeadingCommentRange(sourceFile.text, startPos, commentAtPositionCallback, pos);\r
167 }\r
168 exports.getCommentAtPosition = getCommentAtPosition;\r
169 function commentAtPositionCallback(pos, end, kind, _nl, at) {\r
170     return at >= pos && at < end ? { pos, end, kind } : undefined;\r
171 }\r
172 /**\r
173  * Returns whether the specified position is inside a comment.\r
174  * You can pass an optional `parent` to avoid some work finding the corresponding token starting at `sourceFile`.\r
175  * If the `parent` parameter is passed, `pos` must be between `parent.pos` and `parent.end`.\r
176  */\r
177 function isPositionInComment(sourceFile, pos, parent) {\r
178     return getCommentAtPosition(sourceFile, pos, parent) !== undefined;\r
179 }\r
180 exports.isPositionInComment = isPositionInComment;\r
181 function commentText(sourceText, comment) {\r
182     return sourceText.substring(comment.pos + 2, comment.kind === ts.SyntaxKind.SingleLineCommentTrivia ? comment.end : comment.end - 2);\r
183 }\r
184 exports.commentText = commentText;\r
185 /** Returns the deepest AST Node at `pos`. Returns undefined if `pos` is outside of the range of `node` */\r
186 function getAstNodeAtPosition(node, pos) {\r
187     if (node.pos > pos || node.end <= pos)\r
188         return;\r
189     while (isNodeKind(node.kind)) {\r
190         const nested = ts.forEachChild(node, (child) => child.pos <= pos && child.end > pos ? child : undefined);\r
191         if (nested === undefined)\r
192             break;\r
193         node = nested;\r
194     }\r
195     return node;\r
196 }\r
197 exports.getAstNodeAtPosition = getAstNodeAtPosition;\r
198 /**\r
199  * Returns the NodeWrap of deepest AST node that contains `pos` between its `pos` and `end`.\r
200  * Only returns undefined if pos is outside of `wrap`\r
201  */\r
202 function getWrappedNodeAtPosition(wrap, pos) {\r
203     if (wrap.node.pos > pos || wrap.node.end <= pos)\r
204         return;\r
205     outer: while (true) {\r
206         for (const child of wrap.children) {\r
207             if (child.node.pos > pos)\r
208                 return wrap;\r
209             if (child.node.end > pos) {\r
210                 wrap = child;\r
211                 continue outer;\r
212             }\r
213         }\r
214         return wrap;\r
215     }\r
216 }\r
217 exports.getWrappedNodeAtPosition = getWrappedNodeAtPosition;\r
218 function getPropertyName(propertyName) {\r
219     if (propertyName.kind === ts.SyntaxKind.ComputedPropertyName) {\r
220         const expression = unwrapParentheses(propertyName.expression);\r
221         if (node_1.isPrefixUnaryExpression(expression)) {\r
222             let negate = false;\r
223             switch (expression.operator) {\r
224                 case ts.SyntaxKind.MinusToken:\r
225                     negate = true;\r
226                 // falls through\r
227                 case ts.SyntaxKind.PlusToken:\r
228                     return node_1.isNumericLiteral(expression.operand)\r
229                         ? `${negate ? '-' : ''}${expression.operand.text}`\r
230                         : _3_2_1.isBigIntLiteral(expression.operand)\r
231                             ? `${negate ? '-' : ''}${expression.operand.text.slice(0, -1)}`\r
232                             : undefined;\r
233                 default:\r
234                     return;\r
235             }\r
236         }\r
237         if (_3_2_1.isBigIntLiteral(expression))\r
238             // handle BigInt, even though TypeScript doesn't allow BigInt as computed property name\r
239             return expression.text.slice(0, -1);\r
240         if (node_1.isNumericOrStringLikeLiteral(expression))\r
241             return expression.text;\r
242         return;\r
243     }\r
244     return propertyName.kind === ts.SyntaxKind.PrivateIdentifier ? undefined : propertyName.text;\r
245 }\r
246 exports.getPropertyName = getPropertyName;\r
247 function forEachDestructuringIdentifier(pattern, fn) {\r
248     for (const element of pattern.elements) {\r
249         if (element.kind !== ts.SyntaxKind.BindingElement)\r
250             continue;\r
251         let result;\r
252         if (element.name.kind === ts.SyntaxKind.Identifier) {\r
253             result = fn(element);\r
254         }\r
255         else {\r
256             result = forEachDestructuringIdentifier(element.name, fn);\r
257         }\r
258         if (result)\r
259             return result;\r
260     }\r
261 }\r
262 exports.forEachDestructuringIdentifier = forEachDestructuringIdentifier;\r
263 function forEachDeclaredVariable(declarationList, cb) {\r
264     for (const declaration of declarationList.declarations) {\r
265         let result;\r
266         if (declaration.name.kind === ts.SyntaxKind.Identifier) {\r
267             result = cb(declaration);\r
268         }\r
269         else {\r
270             result = forEachDestructuringIdentifier(declaration.name, cb);\r
271         }\r
272         if (result)\r
273             return result;\r
274     }\r
275 }\r
276 exports.forEachDeclaredVariable = forEachDeclaredVariable;\r
277 var VariableDeclarationKind;\r
278 (function (VariableDeclarationKind) {\r
279     VariableDeclarationKind[VariableDeclarationKind["Var"] = 0] = "Var";\r
280     VariableDeclarationKind[VariableDeclarationKind["Let"] = 1] = "Let";\r
281     VariableDeclarationKind[VariableDeclarationKind["Const"] = 2] = "Const";\r
282 })(VariableDeclarationKind = exports.VariableDeclarationKind || (exports.VariableDeclarationKind = {}));\r
283 function getVariableDeclarationKind(declarationList) {\r
284     if (declarationList.flags & ts.NodeFlags.Let)\r
285         return 1 /* Let */;\r
286     if (declarationList.flags & ts.NodeFlags.Const)\r
287         return 2 /* Const */;\r
288     return 0 /* Var */;\r
289 }\r
290 exports.getVariableDeclarationKind = getVariableDeclarationKind;\r
291 function isBlockScopedVariableDeclarationList(declarationList) {\r
292     return (declarationList.flags & ts.NodeFlags.BlockScoped) !== 0;\r
293 }\r
294 exports.isBlockScopedVariableDeclarationList = isBlockScopedVariableDeclarationList;\r
295 function isBlockScopedVariableDeclaration(declaration) {\r
296     const parent = declaration.parent;\r
297     return parent.kind === ts.SyntaxKind.CatchClause ||\r
298         isBlockScopedVariableDeclarationList(parent);\r
299 }\r
300 exports.isBlockScopedVariableDeclaration = isBlockScopedVariableDeclaration;\r
301 function isBlockScopedDeclarationStatement(statement) {\r
302     switch (statement.kind) {\r
303         case ts.SyntaxKind.VariableStatement:\r
304             return isBlockScopedVariableDeclarationList(statement.declarationList);\r
305         case ts.SyntaxKind.ClassDeclaration:\r
306         case ts.SyntaxKind.EnumDeclaration:\r
307         case ts.SyntaxKind.InterfaceDeclaration:\r
308         case ts.SyntaxKind.TypeAliasDeclaration:\r
309             return true;\r
310         default:\r
311             return false;\r
312     }\r
313 }\r
314 exports.isBlockScopedDeclarationStatement = isBlockScopedDeclarationStatement;\r
315 function isInSingleStatementContext(statement) {\r
316     switch (statement.parent.kind) {\r
317         case ts.SyntaxKind.ForStatement:\r
318         case ts.SyntaxKind.ForInStatement:\r
319         case ts.SyntaxKind.ForOfStatement:\r
320         case ts.SyntaxKind.WhileStatement:\r
321         case ts.SyntaxKind.DoStatement:\r
322         case ts.SyntaxKind.IfStatement:\r
323         case ts.SyntaxKind.WithStatement:\r
324         case ts.SyntaxKind.LabeledStatement:\r
325             return true;\r
326         default:\r
327             return false;\r
328     }\r
329 }\r
330 exports.isInSingleStatementContext = isInSingleStatementContext;\r
331 var ScopeBoundary;\r
332 (function (ScopeBoundary) {\r
333     ScopeBoundary[ScopeBoundary["None"] = 0] = "None";\r
334     ScopeBoundary[ScopeBoundary["Function"] = 1] = "Function";\r
335     ScopeBoundary[ScopeBoundary["Block"] = 2] = "Block";\r
336     ScopeBoundary[ScopeBoundary["Type"] = 4] = "Type";\r
337     ScopeBoundary[ScopeBoundary["ConditionalType"] = 8] = "ConditionalType";\r
338 })(ScopeBoundary = exports.ScopeBoundary || (exports.ScopeBoundary = {}));\r
339 var ScopeBoundarySelector;\r
340 (function (ScopeBoundarySelector) {\r
341     ScopeBoundarySelector[ScopeBoundarySelector["Function"] = 1] = "Function";\r
342     ScopeBoundarySelector[ScopeBoundarySelector["Block"] = 3] = "Block";\r
343     ScopeBoundarySelector[ScopeBoundarySelector["Type"] = 7] = "Type";\r
344     ScopeBoundarySelector[ScopeBoundarySelector["InferType"] = 8] = "InferType";\r
345 })(ScopeBoundarySelector = exports.ScopeBoundarySelector || (exports.ScopeBoundarySelector = {}));\r
346 function isScopeBoundary(node) {\r
347     return isFunctionScopeBoundary(node) || isBlockScopeBoundary(node) || isTypeScopeBoundary(node);\r
348 }\r
349 exports.isScopeBoundary = isScopeBoundary;\r
350 function isTypeScopeBoundary(node) {\r
351     switch (node.kind) {\r
352         case ts.SyntaxKind.InterfaceDeclaration:\r
353         case ts.SyntaxKind.TypeAliasDeclaration:\r
354         case ts.SyntaxKind.MappedType:\r
355             return 4 /* Type */;\r
356         case ts.SyntaxKind.ConditionalType:\r
357             return 8 /* ConditionalType */;\r
358         default:\r
359             return 0 /* None */;\r
360     }\r
361 }\r
362 exports.isTypeScopeBoundary = isTypeScopeBoundary;\r
363 function isFunctionScopeBoundary(node) {\r
364     switch (node.kind) {\r
365         case ts.SyntaxKind.FunctionExpression:\r
366         case ts.SyntaxKind.ArrowFunction:\r
367         case ts.SyntaxKind.Constructor:\r
368         case ts.SyntaxKind.ModuleDeclaration:\r
369         case ts.SyntaxKind.ClassDeclaration:\r
370         case ts.SyntaxKind.ClassExpression:\r
371         case ts.SyntaxKind.EnumDeclaration:\r
372         case ts.SyntaxKind.MethodDeclaration:\r
373         case ts.SyntaxKind.FunctionDeclaration:\r
374         case ts.SyntaxKind.GetAccessor:\r
375         case ts.SyntaxKind.SetAccessor:\r
376         case ts.SyntaxKind.MethodSignature:\r
377         case ts.SyntaxKind.CallSignature:\r
378         case ts.SyntaxKind.ConstructSignature:\r
379         case ts.SyntaxKind.ConstructorType:\r
380         case ts.SyntaxKind.FunctionType:\r
381             return 1 /* Function */;\r
382         case ts.SyntaxKind.SourceFile:\r
383             // if SourceFile is no module, it contributes to the global scope and is therefore no scope boundary\r
384             return ts.isExternalModule(node) ? 1 /* Function */ : 0 /* None */;\r
385         default:\r
386             return 0 /* None */;\r
387     }\r
388 }\r
389 exports.isFunctionScopeBoundary = isFunctionScopeBoundary;\r
390 function isBlockScopeBoundary(node) {\r
391     switch (node.kind) {\r
392         case ts.SyntaxKind.Block:\r
393             const parent = node.parent;\r
394             return parent.kind !== ts.SyntaxKind.CatchClause &&\r
395                 // blocks inside SourceFile are block scope boundaries\r
396                 (parent.kind === ts.SyntaxKind.SourceFile ||\r
397                     // blocks that are direct children of a function scope boundary are no scope boundary\r
398                     // for example the FunctionBlock is part of the function scope of the containing function\r
399                     !isFunctionScopeBoundary(parent))\r
400                 ? 2 /* Block */\r
401                 : 0 /* None */;\r
402         case ts.SyntaxKind.ForStatement:\r
403         case ts.SyntaxKind.ForInStatement:\r
404         case ts.SyntaxKind.ForOfStatement:\r
405         case ts.SyntaxKind.CaseBlock:\r
406         case ts.SyntaxKind.CatchClause:\r
407         case ts.SyntaxKind.WithStatement:\r
408             return 2 /* Block */;\r
409         default:\r
410             return 0 /* None */;\r
411     }\r
412 }\r
413 exports.isBlockScopeBoundary = isBlockScopeBoundary;\r
414 /** Returns true for scope boundaries that have their own `this` reference instead of inheriting it from the containing scope */\r
415 function hasOwnThisReference(node) {\r
416     switch (node.kind) {\r
417         case ts.SyntaxKind.ClassDeclaration:\r
418         case ts.SyntaxKind.ClassExpression:\r
419         case ts.SyntaxKind.FunctionExpression:\r
420             return true;\r
421         case ts.SyntaxKind.FunctionDeclaration:\r
422             return node.body !== undefined;\r
423         case ts.SyntaxKind.MethodDeclaration:\r
424         case ts.SyntaxKind.GetAccessor:\r
425         case ts.SyntaxKind.SetAccessor:\r
426             return node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression;\r
427         default:\r
428             return false;\r
429     }\r
430 }\r
431 exports.hasOwnThisReference = hasOwnThisReference;\r
432 function isFunctionWithBody(node) {\r
433     switch (node.kind) {\r
434         case ts.SyntaxKind.GetAccessor:\r
435         case ts.SyntaxKind.SetAccessor:\r
436         case ts.SyntaxKind.FunctionDeclaration:\r
437         case ts.SyntaxKind.MethodDeclaration:\r
438         case ts.SyntaxKind.Constructor:\r
439             return node.body !== undefined;\r
440         case ts.SyntaxKind.FunctionExpression:\r
441         case ts.SyntaxKind.ArrowFunction:\r
442             return true;\r
443         default:\r
444             return false;\r
445     }\r
446 }\r
447 exports.isFunctionWithBody = isFunctionWithBody;\r
448 /**\r
449  * Iterate over all tokens of `node`\r
450  *\r
451  * @param node The node whose tokens should be visited\r
452  * @param cb Is called for every token contained in `node`\r
453  */\r
454 function forEachToken(node, cb, sourceFile = node.getSourceFile()) {\r
455     const queue = [];\r
456     while (true) {\r
457         if (isTokenKind(node.kind)) {\r
458             cb(node);\r
459         }\r
460         else if (node.kind !== ts.SyntaxKind.JSDocComment) {\r
461             const children = node.getChildren(sourceFile);\r
462             if (children.length === 1) {\r
463                 node = children[0];\r
464                 continue;\r
465             }\r
466             for (let i = children.length - 1; i >= 0; --i)\r
467                 queue.push(children[i]); // add children in reverse order, when we pop the next element from the queue, it's the first child\r
468         }\r
469         if (queue.length === 0)\r
470             break;\r
471         node = queue.pop();\r
472     }\r
473 }\r
474 exports.forEachToken = forEachToken;\r
475 /**\r
476  * Iterate over all tokens and trivia of `node`\r
477  *\r
478  * @description JsDoc comments are treated like regular comments\r
479  *\r
480  * @param node The node whose tokens should be visited\r
481  * @param cb Is called for every token contained in `node` and trivia before the token\r
482  */\r
483 function forEachTokenWithTrivia(node, cb, sourceFile = node.getSourceFile()) {\r
484     const fullText = sourceFile.text;\r
485     const scanner = ts.createScanner(sourceFile.languageVersion, false, sourceFile.languageVariant, fullText);\r
486     return forEachToken(node, (token) => {\r
487         const tokenStart = token.kind === ts.SyntaxKind.JsxText || token.pos === token.end ? token.pos : token.getStart(sourceFile);\r
488         if (tokenStart !== token.pos) {\r
489             // we only have to handle trivia before each token. whitespace at the end of the file is followed by EndOfFileToken\r
490             scanner.setTextPos(token.pos);\r
491             let kind = scanner.scan();\r
492             let pos = scanner.getTokenPos();\r
493             while (pos < tokenStart) {\r
494                 const textPos = scanner.getTextPos();\r
495                 cb(fullText, kind, { pos, end: textPos }, token.parent);\r
496                 if (textPos === tokenStart)\r
497                     break;\r
498                 kind = scanner.scan();\r
499                 pos = scanner.getTokenPos();\r
500             }\r
501         }\r
502         return cb(fullText, token.kind, { end: token.end, pos: tokenStart }, token.parent);\r
503     }, sourceFile);\r
504 }\r
505 exports.forEachTokenWithTrivia = forEachTokenWithTrivia;\r
506 /** Iterate over all comments owned by `node` or its children */\r
507 function forEachComment(node, cb, sourceFile = node.getSourceFile()) {\r
508     /* Visit all tokens and skip trivia.\r
509        Comment ranges between tokens are parsed without the need of a scanner.\r
510        forEachTokenWithWhitespace does intentionally not pay attention to the correct comment ownership of nodes as it always\r
511        scans all trivia before each token, which could include trailing comments of the previous token.\r
512        Comment onwership is done right in this function*/\r
513     const fullText = sourceFile.text;\r
514     const notJsx = sourceFile.languageVariant !== ts.LanguageVariant.JSX;\r
515     return forEachToken(node, (token) => {\r
516         if (token.pos === token.end)\r
517             return;\r
518         if (token.kind !== ts.SyntaxKind.JsxText)\r
519             ts.forEachLeadingCommentRange(fullText, \r
520             // skip shebang at position 0\r
521             token.pos === 0 ? (ts.getShebang(fullText) || '').length : token.pos, commentCallback);\r
522         if (notJsx || canHaveTrailingTrivia(token))\r
523             return ts.forEachTrailingCommentRange(fullText, token.end, commentCallback);\r
524     }, sourceFile);\r
525     function commentCallback(pos, end, kind) {\r
526         cb(fullText, { pos, end, kind });\r
527     }\r
528 }\r
529 exports.forEachComment = forEachComment;\r
530 /** Exclude trailing positions that would lead to scanning for trivia inside JsxText */\r
531 function canHaveTrailingTrivia(token) {\r
532     switch (token.kind) {\r
533         case ts.SyntaxKind.CloseBraceToken:\r
534             // after a JsxExpression inside a JsxElement's body can only be other JsxChild, but no trivia\r
535             return token.parent.kind !== ts.SyntaxKind.JsxExpression || !isJsxElementOrFragment(token.parent.parent);\r
536         case ts.SyntaxKind.GreaterThanToken:\r
537             switch (token.parent.kind) {\r
538                 case ts.SyntaxKind.JsxOpeningElement:\r
539                     // if end is not equal, this is part of the type arguments list. in all other cases it would be inside the element body\r
540                     return token.end !== token.parent.end;\r
541                 case ts.SyntaxKind.JsxOpeningFragment:\r
542                     return false; // would be inside the fragment\r
543                 case ts.SyntaxKind.JsxSelfClosingElement:\r
544                     return token.end !== token.parent.end || // if end is not equal, this is part of the type arguments list\r
545                         !isJsxElementOrFragment(token.parent.parent); // there's only trailing trivia if it's the end of the top element\r
546                 case ts.SyntaxKind.JsxClosingElement:\r
547                 case ts.SyntaxKind.JsxClosingFragment:\r
548                     // there's only trailing trivia if it's the end of the top element\r
549                     return !isJsxElementOrFragment(token.parent.parent.parent);\r
550             }\r
551     }\r
552     return true;\r
553 }\r
554 function isJsxElementOrFragment(node) {\r
555     return node.kind === ts.SyntaxKind.JsxElement || node.kind === ts.SyntaxKind.JsxFragment;\r
556 }\r
557 function getLineRanges(sourceFile) {\r
558     const lineStarts = sourceFile.getLineStarts();\r
559     const result = [];\r
560     const length = lineStarts.length;\r
561     const sourceText = sourceFile.text;\r
562     let pos = 0;\r
563     for (let i = 1; i < length; ++i) {\r
564         const end = lineStarts[i];\r
565         let lineEnd = end;\r
566         for (; lineEnd > pos; --lineEnd)\r
567             if (!ts.isLineBreak(sourceText.charCodeAt(lineEnd - 1)))\r
568                 break;\r
569         result.push({\r
570             pos,\r
571             end,\r
572             contentLength: lineEnd - pos,\r
573         });\r
574         pos = end;\r
575     }\r
576     result.push({\r
577         pos,\r
578         end: sourceFile.end,\r
579         contentLength: sourceFile.end - pos,\r
580     });\r
581     return result;\r
582 }\r
583 exports.getLineRanges = getLineRanges;\r
584 /** Get the line break style used in sourceFile. This function only looks at the first line break. If there is none, \n is assumed. */\r
585 function getLineBreakStyle(sourceFile) {\r
586     const lineStarts = sourceFile.getLineStarts();\r
587     return lineStarts.length === 1 || lineStarts[1] < 2 || sourceFile.text[lineStarts[1] - 2] !== '\r'\r
588         ? '\n'\r
589         : '\r\n';\r
590 }\r
591 exports.getLineBreakStyle = getLineBreakStyle;\r
592 let cachedScanner;\r
593 function scanToken(text, languageVersion) {\r
594     if (cachedScanner === undefined) {\r
595         // cache scanner\r
596         cachedScanner = ts.createScanner(languageVersion, false, undefined, text);\r
597     }\r
598     else {\r
599         cachedScanner.setScriptTarget(languageVersion);\r
600         cachedScanner.setText(text);\r
601     }\r
602     cachedScanner.scan();\r
603     return cachedScanner;\r
604 }\r
605 /**\r
606  * Determines whether the given text parses as a standalone identifier.\r
607  * This is not a guarantee that it works in every context. The property name in PropertyAccessExpressions for example allows reserved words.\r
608  * Depending on the context it could be parsed as contextual keyword or TypeScript keyword.\r
609  */\r
610 function isValidIdentifier(text, languageVersion = ts.ScriptTarget.Latest) {\r
611     const scan = scanToken(text, languageVersion);\r
612     return scan.isIdentifier() && scan.getTextPos() === text.length && scan.getTokenPos() === 0;\r
613 }\r
614 exports.isValidIdentifier = isValidIdentifier;\r
615 function charSize(ch) {\r
616     return ch >= 0x10000 ? 2 : 1;\r
617 }\r
618 /**\r
619  * Determines whether the given text can be used to access a property with a PropertyAccessExpression while preserving the property's name.\r
620  */\r
621 function isValidPropertyAccess(text, languageVersion = ts.ScriptTarget.Latest) {\r
622     if (text.length === 0)\r
623         return false;\r
624     let ch = text.codePointAt(0);\r
625     if (!ts.isIdentifierStart(ch, languageVersion))\r
626         return false;\r
627     for (let i = charSize(ch); i < text.length; i += charSize(ch)) {\r
628         ch = text.codePointAt(i);\r
629         if (!ts.isIdentifierPart(ch, languageVersion))\r
630             return false;\r
631     }\r
632     return true;\r
633 }\r
634 exports.isValidPropertyAccess = isValidPropertyAccess;\r
635 /**\r
636  * Determines whether the given text can be used as unquoted name of a property declaration while preserving the property's name.\r
637  */\r
638 function isValidPropertyName(text, languageVersion = ts.ScriptTarget.Latest) {\r
639     if (isValidPropertyAccess(text, languageVersion))\r
640         return true;\r
641     const scan = scanToken(text, languageVersion);\r
642     return scan.getTextPos() === text.length &&\r
643         scan.getToken() === ts.SyntaxKind.NumericLiteral && scan.getTokenValue() === text; // ensure stringified number equals literal\r
644 }\r
645 exports.isValidPropertyName = isValidPropertyName;\r
646 /**\r
647  * Determines whether the given text can be parsed as a numeric literal.\r
648  */\r
649 function isValidNumericLiteral(text, languageVersion = ts.ScriptTarget.Latest) {\r
650     const scan = scanToken(text, languageVersion);\r
651     return scan.getToken() === ts.SyntaxKind.NumericLiteral && scan.getTextPos() === text.length && scan.getTokenPos() === 0;\r
652 }\r
653 exports.isValidNumericLiteral = isValidNumericLiteral;\r
654 /**\r
655  * Determines whether the given text can be used as JSX tag or attribute name while preserving the exact name.\r
656  */\r
657 function isValidJsxIdentifier(text, languageVersion = ts.ScriptTarget.Latest) {\r
658     if (text.length === 0)\r
659         return false;\r
660     let seenNamespaceSeparator = false;\r
661     let ch = text.codePointAt(0);\r
662     if (!ts.isIdentifierStart(ch, languageVersion))\r
663         return false;\r
664     for (let i = charSize(ch); i < text.length; i += charSize(ch)) {\r
665         ch = text.codePointAt(i);\r
666         if (!ts.isIdentifierPart(ch, languageVersion) && ch !== 45 /* minus */) {\r
667             if (!seenNamespaceSeparator && ch === 58 /* colon */ && i + charSize(ch) !== text.length) {\r
668                 seenNamespaceSeparator = true;\r
669             }\r
670             else {\r
671                 return false;\r
672             }\r
673         }\r
674     }\r
675     return true;\r
676 }\r
677 exports.isValidJsxIdentifier = isValidJsxIdentifier;\r
678 function isNumericPropertyName(name) {\r
679     return String(+name) === name;\r
680 }\r
681 exports.isNumericPropertyName = isNumericPropertyName;\r
682 function isSameLine(sourceFile, pos1, pos2) {\r
683     return ts.getLineAndCharacterOfPosition(sourceFile, pos1).line === ts.getLineAndCharacterOfPosition(sourceFile, pos2).line;\r
684 }\r
685 exports.isSameLine = isSameLine;\r
686 var SideEffectOptions;\r
687 (function (SideEffectOptions) {\r
688     SideEffectOptions[SideEffectOptions["None"] = 0] = "None";\r
689     SideEffectOptions[SideEffectOptions["TaggedTemplate"] = 1] = "TaggedTemplate";\r
690     SideEffectOptions[SideEffectOptions["Constructor"] = 2] = "Constructor";\r
691     SideEffectOptions[SideEffectOptions["JsxElement"] = 4] = "JsxElement";\r
692 })(SideEffectOptions = exports.SideEffectOptions || (exports.SideEffectOptions = {}));\r
693 function hasSideEffects(node, options) {\r
694     var _a, _b;\r
695     const queue = [];\r
696     while (true) {\r
697         switch (node.kind) {\r
698             case ts.SyntaxKind.CallExpression:\r
699             case ts.SyntaxKind.PostfixUnaryExpression:\r
700             case ts.SyntaxKind.AwaitExpression:\r
701             case ts.SyntaxKind.YieldExpression:\r
702             case ts.SyntaxKind.DeleteExpression:\r
703                 return true;\r
704             case ts.SyntaxKind.TypeAssertionExpression:\r
705             case ts.SyntaxKind.AsExpression:\r
706             case ts.SyntaxKind.ParenthesizedExpression:\r
707             case ts.SyntaxKind.NonNullExpression:\r
708             case ts.SyntaxKind.VoidExpression:\r
709             case ts.SyntaxKind.TypeOfExpression:\r
710             case ts.SyntaxKind.PropertyAccessExpression:\r
711             case ts.SyntaxKind.SpreadElement:\r
712             case ts.SyntaxKind.PartiallyEmittedExpression:\r
713                 node = node.expression;\r
714                 continue;\r
715             case ts.SyntaxKind.BinaryExpression:\r
716                 if (isAssignmentKind(node.operatorToken.kind))\r
717                     return true;\r
718                 queue.push(node.right);\r
719                 node = node.left;\r
720                 continue;\r
721             case ts.SyntaxKind.PrefixUnaryExpression:\r
722                 switch (node.operator) {\r
723                     case ts.SyntaxKind.PlusPlusToken:\r
724                     case ts.SyntaxKind.MinusMinusToken:\r
725                         return true;\r
726                     default:\r
727                         node = node.operand;\r
728                         continue;\r
729                 }\r
730             case ts.SyntaxKind.ElementAccessExpression:\r
731                 if (node.argumentExpression !== undefined) // for compatibility with typescript@<2.9.0\r
732                     queue.push(node.argumentExpression);\r
733                 node = node.expression;\r
734                 continue;\r
735             case ts.SyntaxKind.ConditionalExpression:\r
736                 queue.push(node.whenTrue, node.whenFalse);\r
737                 node = node.condition;\r
738                 continue;\r
739             case ts.SyntaxKind.NewExpression:\r
740                 if (options & 2 /* Constructor */)\r
741                     return true;\r
742                 if (node.arguments !== undefined)\r
743                     queue.push(...node.arguments);\r
744                 node = node.expression;\r
745                 continue;\r
746             case ts.SyntaxKind.TaggedTemplateExpression:\r
747                 if (options & 1 /* TaggedTemplate */)\r
748                     return true;\r
749                 queue.push(node.tag);\r
750                 node = node.template;\r
751                 if (node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral)\r
752                     break;\r
753             // falls through\r
754             case ts.SyntaxKind.TemplateExpression:\r
755                 for (const child of node.templateSpans)\r
756                     queue.push(child.expression);\r
757                 break;\r
758             case ts.SyntaxKind.ClassExpression: {\r
759                 if (node.decorators !== undefined)\r
760                     return true;\r
761                 for (const child of node.members) {\r
762                     if (child.decorators !== undefined)\r
763                         return true;\r
764                     if (!hasModifier(child.modifiers, ts.SyntaxKind.DeclareKeyword)) {\r
765                         if (((_a = child.name) === null || _a === void 0 ? void 0 : _a.kind) === ts.SyntaxKind.ComputedPropertyName)\r
766                             queue.push(child.name.expression);\r
767                         if (node_1.isMethodDeclaration(child)) {\r
768                             for (const p of child.parameters)\r
769                                 if (p.decorators !== undefined)\r
770                                     return true;\r
771                         }\r
772                         else if (node_1.isPropertyDeclaration(child) &&\r
773                             child.initializer !== undefined &&\r
774                             hasModifier(child.modifiers, ts.SyntaxKind.StaticKeyword)) {\r
775                             queue.push(child.initializer);\r
776                         }\r
777                     }\r
778                 }\r
779                 const base = getBaseOfClassLikeExpression(node);\r
780                 if (base === undefined)\r
781                     break;\r
782                 node = base.expression;\r
783                 continue;\r
784             }\r
785             case ts.SyntaxKind.ArrayLiteralExpression:\r
786                 queue.push(...node.elements);\r
787                 break;\r
788             case ts.SyntaxKind.ObjectLiteralExpression:\r
789                 for (const child of node.properties) {\r
790                     if (((_b = child.name) === null || _b === void 0 ? void 0 : _b.kind) === ts.SyntaxKind.ComputedPropertyName)\r
791                         queue.push(child.name.expression);\r
792                     switch (child.kind) {\r
793                         case ts.SyntaxKind.PropertyAssignment:\r
794                             queue.push(child.initializer);\r
795                             break;\r
796                         case ts.SyntaxKind.SpreadAssignment:\r
797                             queue.push(child.expression);\r
798                     }\r
799                 }\r
800                 break;\r
801             case ts.SyntaxKind.JsxExpression:\r
802                 if (node.expression === undefined)\r
803                     break;\r
804                 node = node.expression;\r
805                 continue;\r
806             case ts.SyntaxKind.JsxElement:\r
807             case ts.SyntaxKind.JsxFragment:\r
808                 for (const child of node.children)\r
809                     if (child.kind !== ts.SyntaxKind.JsxText)\r
810                         queue.push(child);\r
811                 if (node.kind === ts.SyntaxKind.JsxFragment)\r
812                     break;\r
813                 node = node.openingElement;\r
814             // falls through\r
815             case ts.SyntaxKind.JsxSelfClosingElement:\r
816             case ts.SyntaxKind.JsxOpeningElement:\r
817                 if (options & 4 /* JsxElement */)\r
818                     return true;\r
819                 for (const child of node.attributes.properties) {\r
820                     if (child.kind === ts.SyntaxKind.JsxSpreadAttribute) {\r
821                         queue.push(child.expression);\r
822                     }\r
823                     else if (child.initializer !== undefined) {\r
824                         queue.push(child.initializer);\r
825                     }\r
826                 }\r
827                 break;\r
828             case ts.SyntaxKind.CommaListExpression:\r
829                 queue.push(...node.elements);\r
830         }\r
831         if (queue.length === 0)\r
832             return false;\r
833         node = queue.pop();\r
834     }\r
835 }\r
836 exports.hasSideEffects = hasSideEffects;\r
837 /** Returns the VariableDeclaration or ParameterDeclaration that contains the BindingElement */\r
838 function getDeclarationOfBindingElement(node) {\r
839     let parent = node.parent.parent;\r
840     while (parent.kind === ts.SyntaxKind.BindingElement)\r
841         parent = parent.parent.parent;\r
842     return parent;\r
843 }\r
844 exports.getDeclarationOfBindingElement = getDeclarationOfBindingElement;\r
845 function isExpressionValueUsed(node) {\r
846     while (true) {\r
847         const parent = node.parent;\r
848         switch (parent.kind) {\r
849             case ts.SyntaxKind.CallExpression:\r
850             case ts.SyntaxKind.NewExpression:\r
851             case ts.SyntaxKind.ElementAccessExpression:\r
852             case ts.SyntaxKind.WhileStatement:\r
853             case ts.SyntaxKind.DoStatement:\r
854             case ts.SyntaxKind.WithStatement:\r
855             case ts.SyntaxKind.ThrowStatement:\r
856             case ts.SyntaxKind.ReturnStatement:\r
857             case ts.SyntaxKind.JsxExpression:\r
858             case ts.SyntaxKind.JsxSpreadAttribute:\r
859             case ts.SyntaxKind.JsxElement:\r
860             case ts.SyntaxKind.JsxFragment:\r
861             case ts.SyntaxKind.JsxSelfClosingElement:\r
862             case ts.SyntaxKind.ComputedPropertyName:\r
863             case ts.SyntaxKind.ArrowFunction:\r
864             case ts.SyntaxKind.ExportSpecifier:\r
865             case ts.SyntaxKind.ExportAssignment:\r
866             case ts.SyntaxKind.ImportDeclaration:\r
867             case ts.SyntaxKind.ExternalModuleReference:\r
868             case ts.SyntaxKind.Decorator:\r
869             case ts.SyntaxKind.TaggedTemplateExpression:\r
870             case ts.SyntaxKind.TemplateSpan:\r
871             case ts.SyntaxKind.ExpressionWithTypeArguments:\r
872             case ts.SyntaxKind.TypeOfExpression:\r
873             case ts.SyntaxKind.AwaitExpression:\r
874             case ts.SyntaxKind.YieldExpression:\r
875             case ts.SyntaxKind.LiteralType:\r
876             case ts.SyntaxKind.JsxAttributes:\r
877             case ts.SyntaxKind.JsxOpeningElement:\r
878             case ts.SyntaxKind.JsxClosingElement:\r
879             case ts.SyntaxKind.IfStatement:\r
880             case ts.SyntaxKind.CaseClause:\r
881             case ts.SyntaxKind.SwitchStatement:\r
882                 return true;\r
883             case ts.SyntaxKind.PropertyAccessExpression:\r
884                 return parent.expression === node;\r
885             case ts.SyntaxKind.QualifiedName:\r
886                 return parent.left === node;\r
887             case ts.SyntaxKind.ShorthandPropertyAssignment:\r
888                 return parent.objectAssignmentInitializer === node ||\r
889                     !isInDestructuringAssignment(parent);\r
890             case ts.SyntaxKind.PropertyAssignment:\r
891                 return parent.initializer === node && !isInDestructuringAssignment(parent);\r
892             case ts.SyntaxKind.SpreadAssignment:\r
893             case ts.SyntaxKind.SpreadElement:\r
894             case ts.SyntaxKind.ArrayLiteralExpression:\r
895                 return !isInDestructuringAssignment(parent);\r
896             case ts.SyntaxKind.ParenthesizedExpression:\r
897             case ts.SyntaxKind.AsExpression:\r
898             case ts.SyntaxKind.TypeAssertionExpression:\r
899             case ts.SyntaxKind.PostfixUnaryExpression:\r
900             case ts.SyntaxKind.PrefixUnaryExpression:\r
901             case ts.SyntaxKind.NonNullExpression:\r
902                 node = parent;\r
903                 continue;\r
904             case ts.SyntaxKind.ForStatement:\r
905                 return parent.condition === node;\r
906             case ts.SyntaxKind.ForInStatement:\r
907             case ts.SyntaxKind.ForOfStatement:\r
908                 return parent.expression === node;\r
909             case ts.SyntaxKind.ConditionalExpression:\r
910                 if (parent.condition === node)\r
911                     return true;\r
912                 node = parent;\r
913                 break;\r
914             case ts.SyntaxKind.PropertyDeclaration:\r
915             case ts.SyntaxKind.BindingElement:\r
916             case ts.SyntaxKind.VariableDeclaration:\r
917             case ts.SyntaxKind.Parameter:\r
918             case ts.SyntaxKind.EnumMember:\r
919                 return parent.initializer === node;\r
920             case ts.SyntaxKind.ImportEqualsDeclaration:\r
921                 return parent.moduleReference === node;\r
922             case ts.SyntaxKind.CommaListExpression:\r
923                 if (parent.elements[parent.elements.length - 1] !== node)\r
924                     return false;\r
925                 node = parent;\r
926                 break;\r
927             case ts.SyntaxKind.BinaryExpression:\r
928                 if (parent.right === node) {\r
929                     if (parent.operatorToken.kind === ts.SyntaxKind.CommaToken) {\r
930                         node = parent;\r
931                         break;\r
932                     }\r
933                     return true;\r
934                 }\r
935                 switch (parent.operatorToken.kind) {\r
936                     case ts.SyntaxKind.CommaToken:\r
937                     case ts.SyntaxKind.EqualsToken:\r
938                         return false;\r
939                     case ts.SyntaxKind.EqualsEqualsEqualsToken:\r
940                     case ts.SyntaxKind.EqualsEqualsToken:\r
941                     case ts.SyntaxKind.ExclamationEqualsEqualsToken:\r
942                     case ts.SyntaxKind.ExclamationEqualsToken:\r
943                     case ts.SyntaxKind.InstanceOfKeyword:\r
944                     case ts.SyntaxKind.PlusToken:\r
945                     case ts.SyntaxKind.MinusToken:\r
946                     case ts.SyntaxKind.AsteriskToken:\r
947                     case ts.SyntaxKind.SlashToken:\r
948                     case ts.SyntaxKind.PercentToken:\r
949                     case ts.SyntaxKind.AsteriskAsteriskToken:\r
950                     case ts.SyntaxKind.GreaterThanToken:\r
951                     case ts.SyntaxKind.GreaterThanGreaterThanToken:\r
952                     case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:\r
953                     case ts.SyntaxKind.GreaterThanEqualsToken:\r
954                     case ts.SyntaxKind.LessThanToken:\r
955                     case ts.SyntaxKind.LessThanLessThanToken:\r
956                     case ts.SyntaxKind.LessThanEqualsToken:\r
957                     case ts.SyntaxKind.AmpersandToken:\r
958                     case ts.SyntaxKind.BarToken:\r
959                     case ts.SyntaxKind.CaretToken:\r
960                     case ts.SyntaxKind.BarBarToken:\r
961                     case ts.SyntaxKind.AmpersandAmpersandToken:\r
962                     case ts.SyntaxKind.QuestionQuestionToken:\r
963                     case ts.SyntaxKind.InKeyword:\r
964                     case ts.SyntaxKind.QuestionQuestionEqualsToken:\r
965                     case ts.SyntaxKind.AmpersandAmpersandEqualsToken:\r
966                     case ts.SyntaxKind.BarBarEqualsToken:\r
967                         return true;\r
968                     default:\r
969                         node = parent;\r
970                 }\r
971                 break;\r
972             default:\r
973                 return false;\r
974         }\r
975     }\r
976 }\r
977 exports.isExpressionValueUsed = isExpressionValueUsed;\r
978 function isInDestructuringAssignment(node) {\r
979     switch (node.kind) {\r
980         case ts.SyntaxKind.ShorthandPropertyAssignment:\r
981             if (node.objectAssignmentInitializer !== undefined)\r
982                 return true;\r
983         // falls through\r
984         case ts.SyntaxKind.PropertyAssignment:\r
985         case ts.SyntaxKind.SpreadAssignment:\r
986             node = node.parent;\r
987             break;\r
988         case ts.SyntaxKind.SpreadElement:\r
989             if (node.parent.kind !== ts.SyntaxKind.ArrayLiteralExpression)\r
990                 return false;\r
991             node = node.parent;\r
992     }\r
993     while (true) {\r
994         switch (node.parent.kind) {\r
995             case ts.SyntaxKind.BinaryExpression:\r
996                 return node.parent.left === node &&\r
997                     node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken;\r
998             case ts.SyntaxKind.ForOfStatement:\r
999                 return node.parent.initializer === node;\r
1000             case ts.SyntaxKind.ArrayLiteralExpression:\r
1001             case ts.SyntaxKind.ObjectLiteralExpression:\r
1002                 node = node.parent;\r
1003                 break;\r
1004             case ts.SyntaxKind.SpreadAssignment:\r
1005             case ts.SyntaxKind.PropertyAssignment:\r
1006                 node = node.parent.parent;\r
1007                 break;\r
1008             case ts.SyntaxKind.SpreadElement:\r
1009                 if (node.parent.parent.kind !== ts.SyntaxKind.ArrayLiteralExpression)\r
1010                     return false;\r
1011                 node = node.parent.parent;\r
1012                 break;\r
1013             default:\r
1014                 return false;\r
1015         }\r
1016     }\r
1017 }\r
1018 var AccessKind;\r
1019 (function (AccessKind) {\r
1020     AccessKind[AccessKind["None"] = 0] = "None";\r
1021     AccessKind[AccessKind["Read"] = 1] = "Read";\r
1022     AccessKind[AccessKind["Write"] = 2] = "Write";\r
1023     AccessKind[AccessKind["Delete"] = 4] = "Delete";\r
1024     AccessKind[AccessKind["ReadWrite"] = 3] = "ReadWrite";\r
1025     AccessKind[AccessKind["Modification"] = 6] = "Modification";\r
1026 })(AccessKind = exports.AccessKind || (exports.AccessKind = {}));\r
1027 function getAccessKind(node) {\r
1028     const parent = node.parent;\r
1029     switch (parent.kind) {\r
1030         case ts.SyntaxKind.DeleteExpression:\r
1031             return 4 /* Delete */;\r
1032         case ts.SyntaxKind.PostfixUnaryExpression:\r
1033             return 3 /* ReadWrite */;\r
1034         case ts.SyntaxKind.PrefixUnaryExpression:\r
1035             return parent.operator === ts.SyntaxKind.PlusPlusToken ||\r
1036                 parent.operator === ts.SyntaxKind.MinusMinusToken\r
1037                 ? 3 /* ReadWrite */\r
1038                 : 1 /* Read */;\r
1039         case ts.SyntaxKind.BinaryExpression:\r
1040             return parent.right === node\r
1041                 ? 1 /* Read */\r
1042                 : !isAssignmentKind(parent.operatorToken.kind)\r
1043                     ? 1 /* Read */\r
1044                     : parent.operatorToken.kind === ts.SyntaxKind.EqualsToken\r
1045                         ? 2 /* Write */\r
1046                         : 3 /* ReadWrite */;\r
1047         case ts.SyntaxKind.ShorthandPropertyAssignment:\r
1048             return parent.objectAssignmentInitializer === node\r
1049                 ? 1 /* Read */\r
1050                 : isInDestructuringAssignment(parent)\r
1051                     ? 2 /* Write */\r
1052                     : 1 /* Read */;\r
1053         case ts.SyntaxKind.PropertyAssignment:\r
1054             return parent.name === node\r
1055                 ? 0 /* None */\r
1056                 : isInDestructuringAssignment(parent)\r
1057                     ? 2 /* Write */\r
1058                     : 1 /* Read */;\r
1059         case ts.SyntaxKind.ArrayLiteralExpression:\r
1060         case ts.SyntaxKind.SpreadElement:\r
1061         case ts.SyntaxKind.SpreadAssignment:\r
1062             return isInDestructuringAssignment(parent)\r
1063                 ? 2 /* Write */\r
1064                 : 1 /* Read */;\r
1065         case ts.SyntaxKind.ParenthesizedExpression:\r
1066         case ts.SyntaxKind.NonNullExpression:\r
1067         case ts.SyntaxKind.TypeAssertionExpression:\r
1068         case ts.SyntaxKind.AsExpression:\r
1069             // (<number>foo! as {})++\r
1070             return getAccessKind(parent);\r
1071         case ts.SyntaxKind.ForOfStatement:\r
1072         case ts.SyntaxKind.ForInStatement:\r
1073             return parent.initializer === node\r
1074                 ? 2 /* Write */\r
1075                 : 1 /* Read */;\r
1076         case ts.SyntaxKind.ExpressionWithTypeArguments:\r
1077             return parent.parent.token === ts.SyntaxKind.ExtendsKeyword &&\r
1078                 parent.parent.parent.kind !== ts.SyntaxKind.InterfaceDeclaration\r
1079                 ? 1 /* Read */\r
1080                 : 0 /* None */;\r
1081         case ts.SyntaxKind.ComputedPropertyName:\r
1082         case ts.SyntaxKind.ExpressionStatement:\r
1083         case ts.SyntaxKind.TypeOfExpression:\r
1084         case ts.SyntaxKind.ElementAccessExpression:\r
1085         case ts.SyntaxKind.ForStatement:\r
1086         case ts.SyntaxKind.IfStatement:\r
1087         case ts.SyntaxKind.DoStatement:\r
1088         case ts.SyntaxKind.WhileStatement:\r
1089         case ts.SyntaxKind.SwitchStatement:\r
1090         case ts.SyntaxKind.WithStatement:\r
1091         case ts.SyntaxKind.ThrowStatement:\r
1092         case ts.SyntaxKind.CallExpression:\r
1093         case ts.SyntaxKind.NewExpression:\r
1094         case ts.SyntaxKind.TaggedTemplateExpression:\r
1095         case ts.SyntaxKind.JsxExpression:\r
1096         case ts.SyntaxKind.Decorator:\r
1097         case ts.SyntaxKind.TemplateSpan:\r
1098         case ts.SyntaxKind.JsxOpeningElement:\r
1099         case ts.SyntaxKind.JsxSelfClosingElement:\r
1100         case ts.SyntaxKind.JsxSpreadAttribute:\r
1101         case ts.SyntaxKind.VoidExpression:\r
1102         case ts.SyntaxKind.ReturnStatement:\r
1103         case ts.SyntaxKind.AwaitExpression:\r
1104         case ts.SyntaxKind.YieldExpression:\r
1105         case ts.SyntaxKind.ConditionalExpression:\r
1106         case ts.SyntaxKind.CaseClause:\r
1107         case ts.SyntaxKind.JsxElement:\r
1108             return 1 /* Read */;\r
1109         case ts.SyntaxKind.ArrowFunction:\r
1110             return parent.body === node\r
1111                 ? 1 /* Read */\r
1112                 : 2 /* Write */;\r
1113         case ts.SyntaxKind.PropertyDeclaration:\r
1114         case ts.SyntaxKind.VariableDeclaration:\r
1115         case ts.SyntaxKind.Parameter:\r
1116         case ts.SyntaxKind.EnumMember:\r
1117         case ts.SyntaxKind.BindingElement:\r
1118         case ts.SyntaxKind.JsxAttribute:\r
1119             return parent.initializer === node\r
1120                 ? 1 /* Read */\r
1121                 : 0 /* None */;\r
1122         case ts.SyntaxKind.PropertyAccessExpression:\r
1123             return parent.expression === node\r
1124                 ? 1 /* Read */\r
1125                 : 0 /* None */;\r
1126         case ts.SyntaxKind.ExportAssignment:\r
1127             return parent.isExportEquals\r
1128                 ? 1 /* Read */\r
1129                 : 0 /* None */;\r
1130     }\r
1131     return 0 /* None */;\r
1132 }\r
1133 exports.getAccessKind = getAccessKind;\r
1134 function isReassignmentTarget(node) {\r
1135     return (getAccessKind(node) & 2 /* Write */) !== 0;\r
1136 }\r
1137 exports.isReassignmentTarget = isReassignmentTarget;\r
1138 function canHaveJsDoc(node) {\r
1139     const kind = node.kind;\r
1140     switch (kind) {\r
1141         case ts.SyntaxKind.Parameter:\r
1142         case ts.SyntaxKind.CallSignature:\r
1143         case ts.SyntaxKind.ConstructSignature:\r
1144         case ts.SyntaxKind.MethodSignature:\r
1145         case ts.SyntaxKind.PropertySignature:\r
1146         case ts.SyntaxKind.ArrowFunction:\r
1147         case ts.SyntaxKind.ParenthesizedExpression:\r
1148         case ts.SyntaxKind.SpreadAssignment:\r
1149         case ts.SyntaxKind.ShorthandPropertyAssignment:\r
1150         case ts.SyntaxKind.PropertyAssignment:\r
1151         case ts.SyntaxKind.FunctionExpression:\r
1152         case ts.SyntaxKind.LabeledStatement:\r
1153         case ts.SyntaxKind.ExpressionStatement:\r
1154         case ts.SyntaxKind.VariableStatement:\r
1155         case ts.SyntaxKind.FunctionDeclaration:\r
1156         case ts.SyntaxKind.Constructor:\r
1157         case ts.SyntaxKind.MethodDeclaration:\r
1158         case ts.SyntaxKind.PropertyDeclaration:\r
1159         case ts.SyntaxKind.GetAccessor:\r
1160         case ts.SyntaxKind.SetAccessor:\r
1161         case ts.SyntaxKind.ClassDeclaration:\r
1162         case ts.SyntaxKind.ClassExpression:\r
1163         case ts.SyntaxKind.InterfaceDeclaration:\r
1164         case ts.SyntaxKind.TypeAliasDeclaration:\r
1165         case ts.SyntaxKind.EnumMember:\r
1166         case ts.SyntaxKind.EnumDeclaration:\r
1167         case ts.SyntaxKind.ModuleDeclaration:\r
1168         case ts.SyntaxKind.ImportEqualsDeclaration:\r
1169         case ts.SyntaxKind.ImportDeclaration:\r
1170         case ts.SyntaxKind.NamespaceExportDeclaration:\r
1171         case ts.SyntaxKind.ExportAssignment:\r
1172         case ts.SyntaxKind.IndexSignature:\r
1173         case ts.SyntaxKind.FunctionType:\r
1174         case ts.SyntaxKind.ConstructorType:\r
1175         case ts.SyntaxKind.JSDocFunctionType:\r
1176         case ts.SyntaxKind.ExportDeclaration:\r
1177         case ts.SyntaxKind.NamedTupleMember:\r
1178         case ts.SyntaxKind.EndOfFileToken:\r
1179             return true;\r
1180         default:\r
1181             return false;\r
1182     }\r
1183 }\r
1184 exports.canHaveJsDoc = canHaveJsDoc;\r
1185 /** Gets the JSDoc of a node. For performance reasons this function should only be called when `canHaveJsDoc` returns true. */\r
1186 function getJsDoc(node, sourceFile) {\r
1187     const result = [];\r
1188     for (const child of node.getChildren(sourceFile)) {\r
1189         if (!node_1.isJsDoc(child))\r
1190             break;\r
1191         result.push(child);\r
1192     }\r
1193     return result;\r
1194 }\r
1195 exports.getJsDoc = getJsDoc;\r
1196 /**\r
1197  * Parses the JsDoc of any node. This function is made for nodes that don't get their JsDoc parsed by the TypeScript parser.\r
1198  *\r
1199  * @param considerTrailingComments When set to `true` this function uses the trailing comments if the node starts on the same line\r
1200  *                                 as the previous node ends.\r
1201  */\r
1202 function parseJsDocOfNode(node, considerTrailingComments, sourceFile = node.getSourceFile()) {\r
1203     if (canHaveJsDoc(node) && node.kind !== ts.SyntaxKind.EndOfFileToken) {\r
1204         const result = getJsDoc(node, sourceFile);\r
1205         if (result.length !== 0 || !considerTrailingComments)\r
1206             return result;\r
1207     }\r
1208     return parseJsDocWorker(node, node.getStart(sourceFile), sourceFile, considerTrailingComments);\r
1209 }\r
1210 exports.parseJsDocOfNode = parseJsDocOfNode;\r
1211 function parseJsDocWorker(node, nodeStart, sourceFile, considerTrailingComments) {\r
1212     const start = ts[considerTrailingComments && isSameLine(sourceFile, node.pos, nodeStart)\r
1213         ? 'forEachTrailingCommentRange'\r
1214         : 'forEachLeadingCommentRange'](sourceFile.text, node.pos, \r
1215     // return object to make `0` a truthy value\r
1216     (pos, _end, kind) => kind === ts.SyntaxKind.MultiLineCommentTrivia && sourceFile.text[pos + 2] === '*' ? { pos } : undefined);\r
1217     if (start === undefined)\r
1218         return [];\r
1219     const startPos = start.pos;\r
1220     const text = sourceFile.text.slice(startPos, nodeStart);\r
1221     const newSourceFile = ts.createSourceFile('jsdoc.ts', `${text}var a;`, sourceFile.languageVersion);\r
1222     const result = getJsDoc(newSourceFile.statements[0], newSourceFile);\r
1223     for (const doc of result)\r
1224         updateNode(doc, node);\r
1225     return result;\r
1226     function updateNode(n, parent) {\r
1227         n.pos += startPos;\r
1228         n.end += startPos;\r
1229         n.parent = parent;\r
1230         return ts.forEachChild(n, (child) => updateNode(child, n), (children) => {\r
1231             children.pos += startPos;\r
1232             children.end += startPos;\r
1233             for (const child of children)\r
1234                 updateNode(child, n);\r
1235         });\r
1236     }\r
1237 }\r
1238 var ImportKind;\r
1239 (function (ImportKind) {\r
1240     ImportKind[ImportKind["ImportDeclaration"] = 1] = "ImportDeclaration";\r
1241     ImportKind[ImportKind["ImportEquals"] = 2] = "ImportEquals";\r
1242     ImportKind[ImportKind["ExportFrom"] = 4] = "ExportFrom";\r
1243     ImportKind[ImportKind["DynamicImport"] = 8] = "DynamicImport";\r
1244     ImportKind[ImportKind["Require"] = 16] = "Require";\r
1245     ImportKind[ImportKind["ImportType"] = 32] = "ImportType";\r
1246     ImportKind[ImportKind["All"] = 63] = "All";\r
1247     ImportKind[ImportKind["AllImports"] = 59] = "AllImports";\r
1248     ImportKind[ImportKind["AllStaticImports"] = 3] = "AllStaticImports";\r
1249     ImportKind[ImportKind["AllImportExpressions"] = 24] = "AllImportExpressions";\r
1250     ImportKind[ImportKind["AllRequireLike"] = 18] = "AllRequireLike";\r
1251     // @internal\r
1252     ImportKind[ImportKind["AllNestedImports"] = 56] = "AllNestedImports";\r
1253     // @internal\r
1254     ImportKind[ImportKind["AllTopLevelImports"] = 7] = "AllTopLevelImports";\r
1255 })(ImportKind = exports.ImportKind || (exports.ImportKind = {}));\r
1256 function findImports(sourceFile, kinds, ignoreFileName = true) {\r
1257     const result = [];\r
1258     for (const node of findImportLikeNodes(sourceFile, kinds, ignoreFileName)) {\r
1259         switch (node.kind) {\r
1260             case ts.SyntaxKind.ImportDeclaration:\r
1261                 addIfTextualLiteral(node.moduleSpecifier);\r
1262                 break;\r
1263             case ts.SyntaxKind.ImportEqualsDeclaration:\r
1264                 addIfTextualLiteral(node.moduleReference.expression);\r
1265                 break;\r
1266             case ts.SyntaxKind.ExportDeclaration:\r
1267                 addIfTextualLiteral(node.moduleSpecifier);\r
1268                 break;\r
1269             case ts.SyntaxKind.CallExpression:\r
1270                 addIfTextualLiteral(node.arguments[0]);\r
1271                 break;\r
1272             case ts.SyntaxKind.ImportType:\r
1273                 if (node_1.isLiteralTypeNode(node.argument))\r
1274                     addIfTextualLiteral(node.argument.literal);\r
1275                 break;\r
1276             default:\r
1277                 throw new Error('unexpected node');\r
1278         }\r
1279     }\r
1280     return result;\r
1281     function addIfTextualLiteral(node) {\r
1282         if (node_1.isTextualLiteral(node))\r
1283             result.push(node);\r
1284     }\r
1285 }\r
1286 exports.findImports = findImports;\r
1287 function findImportLikeNodes(sourceFile, kinds, ignoreFileName = true) {\r
1288     return new ImportFinder(sourceFile, kinds, ignoreFileName).find();\r
1289 }\r
1290 exports.findImportLikeNodes = findImportLikeNodes;\r
1291 class ImportFinder {\r
1292     constructor(_sourceFile, _options, _ignoreFileName) {\r
1293         this._sourceFile = _sourceFile;\r
1294         this._options = _options;\r
1295         this._ignoreFileName = _ignoreFileName;\r
1296         this._result = [];\r
1297     }\r
1298     find() {\r
1299         if (this._sourceFile.isDeclarationFile)\r
1300             this._options &= ~24 /* AllImportExpressions */;\r
1301         if (this._options & 7 /* AllTopLevelImports */)\r
1302             this._findImports(this._sourceFile.statements);\r
1303         if (this._options & 56 /* AllNestedImports */)\r
1304             this._findNestedImports();\r
1305         return this._result;\r
1306     }\r
1307     _findImports(statements) {\r
1308         for (const statement of statements) {\r
1309             if (node_1.isImportDeclaration(statement)) {\r
1310                 if (this._options & 1 /* ImportDeclaration */)\r
1311                     this._result.push(statement);\r
1312             }\r
1313             else if (node_1.isImportEqualsDeclaration(statement)) {\r
1314                 if (this._options & 2 /* ImportEquals */ &&\r
1315                     statement.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)\r
1316                     this._result.push(statement);\r
1317             }\r
1318             else if (node_1.isExportDeclaration(statement)) {\r
1319                 if (statement.moduleSpecifier !== undefined && this._options & 4 /* ExportFrom */)\r
1320                     this._result.push(statement);\r
1321             }\r
1322             else if (node_1.isModuleDeclaration(statement)) {\r
1323                 this._findImportsInModule(statement);\r
1324             }\r
1325         }\r
1326     }\r
1327     _findImportsInModule(declaration) {\r
1328         if (declaration.body === undefined)\r
1329             return;\r
1330         if (declaration.body.kind === ts.SyntaxKind.ModuleDeclaration)\r
1331             return this._findImportsInModule(declaration.body);\r
1332         this._findImports(declaration.body.statements);\r
1333     }\r
1334     _findNestedImports() {\r
1335         const isJavaScriptFile = this._ignoreFileName || (this._sourceFile.flags & ts.NodeFlags.JavaScriptFile) !== 0;\r
1336         let re;\r
1337         let includeJsDoc;\r
1338         if ((this._options & 56 /* AllNestedImports */) === 16 /* Require */) {\r
1339             if (!isJavaScriptFile)\r
1340                 return; // don't look for 'require' in TS files\r
1341             re = /\brequire\s*[</(]/g;\r
1342             includeJsDoc = false;\r
1343         }\r
1344         else if (this._options & 16 /* Require */ && isJavaScriptFile) {\r
1345             re = /\b(?:import|require)\s*[</(]/g;\r
1346             includeJsDoc = (this._options & 32 /* ImportType */) !== 0;\r
1347         }\r
1348         else {\r
1349             re = /\bimport\s*[</(]/g;\r
1350             includeJsDoc = isJavaScriptFile && (this._options & 32 /* ImportType */) !== 0;\r
1351         }\r
1352         for (let match = re.exec(this._sourceFile.text); match !== null; match = re.exec(this._sourceFile.text)) {\r
1353             const token = getTokenAtPositionWorker(this._sourceFile, match.index, this._sourceFile, \r
1354             // only look for ImportTypeNode within JSDoc in JS files\r
1355             match[0][0] === 'i' && includeJsDoc);\r
1356             if (token.kind === ts.SyntaxKind.ImportKeyword) {\r
1357                 if (token.end - 'import'.length !== match.index)\r
1358                     continue;\r
1359                 switch (token.parent.kind) {\r
1360                     case ts.SyntaxKind.ImportType:\r
1361                         this._result.push(token.parent);\r
1362                         break;\r
1363                     case ts.SyntaxKind.CallExpression:\r
1364                         if (token.parent.arguments.length > 1)\r
1365                             this._result.push(token.parent);\r
1366                 }\r
1367             }\r
1368             else if (token.kind === ts.SyntaxKind.Identifier &&\r
1369                 token.end - 'require'.length === match.index &&\r
1370                 token.parent.kind === ts.SyntaxKind.CallExpression &&\r
1371                 token.parent.expression === token &&\r
1372                 token.parent.arguments.length === 1) {\r
1373                 this._result.push(token.parent);\r
1374             }\r
1375         }\r
1376     }\r
1377 }\r
1378 /**\r
1379  * Ambient context means the statement itself has the `declare` keyword\r
1380  * or is inside a `declare namespace`,  `delcare module` or `declare global`.\r
1381  */\r
1382 function isStatementInAmbientContext(node) {\r
1383     while (node.flags & ts.NodeFlags.NestedNamespace)\r
1384         node = node.parent;\r
1385     return hasModifier(node.modifiers, ts.SyntaxKind.DeclareKeyword) || isAmbientModuleBlock(node.parent);\r
1386 }\r
1387 exports.isStatementInAmbientContext = isStatementInAmbientContext;\r
1388 /** Includes `declare namespace`, `declare module` and `declare global` and namespace nested in one of the aforementioned. */\r
1389 function isAmbientModuleBlock(node) {\r
1390     while (node.kind === ts.SyntaxKind.ModuleBlock) {\r
1391         do\r
1392             node = node.parent;\r
1393         while (node.flags & ts.NodeFlags.NestedNamespace);\r
1394         if (hasModifier(node.modifiers, ts.SyntaxKind.DeclareKeyword))\r
1395             return true;\r
1396         node = node.parent;\r
1397     }\r
1398     return false;\r
1399 }\r
1400 exports.isAmbientModuleBlock = isAmbientModuleBlock;\r
1401 function getIIFE(func) {\r
1402     let node = func.parent;\r
1403     while (node.kind === ts.SyntaxKind.ParenthesizedExpression)\r
1404         node = node.parent;\r
1405     return node_1.isCallExpression(node) && func.end <= node.expression.end ? node : undefined;\r
1406 }\r
1407 exports.getIIFE = getIIFE;\r
1408 function isStrictCompilerOptionEnabled(options, option) {\r
1409     return (options.strict ? options[option] !== false : options[option] === true) &&\r
1410         (option !== 'strictPropertyInitialization' || isStrictCompilerOptionEnabled(options, 'strictNullChecks'));\r
1411 }\r
1412 exports.isStrictCompilerOptionEnabled = isStrictCompilerOptionEnabled;\r
1413 // https://github.com/ajafff/tslint-consistent-codestyle/issues/85\r
1414 /**\r
1415  * Checks if a given compiler option is enabled.\r
1416  * It handles dependencies of options, e.g. `declaration` is implicitly enabled by `composite` or `strictNullChecks` is enabled by `strict`.\r
1417  * However, it does not check dependencies that are already checked and reported as errors, e.g. `checkJs` without `allowJs`.\r
1418  * This function only handles boolean flags.\r
1419  */\r
1420 function isCompilerOptionEnabled(options, option) {\r
1421     switch (option) {\r
1422         case 'stripInternal':\r
1423         case 'declarationMap':\r
1424         case 'emitDeclarationOnly':\r
1425             return options[option] === true && isCompilerOptionEnabled(options, 'declaration');\r
1426         case 'declaration':\r
1427             return options.declaration || isCompilerOptionEnabled(options, 'composite');\r
1428         case 'incremental':\r
1429             return options.incremental === undefined ? isCompilerOptionEnabled(options, 'composite') : options.incremental;\r
1430         case 'skipDefaultLibCheck':\r
1431             return options.skipDefaultLibCheck || isCompilerOptionEnabled(options, 'skipLibCheck');\r
1432         case 'suppressImplicitAnyIndexErrors':\r
1433             return options.suppressImplicitAnyIndexErrors === true && isCompilerOptionEnabled(options, 'noImplicitAny');\r
1434         case 'allowSyntheticDefaultImports':\r
1435             return options.allowSyntheticDefaultImports !== undefined\r
1436                 ? options.allowSyntheticDefaultImports\r
1437                 : isCompilerOptionEnabled(options, 'esModuleInterop') || options.module === ts.ModuleKind.System;\r
1438         case 'noUncheckedIndexedAccess':\r
1439             return options.noUncheckedIndexedAccess === true && isCompilerOptionEnabled(options, 'strictNullChecks');\r
1440         case 'allowJs':\r
1441             return options.allowJs === undefined ? isCompilerOptionEnabled(options, 'checkJs') : options.allowJs;\r
1442         case 'noImplicitAny':\r
1443         case 'noImplicitThis':\r
1444         case 'strictNullChecks':\r
1445         case 'strictFunctionTypes':\r
1446         case 'strictPropertyInitialization':\r
1447         case 'alwaysStrict':\r
1448         case 'strictBindCallApply':\r
1449             return isStrictCompilerOptionEnabled(options, option);\r
1450     }\r
1451     return options[option] === true;\r
1452 }\r
1453 exports.isCompilerOptionEnabled = isCompilerOptionEnabled;\r
1454 /**\r
1455  * Has nothing to do with `isAmbientModuleBlock`.\r
1456  *\r
1457  * @returns `true` if it's a global augmentation or has a string name.\r
1458  */\r
1459 function isAmbientModule(node) {\r
1460     return node.name.kind === ts.SyntaxKind.StringLiteral || (node.flags & ts.NodeFlags.GlobalAugmentation) !== 0;\r
1461 }\r
1462 exports.isAmbientModule = isAmbientModule;\r
1463 /**\r
1464  * @deprecated use `getTsCheckDirective` instead since `// @ts-nocheck` is no longer restricted to JS files.\r
1465  * @returns the last `// @ts-check` or `// @ts-nocheck` directive in the given file.\r
1466  */\r
1467 function getCheckJsDirective(source) {\r
1468     return getTsCheckDirective(source);\r
1469 }\r
1470 exports.getCheckJsDirective = getCheckJsDirective;\r
1471 /** @returns the last `// @ts-check` or `// @ts-nocheck` directive in the given file. */\r
1472 function getTsCheckDirective(source) {\r
1473     let directive;\r
1474     // needs to work around a shebang issue until https://github.com/Microsoft/TypeScript/issues/28477 is resolved\r
1475     ts.forEachLeadingCommentRange(source, (ts.getShebang(source) || '').length, (pos, end, kind) => {\r
1476         if (kind === ts.SyntaxKind.SingleLineCommentTrivia) {\r
1477             const text = source.slice(pos, end);\r
1478             const match = /^\/{2,3}\s*@ts-(no)?check(?:\s|$)/i.exec(text);\r
1479             if (match !== null)\r
1480                 directive = { pos, end, enabled: match[1] === undefined };\r
1481         }\r
1482     });\r
1483     return directive;\r
1484 }\r
1485 exports.getTsCheckDirective = getTsCheckDirective;\r
1486 function isConstAssertion(node) {\r
1487     return node_1.isTypeReferenceNode(node.type) &&\r
1488         node.type.typeName.kind === ts.SyntaxKind.Identifier &&\r
1489         node.type.typeName.escapedText === 'const';\r
1490 }\r
1491 exports.isConstAssertion = isConstAssertion;\r
1492 /** Detects whether an expression is affected by an enclosing 'as const' assertion and therefore treated literally. */\r
1493 function isInConstContext(node) {\r
1494     let current = node;\r
1495     while (true) {\r
1496         const parent = current.parent;\r
1497         outer: switch (parent.kind) {\r
1498             case ts.SyntaxKind.TypeAssertionExpression:\r
1499             case ts.SyntaxKind.AsExpression:\r
1500                 return isConstAssertion(parent);\r
1501             case ts.SyntaxKind.PrefixUnaryExpression:\r
1502                 if (current.kind !== ts.SyntaxKind.NumericLiteral)\r
1503                     return false;\r
1504                 switch (parent.operator) {\r
1505                     case ts.SyntaxKind.PlusToken:\r
1506                     case ts.SyntaxKind.MinusToken:\r
1507                         current = parent;\r
1508                         break outer;\r
1509                     default:\r
1510                         return false;\r
1511                 }\r
1512             case ts.SyntaxKind.PropertyAssignment:\r
1513                 if (parent.initializer !== current)\r
1514                     return false;\r
1515                 current = parent.parent;\r
1516                 break;\r
1517             case ts.SyntaxKind.ShorthandPropertyAssignment:\r
1518                 current = parent.parent;\r
1519                 break;\r
1520             case ts.SyntaxKind.ParenthesizedExpression:\r
1521             case ts.SyntaxKind.ArrayLiteralExpression:\r
1522             case ts.SyntaxKind.ObjectLiteralExpression:\r
1523             case ts.SyntaxKind.TemplateExpression:\r
1524                 current = parent;\r
1525                 break;\r
1526             default:\r
1527                 return false;\r
1528         }\r
1529     }\r
1530 }\r
1531 exports.isInConstContext = isInConstContext;\r
1532 /** Returns true for `Object.defineProperty(o, 'prop', {value, writable: false})` and  `Object.defineProperty(o, 'prop', {get: () => 1})`*/\r
1533 function isReadonlyAssignmentDeclaration(node, checker) {\r
1534     if (!isBindableObjectDefinePropertyCall(node))\r
1535         return false;\r
1536     const descriptorType = checker.getTypeAtLocation(node.arguments[2]);\r
1537     if (descriptorType.getProperty('value') === undefined)\r
1538         return descriptorType.getProperty('set') === undefined;\r
1539     const writableProp = descriptorType.getProperty('writable');\r
1540     if (writableProp === undefined)\r
1541         return false;\r
1542     const writableType = writableProp.valueDeclaration !== undefined && node_1.isPropertyAssignment(writableProp.valueDeclaration)\r
1543         ? checker.getTypeAtLocation(writableProp.valueDeclaration.initializer)\r
1544         : checker.getTypeOfSymbolAtLocation(writableProp, node.arguments[2]);\r
1545     return type_1.isBooleanLiteralType(writableType, false);\r
1546 }\r
1547 exports.isReadonlyAssignmentDeclaration = isReadonlyAssignmentDeclaration;\r
1548 /** Determines whether a call to `Object.defineProperty` is statically analyzable. */\r
1549 function isBindableObjectDefinePropertyCall(node) {\r
1550     return node.arguments.length === 3 &&\r
1551         node_1.isEntityNameExpression(node.arguments[0]) &&\r
1552         node_1.isNumericOrStringLikeLiteral(node.arguments[1]) &&\r
1553         node_1.isPropertyAccessExpression(node.expression) &&\r
1554         node.expression.name.escapedText === 'defineProperty' &&\r
1555         node_1.isIdentifier(node.expression.expression) &&\r
1556         node.expression.expression.escapedText === 'Object';\r
1557 }\r
1558 exports.isBindableObjectDefinePropertyCall = isBindableObjectDefinePropertyCall;\r
1559 function isWellKnownSymbolLiterally(node) {\r
1560     return ts.isPropertyAccessExpression(node) &&\r
1561         ts.isIdentifier(node.expression) &&\r
1562         node.expression.escapedText === 'Symbol';\r
1563 }\r
1564 exports.isWellKnownSymbolLiterally = isWellKnownSymbolLiterally;\r
1565 /** @deprecated typescript 4.3 removed the concept of literal well known symbols. Use `getPropertyNameFromType` instead. */\r
1566 function getPropertyNameOfWellKnownSymbol(node) {\r
1567     return {\r
1568         displayName: `[Symbol.${node.name.text}]`,\r
1569         symbolName: ('__@' + node.name.text),\r
1570     };\r
1571 }\r
1572 exports.getPropertyNameOfWellKnownSymbol = getPropertyNameOfWellKnownSymbol;\r
1573 const isTsBefore43 = (([major, minor]) => major < '4' || major === '4' && minor < '3')(ts.versionMajorMinor.split('.'));\r
1574 function getLateBoundPropertyNames(node, checker) {\r
1575     const result = {\r
1576         known: true,\r
1577         names: [],\r
1578     };\r
1579     node = unwrapParentheses(node);\r
1580     if (isTsBefore43 && isWellKnownSymbolLiterally(node)) {\r
1581         result.names.push(getPropertyNameOfWellKnownSymbol(node)); // wotan-disable-line no-unstable-api-use\r
1582     }\r
1583     else {\r
1584         const type = checker.getTypeAtLocation(node);\r
1585         for (const key of type_1.unionTypeParts(checker.getBaseConstraintOfType(type) || type)) {\r
1586             const propertyName = type_1.getPropertyNameFromType(key);\r
1587             if (propertyName) {\r
1588                 result.names.push(propertyName);\r
1589             }\r
1590             else {\r
1591                 result.known = false;\r
1592             }\r
1593         }\r
1594     }\r
1595     return result;\r
1596 }\r
1597 exports.getLateBoundPropertyNames = getLateBoundPropertyNames;\r
1598 function getLateBoundPropertyNamesOfPropertyName(node, checker) {\r
1599     const staticName = getPropertyName(node);\r
1600     return staticName !== undefined\r
1601         ? { known: true, names: [{ displayName: staticName, symbolName: ts.escapeLeadingUnderscores(staticName) }] }\r
1602         : node.kind === ts.SyntaxKind.PrivateIdentifier\r
1603             ? { known: true, names: [{ displayName: node.text, symbolName: checker.getSymbolAtLocation(node).escapedName }] }\r
1604             : getLateBoundPropertyNames(node.expression, checker);\r
1605 }\r
1606 exports.getLateBoundPropertyNamesOfPropertyName = getLateBoundPropertyNamesOfPropertyName;\r
1607 /** Most declarations demand there to be only one statically known name, e.g. class members with computed name. */\r
1608 function getSingleLateBoundPropertyNameOfPropertyName(node, checker) {\r
1609     const staticName = getPropertyName(node);\r
1610     if (staticName !== undefined)\r
1611         return { displayName: staticName, symbolName: ts.escapeLeadingUnderscores(staticName) };\r
1612     if (node.kind === ts.SyntaxKind.PrivateIdentifier)\r
1613         return { displayName: node.text, symbolName: checker.getSymbolAtLocation(node).escapedName };\r
1614     const { expression } = node;\r
1615     return isTsBefore43 && isWellKnownSymbolLiterally(expression)\r
1616         ? getPropertyNameOfWellKnownSymbol(expression) // wotan-disable-line no-unstable-api-use\r
1617         : type_1.getPropertyNameFromType(checker.getTypeAtLocation(expression));\r
1618 }\r
1619 exports.getSingleLateBoundPropertyNameOfPropertyName = getSingleLateBoundPropertyNameOfPropertyName;\r
1620 function unwrapParentheses(node) {\r
1621     while (node.kind === ts.SyntaxKind.ParenthesizedExpression)\r
1622         node = node.expression;\r
1623     return node;\r
1624 }\r
1625 exports.unwrapParentheses = unwrapParentheses;\r
1626 function formatPseudoBigInt(v) {\r
1627     return `${v.negative ? '-' : ''}${v.base10Value}n`;\r
1628 }\r
1629 exports.formatPseudoBigInt = formatPseudoBigInt;\r
1630 /**\r
1631  * Determines whether the given `SwitchStatement`'s `case` clauses cover every possible value of the switched expression.\r
1632  * The logic is the same as TypeScript's control flow analysis.\r
1633  * This does **not** check whether all `case` clauses do a certain action like assign a variable or return a value.\r
1634  * This function ignores the `default` clause if present.\r
1635  */\r
1636 function hasExhaustiveCaseClauses(node, checker) {\r
1637     const caseClauses = node.caseBlock.clauses.filter(node_1.isCaseClause);\r
1638     if (caseClauses.length === 0)\r
1639         return false;\r
1640     const typeParts = type_1.unionTypeParts(checker.getTypeAtLocation(node.expression));\r
1641     if (typeParts.length > caseClauses.length)\r
1642         return false;\r
1643     const types = new Set(typeParts.map(getPrimitiveLiteralFromType));\r
1644     if (types.has(undefined))\r
1645         return false;\r
1646     const seen = new Set();\r
1647     for (const clause of caseClauses) {\r
1648         const expressionType = checker.getTypeAtLocation(clause.expression);\r
1649         if (exports.isTypeFlagSet(expressionType, ts.TypeFlags.Never))\r
1650             continue; // additional case clause with 'never' is always allowed\r
1651         const type = getPrimitiveLiteralFromType(expressionType);\r
1652         if (types.has(type)) {\r
1653             seen.add(type);\r
1654         }\r
1655         else if (type !== 'null' && type !== 'undefined') { // additional case clauses with 'null' and 'undefined' are always allowed\r
1656             return false;\r
1657         }\r
1658     }\r
1659     return types.size === seen.size;\r
1660 }\r
1661 exports.hasExhaustiveCaseClauses = hasExhaustiveCaseClauses;\r
1662 function getPrimitiveLiteralFromType(t) {\r
1663     if (exports.isTypeFlagSet(t, ts.TypeFlags.Null))\r
1664         return 'null';\r
1665     if (exports.isTypeFlagSet(t, ts.TypeFlags.Undefined))\r
1666         return 'undefined';\r
1667     if (exports.isTypeFlagSet(t, ts.TypeFlags.NumberLiteral))\r
1668         return `${exports.isTypeFlagSet(t, ts.TypeFlags.EnumLiteral) ? 'enum:' : ''}${t.value}`;\r
1669     if (exports.isTypeFlagSet(t, ts.TypeFlags.StringLiteral))\r
1670         return `${exports.isTypeFlagSet(t, ts.TypeFlags.EnumLiteral) ? 'enum:' : ''}string:${t.value}`;\r
1671     if (exports.isTypeFlagSet(t, ts.TypeFlags.BigIntLiteral))\r
1672         return formatPseudoBigInt(t.value);\r
1673     if (_3_2_1.isUniqueESSymbolType(t))\r
1674         return t.escapedName;\r
1675     if (type_1.isBooleanLiteralType(t, true))\r
1676         return 'true';\r
1677     if (type_1.isBooleanLiteralType(t, false))\r
1678         return 'false';\r
1679 }\r
1680 function getBaseOfClassLikeExpression(node) {\r
1681     var _a;\r
1682     if (((_a = node.heritageClauses) === null || _a === void 0 ? void 0 : _a[0].token) === ts.SyntaxKind.ExtendsKeyword)\r
1683         return node.heritageClauses[0].types[0];\r
1684 }\r
1685 exports.getBaseOfClassLikeExpression = getBaseOfClassLikeExpression;\r
1686 //# sourceMappingURL=util.js.map