2 Object.defineProperty(exports, "__esModule", { value: true });
3 const ts = require("typescript");
4 const node_1 = require("../typeguard/node");
5 const _3_2_1 = require("../typeguard/3.2");
6 const type_1 = require("./type");
7 function getChildOfKind(node, kind, sourceFile) {
8 for (const child of node.getChildren(sourceFile))
9 if (child.kind === kind)
12 exports.getChildOfKind = getChildOfKind;
13 function isTokenKind(kind) {
14 return kind >= ts.SyntaxKind.FirstToken && kind <= ts.SyntaxKind.LastToken;
16 exports.isTokenKind = isTokenKind;
17 function isNodeKind(kind) {
18 return kind >= ts.SyntaxKind.FirstNode;
20 exports.isNodeKind = isNodeKind;
21 function isAssignmentKind(kind) {
22 return kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
24 exports.isAssignmentKind = isAssignmentKind;
25 function isTypeNodeKind(kind) {
26 return kind >= ts.SyntaxKind.FirstTypeNode && kind <= ts.SyntaxKind.LastTypeNode;
28 exports.isTypeNodeKind = isTypeNodeKind;
29 function isJsDocKind(kind) {
30 return kind >= ts.SyntaxKind.FirstJSDocNode && kind <= ts.SyntaxKind.LastJSDocNode;
32 exports.isJsDocKind = isJsDocKind;
33 function isKeywordKind(kind) {
34 return kind >= ts.SyntaxKind.FirstKeyword && kind <= ts.SyntaxKind.LastKeyword;
36 exports.isKeywordKind = isKeywordKind;
37 function isThisParameter(parameter) {
38 return parameter.name.kind === ts.SyntaxKind.Identifier && parameter.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword;
40 exports.isThisParameter = isThisParameter;
41 function getModifier(node, kind) {
42 if (node.modifiers !== undefined)
43 for (const modifier of node.modifiers)
44 if (modifier.kind === kind)
47 exports.getModifier = getModifier;
48 function hasModifier(modifiers, ...kinds) {
49 if (modifiers === undefined)
51 for (const modifier of modifiers)
52 if (kinds.includes(modifier.kind))
56 exports.hasModifier = hasModifier;
57 function isParameterProperty(node) {
58 return hasModifier(node.modifiers, ts.SyntaxKind.PublicKeyword, ts.SyntaxKind.ProtectedKeyword, ts.SyntaxKind.PrivateKeyword, ts.SyntaxKind.ReadonlyKeyword);
60 exports.isParameterProperty = isParameterProperty;
61 function hasAccessModifier(node) {
62 return hasModifier(node.modifiers, ts.SyntaxKind.PublicKeyword, ts.SyntaxKind.ProtectedKeyword, ts.SyntaxKind.PrivateKeyword);
64 exports.hasAccessModifier = hasAccessModifier;
65 function isFlagSet(obj, flag) {
66 return (obj.flags & flag) !== 0;
68 exports.isNodeFlagSet = isFlagSet;
69 exports.isTypeFlagSet = isFlagSet;
70 exports.isSymbolFlagSet = isFlagSet;
71 function isObjectFlagSet(objectType, flag) {
72 return (objectType.objectFlags & flag) !== 0;
74 exports.isObjectFlagSet = isObjectFlagSet;
75 function isModifierFlagSet(node, flag) {
76 return (ts.getCombinedModifierFlags(node) & flag) !== 0;
78 exports.isModifierFlagSet = isModifierFlagSet;
79 function getPreviousStatement(statement) {
80 const parent = statement.parent;
81 if (node_1.isBlockLike(parent)) {
82 const index = parent.statements.indexOf(statement);
84 return parent.statements[index - 1];
87 exports.getPreviousStatement = getPreviousStatement;
88 function getNextStatement(statement) {
89 const parent = statement.parent;
90 if (node_1.isBlockLike(parent)) {
91 const index = parent.statements.indexOf(statement);
92 if (index < parent.statements.length)
93 return parent.statements[index + 1];
96 exports.getNextStatement = getNextStatement;
97 function getPreviousToken(node, sourceFile) {
98 let parent = node.parent;
99 while (parent !== undefined && parent.pos === node.pos)
100 parent = parent.parent;
101 if (parent === undefined)
103 outer: while (true) {
104 const children = parent.getChildren(sourceFile);
105 for (let i = children.length - 1; i >= 0; --i) {
106 const child = children[i];
107 if (child.pos < node.pos && child.kind !== ts.SyntaxKind.JSDocComment) {
108 if (isTokenKind(child.kind))
117 exports.getPreviousToken = getPreviousToken;
118 function getNextToken(node, sourceFile = node.getSourceFile()) {
119 if (node.kind === ts.SyntaxKind.SourceFile || node.kind === ts.SyntaxKind.EndOfFileToken)
121 const end = node.end;
123 while (node.end === end) {
124 if (node.parent === undefined)
125 return node.endOfFileToken;
128 return getTokenAtPositionWorker(node, end, sourceFile, false);
130 exports.getNextToken = getNextToken;
131 function getTokenAtPosition(parent, pos, sourceFile, allowJsDoc) {
132 if (pos < parent.pos || pos >= parent.end)
134 if (isTokenKind(parent.kind))
136 if (sourceFile === undefined)
137 sourceFile = parent.getSourceFile();
138 return getTokenAtPositionWorker(parent, pos, sourceFile, allowJsDoc === true);
140 exports.getTokenAtPosition = getTokenAtPosition;
141 function getTokenAtPositionWorker(node, pos, sourceFile, allowJsDoc) {
142 outer: while (true) {
143 for (const child of node.getChildren(sourceFile)) {
144 if (child.end > pos && (allowJsDoc || child.kind !== ts.SyntaxKind.JSDocComment)) {
145 if (isTokenKind(child.kind))
154 function getCommentAtPosition(sourceFile, pos, parent = sourceFile) {
155 const token = getTokenAtPosition(parent, pos, sourceFile);
156 if (token === undefined || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || '').length)
158 const startPos = token.pos === 0
159 ? (ts.getShebang(sourceFile.text) || '').length
161 return startPos !== 0 && ts.forEachTrailingCommentRange(sourceFile.text, startPos, commentAtPositionCallback, pos) ||
162 ts.forEachLeadingCommentRange(sourceFile.text, startPos, commentAtPositionCallback, pos);
164 exports.getCommentAtPosition = getCommentAtPosition;
165 function commentAtPositionCallback(pos, end, kind, _nl, at) {
166 return at >= pos && at < end ? { pos, end, kind } : undefined;
168 function isPositionInComment(sourceFile, pos, parent) {
169 return getCommentAtPosition(sourceFile, pos, parent) !== undefined;
171 exports.isPositionInComment = isPositionInComment;
172 function commentText(sourceText, comment) {
173 return sourceText.substring(comment.pos + 2, comment.kind === ts.SyntaxKind.SingleLineCommentTrivia ? comment.end : comment.end - 2);
175 exports.commentText = commentText;
176 function getWrappedNodeAtPosition(wrap, pos) {
177 if (wrap.node.pos > pos || wrap.node.end <= pos)
179 outer: while (true) {
180 for (const child of wrap.children) {
181 if (child.node.pos > pos)
183 if (child.node.end > pos) {
191 exports.getWrappedNodeAtPosition = getWrappedNodeAtPosition;
192 function getPropertyName(propertyName) {
193 if (propertyName.kind === ts.SyntaxKind.ComputedPropertyName) {
194 if (!node_1.isLiteralExpression(propertyName.expression))
196 if (_3_2_1.isBigIntLiteral(propertyName.expression))
197 return propertyName.expression.text.slice(0, -1);
198 return propertyName.expression.text;
200 return propertyName.text;
202 exports.getPropertyName = getPropertyName;
203 function forEachDestructuringIdentifier(pattern, fn) {
204 for (const element of pattern.elements) {
205 if (element.kind !== ts.SyntaxKind.BindingElement)
208 if (element.name.kind === ts.SyntaxKind.Identifier) {
209 result = fn(element);
212 result = forEachDestructuringIdentifier(element.name, fn);
218 exports.forEachDestructuringIdentifier = forEachDestructuringIdentifier;
219 function forEachDeclaredVariable(declarationList, cb) {
220 for (const declaration of declarationList.declarations) {
222 if (declaration.name.kind === ts.SyntaxKind.Identifier) {
223 result = cb(declaration);
226 result = forEachDestructuringIdentifier(declaration.name, cb);
232 exports.forEachDeclaredVariable = forEachDeclaredVariable;
233 var VariableDeclarationKind;
234 (function (VariableDeclarationKind) {
235 VariableDeclarationKind[VariableDeclarationKind["Var"] = 0] = "Var";
236 VariableDeclarationKind[VariableDeclarationKind["Let"] = 1] = "Let";
237 VariableDeclarationKind[VariableDeclarationKind["Const"] = 2] = "Const";
238 })(VariableDeclarationKind = exports.VariableDeclarationKind || (exports.VariableDeclarationKind = {}));
239 function getVariableDeclarationKind(declarationList) {
240 if (declarationList.flags & ts.NodeFlags.Let)
242 if (declarationList.flags & ts.NodeFlags.Const)
246 exports.getVariableDeclarationKind = getVariableDeclarationKind;
247 function isBlockScopedVariableDeclarationList(declarationList) {
248 return (declarationList.flags & ts.NodeFlags.BlockScoped) !== 0;
250 exports.isBlockScopedVariableDeclarationList = isBlockScopedVariableDeclarationList;
251 function isBlockScopedVariableDeclaration(declaration) {
252 const parent = declaration.parent;
253 return parent.kind === ts.SyntaxKind.CatchClause ||
254 isBlockScopedVariableDeclarationList(parent);
256 exports.isBlockScopedVariableDeclaration = isBlockScopedVariableDeclaration;
257 function isBlockScopedDeclarationStatement(statement) {
258 switch (statement.kind) {
259 case ts.SyntaxKind.VariableStatement:
260 return isBlockScopedVariableDeclarationList(statement.declarationList);
261 case ts.SyntaxKind.ClassDeclaration:
262 case ts.SyntaxKind.EnumDeclaration:
263 case ts.SyntaxKind.InterfaceDeclaration:
264 case ts.SyntaxKind.TypeAliasDeclaration:
270 exports.isBlockScopedDeclarationStatement = isBlockScopedDeclarationStatement;
271 function isInSingleStatementContext(statement) {
272 switch (statement.parent.kind) {
273 case ts.SyntaxKind.ForStatement:
274 case ts.SyntaxKind.ForInStatement:
275 case ts.SyntaxKind.ForOfStatement:
276 case ts.SyntaxKind.WhileStatement:
277 case ts.SyntaxKind.DoStatement:
278 case ts.SyntaxKind.IfStatement:
279 case ts.SyntaxKind.WithStatement:
280 case ts.SyntaxKind.LabeledStatement:
286 exports.isInSingleStatementContext = isInSingleStatementContext;
288 (function (ScopeBoundary) {
289 ScopeBoundary[ScopeBoundary["None"] = 0] = "None";
290 ScopeBoundary[ScopeBoundary["Function"] = 1] = "Function";
291 ScopeBoundary[ScopeBoundary["Block"] = 2] = "Block";
292 ScopeBoundary[ScopeBoundary["Type"] = 4] = "Type";
293 ScopeBoundary[ScopeBoundary["ConditionalType"] = 8] = "ConditionalType";
294 })(ScopeBoundary = exports.ScopeBoundary || (exports.ScopeBoundary = {}));
295 var ScopeBoundarySelector;
296 (function (ScopeBoundarySelector) {
297 ScopeBoundarySelector[ScopeBoundarySelector["Function"] = 1] = "Function";
298 ScopeBoundarySelector[ScopeBoundarySelector["Block"] = 3] = "Block";
299 ScopeBoundarySelector[ScopeBoundarySelector["Type"] = 7] = "Type";
300 ScopeBoundarySelector[ScopeBoundarySelector["InferType"] = 8] = "InferType";
301 })(ScopeBoundarySelector = exports.ScopeBoundarySelector || (exports.ScopeBoundarySelector = {}));
302 function isScopeBoundary(node) {
303 return isFunctionScopeBoundary(node) || isBlockScopeBoundary(node) || isTypeScopeBoundary(node);
305 exports.isScopeBoundary = isScopeBoundary;
306 function isTypeScopeBoundary(node) {
308 case ts.SyntaxKind.InterfaceDeclaration:
309 case ts.SyntaxKind.TypeAliasDeclaration:
310 case ts.SyntaxKind.MappedType:
312 case ts.SyntaxKind.ConditionalType:
318 exports.isTypeScopeBoundary = isTypeScopeBoundary;
319 function isFunctionScopeBoundary(node) {
321 case ts.SyntaxKind.FunctionExpression:
322 case ts.SyntaxKind.ArrowFunction:
323 case ts.SyntaxKind.Constructor:
324 case ts.SyntaxKind.ModuleDeclaration:
325 case ts.SyntaxKind.ClassDeclaration:
326 case ts.SyntaxKind.ClassExpression:
327 case ts.SyntaxKind.EnumDeclaration:
328 case ts.SyntaxKind.MethodDeclaration:
329 case ts.SyntaxKind.FunctionDeclaration:
330 case ts.SyntaxKind.GetAccessor:
331 case ts.SyntaxKind.SetAccessor:
332 case ts.SyntaxKind.MethodSignature:
333 case ts.SyntaxKind.CallSignature:
334 case ts.SyntaxKind.ConstructSignature:
335 case ts.SyntaxKind.ConstructorType:
336 case ts.SyntaxKind.FunctionType:
338 case ts.SyntaxKind.SourceFile:
339 return ts.isExternalModule(node) ? 1 : 0;
344 exports.isFunctionScopeBoundary = isFunctionScopeBoundary;
345 function isBlockScopeBoundary(node) {
347 case ts.SyntaxKind.Block:
348 const parent = node.parent;
349 return parent.kind !== ts.SyntaxKind.CatchClause &&
350 (parent.kind === ts.SyntaxKind.SourceFile ||
351 !isFunctionScopeBoundary(parent))
354 case ts.SyntaxKind.ForStatement:
355 case ts.SyntaxKind.ForInStatement:
356 case ts.SyntaxKind.ForOfStatement:
357 case ts.SyntaxKind.CaseBlock:
358 case ts.SyntaxKind.CatchClause:
359 case ts.SyntaxKind.WithStatement:
365 exports.isBlockScopeBoundary = isBlockScopeBoundary;
366 function hasOwnThisReference(node) {
368 case ts.SyntaxKind.ClassDeclaration:
369 case ts.SyntaxKind.ClassExpression:
370 case ts.SyntaxKind.FunctionExpression:
372 case ts.SyntaxKind.FunctionDeclaration:
373 return node.body !== undefined;
374 case ts.SyntaxKind.MethodDeclaration:
375 case ts.SyntaxKind.GetAccessor:
376 case ts.SyntaxKind.SetAccessor:
377 return node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression;
382 exports.hasOwnThisReference = hasOwnThisReference;
383 function isFunctionWithBody(node) {
385 case ts.SyntaxKind.GetAccessor:
386 case ts.SyntaxKind.SetAccessor:
387 case ts.SyntaxKind.FunctionDeclaration:
388 case ts.SyntaxKind.MethodDeclaration:
389 case ts.SyntaxKind.Constructor:
390 return node.body !== undefined;
391 case ts.SyntaxKind.FunctionExpression:
392 case ts.SyntaxKind.ArrowFunction:
398 exports.isFunctionWithBody = isFunctionWithBody;
399 function forEachToken(node, cb, sourceFile = node.getSourceFile()) {
400 return (function iterate(child) {
401 if (isTokenKind(child.kind))
403 if (child.kind !== ts.SyntaxKind.JSDocComment)
404 return child.getChildren(sourceFile).forEach(iterate);
407 exports.forEachToken = forEachToken;
408 function forEachTokenWithTrivia(node, cb, sourceFile = node.getSourceFile()) {
409 const fullText = sourceFile.text;
410 const scanner = ts.createScanner(sourceFile.languageVersion, false, sourceFile.languageVariant, fullText);
411 return forEachToken(node, (token) => {
412 const tokenStart = token.kind === ts.SyntaxKind.JsxText || token.pos === token.end ? token.pos : token.getStart(sourceFile);
413 if (tokenStart !== token.pos) {
414 scanner.setTextPos(token.pos);
415 let kind = scanner.scan();
416 let pos = scanner.getTokenPos();
417 while (pos < tokenStart) {
418 const textPos = scanner.getTextPos();
419 cb(fullText, kind, { pos, end: textPos }, token.parent);
420 if (textPos === tokenStart)
422 kind = scanner.scan();
423 pos = scanner.getTokenPos();
426 return cb(fullText, token.kind, { end: token.end, pos: tokenStart }, token.parent);
429 exports.forEachTokenWithTrivia = forEachTokenWithTrivia;
430 function forEachComment(node, cb, sourceFile = node.getSourceFile()) {
431 const fullText = sourceFile.text;
432 const notJsx = sourceFile.languageVariant !== ts.LanguageVariant.JSX;
433 return forEachToken(node, (token) => {
434 if (token.pos === token.end)
436 if (token.kind !== ts.SyntaxKind.JsxText)
437 ts.forEachLeadingCommentRange(fullText, token.pos === 0 ? (ts.getShebang(fullText) || '').length : token.pos, commentCallback);
438 if (notJsx || canHaveTrailingTrivia(token))
439 return ts.forEachTrailingCommentRange(fullText, token.end, commentCallback);
441 function commentCallback(pos, end, kind) {
442 cb(fullText, { pos, end, kind });
445 exports.forEachComment = forEachComment;
446 function canHaveTrailingTrivia(token) {
447 switch (token.kind) {
448 case ts.SyntaxKind.CloseBraceToken:
449 return token.parent.kind !== ts.SyntaxKind.JsxExpression || !isJsxElementOrFragment(token.parent.parent);
450 case ts.SyntaxKind.GreaterThanToken:
451 switch (token.parent.kind) {
452 case ts.SyntaxKind.JsxOpeningElement:
453 return token.end !== token.parent.end;
454 case ts.SyntaxKind.JsxOpeningFragment:
456 case ts.SyntaxKind.JsxSelfClosingElement:
457 return token.end !== token.parent.end ||
458 !isJsxElementOrFragment(token.parent.parent);
459 case ts.SyntaxKind.JsxClosingElement:
460 case ts.SyntaxKind.JsxClosingFragment:
461 return !isJsxElementOrFragment(token.parent.parent.parent);
466 function isJsxElementOrFragment(node) {
467 return node.kind === ts.SyntaxKind.JsxElement || node.kind === ts.SyntaxKind.JsxFragment;
469 function getLineRanges(sourceFile) {
470 const lineStarts = sourceFile.getLineStarts();
472 const length = lineStarts.length;
473 const sourceText = sourceFile.text;
475 for (let i = 1; i < length; ++i) {
476 const end = lineStarts[i];
478 for (; lineEnd > pos; --lineEnd)
479 if (!ts.isLineBreak(sourceText.charCodeAt(lineEnd - 1)))
484 contentLength: lineEnd - pos,
491 contentLength: sourceFile.end - pos,
495 exports.getLineRanges = getLineRanges;
496 function getLineBreakStyle(sourceFile) {
497 const lineStarts = sourceFile.getLineStarts();
498 return lineStarts.length === 1 || lineStarts[1] < 2 || sourceFile.text[lineStarts[1] - 2] !== '\r'
502 exports.getLineBreakStyle = getLineBreakStyle;
504 function scanToken(text, languageVersion) {
505 if (cachedScanner === undefined) {
506 cachedScanner = ts.createScanner(languageVersion, false, undefined, text);
509 cachedScanner.setScriptTarget(languageVersion);
510 cachedScanner.setText(text);
512 cachedScanner.scan();
513 return cachedScanner;
515 function isValidIdentifier(text, languageVersion = ts.ScriptTarget.Latest) {
516 const scan = scanToken(text, languageVersion);
517 return scan.isIdentifier() && scan.getTextPos() === text.length && scan.getTokenPos() === 0;
519 exports.isValidIdentifier = isValidIdentifier;
520 function charSize(ch) {
521 return ch >= 0x10000 ? 2 : 1;
523 function isValidPropertyAccess(text, languageVersion = ts.ScriptTarget.Latest) {
524 if (text.length === 0)
526 let ch = text.codePointAt(0);
527 if (!ts.isIdentifierStart(ch, languageVersion))
529 for (let i = charSize(ch); i < text.length; i += charSize(ch)) {
530 ch = text.codePointAt(i);
531 if (!ts.isIdentifierPart(ch, languageVersion))
536 exports.isValidPropertyAccess = isValidPropertyAccess;
537 function isValidPropertyName(text, languageVersion = ts.ScriptTarget.Latest) {
538 if (isValidPropertyAccess(text, languageVersion))
540 const scan = scanToken(text, languageVersion);
541 return scan.getTextPos() === text.length &&
542 scan.getToken() === ts.SyntaxKind.NumericLiteral && scan.getTokenValue() === text;
544 exports.isValidPropertyName = isValidPropertyName;
545 function isValidNumericLiteral(text, languageVersion = ts.ScriptTarget.Latest) {
546 const scan = scanToken(text, languageVersion);
547 return scan.getToken() === ts.SyntaxKind.NumericLiteral && scan.getTextPos() === text.length && scan.getTokenPos() === 0;
549 exports.isValidNumericLiteral = isValidNumericLiteral;
550 function isValidJsxIdentifier(text, languageVersion = ts.ScriptTarget.Latest) {
551 if (text.length === 0)
553 let ch = text.codePointAt(0);
554 if (!ts.isIdentifierStart(ch, languageVersion))
556 for (let i = charSize(ch); i < text.length; i += charSize(ch)) {
557 ch = text.codePointAt(i);
558 if (!ts.isIdentifierPart(ch, languageVersion) && ch !== 45)
563 exports.isValidJsxIdentifier = isValidJsxIdentifier;
564 function isNumericPropertyName(name) {
565 return String(+name) === name;
567 exports.isNumericPropertyName = isNumericPropertyName;
568 function isSameLine(sourceFile, pos1, pos2) {
569 return ts.getLineAndCharacterOfPosition(sourceFile, pos1).line === ts.getLineAndCharacterOfPosition(sourceFile, pos2).line;
571 exports.isSameLine = isSameLine;
572 var SideEffectOptions;
573 (function (SideEffectOptions) {
574 SideEffectOptions[SideEffectOptions["None"] = 0] = "None";
575 SideEffectOptions[SideEffectOptions["TaggedTemplate"] = 1] = "TaggedTemplate";
576 SideEffectOptions[SideEffectOptions["Constructor"] = 2] = "Constructor";
577 SideEffectOptions[SideEffectOptions["JsxElement"] = 4] = "JsxElement";
578 })(SideEffectOptions = exports.SideEffectOptions || (exports.SideEffectOptions = {}));
579 function hasSideEffects(node, options) {
581 case ts.SyntaxKind.CallExpression:
582 case ts.SyntaxKind.PostfixUnaryExpression:
583 case ts.SyntaxKind.AwaitExpression:
584 case ts.SyntaxKind.YieldExpression:
585 case ts.SyntaxKind.DeleteExpression:
587 case ts.SyntaxKind.TypeAssertionExpression:
588 case ts.SyntaxKind.AsExpression:
589 case ts.SyntaxKind.ParenthesizedExpression:
590 case ts.SyntaxKind.NonNullExpression:
591 case ts.SyntaxKind.VoidExpression:
592 case ts.SyntaxKind.TypeOfExpression:
593 case ts.SyntaxKind.PropertyAccessExpression:
594 case ts.SyntaxKind.SpreadElement:
595 case ts.SyntaxKind.PartiallyEmittedExpression:
596 return hasSideEffects(node.expression, options);
597 case ts.SyntaxKind.BinaryExpression:
598 return isAssignmentKind(node.operatorToken.kind) ||
599 hasSideEffects(node.left, options) ||
600 hasSideEffects(node.right, options);
601 case ts.SyntaxKind.PrefixUnaryExpression:
602 switch (node.operator) {
603 case ts.SyntaxKind.PlusPlusToken:
604 case ts.SyntaxKind.MinusMinusToken:
607 return hasSideEffects(node.operand, options);
609 case ts.SyntaxKind.ElementAccessExpression:
610 return hasSideEffects(node.expression, options) ||
611 node.argumentExpression !== undefined &&
612 hasSideEffects(node.argumentExpression, options);
613 case ts.SyntaxKind.ConditionalExpression:
614 return hasSideEffects(node.condition, options) ||
615 hasSideEffects(node.whenTrue, options) ||
616 hasSideEffects(node.whenFalse, options);
617 case ts.SyntaxKind.NewExpression:
618 if (options & 2 || hasSideEffects(node.expression, options))
620 if (node.arguments !== undefined)
621 for (const child of node.arguments)
622 if (hasSideEffects(child, options))
625 case ts.SyntaxKind.TaggedTemplateExpression:
626 if (options & 1 || hasSideEffects(node.tag, options))
628 if (node.template.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral)
630 node = node.template;
631 case ts.SyntaxKind.TemplateExpression:
632 for (const child of node.templateSpans)
633 if (hasSideEffects(child.expression, options))
636 case ts.SyntaxKind.ClassExpression:
637 return classExpressionHasSideEffects(node, options);
638 case ts.SyntaxKind.ArrayLiteralExpression:
639 for (const child of node.elements)
640 if (hasSideEffects(child, options))
643 case ts.SyntaxKind.ObjectLiteralExpression:
644 for (const child of node.properties) {
645 if (child.name !== undefined && child.name.kind === ts.SyntaxKind.ComputedPropertyName &&
646 hasSideEffects(child.name.expression, options))
648 switch (child.kind) {
649 case ts.SyntaxKind.PropertyAssignment:
650 if (hasSideEffects(child.initializer, options))
653 case ts.SyntaxKind.SpreadAssignment:
654 if (hasSideEffects(child.expression, options))
659 case ts.SyntaxKind.JsxExpression:
660 return node.expression !== undefined && hasSideEffects(node.expression, options);
661 case ts.SyntaxKind.JsxElement:
662 case ts.SyntaxKind.JsxFragment:
663 for (const child of node.children)
664 if (child.kind !== ts.SyntaxKind.JsxText && hasSideEffects(child, options))
666 if (node.kind === ts.SyntaxKind.JsxFragment)
668 node = node.openingElement;
669 case ts.SyntaxKind.JsxSelfClosingElement:
670 case ts.SyntaxKind.JsxOpeningElement:
673 for (const child of node.attributes.properties) {
674 if (child.kind === ts.SyntaxKind.JsxSpreadAttribute) {
675 if (hasSideEffects(child.expression, options))
678 else if (child.initializer !== undefined && hasSideEffects(child.initializer, options)) {
683 case ts.SyntaxKind.CommaListExpression:
684 for (const child of node.elements)
685 if (hasSideEffects(child, options))
692 exports.hasSideEffects = hasSideEffects;
693 function classExpressionHasSideEffects(node, options) {
694 if (node.heritageClauses !== undefined && node.heritageClauses[0].token === ts.SyntaxKind.ExtendsKeyword)
695 for (const base of node.heritageClauses[0].types)
696 if (hasSideEffects(base.expression, options))
698 for (const child of node.members)
699 if (child.name !== undefined && child.name.kind === ts.SyntaxKind.ComputedPropertyName &&
700 hasSideEffects(child.name.expression, options) ||
701 node_1.isPropertyDeclaration(child) && child.initializer !== undefined &&
702 hasSideEffects(child.initializer, options))
706 function getDeclarationOfBindingElement(node) {
707 let parent = node.parent.parent;
708 while (parent.kind === ts.SyntaxKind.BindingElement)
709 parent = parent.parent.parent;
712 exports.getDeclarationOfBindingElement = getDeclarationOfBindingElement;
713 function isExpressionValueUsed(node) {
715 const parent = node.parent;
716 switch (parent.kind) {
717 case ts.SyntaxKind.CallExpression:
718 case ts.SyntaxKind.NewExpression:
719 case ts.SyntaxKind.ElementAccessExpression:
720 case ts.SyntaxKind.WhileStatement:
721 case ts.SyntaxKind.DoStatement:
722 case ts.SyntaxKind.WithStatement:
723 case ts.SyntaxKind.ThrowStatement:
724 case ts.SyntaxKind.ReturnStatement:
725 case ts.SyntaxKind.JsxExpression:
726 case ts.SyntaxKind.JsxSpreadAttribute:
727 case ts.SyntaxKind.JsxElement:
728 case ts.SyntaxKind.JsxFragment:
729 case ts.SyntaxKind.JsxSelfClosingElement:
730 case ts.SyntaxKind.ComputedPropertyName:
731 case ts.SyntaxKind.ArrowFunction:
732 case ts.SyntaxKind.ExportSpecifier:
733 case ts.SyntaxKind.ExportAssignment:
734 case ts.SyntaxKind.ImportDeclaration:
735 case ts.SyntaxKind.ExternalModuleReference:
736 case ts.SyntaxKind.Decorator:
737 case ts.SyntaxKind.TaggedTemplateExpression:
738 case ts.SyntaxKind.TemplateSpan:
739 case ts.SyntaxKind.ExpressionWithTypeArguments:
740 case ts.SyntaxKind.TypeOfExpression:
741 case ts.SyntaxKind.AwaitExpression:
742 case ts.SyntaxKind.YieldExpression:
743 case ts.SyntaxKind.LiteralType:
744 case ts.SyntaxKind.JsxAttributes:
745 case ts.SyntaxKind.JsxOpeningElement:
746 case ts.SyntaxKind.JsxClosingElement:
747 case ts.SyntaxKind.IfStatement:
748 case ts.SyntaxKind.CaseClause:
749 case ts.SyntaxKind.SwitchStatement:
751 case ts.SyntaxKind.PropertyAccessExpression:
752 return parent.expression === node;
753 case ts.SyntaxKind.QualifiedName:
754 return parent.left === node;
755 case ts.SyntaxKind.ShorthandPropertyAssignment:
756 return parent.objectAssignmentInitializer === node ||
757 !isInDestructuringAssignment(parent);
758 case ts.SyntaxKind.PropertyAssignment:
759 return parent.initializer === node && !isInDestructuringAssignment(parent);
760 case ts.SyntaxKind.SpreadAssignment:
761 case ts.SyntaxKind.SpreadElement:
762 case ts.SyntaxKind.ArrayLiteralExpression:
763 return !isInDestructuringAssignment(parent);
764 case ts.SyntaxKind.ParenthesizedExpression:
765 case ts.SyntaxKind.AsExpression:
766 case ts.SyntaxKind.TypeAssertionExpression:
767 case ts.SyntaxKind.PostfixUnaryExpression:
768 case ts.SyntaxKind.PrefixUnaryExpression:
769 case ts.SyntaxKind.NonNullExpression:
772 case ts.SyntaxKind.ForStatement:
773 return parent.condition === node;
774 case ts.SyntaxKind.ForInStatement:
775 case ts.SyntaxKind.ForOfStatement:
776 return parent.expression === node;
777 case ts.SyntaxKind.ConditionalExpression:
778 if (parent.condition === node)
782 case ts.SyntaxKind.PropertyDeclaration:
783 case ts.SyntaxKind.BindingElement:
784 case ts.SyntaxKind.VariableDeclaration:
785 case ts.SyntaxKind.Parameter:
786 case ts.SyntaxKind.EnumMember:
787 return parent.initializer === node;
788 case ts.SyntaxKind.ImportEqualsDeclaration:
789 return parent.moduleReference === node;
790 case ts.SyntaxKind.CommaListExpression:
791 if (parent.elements[parent.elements.length - 1] !== node)
795 case ts.SyntaxKind.BinaryExpression:
796 if (parent.right === node) {
797 if (parent.operatorToken.kind === ts.SyntaxKind.CommaToken) {
803 switch (parent.operatorToken.kind) {
804 case ts.SyntaxKind.CommaToken:
805 case ts.SyntaxKind.EqualsToken:
807 case ts.SyntaxKind.EqualsEqualsEqualsToken:
808 case ts.SyntaxKind.EqualsEqualsToken:
809 case ts.SyntaxKind.ExclamationEqualsEqualsToken:
810 case ts.SyntaxKind.ExclamationEqualsToken:
811 case ts.SyntaxKind.InstanceOfKeyword:
812 case ts.SyntaxKind.PlusToken:
813 case ts.SyntaxKind.MinusToken:
814 case ts.SyntaxKind.AsteriskToken:
815 case ts.SyntaxKind.SlashToken:
816 case ts.SyntaxKind.PercentToken:
817 case ts.SyntaxKind.AsteriskAsteriskToken:
818 case ts.SyntaxKind.GreaterThanToken:
819 case ts.SyntaxKind.GreaterThanGreaterThanToken:
820 case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
821 case ts.SyntaxKind.GreaterThanEqualsToken:
822 case ts.SyntaxKind.LessThanToken:
823 case ts.SyntaxKind.LessThanLessThanToken:
824 case ts.SyntaxKind.LessThanEqualsToken:
825 case ts.SyntaxKind.AmpersandToken:
826 case ts.SyntaxKind.BarToken:
827 case ts.SyntaxKind.CaretToken:
828 case ts.SyntaxKind.BarBarToken:
829 case ts.SyntaxKind.AmpersandAmpersandToken:
830 case ts.SyntaxKind.InKeyword:
841 exports.isExpressionValueUsed = isExpressionValueUsed;
842 function isInDestructuringAssignment(node) {
844 case ts.SyntaxKind.ShorthandPropertyAssignment:
845 if (node.objectAssignmentInitializer !== undefined)
847 case ts.SyntaxKind.PropertyAssignment:
848 case ts.SyntaxKind.SpreadAssignment:
851 case ts.SyntaxKind.SpreadElement:
852 if (node.parent.kind !== ts.SyntaxKind.ArrayLiteralExpression)
857 switch (node.parent.kind) {
858 case ts.SyntaxKind.BinaryExpression:
859 return node.parent.left === node &&
860 node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken;
861 case ts.SyntaxKind.ForOfStatement:
862 return node.parent.initializer === node;
863 case ts.SyntaxKind.ArrayLiteralExpression:
864 case ts.SyntaxKind.ObjectLiteralExpression:
867 case ts.SyntaxKind.SpreadAssignment:
868 case ts.SyntaxKind.PropertyAssignment:
869 node = node.parent.parent;
871 case ts.SyntaxKind.SpreadElement:
872 if (node.parent.parent.kind !== ts.SyntaxKind.ArrayLiteralExpression)
874 node = node.parent.parent;
882 (function (AccessKind) {
883 AccessKind[AccessKind["None"] = 0] = "None";
884 AccessKind[AccessKind["Read"] = 1] = "Read";
885 AccessKind[AccessKind["Write"] = 2] = "Write";
886 AccessKind[AccessKind["Delete"] = 4] = "Delete";
887 AccessKind[AccessKind["ReadWrite"] = 3] = "ReadWrite";
888 AccessKind[AccessKind["Modification"] = 6] = "Modification";
889 })(AccessKind = exports.AccessKind || (exports.AccessKind = {}));
890 function getAccessKind(node) {
891 const parent = node.parent;
892 switch (parent.kind) {
893 case ts.SyntaxKind.DeleteExpression:
895 case ts.SyntaxKind.PostfixUnaryExpression:
897 case ts.SyntaxKind.PrefixUnaryExpression:
898 return parent.operator === ts.SyntaxKind.PlusPlusToken ||
899 parent.operator === ts.SyntaxKind.MinusMinusToken
902 case ts.SyntaxKind.BinaryExpression:
903 return parent.right === node
905 : !isAssignmentKind(parent.operatorToken.kind)
907 : parent.operatorToken.kind === ts.SyntaxKind.EqualsToken
910 case ts.SyntaxKind.ShorthandPropertyAssignment:
911 return parent.objectAssignmentInitializer === node
913 : isInDestructuringAssignment(parent)
916 case ts.SyntaxKind.PropertyAssignment:
917 return parent.name === node
919 : isInDestructuringAssignment(parent)
922 case ts.SyntaxKind.ArrayLiteralExpression:
923 case ts.SyntaxKind.SpreadElement:
924 case ts.SyntaxKind.SpreadAssignment:
925 return isInDestructuringAssignment(parent)
928 case ts.SyntaxKind.ParenthesizedExpression:
929 case ts.SyntaxKind.NonNullExpression:
930 case ts.SyntaxKind.TypeAssertionExpression:
931 case ts.SyntaxKind.AsExpression:
932 return getAccessKind(parent);
933 case ts.SyntaxKind.ForOfStatement:
934 case ts.SyntaxKind.ForInStatement:
935 return parent.initializer === node
938 case ts.SyntaxKind.ExpressionWithTypeArguments:
939 return parent.parent.token === ts.SyntaxKind.ExtendsKeyword &&
940 parent.parent.parent.kind !== ts.SyntaxKind.InterfaceDeclaration
943 case ts.SyntaxKind.ComputedPropertyName:
944 case ts.SyntaxKind.ExpressionStatement:
945 case ts.SyntaxKind.TypeOfExpression:
946 case ts.SyntaxKind.ElementAccessExpression:
947 case ts.SyntaxKind.ForStatement:
948 case ts.SyntaxKind.IfStatement:
949 case ts.SyntaxKind.DoStatement:
950 case ts.SyntaxKind.WhileStatement:
951 case ts.SyntaxKind.SwitchStatement:
952 case ts.SyntaxKind.WithStatement:
953 case ts.SyntaxKind.ThrowStatement:
954 case ts.SyntaxKind.CallExpression:
955 case ts.SyntaxKind.NewExpression:
956 case ts.SyntaxKind.TaggedTemplateExpression:
957 case ts.SyntaxKind.JsxExpression:
958 case ts.SyntaxKind.Decorator:
959 case ts.SyntaxKind.TemplateSpan:
960 case ts.SyntaxKind.JsxOpeningElement:
961 case ts.SyntaxKind.JsxSelfClosingElement:
962 case ts.SyntaxKind.JsxSpreadAttribute:
963 case ts.SyntaxKind.VoidExpression:
964 case ts.SyntaxKind.ReturnStatement:
965 case ts.SyntaxKind.AwaitExpression:
966 case ts.SyntaxKind.YieldExpression:
967 case ts.SyntaxKind.ConditionalExpression:
968 case ts.SyntaxKind.CaseClause:
969 case ts.SyntaxKind.JsxElement:
971 case ts.SyntaxKind.ArrowFunction:
972 return parent.body === node
975 case ts.SyntaxKind.PropertyDeclaration:
976 case ts.SyntaxKind.VariableDeclaration:
977 case ts.SyntaxKind.Parameter:
978 case ts.SyntaxKind.EnumMember:
979 case ts.SyntaxKind.BindingElement:
980 case ts.SyntaxKind.JsxAttribute:
981 return parent.initializer === node
984 case ts.SyntaxKind.PropertyAccessExpression:
985 return parent.expression === node
988 case ts.SyntaxKind.ExportAssignment:
989 return parent.isExportEquals
995 exports.getAccessKind = getAccessKind;
996 function isReassignmentTarget(node) {
997 return (getAccessKind(node) & 2) !== 0;
999 exports.isReassignmentTarget = isReassignmentTarget;
1000 function canHaveJsDoc(node) {
1001 const kind = node.kind;
1003 case ts.SyntaxKind.Parameter:
1004 case ts.SyntaxKind.CallSignature:
1005 case ts.SyntaxKind.ConstructSignature:
1006 case ts.SyntaxKind.MethodSignature:
1007 case ts.SyntaxKind.PropertySignature:
1008 case ts.SyntaxKind.ArrowFunction:
1009 case ts.SyntaxKind.ParenthesizedExpression:
1010 case ts.SyntaxKind.SpreadAssignment:
1011 case ts.SyntaxKind.ShorthandPropertyAssignment:
1012 case ts.SyntaxKind.PropertyAssignment:
1013 case ts.SyntaxKind.FunctionExpression:
1014 case ts.SyntaxKind.FunctionDeclaration:
1015 case ts.SyntaxKind.LabeledStatement:
1016 case ts.SyntaxKind.ExpressionStatement:
1017 case ts.SyntaxKind.VariableStatement:
1018 case ts.SyntaxKind.Constructor:
1019 case ts.SyntaxKind.MethodDeclaration:
1020 case ts.SyntaxKind.PropertyDeclaration:
1021 case ts.SyntaxKind.GetAccessor:
1022 case ts.SyntaxKind.SetAccessor:
1023 case ts.SyntaxKind.ClassDeclaration:
1024 case ts.SyntaxKind.ClassExpression:
1025 case ts.SyntaxKind.InterfaceDeclaration:
1026 case ts.SyntaxKind.TypeAliasDeclaration:
1027 case ts.SyntaxKind.EnumMember:
1028 case ts.SyntaxKind.EnumDeclaration:
1029 case ts.SyntaxKind.ModuleDeclaration:
1030 case ts.SyntaxKind.ImportEqualsDeclaration:
1031 case ts.SyntaxKind.IndexSignature:
1032 case ts.SyntaxKind.FunctionType:
1033 case ts.SyntaxKind.ConstructorType:
1034 case ts.SyntaxKind.JSDocFunctionType:
1035 case ts.SyntaxKind.EndOfFileToken:
1036 case ts.SyntaxKind.ExportDeclaration:
1042 exports.canHaveJsDoc = canHaveJsDoc;
1043 function getJsDoc(node, sourceFile) {
1044 if (node.kind === ts.SyntaxKind.EndOfFileToken)
1045 return parseJsDocWorker(node, sourceFile || node.parent);
1047 for (const child of node.getChildren(sourceFile)) {
1048 if (!node_1.isJsDoc(child))
1054 exports.getJsDoc = getJsDoc;
1055 function parseJsDocOfNode(node, considerTrailingComments, sourceFile = node.getSourceFile()) {
1056 if (canHaveJsDoc(node) && node.kind !== ts.SyntaxKind.EndOfFileToken) {
1057 const result = getJsDoc(node, sourceFile);
1058 if (result.length !== 0 || !considerTrailingComments)
1061 return parseJsDocWorker(node, sourceFile, considerTrailingComments);
1063 exports.parseJsDocOfNode = parseJsDocOfNode;
1064 function parseJsDocWorker(node, sourceFile, considerTrailingComments) {
1065 const nodeStart = node.getStart(sourceFile);
1066 const start = ts[considerTrailingComments && isSameLine(sourceFile, node.pos, nodeStart)
1067 ? 'forEachTrailingCommentRange'
1068 : 'forEachLeadingCommentRange'](sourceFile.text, node.pos, (pos, _end, kind) => kind === ts.SyntaxKind.MultiLineCommentTrivia && sourceFile.text[pos + 2] === '*' ? { pos } : undefined);
1069 if (start === undefined)
1071 const startPos = start.pos;
1072 const text = sourceFile.text.slice(startPos, nodeStart);
1073 const newSourceFile = ts.createSourceFile('jsdoc.ts', `${text}var a;`, sourceFile.languageVersion);
1074 const result = getJsDoc(newSourceFile.statements[0], newSourceFile);
1075 for (const doc of result)
1076 updateNode(doc, node);
1078 function updateNode(n, parent) {
1082 return ts.forEachChild(n, (child) => updateNode(child, n), (children) => {
1083 children.pos += startPos;
1084 children.end += startPos;
1085 for (const child of children)
1086 updateNode(child, n);
1091 (function (ImportKind) {
1092 ImportKind[ImportKind["ImportDeclaration"] = 1] = "ImportDeclaration";
1093 ImportKind[ImportKind["ImportEquals"] = 2] = "ImportEquals";
1094 ImportKind[ImportKind["ExportFrom"] = 4] = "ExportFrom";
1095 ImportKind[ImportKind["DynamicImport"] = 8] = "DynamicImport";
1096 ImportKind[ImportKind["Require"] = 16] = "Require";
1097 ImportKind[ImportKind["ImportType"] = 32] = "ImportType";
1098 ImportKind[ImportKind["All"] = 63] = "All";
1099 ImportKind[ImportKind["AllImports"] = 59] = "AllImports";
1100 ImportKind[ImportKind["AllStaticImports"] = 3] = "AllStaticImports";
1101 ImportKind[ImportKind["AllImportExpressions"] = 24] = "AllImportExpressions";
1102 ImportKind[ImportKind["AllRequireLike"] = 18] = "AllRequireLike";
1103 ImportKind[ImportKind["AllNestedImports"] = 56] = "AllNestedImports";
1104 ImportKind[ImportKind["AllTopLevelImports"] = 7] = "AllTopLevelImports";
1105 })(ImportKind = exports.ImportKind || (exports.ImportKind = {}));
1106 function findImports(sourceFile, kinds) {
1108 for (const node of findImportLikeNodes(sourceFile, kinds)) {
1109 switch (node.kind) {
1110 case ts.SyntaxKind.ImportDeclaration:
1111 addIfTextualLiteral(node.moduleSpecifier);
1113 case ts.SyntaxKind.ImportEqualsDeclaration:
1114 addIfTextualLiteral(node.moduleReference.expression);
1116 case ts.SyntaxKind.ExportDeclaration:
1117 addIfTextualLiteral(node.moduleSpecifier);
1119 case ts.SyntaxKind.CallExpression:
1120 addIfTextualLiteral(node.arguments[0]);
1122 case ts.SyntaxKind.ImportType:
1123 if (node_1.isLiteralTypeNode(node.argument))
1124 addIfTextualLiteral(node.argument.literal);
1127 throw new Error('unexpected node');
1131 function addIfTextualLiteral(node) {
1132 if (node_1.isTextualLiteral(node))
1136 exports.findImports = findImports;
1137 function findImportLikeNodes(sourceFile, kinds) {
1138 return new ImportFinder(sourceFile, kinds).find();
1140 exports.findImportLikeNodes = findImportLikeNodes;
1141 class ImportFinder {
1142 constructor(_sourceFile, _options) {
1143 this._sourceFile = _sourceFile;
1144 this._options = _options;
1148 if (this._sourceFile.isDeclarationFile)
1149 this._options &= ~24;
1150 if (this._options & 7)
1151 this._findImports(this._sourceFile.statements);
1152 if (this._options & 56)
1153 this._findNestedImports();
1154 return this._result;
1156 _findImports(statements) {
1157 for (const statement of statements) {
1158 if (node_1.isImportDeclaration(statement)) {
1159 if (this._options & 1)
1160 this._result.push(statement);
1162 else if (node_1.isImportEqualsDeclaration(statement)) {
1163 if (this._options & 2 &&
1164 statement.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)
1165 this._result.push(statement);
1167 else if (node_1.isExportDeclaration(statement)) {
1168 if (statement.moduleSpecifier !== undefined && this._options & 4)
1169 this._result.push(statement);
1171 else if (node_1.isModuleDeclaration(statement)) {
1172 this._findImportsInModule(statement);
1176 _findImportsInModule(declaration) {
1177 if (declaration.body === undefined)
1179 if (declaration.body.kind === ts.SyntaxKind.ModuleDeclaration)
1180 return this._findImportsInModule(declaration.body);
1181 this._findImports(declaration.body.statements);
1183 _findNestedImports() {
1185 if ((this._options & 56) === 16) {
1186 re = /\brequire\s*[</(]/g;
1188 else if (this._options & 16) {
1189 re = /\b(?:import|require)\s*[</(]/g;
1192 re = /\bimport\s*[</(]/g;
1194 const isJavaScriptFile = (this._sourceFile.flags & ts.NodeFlags.JavaScriptFile) !== 0;
1195 for (let match = re.exec(this._sourceFile.text); match !== null; match = re.exec(this._sourceFile.text)) {
1196 const token = getTokenAtPositionWorker(this._sourceFile, match.index, this._sourceFile, match[0][0] === 'i' && isJavaScriptFile);
1197 if (token.kind === ts.SyntaxKind.ImportKeyword) {
1198 if (token.end - 'import'.length !== match.index)
1200 switch (token.parent.kind) {
1201 case ts.SyntaxKind.ImportType:
1202 this._result.push(token.parent);
1204 case ts.SyntaxKind.CallExpression:
1205 if (token.parent.arguments.length === 1)
1206 this._result.push(token.parent);
1209 else if (token.kind === ts.SyntaxKind.Identifier &&
1210 token.end - 'require'.length === match.index &&
1211 token.parent.kind === ts.SyntaxKind.CallExpression &&
1212 token.parent.expression === token &&
1213 token.parent.arguments.length === 1) {
1214 this._result.push(token.parent);
1219 function isStatementInAmbientContext(node) {
1220 while (node.flags & ts.NodeFlags.NestedNamespace)
1222 return hasModifier(node.modifiers, ts.SyntaxKind.DeclareKeyword) || isAmbientModuleBlock(node.parent);
1224 exports.isStatementInAmbientContext = isStatementInAmbientContext;
1225 function isAmbientModuleBlock(node) {
1226 while (node.kind === ts.SyntaxKind.ModuleBlock) {
1229 while (node.flags & ts.NodeFlags.NestedNamespace);
1230 if (hasModifier(node.modifiers, ts.SyntaxKind.DeclareKeyword))
1236 exports.isAmbientModuleBlock = isAmbientModuleBlock;
1237 function getIIFE(func) {
1238 let node = func.parent;
1239 while (node.kind === ts.SyntaxKind.ParenthesizedExpression)
1241 return node_1.isCallExpression(node) && func.end <= node.expression.end ? node : undefined;
1243 exports.getIIFE = getIIFE;
1244 function isStrictCompilerOptionEnabled(options, option) {
1245 return (options.strict ? options[option] !== false : options[option] === true) &&
1246 (option !== 'strictPropertyInitialization' || isStrictCompilerOptionEnabled(options, 'strictNullChecks'));
1248 exports.isStrictCompilerOptionEnabled = isStrictCompilerOptionEnabled;
1249 function isCompilerOptionEnabled(options, option) {
1251 case 'stripInternal':
1252 return options.stripInternal === true && isCompilerOptionEnabled(options, 'declaration');
1254 return options.declaration || isCompilerOptionEnabled(options, 'composite');
1256 return options.incremental === undefined ? isCompilerOptionEnabled(options, 'composite') : options.incremental;
1257 case 'skipDefaultLibCheck':
1258 return options.skipDefaultLibCheck || isCompilerOptionEnabled(options, 'skipLibCheck');
1259 case 'suppressImplicitAnyIndexErrors':
1260 return options.suppressImplicitAnyIndexErrors === true && isCompilerOptionEnabled(options, 'noImplicitAny');
1261 case 'allowSyntheticDefaultImports':
1262 return options.allowSyntheticDefaultImports !== undefined
1263 ? options.allowSyntheticDefaultImports
1264 : isCompilerOptionEnabled(options, 'esModuleInterop') || options.module === ts.ModuleKind.System;
1265 case 'noImplicitAny':
1266 case 'noImplicitThis':
1267 case 'strictNullChecks':
1268 case 'strictFunctionTypes':
1269 case 'strictPropertyInitialization':
1270 case 'alwaysStrict':
1271 case 'strictBindCallApply':
1272 return isStrictCompilerOptionEnabled(options, option);
1274 return options[option] === true;
1276 exports.isCompilerOptionEnabled = isCompilerOptionEnabled;
1277 function isAmbientModule(node) {
1278 return node.name.kind === ts.SyntaxKind.StringLiteral || (node.flags & ts.NodeFlags.GlobalAugmentation) !== 0;
1280 exports.isAmbientModule = isAmbientModule;
1281 function getCheckJsDirective(source) {
1283 ts.forEachLeadingCommentRange(source, (ts.getShebang(source) || '').length, (pos, end, kind) => {
1284 if (kind === ts.SyntaxKind.SingleLineCommentTrivia) {
1285 const text = source.slice(pos, end);
1286 const match = /^\/{2,3}\s*@ts-(no)?check(?:\s|$)/i.exec(text);
1288 directive = { pos, end, enabled: match[1] === undefined };
1293 exports.getCheckJsDirective = getCheckJsDirective;
1294 function isConstAssertion(node) {
1295 return node_1.isTypeReferenceNode(node.type) &&
1296 node.type.typeName.kind === ts.SyntaxKind.Identifier &&
1297 node.type.typeName.escapedText === 'const';
1299 exports.isConstAssertion = isConstAssertion;
1300 function isInConstContext(node) {
1303 const parent = current.parent;
1304 outer: switch (parent.kind) {
1305 case ts.SyntaxKind.TypeAssertionExpression:
1306 case ts.SyntaxKind.AsExpression:
1307 return isConstAssertion(parent);
1308 case ts.SyntaxKind.PrefixUnaryExpression:
1309 if (current.kind !== ts.SyntaxKind.NumericLiteral)
1311 switch (parent.operator) {
1312 case ts.SyntaxKind.PlusToken:
1313 case ts.SyntaxKind.MinusToken:
1319 case ts.SyntaxKind.PropertyAssignment:
1320 if (parent.initializer !== current)
1322 current = parent.parent;
1324 case ts.SyntaxKind.ShorthandPropertyAssignment:
1325 current = parent.parent;
1327 case ts.SyntaxKind.ParenthesizedExpression:
1328 case ts.SyntaxKind.ArrayLiteralExpression:
1329 case ts.SyntaxKind.ObjectLiteralExpression:
1337 exports.isInConstContext = isInConstContext;
1338 function isReadonlyAssignmentDeclaration(node, checker) {
1339 if (!isBindableObjectDefinePropertyCall(node))
1341 const descriptorType = checker.getTypeAtLocation(node.arguments[2]);
1342 if (descriptorType.getProperty('value') === undefined)
1343 return descriptorType.getProperty('set') === undefined;
1344 const writableProp = descriptorType.getProperty('writable');
1345 if (writableProp === undefined)
1347 const writableType = writableProp.valueDeclaration !== undefined && node_1.isPropertyAssignment(writableProp.valueDeclaration)
1348 ? checker.getTypeAtLocation(writableProp.valueDeclaration.initializer)
1349 : checker.getTypeOfSymbolAtLocation(writableProp, node.arguments[2]);
1350 return type_1.isBooleanLiteralType(writableType, false);
1352 exports.isReadonlyAssignmentDeclaration = isReadonlyAssignmentDeclaration;
1353 function isBindableObjectDefinePropertyCall(node) {
1354 return node.arguments.length === 3 &&
1355 node_1.isEntityNameExpression(node.arguments[0]) &&
1356 node_1.isNumericOrStringLikeLiteral(node.arguments[1]) &&
1357 node_1.isPropertyAccessExpression(node.expression) &&
1358 node.expression.name.escapedText === 'defineProperty' &&
1359 node_1.isIdentifier(node.expression.expression) &&
1360 node.expression.expression.escapedText === 'Object';
1362 exports.isBindableObjectDefinePropertyCall = isBindableObjectDefinePropertyCall;
1363 function isWellKnownSymbolLiterally(node) {
1364 return ts.isPropertyAccessExpression(node) &&
1365 ts.isIdentifier(node.expression) &&
1366 node.expression.escapedText === 'Symbol';
1368 exports.isWellKnownSymbolLiterally = isWellKnownSymbolLiterally;
1369 function getPropertyNameOfWellKnownSymbol(node) {
1371 displayName: `[Symbol.${node.name.text}]`,
1372 symbolName: ('__@' + node.name.text),
1375 exports.getPropertyNameOfWellKnownSymbol = getPropertyNameOfWellKnownSymbol;
1376 function getLateBoundPropertyNames(node, checker) {
1381 node = unwrapParentheses(node);
1382 if (isWellKnownSymbolLiterally(node)) {
1383 result.names.push(getPropertyNameOfWellKnownSymbol(node));
1386 const type = checker.getTypeAtLocation(node);
1387 for (const key of type_1.unionTypeParts(checker.getBaseConstraintOfType(type) || type)) {
1388 const propertyName = type_1.getPropertyNameFromType(key);
1390 result.names.push(propertyName);
1393 result.known = false;
1399 exports.getLateBoundPropertyNames = getLateBoundPropertyNames;
1400 function getLateBoundPropertyNamesOfPropertyName(node, checker) {
1401 const staticName = getPropertyName(node);
1402 return staticName !== undefined
1403 ? { known: true, names: [{ displayName: staticName, symbolName: ts.escapeLeadingUnderscores(staticName) }] }
1404 : getLateBoundPropertyNames(node.expression, checker);
1406 exports.getLateBoundPropertyNamesOfPropertyName = getLateBoundPropertyNamesOfPropertyName;
1407 function getSingleLateBoundPropertyNameOfPropertyName(node, checker) {
1408 const staticName = getPropertyName(node);
1409 if (staticName !== undefined)
1410 return { displayName: staticName, symbolName: ts.escapeLeadingUnderscores(staticName) };
1411 const { expression } = node;
1412 return isWellKnownSymbolLiterally(expression)
1413 ? getPropertyNameOfWellKnownSymbol(expression)
1414 : type_1.getPropertyNameFromType(checker.getTypeAtLocation(expression));
1416 exports.getSingleLateBoundPropertyNameOfPropertyName = getSingleLateBoundPropertyNameOfPropertyName;
1417 function unwrapParentheses(node) {
1418 while (node.kind === ts.SyntaxKind.ParenthesizedExpression)
1419 node = node.expression;
1422 exports.unwrapParentheses = unwrapParentheses;