'use strict'; var common = require('@ts-morph/common'); var CodeBlockWriter = require('code-block-writer'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var CodeBlockWriter__default = /*#__PURE__*/_interopDefaultCompat(CodeBlockWriter); class AdvancedIterator { #iterator; #buffer = [undefined, undefined, undefined]; #bufferIndex = 0; #isDone = false; #nextCount = 0; constructor(iterator) { this.#iterator = iterator; this.#advance(); } get done() { return this.#isDone; } get current() { if (this.#nextCount === 0) throw new common.errors.InvalidOperationError("Cannot get the current when the iterator has not been advanced."); return this.#buffer[this.#bufferIndex]; } get previous() { if (this.#nextCount <= 1) throw new common.errors.InvalidOperationError("Cannot get the previous when the iterator has not advanced enough."); return this.#buffer[(this.#bufferIndex + this.#buffer.length - 1) % this.#buffer.length]; } get peek() { if (this.#isDone) throw new common.errors.InvalidOperationError("Cannot peek at the end of the iterator."); return this.#buffer[(this.#bufferIndex + 1) % this.#buffer.length]; } next() { if (this.done) throw new common.errors.InvalidOperationError("Cannot get the next when at the end of the iterator."); const next = this.#buffer[this.#getNextBufferIndex()]; this.#advance(); this.#nextCount++; return next; } *rest() { while (!this.done) yield this.next(); } #advance() { const next = this.#iterator.next(); this.#bufferIndex = this.#getNextBufferIndex(); if (next.done) { this.#isDone = true; return; } this.#buffer[this.#getNextBufferIndex()] = next.value; } #getNextBufferIndex() { return (this.#bufferIndex + 1) % this.#buffer.length; } } const CharCodes = { ASTERISK: "*".charCodeAt(0), NEWLINE: "\n".charCodeAt(0), CARRIAGE_RETURN: "\r".charCodeAt(0), SPACE: " ".charCodeAt(0), TAB: "\t".charCodeAt(0), CLOSE_BRACE: "}".charCodeAt(0), }; function getNodeByNameOrFindFunction(items, nameOrFindFunc) { let findFunc; if (typeof nameOrFindFunc === "string") findFunc = dec => nodeHasName(dec, nameOrFindFunc); else findFunc = nameOrFindFunc; return items.find(findFunc); } function nodeHasName(node, name) { if (node.getNameNode == null) return false; const nameNode = node.getNameNode(); if (nameNode == null) return false; if (Node.isArrayBindingPattern(nameNode) || Node.isObjectBindingPattern(nameNode)) return nameNode.getElements().some(element => nodeHasName(element, name)); const nodeName = node.getName != null ? node.getName() : nameNode.getText(); return nodeName === name; } function getNotFoundErrorMessageForNameOrFindFunction(findName, nameOrFindFunction) { if (typeof nameOrFindFunction === "string") return `Expected to find ${findName} named '${nameOrFindFunction}'.`; return `Expected to find ${findName} that matched the provided condition.`; } exports.CommentNodeKind = void 0; (function (CommentNodeKind) { CommentNodeKind[CommentNodeKind["Statement"] = 0] = "Statement"; CommentNodeKind[CommentNodeKind["ClassElement"] = 1] = "ClassElement"; CommentNodeKind[CommentNodeKind["TypeElement"] = 2] = "TypeElement"; CommentNodeKind[CommentNodeKind["ObjectLiteralElement"] = 3] = "ObjectLiteralElement"; CommentNodeKind[CommentNodeKind["EnumMember"] = 4] = "EnumMember"; })(exports.CommentNodeKind || (exports.CommentNodeKind = {})); class CompilerCommentNode { #fullStart; #start; #sourceFile; constructor(fullStart, pos, end, kind, sourceFile, parent) { this.#fullStart = fullStart; this.#start = pos; this.#sourceFile = sourceFile; this.pos = pos; this.end = end; this.kind = kind; this.flags = common.ts.NodeFlags.None; this.parent = parent; } pos; end; kind; flags; modifiers; parent; getSourceFile() { return this.#sourceFile; } getChildCount(sourceFile) { return 0; } getChildAt(index, sourceFile) { return undefined; } getChildren(sourceFile) { return []; } getStart(sourceFile, includeJsDocComment) { return this.#start; } getFullStart() { return this.#fullStart; } getEnd() { return this.end; } getWidth(sourceFile) { return this.end - this.#start; } getFullWidth() { return this.end - this.#fullStart; } getLeadingTriviaWidth(sourceFile) { return this.#start - this.#fullStart; } getFullText(sourceFile) { return this.#sourceFile.text.substring(this.#fullStart, this.end); } getText(sourceFile) { return this.#sourceFile.text.substring(this.#start, this.end); } getFirstToken(sourceFile) { return undefined; } getLastToken(sourceFile) { return undefined; } forEachChild(cbNode, cbNodeArray) { return undefined; } } class CompilerCommentStatement extends CompilerCommentNode { _jsdocContainerBrand; _statementBrand; _commentKind = exports.CommentNodeKind.Statement; } class CompilerCommentClassElement extends CompilerCommentNode { _classElementBrand; _declarationBrand; _commentKind = exports.CommentNodeKind.ClassElement; } class CompilerCommentTypeElement extends CompilerCommentNode { _typeElementBrand; _declarationBrand; _commentKind = exports.CommentNodeKind.TypeElement; } class CompilerCommentObjectLiteralElement extends CompilerCommentNode { _declarationBrand; _objectLiteralBrand; declarationBrand; _commentKind = exports.CommentNodeKind.ObjectLiteralElement; } class CompilerCommentEnumMember extends CompilerCommentNode { _commentKind = exports.CommentNodeKind.EnumMember; } var CommentKind; (function (CommentKind) { CommentKind[CommentKind["SingleLine"] = 0] = "SingleLine"; CommentKind[CommentKind["MultiLine"] = 1] = "MultiLine"; CommentKind[CommentKind["JsDoc"] = 2] = "JsDoc"; })(CommentKind || (CommentKind = {})); const childrenSaver = new WeakMap(); const commentNodeParserKinds = new Set([ common.SyntaxKind.SourceFile, common.SyntaxKind.Block, common.SyntaxKind.ModuleBlock, common.SyntaxKind.CaseClause, common.SyntaxKind.DefaultClause, common.SyntaxKind.ClassDeclaration, common.SyntaxKind.InterfaceDeclaration, common.SyntaxKind.EnumDeclaration, common.SyntaxKind.ClassExpression, common.SyntaxKind.TypeLiteral, common.SyntaxKind.ObjectLiteralExpression, ]); class CommentNodeParser { constructor() { } static getOrParseChildren(container, sourceFile) { if (isSyntaxList(container)) container = container.parent; let children = childrenSaver.get(container); if (children == null) { children = Array.from(getNodes(container, sourceFile)); childrenSaver.set(container, children); } return children; } static shouldParseChildren(container) { return commentNodeParserKinds.has(container.kind) && container.pos !== container.end; } static hasParsedChildren(container) { if (isSyntaxList(container)) container = container.parent; return childrenSaver.has(container); } static isCommentStatement(node) { return node._commentKind === exports.CommentNodeKind.Statement; } static isCommentClassElement(node) { return node._commentKind === exports.CommentNodeKind.ClassElement; } static isCommentTypeElement(node) { return node._commentKind === exports.CommentNodeKind.TypeElement; } static isCommentObjectLiteralElement(node) { return node._commentKind === exports.CommentNodeKind.ObjectLiteralElement; } static isCommentEnumMember(node) { return node._commentKind === exports.CommentNodeKind.EnumMember; } static getContainerBodyPos(container, sourceFile) { if (common.ts.isSourceFile(container)) return 0; if (common.ts.isClassDeclaration(container) || common.ts.isEnumDeclaration(container) || common.ts.isInterfaceDeclaration(container) || common.ts.isTypeLiteralNode(container) || common.ts.isClassExpression(container) || common.ts.isBlock(container) || common.ts.isModuleBlock(container) || common.ts.isObjectLiteralExpression(container)) { return getTokenEnd(container, common.SyntaxKind.OpenBraceToken); } if (common.ts.isCaseClause(container) || common.ts.isDefaultClause(container)) return getTokenEnd(container, common.SyntaxKind.ColonToken); return common.errors.throwNotImplementedForNeverValueError(container); function getTokenEnd(node, kind) { return node.getChildren(sourceFile).find(c => c.kind === kind)?.end; } } } function* getNodes(container, sourceFile) { const sourceFileText = sourceFile.text; const childNodes = getContainerChildren(); const createComment = getCreationFunction(); if (childNodes.length === 0) { const bodyStartPos = CommentNodeParser.getContainerBodyPos(container, sourceFile); if (bodyStartPos != null) yield* getCommentNodes(bodyStartPos, false); } else { for (const childNode of childNodes) { yield* getCommentNodes(childNode.pos, true); yield childNode; } const lastChild = childNodes[childNodes.length - 1]; yield* getCommentNodes(lastChild.end, false); } function* getCommentNodes(pos, stopAtJsDoc) { const fullStart = pos; skipTrailingLine(); const leadingComments = Array.from(getLeadingComments()); const maxEnd = sourceFileText.length === pos || sourceFileText[pos] === "}" ? pos : common.StringUtils.getLineStartFromPos(sourceFileText, pos); for (const leadingComment of leadingComments) { if (leadingComment.end <= maxEnd) yield leadingComment; } function skipTrailingLine() { if (pos === 0) return; let lineEnd = common.StringUtils.getLineEndFromPos(sourceFileText, pos); while (pos < lineEnd) { const commentKind = getCommentKind(); if (commentKind != null) { const comment = parseForComment(commentKind); if (comment.kind === common.SyntaxKind.SingleLineCommentTrivia) return; else lineEnd = common.StringUtils.getLineEndFromPos(sourceFileText, pos); } else if (!common.StringUtils.isWhitespace(sourceFileText[pos]) && sourceFileText[pos] !== ",") return; else pos++; } while (common.StringUtils.startsWithNewLine(sourceFileText[pos])) pos++; } function* getLeadingComments() { while (pos < sourceFileText.length) { const commentKind = getCommentKind(); if (commentKind != null) { const isJsDoc = commentKind === CommentKind.JsDoc; if (isJsDoc && stopAtJsDoc) return; else yield parseForComment(commentKind); skipTrailingLine(); } else if (!common.StringUtils.isWhitespace(sourceFileText[pos])) return; else pos++; } } function parseForComment(commentKind) { if (commentKind === CommentKind.SingleLine) return parseSingleLineComment(); const isJsDoc = commentKind === CommentKind.JsDoc; return parseMultiLineComment(isJsDoc); } function getCommentKind() { const currentChar = sourceFileText[pos]; if (currentChar !== "/") return undefined; const nextChar = sourceFileText[pos + 1]; if (nextChar === "/") return CommentKind.SingleLine; if (nextChar !== "*") return undefined; const nextNextChar = sourceFileText[pos + 2]; return nextNextChar === "*" ? CommentKind.JsDoc : CommentKind.MultiLine; } function parseSingleLineComment() { const start = pos; skipSingleLineComment(); const end = pos; return createComment(fullStart, start, end, common.SyntaxKind.SingleLineCommentTrivia); } function skipSingleLineComment() { pos += 2; while (pos < sourceFileText.length && sourceFileText[pos] !== "\n" && sourceFileText[pos] !== "\r") pos++; } function parseMultiLineComment(isJsDoc) { const start = pos; skipSlashStarComment(isJsDoc); const end = pos; return createComment(fullStart, start, end, common.SyntaxKind.MultiLineCommentTrivia); } function skipSlashStarComment(isJsDoc) { pos += isJsDoc ? 3 : 2; while (pos < sourceFileText.length) { if (sourceFileText[pos] === "*" && sourceFileText[pos + 1] === "/") { pos += 2; break; } pos++; } } } function getContainerChildren() { if (common.ts.isSourceFile(container) || common.ts.isBlock(container) || common.ts.isModuleBlock(container) || common.ts.isCaseClause(container) || common.ts.isDefaultClause(container)) return container.statements; if (common.ts.isClassDeclaration(container) || common.ts.isClassExpression(container) || common.ts.isEnumDeclaration(container) || common.ts.isInterfaceDeclaration(container) || common.ts.isTypeLiteralNode(container) || common.ts.isClassExpression(container)) { return container.members; } if (common.ts.isObjectLiteralExpression(container)) return container.properties; return common.errors.throwNotImplementedForNeverValueError(container); } function getCreationFunction() { const ctor = getCtor(); return (fullStart, pos, end, kind) => new ctor(fullStart, pos, end, kind, sourceFile, container); function getCtor() { if (isStatementContainerNode(container)) return CompilerCommentStatement; if (common.ts.isClassLike(container)) return CompilerCommentClassElement; if (common.ts.isInterfaceDeclaration(container) || common.ts.isTypeLiteralNode(container)) return CompilerCommentTypeElement; if (common.ts.isObjectLiteralExpression(container)) return CompilerCommentObjectLiteralElement; if (common.ts.isEnumDeclaration(container)) return CompilerCommentEnumMember; throw new common.errors.NotImplementedError(`Not implemented comment node container type: ${common.getSyntaxKindName(container.kind)}`); } } } function isSyntaxList(node) { return node.kind === common.SyntaxKind.SyntaxList; } function isStatementContainerNode(node) { return getStatementContainerNode() != null; function getStatementContainerNode() { const container = node; if (common.ts.isSourceFile(container) || common.ts.isBlock(container) || common.ts.isModuleBlock(container) || common.ts.isCaseClause(container) || common.ts.isDefaultClause(container)) { return container; } return undefined; } } const forEachChildSaver = new WeakMap(); const getChildrenSaver = new WeakMap(); class ExtendedParser { static getContainerArray(container, sourceFile) { return CommentNodeParser.getOrParseChildren(container, sourceFile); } static hasParsedTokens(node) { return getChildrenSaver.has(node) || node.kind == common.SyntaxKind.SyntaxList; } static getCompilerChildrenFast(node, sourceFile) { if (ExtendedParser.hasParsedTokens(node)) return ExtendedParser.getCompilerChildren(node, sourceFile); return ExtendedParser.getCompilerForEachChildren(node, sourceFile); } static getCompilerForEachChildren(node, sourceFile) { if (CommentNodeParser.shouldParseChildren(node)) { let result = forEachChildSaver.get(node); if (result == null) { result = getForEachChildren(); mergeInComments(result, CommentNodeParser.getOrParseChildren(node, sourceFile)); forEachChildSaver.set(node, result); } return result; } return getForEachChildren(); function getForEachChildren() { const children = []; node.forEachChild(child => { children.push(child); }); return children; } } static getCompilerChildren(node, sourceFile) { let result = getChildrenSaver.get(node); if (result == null) { if (isStatementMemberOrPropertyHoldingSyntaxList()) { const newArray = [...node.getChildren(sourceFile)]; mergeInComments(newArray, CommentNodeParser.getOrParseChildren(node, sourceFile)); result = newArray; } else { result = node.getChildren(sourceFile); } getChildrenSaver.set(node, result); } return result; function isStatementMemberOrPropertyHoldingSyntaxList() { if (node.kind !== common.ts.SyntaxKind.SyntaxList) return false; const parent = node.parent; if (!CommentNodeParser.shouldParseChildren(parent)) return false; return CommentNodeParser.getContainerBodyPos(parent, sourceFile) === node.pos; } } } function mergeInComments(nodes, otherNodes) { let currentIndex = 0; for (const child of otherNodes) { if (child.kind !== common.SyntaxKind.SingleLineCommentTrivia && child.kind !== common.SyntaxKind.MultiLineCommentTrivia) continue; while (currentIndex < nodes.length && nodes[currentIndex].end < child.end) currentIndex++; nodes.splice(currentIndex, 0, child); currentIndex++; } } function isComment(node) { return node.kind === common.ts.SyntaxKind.SingleLineCommentTrivia || node.kind === common.ts.SyntaxKind.MultiLineCommentTrivia; } function getParentSyntaxList(node, sourceFile) { if (node.kind === common.SyntaxKind.EndOfFileToken) return undefined; const parent = node.parent; if (parent == null) return undefined; const { pos, end } = node; for (const child of ExtendedParser.getCompilerChildren(parent, sourceFile)) { if (child.pos > end || child === node) return undefined; if (child.kind === common.SyntaxKind.SyntaxList && child.pos <= pos && child.end >= end) return child; } return undefined; } function getSymbolByNameOrFindFunction(items, nameOrFindFunc) { let findFunc; if (typeof nameOrFindFunc === "string") findFunc = dec => dec.getName() === nameOrFindFunc; else findFunc = nameOrFindFunc; return items.find(findFunc); } function isNodeAmbientOrInAmbientContext(node) { if (checkNodeIsAmbient(node) || node._sourceFile.isDeclarationFile()) return true; for (const ancestor of node._getAncestorsIterator(false)) { if (checkNodeIsAmbient(ancestor)) return true; } return false; } function checkNodeIsAmbient(node) { const isThisAmbient = (node.getCombinedModifierFlags() & common.ts.ModifierFlags.Ambient) === common.ts.ModifierFlags.Ambient; return isThisAmbient || Node.isInterfaceDeclaration(node) || Node.isTypeAliasDeclaration(node); } function isStringKind(kind) { switch (kind) { case common.SyntaxKind.StringLiteral: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.TemplateHead: case common.SyntaxKind.TemplateMiddle: case common.SyntaxKind.TemplateTail: return true; default: return false; } } class ModuleUtils { constructor() { } static isModuleSpecifierRelative(text) { return text.startsWith("./") || text.startsWith("../"); } static getReferencedSourceFileFromSymbol(symbol) { const declarations = symbol.getDeclarations(); if (declarations.length === 0 || declarations[0].getKind() !== common.SyntaxKind.SourceFile) return undefined; return declarations[0]; } } function printNode(node, sourceFileOrOptions, secondOverloadOptions) { const isFirstOverload = sourceFileOrOptions == null || sourceFileOrOptions.kind !== common.SyntaxKind.SourceFile; const options = getOptions(); const sourceFile = getSourceFile(); const printer = common.ts.createPrinter({ newLine: options.newLineKind ?? common.NewLineKind.LineFeed, removeComments: options.removeComments || false, }); if (sourceFile == null) return printer.printFile(node); else return printer.printNode(options.emitHint ?? common.EmitHint.Unspecified, node, sourceFile); function getSourceFile() { if (isFirstOverload) { if (node.kind === common.SyntaxKind.SourceFile) return undefined; const topParent = getNodeSourceFile(); if (topParent == null) { const scriptKind = getScriptKind(); return common.ts.createSourceFile(`print.${getFileExt(scriptKind)}`, "", common.ScriptTarget.Latest, false, scriptKind); } return topParent; } return sourceFileOrOptions; function getScriptKind() { return options.scriptKind ?? common.ScriptKind.TSX; } function getFileExt(scriptKind) { if (scriptKind === common.ScriptKind.JSX || scriptKind === common.ScriptKind.TSX) return "tsx"; return "ts"; } } function getNodeSourceFile() { let topNode = node.parent; while (topNode != null && topNode.parent != null) topNode = topNode.parent; return topNode; } function getOptions() { return (isFirstOverload ? sourceFileOrOptions : secondOverloadOptions) || {}; } } exports.IndentationText = void 0; (function (IndentationText) { IndentationText["TwoSpaces"] = " "; IndentationText["FourSpaces"] = " "; IndentationText["EightSpaces"] = " "; IndentationText["Tab"] = "\t"; })(exports.IndentationText || (exports.IndentationText = {})); class ManipulationSettingsContainer extends common.SettingsContainer { #editorSettings; #formatCodeSettings; #userPreferences; constructor() { super({ indentationText: exports.IndentationText.FourSpaces, newLineKind: common.NewLineKind.LineFeed, quoteKind: exports.QuoteKind.Double, insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, usePrefixAndSuffixTextForRename: false, useTrailingCommas: false, }); } getEditorSettings() { if (this.#editorSettings == null) { this.#editorSettings = {}; fillDefaultEditorSettings(this.#editorSettings, this); } return { ...this.#editorSettings }; } getFormatCodeSettings() { if (this.#formatCodeSettings == null) { this.#formatCodeSettings = { ...this.getEditorSettings(), insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: this._settings.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces, }; } return { ...this.#formatCodeSettings }; } getUserPreferences() { if (this.#userPreferences == null) { this.#userPreferences = { quotePreference: this.getQuoteKind() === exports.QuoteKind.Double ? "double" : "single", providePrefixAndSuffixTextForRename: this.getUsePrefixAndSuffixTextForRename(), }; } return { ...this.#userPreferences }; } getQuoteKind() { return this._settings.quoteKind; } getNewLineKind() { return this._settings.newLineKind; } getNewLineKindAsString() { return newLineKindToString(this.getNewLineKind()); } getIndentationText() { return this._settings.indentationText; } getUsePrefixAndSuffixTextForRename() { return this._settings.usePrefixAndSuffixTextForRename; } getUseTrailingCommas() { return this._settings.useTrailingCommas; } set(settings) { super.set(settings); this.#editorSettings = undefined; this.#formatCodeSettings = undefined; this.#userPreferences = undefined; } _getIndentSizeInSpaces() { const indentationText = this.getIndentationText(); switch (indentationText) { case exports.IndentationText.EightSpaces: return 8; case exports.IndentationText.FourSpaces: return 4; case exports.IndentationText.TwoSpaces: return 2; case exports.IndentationText.Tab: return 4; default: return common.errors.throwNotImplementedForNeverValueError(indentationText); } } } function setValueIfUndefined(obj, propertyName, defaultValue) { if (typeof obj[propertyName] === "undefined") obj[propertyName] = defaultValue; } function fillDefaultEditorSettings(settings, manipulationSettings) { setValueIfUndefined(settings, "convertTabsToSpaces", manipulationSettings.getIndentationText() !== exports.IndentationText.Tab); setValueIfUndefined(settings, "newLineCharacter", manipulationSettings.getNewLineKindAsString()); setValueIfUndefined(settings, "indentStyle", common.ts.IndentStyle.Smart); setValueIfUndefined(settings, "indentSize", manipulationSettings.getIndentationText().length); setValueIfUndefined(settings, "tabSize", manipulationSettings.getIndentationText().length); } function fillDefaultFormatCodeSettings(settings, manipulationSettings) { fillDefaultEditorSettings(settings, manipulationSettings); setValueIfUndefined(settings, "insertSpaceAfterCommaDelimiter", true); setValueIfUndefined(settings, "insertSpaceAfterConstructor", false); setValueIfUndefined(settings, "insertSpaceAfterSemicolonInForStatements", true); setValueIfUndefined(settings, "insertSpaceAfterKeywordsInControlFlowStatements", true); setValueIfUndefined(settings, "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces", true); setValueIfUndefined(settings, "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", false); setValueIfUndefined(settings, "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", false); setValueIfUndefined(settings, "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces", false); setValueIfUndefined(settings, "insertSpaceBeforeFunctionParenthesis", false); setValueIfUndefined(settings, "insertSpaceBeforeAndAfterBinaryOperators", true); setValueIfUndefined(settings, "placeOpenBraceOnNewLineForFunctions", false); setValueIfUndefined(settings, "placeOpenBraceOnNewLineForControlBlocks", false); setValueIfUndefined(settings, "ensureNewLineAtEndOfFile", true); } function getTextFromStringOrWriter(writer, textOrWriterFunction) { printTextFromStringOrWriter(writer, textOrWriterFunction); return writer.toString(); } function printTextFromStringOrWriter(writer, textOrWriterFunction) { if (typeof textOrWriterFunction === "string") writer.write(textOrWriterFunction); else if (textOrWriterFunction instanceof Function) textOrWriterFunction(writer); else { for (let i = 0; i < textOrWriterFunction.length; i++) { if (i > 0) writer.newLineIfLastNot(); printTextFromStringOrWriter(writer, textOrWriterFunction[i]); } } } class EnableableLogger { #enabled = false; setEnabled(enabled) { this.#enabled = enabled; } log(text) { if (this.#enabled) this.logInternal(text); } warn(text) { if (this.#enabled) this.warnInternal(text); } } class ConsoleLogger extends EnableableLogger { logInternal(text) { console.log(text); } warnInternal(text) { console.warn(text); } } const reg = /^[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc0-9\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19d9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]*$/; const bannedNames = new Set([ "do", "if", "in", "for", "let", "new", "try", "var", "case", "else", "enum", "eval", "false", "null", "this", "true", "void", "with", "break", "catch", "class", "const", "super", "throw", "while", "yield", "delete", "export", "import", "public", "return", "static", "switch", "typeof", "default", "extends", "finally", "package", "private", "continue", "debugger", "function", "arguments", "interface", "protected", "implements", "instanceof" ]); function isValidVariableName(variableName) { if (bannedNames.has(variableName)) return false; if (isAlphaNumeric(variableName)) return true; return reg.test(variableName); } function isAlphaNumeric(variableName) { for (let i = 0; i < variableName.length; i++) { const ch = variableName.charCodeAt(i); if (!(ch >= 48 && ch <= 57) && !(ch >= 65 && ch <= 90) && !(ch >= 97 && ch <= 122)) { return false; } } return true; } function newLineKindToString(kind) { switch (kind) { case common.NewLineKind.CarriageReturnLineFeed: return "\r\n"; case common.NewLineKind.LineFeed: return "\n"; default: throw new common.errors.NotImplementedError(`Not implemented newline kind: ${kind}`); } } class LazyReferenceCoordinator { #dirtySourceFiles = new Set(); constructor(factory) { const onSourceFileModified = (sourceFile) => { if (!sourceFile.wasForgotten()) this.#dirtySourceFiles.add(sourceFile); }; factory.onSourceFileAdded(sourceFile => { this.#dirtySourceFiles.add(sourceFile); sourceFile.onModified(onSourceFileModified); }); factory.onSourceFileRemoved(sourceFile => { sourceFile._referenceContainer.clear(); this.#dirtySourceFiles.delete(sourceFile); sourceFile.onModified(onSourceFileModified, false); }); } refreshDirtySourceFiles() { for (const sourceFile of this.#dirtySourceFiles.values()) sourceFile._referenceContainer.refresh(); this.clearDirtySourceFiles(); } refreshSourceFileIfDirty(sourceFile) { if (!this.#dirtySourceFiles.has(sourceFile)) return; sourceFile._referenceContainer.refresh(); this.clearDirtyForSourceFile(sourceFile); } addDirtySourceFile(sourceFile) { this.#dirtySourceFiles.add(sourceFile); } clearDirtySourceFiles() { this.#dirtySourceFiles.clear(); } clearDirtyForSourceFile(sourceFile) { this.#dirtySourceFiles.delete(sourceFile); } } class SourceFileReferenceContainer { #sourceFile; #nodesInThis = new common.KeyValueCache(); #nodesInOther = new common.KeyValueCache(); #unresolvedLiterals = []; constructor(sourceFile) { this.#sourceFile = sourceFile; } getDependentSourceFiles() { this.#sourceFile._context.lazyReferenceCoordinator.refreshDirtySourceFiles(); const hashSet = new Set(); for (const nodeInOther of this.#nodesInOther.getKeys()) hashSet.add(nodeInOther._sourceFile); return hashSet.values(); } getLiteralsReferencingOtherSourceFilesEntries() { this.#sourceFile._context.lazyReferenceCoordinator.refreshSourceFileIfDirty(this.#sourceFile); return this.#nodesInThis.getEntries(); } getReferencingLiteralsInOtherSourceFiles() { this.#sourceFile._context.lazyReferenceCoordinator.refreshDirtySourceFiles(); return this.#nodesInOther.getKeys(); } refresh() { if (this.#unresolvedLiterals.length > 0) this.#sourceFile._context.compilerFactory.onSourceFileAdded(this.#resolveUnresolved, false); this.clear(); this.#populateReferences(); if (this.#unresolvedLiterals.length > 0) this.#sourceFile._context.compilerFactory.onSourceFileAdded(this.#resolveUnresolved); } clear() { this.#unresolvedLiterals.length = 0; for (const [node, sourceFile] of this.#nodesInThis.getEntries()) { this.#nodesInThis.removeByKey(node); sourceFile._referenceContainer.#nodesInOther.removeByKey(node); } } #resolveUnresolved = () => { for (let i = this.#unresolvedLiterals.length - 1; i >= 0; i--) { const literal = this.#unresolvedLiterals[i]; const sourceFile = this.#getSourceFileForLiteral(literal); if (sourceFile != null) { this.#unresolvedLiterals.splice(i, 1); this.#addNodeInThis(literal, sourceFile); } } if (this.#unresolvedLiterals.length === 0) this.#sourceFile._context.compilerFactory.onSourceFileAdded(this.#resolveUnresolved, false); }; #populateReferences() { this.#sourceFile._context.compilerFactory.forgetNodesCreatedInBlock(remember => { for (const literal of this.#sourceFile.getImportStringLiterals()) { const sourceFile = this.#getSourceFileForLiteral(literal); remember(literal); if (sourceFile == null) this.#unresolvedLiterals.push(literal); else this.#addNodeInThis(literal, sourceFile); } }); } #getSourceFileForLiteral(literal) { const parent = literal.getParentOrThrow(); const grandParent = parent.getParent(); if (Node.isImportDeclaration(parent) || Node.isExportDeclaration(parent)) return parent.getModuleSpecifierSourceFile(); else if (grandParent != null && Node.isImportEqualsDeclaration(grandParent)) return grandParent.getExternalModuleReferenceSourceFile(); else if (grandParent != null && Node.isImportTypeNode(grandParent)) { const importTypeSymbol = grandParent.getSymbol(); if (importTypeSymbol != null) return ModuleUtils.getReferencedSourceFileFromSymbol(importTypeSymbol); } else if (Node.isCallExpression(parent)) { const literalSymbol = literal.getSymbol(); if (literalSymbol != null) return ModuleUtils.getReferencedSourceFileFromSymbol(literalSymbol); } else { this.#sourceFile._context.logger.warn(`Unknown import string literal parent: ${parent.getKindName()}`); } return undefined; } #addNodeInThis(literal, sourceFile) { this.#nodesInThis.set(literal, sourceFile); sourceFile._referenceContainer.#nodesInOther.set(literal, sourceFile); } } function getCompilerOptionsFromTsConfig(filePath, options = {}) { const result = common.getCompilerOptionsFromTsConfig(filePath, options); return { options: result.options, errors: result.errors.map(error => new Diagnostic(undefined, error)), }; } common.ts.version.split(".").map(v => parseInt(v, 10)); class WriterUtils { constructor() { } static getLastCharactersToPos(writer, pos) { const writerLength = writer.getLength(); const charCount = writerLength - pos; const chars = new Array(charCount); writer.iterateLastChars((char, i) => { const insertPos = i - pos; if (insertPos < 0) return true; chars[insertPos] = char; return undefined; }); return chars.join(""); } } function callBaseGetStructure(basePrototype, node, structure) { let newStructure; if (basePrototype.getStructure != null) newStructure = basePrototype.getStructure.call(node); else newStructure = {}; if (structure != null) Object.assign(newStructure, structure); return newStructure; } function callBaseSet(basePrototype, node, structure) { if (basePrototype.set != null) basePrototype.set.call(node, structure); } function AmbientableNode(Base) { return class extends Base { hasDeclareKeyword() { return this.getDeclareKeyword() != null; } getDeclareKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getDeclareKeyword(), message ?? "Expected to find a declare keyword.", this); } getDeclareKeyword() { return this.getFirstModifierByKind(common.SyntaxKind.DeclareKeyword); } isAmbient() { return isNodeAmbientOrInAmbientContext(this); } setHasDeclareKeyword(value) { this.toggleModifier("declare", value); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.hasDeclareKeyword != null) this.setHasDeclareKeyword(structure.hasDeclareKeyword); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { hasDeclareKeyword: this.hasDeclareKeyword(), }); } }; } var FormattingKind; (function (FormattingKind) { FormattingKind[FormattingKind["Newline"] = 0] = "Newline"; FormattingKind[FormattingKind["Blankline"] = 1] = "Blankline"; FormattingKind[FormattingKind["Space"] = 2] = "Space"; FormattingKind[FormattingKind["None"] = 3] = "None"; })(FormattingKind || (FormattingKind = {})); function getClassMemberFormatting(parent, member) { if (Node.isAmbientable(parent) && parent.isAmbient()) return FormattingKind.Newline; if (hasBody$1(member)) return FormattingKind.Blankline; return FormattingKind.Newline; } function hasBody$1(node) { if (Node.isBodyable(node) && node.getBody() != null) return true; if (Node.isBodied(node)) return true; return false; } function getFormattingKindText(formattingKind, opts) { switch (formattingKind) { case FormattingKind.Space: return " "; case FormattingKind.Newline: return opts.newLineKind; case FormattingKind.Blankline: return opts.newLineKind + opts.newLineKind; case FormattingKind.None: return ""; default: throw new common.errors.NotImplementedError(`Not implemented formatting kind: ${formattingKind}`); } } function getInterfaceMemberFormatting(parent, member) { return FormattingKind.Newline; } function hasBody(node) { if (Node.isBodyable(node) && node.hasBody()) return true; if (Node.isBodied(node)) return true; return Node.isInterfaceDeclaration(node) || Node.isClassDeclaration(node) || Node.isEnumDeclaration(node); } function getStatementedNodeChildFormatting(parent, member) { if (hasBody(member)) return FormattingKind.Blankline; return FormattingKind.Newline; } function getClausedNodeChildFormatting(parent, member) { return FormattingKind.Newline; } function getGeneralFormatting(parent, child) { if (Node.isClassDeclaration(parent)) return getClassMemberFormatting(parent, child); if (Node.isInterfaceDeclaration(parent)) return getInterfaceMemberFormatting(); return getStatementedNodeChildFormatting(parent, child); } function getTextFromTextChanges(sourceFile, textChanges) { const text = sourceFile.getFullText(); const editResult = []; let start = 0; for (const { edit } of getSortedTextChanges()) { const span = edit.getSpan(); const beforeEdit = text.slice(start, span.getStart()); start = span.getEnd(); editResult.push(beforeEdit); editResult.push(edit.getNewText()); } editResult.push(text.slice(start)); return editResult.join(""); function getSortedTextChanges() { return textChanges.map((edit, index) => ({ edit: toWrappedTextChange(edit), index })).sort((a, b) => { const aStart = a.edit.getSpan().getStart(); const bStart = b.edit.getSpan().getStart(); const difference = aStart - bStart; if (difference === 0) return a.index < b.index ? -1 : 1; return difference < 0 ? -1 : 1; }); } function toWrappedTextChange(change) { if (change instanceof TextChange) return change; else return new TextChange(change); } } function getNewInsertCode(opts) { const { structures, newCodes, parent, getSeparator, previousFormattingKind, nextFormattingKind } = opts; const indentationText = opts.indentationText ?? parent.getChildIndentationText(); const newLineKind = parent._context.manipulationSettings.getNewLineKindAsString(); return getFormattingKindTextWithIndent(previousFormattingKind) + getChildCode() + getFormattingKindTextWithIndent(nextFormattingKind); function getChildCode() { let code = newCodes[0]; for (let i = 1; i < newCodes.length; i++) { const formattingKind = getSeparator(structures[i - 1], structures[i]); code += getFormattingKindTextWithIndent(formattingKind); code += newCodes[i]; } return code; } function getFormattingKindTextWithIndent(formattingKind) { let code = getFormattingKindText(formattingKind, { newLineKind }); if (formattingKind === FormattingKind.Newline || formattingKind === FormattingKind.Blankline) code += indentationText; return code; } } const scanner = common.ts.createScanner(common.ts.ScriptTarget.Latest, true); function appendCommaToText(text) { const pos = getAppendCommaPos(text); if (pos === -1) return text; return text.substring(0, pos) + "," + text.substring(pos); } function getAppendCommaPos(text) { scanner.setText(text); try { if (scanner.scan() === common.ts.SyntaxKind.EndOfFileToken) return -1; while (scanner.scan() !== common.ts.SyntaxKind.EndOfFileToken) { } const pos = scanner.getStartPos(); return text[pos - 1] === "," ? -1 : pos; } finally { scanner.setText(undefined); } } function getEndIndexFromArray(array) { return array?.length ?? 0; } function getNextMatchingPos(text, pos, condition) { while (pos < text.length) { const charCode = text.charCodeAt(pos); if (!condition(charCode)) pos++; else break; } return pos; } function getPreviousMatchingPos(text, pos, condition) { while (pos > 0) { const charCode = text.charCodeAt(pos - 1); if (!condition(charCode)) pos--; else break; } return pos; } function getNextNonWhitespacePos(text, pos) { return getNextMatchingPos(text, pos, isNotWhitespace); } function getPreviousNonWhitespacePos(text, pos) { return getPreviousMatchingPos(text, pos, isNotWhitespace); } function isNotWhitespace(charCode) { return !common.StringUtils.isWhitespaceCharCode(charCode); } function getPosAtEndOfPreviousLine(fullText, pos) { while (pos > 0) { pos--; if (fullText[pos] === "\n") { if (fullText[pos - 1] === "\r") return pos - 1; return pos; } } return pos; } function getPosAtNextNonBlankLine(text, pos) { let newPos = pos; for (let i = pos; i < text.length; i++) { if (text[i] === " " || text[i] === "\t") continue; if (text[i] === "\r" && text[i + 1] === "\n" || text[i] === "\n") { newPos = i + 1; if (text[i] === "\r") { i++; newPos++; } continue; } return newPos; } return newPos; } function getPosAtStartOfLineOrNonWhitespace(fullText, pos) { while (pos > 0) { pos--; const currentChar = fullText[pos]; if (currentChar === "\n") return pos + 1; else if (currentChar !== " " && currentChar !== "\t") return pos + 1; } return pos; } function getInsertPosFromIndex(index, syntaxList, children) { if (index === 0) { const parent = syntaxList.getParentOrThrow(); if (Node.isSourceFile(parent)) return 0; else if (Node.isCaseClause(parent) || Node.isDefaultClause(parent)) { const colonToken = parent.getFirstChildByKindOrThrow(common.SyntaxKind.ColonToken); return colonToken.getEnd(); } const isInline = syntaxList !== parent.getChildSyntaxList(); if (isInline) return syntaxList.getStart(); const parentContainer = getParentContainerOrThrow(parent); const openBraceToken = parentContainer.getFirstChildByKindOrThrow(common.SyntaxKind.OpenBraceToken); return openBraceToken.getEnd(); } else { return children[index - 1].getEnd(); } } function getEndPosFromIndex(index, parent, children, fullText) { let endPos; if (index === children.length) { if (Node.isSourceFile(parent)) endPos = parent.getEnd(); else if (Node.isCaseClause(parent) || Node.isDefaultClause(parent)) endPos = parent.getEnd(); else { const parentContainer = getParentContainerOrThrow(parent); const closeBraceToken = parentContainer.getLastChildByKind(common.SyntaxKind.CloseBraceToken); if (closeBraceToken == null) endPos = parent.getEnd(); else endPos = closeBraceToken.getStart(); } } else { endPos = children[index].getNonWhitespaceStart(); } return getPosAtStartOfLineOrNonWhitespace(fullText, endPos); } function getParentContainerOrThrow(parent) { if (Node.isModuleDeclaration(parent)) { const innerBody = parent._getInnerBody(); if (innerBody == null) throw new common.errors.InvalidOperationError("This operation requires the module to have a body."); return innerBody; } else if (Node.isBodied(parent)) return parent.getBody(); else if (Node.isBodyable(parent)) return parent.getBodyOrThrow(); else return parent; } function fromAbstractableNode(node) { return { isAbstract: node.isAbstract(), }; } function fromAmbientableNode(node) { return { hasDeclareKeyword: node.hasDeclareKeyword(), }; } function fromExportableNode(node) { return { isDefaultExport: node.hasDefaultKeyword(), isExported: node.hasExportKeyword(), }; } function fromStaticableNode(node) { return { isStatic: node.isStatic(), }; } function fromScopedNode(node) { return { scope: node.hasScopeKeyword() ? node.getScope() : undefined, }; } function fromOverrideableNode(node) { return { hasOverrideKeyword: node.hasOverrideKeyword(), }; } function fromQuestionTokenableNode(node) { return { hasQuestionToken: node.hasQuestionToken(), }; } function getNodesToReturn(oldChildren, newChildren, index, allowCommentNodes) { const oldChildCount = typeof oldChildren === "number" ? oldChildren : oldChildren.length; const newLength = newChildren.length - oldChildCount; const result = []; for (let i = 0; i < newLength; i++) { const currentChild = newChildren[index + i]; if (allowCommentNodes || !Node.isCommentNode(currentChild)) result.push(currentChild); } return result; } function getRangeWithoutCommentsFromArray(array, index, length, expectedKind) { const children = []; while (index < array.length && children.length < length) { const child = array[index]; const childKind = child.getKind(); if (childKind !== common.SyntaxKind.SingleLineCommentTrivia && childKind !== common.SyntaxKind.MultiLineCommentTrivia) { if (childKind !== expectedKind) { throw new common.errors.NotImplementedError(`Unexpected! Inserting syntax kind of ${common.getSyntaxKindName(expectedKind)}` + `, but ${child.getKindName()} was inserted.`); } children.push(child); } index++; } if (children.length !== length) throw new common.errors.NotImplementedError(`Unexpected! Inserted ${length} child/children, but ${children.length} were inserted.`); return children; } function fromConstructorDeclarationOverload(node) { const structure = {}; Object.assign(structure, fromScopedNode(node)); return structure; } function fromFunctionDeclarationOverload(node) { const structure = {}; Object.assign(structure, fromAmbientableNode(node)); Object.assign(structure, fromExportableNode(node)); return structure; } function fromMethodDeclarationOverload(node) { const structure = {}; Object.assign(structure, fromStaticableNode(node)); Object.assign(structure, fromAbstractableNode(node)); Object.assign(structure, fromScopedNode(node)); Object.assign(structure, fromQuestionTokenableNode(node)); Object.assign(structure, fromOverrideableNode(node)); return structure; } function verifyAndGetIndex(index, length) { const newIndex = index < 0 ? length + index : index; if (newIndex < 0) throw new common.errors.InvalidOperationError(`Invalid index: The max negative index is ${length * -1}, but ${index} was specified.`); if (index > length) throw new common.errors.InvalidOperationError(`Invalid index: The max index is ${length}, but ${index} was specified.`); return newIndex; } class NodeHandlerHelper { #compilerFactory; constructor(compilerFactory) { this.#compilerFactory = compilerFactory; } handleForValues(handler, currentNode, newNode, newSourceFile) { if (this.#compilerFactory.hasCompilerNode(currentNode)) handler.handleNode(this.#compilerFactory.getExistingNodeFromCompilerNode(currentNode), newNode, newSourceFile); else if (currentNode.kind === common.SyntaxKind.SyntaxList) { const sourceFile = this.#compilerFactory.getExistingNodeFromCompilerNode(currentNode.getSourceFile()); handler.handleNode(this.#compilerFactory.getNodeFromCompilerNode(currentNode, sourceFile), newNode, newSourceFile); } } forgetNodeIfNecessary(currentNode) { if (this.#compilerFactory.hasCompilerNode(currentNode)) this.#compilerFactory.getExistingNodeFromCompilerNode(currentNode).forget(); } getCompilerChildrenAsIterators(currentNode, newNode, newSourceFile) { const children = this.getCompilerChildren(currentNode, newNode, newSourceFile); return [ new AdvancedIterator(common.ArrayUtils.toIterator(children[0])), new AdvancedIterator(common.ArrayUtils.toIterator(children[1])), ]; } getCompilerChildren(currentNode, newNode, newSourceFile) { const currentCompilerNode = currentNode.compilerNode; const currentSourceFile = currentNode._sourceFile.compilerNode; return [ ExtendedParser.getCompilerChildren(currentCompilerNode, currentSourceFile), ExtendedParser.getCompilerChildren(newNode, newSourceFile), ]; } getChildrenFast(currentNode, newNode, newSourceFile) { const currentCompilerNode = currentNode.compilerNode; const currentSourceFile = currentNode._sourceFile.compilerNode; if (ExtendedParser.hasParsedTokens(currentCompilerNode)) { return [ ExtendedParser.getCompilerChildren(currentCompilerNode, currentSourceFile), ExtendedParser.getCompilerChildren(newNode, newSourceFile), ]; } return [ ExtendedParser.getCompilerForEachChildren(currentCompilerNode, currentSourceFile), ExtendedParser.getCompilerForEachChildren(newNode, newSourceFile), ]; } } class StraightReplacementNodeHandler { compilerFactory; helper; constructor(compilerFactory) { this.compilerFactory = compilerFactory; this.helper = new NodeHandlerHelper(compilerFactory); } handleNode(currentNode, newNode, newSourceFile) { if (currentNode.getKind() !== newNode.kind) { const kinds = [currentNode.getKind(), newNode.kind]; if (kinds.includes(common.ts.SyntaxKind.Identifier) && kinds.includes(common.ts.SyntaxKind.PrivateIdentifier)) { currentNode.forget(); return; } throw new common.errors.InvalidOperationError(`Error replacing tree! Perhaps a syntax error was inserted ` + `(Current: ${currentNode.getKindName()} -- New: ${common.getSyntaxKindName(newNode.kind)}).`); } if (currentNode._hasWrappedChildren()) this.#handleChildren(currentNode, newNode, newSourceFile); this.compilerFactory.replaceCompilerNode(currentNode, newNode); } #handleChildren(currentNode, newNode, newSourceFile) { const [currentChildren, newChildren] = this.helper.getChildrenFast(currentNode, newNode, newSourceFile); if (currentChildren.length !== newChildren.length) { throw new Error(`Error replacing tree: The children of the old and new trees were expected to have the ` + `same count (${currentChildren.length}:${newChildren.length}).`); } for (let i = 0; i < currentChildren.length; i++) this.helper.handleForValues(this, currentChildren[i], newChildren[i], newSourceFile); } } class ChangeChildOrderParentHandler { #compilerFactory; #straightReplacementNodeHandler; #helper; #oldIndex; #newIndex; constructor(compilerFactory, opts) { this.#straightReplacementNodeHandler = new StraightReplacementNodeHandler(compilerFactory); this.#helper = new NodeHandlerHelper(compilerFactory); this.#oldIndex = opts.oldIndex; this.#newIndex = opts.newIndex; this.#compilerFactory = compilerFactory; } handleNode(currentNode, newNode, newSourceFile) { const [currentChildren, newChildren] = this.#helper.getCompilerChildren(currentNode, newNode, newSourceFile); const currentChildrenInNewOrder = this.#getChildrenInNewOrder(currentChildren); common.errors.throwIfNotEqual(newChildren.length, currentChildrenInNewOrder.length, "New children length should match the old children length."); for (let i = 0; i < newChildren.length; i++) this.#helper.handleForValues(this.#straightReplacementNodeHandler, currentChildrenInNewOrder[i], newChildren[i], newSourceFile); this.#compilerFactory.replaceCompilerNode(currentNode, newNode); } #getChildrenInNewOrder(children) { const result = [...children]; const movingNode = result.splice(this.#oldIndex, 1)[0]; result.splice(this.#newIndex, 0, movingNode); return result; } } class DefaultParentHandler { #compilerFactory; #straightReplacementNodeHandler; #helper; #childCount; #isFirstChild; #replacingNodes; #customMappings; constructor(compilerFactory, opts) { this.#straightReplacementNodeHandler = new StraightReplacementNodeHandler(compilerFactory); this.#helper = new NodeHandlerHelper(compilerFactory); this.#childCount = opts.childCount; this.#isFirstChild = opts.isFirstChild; this.#replacingNodes = opts.replacingNodes?.map(n => n.compilerNode); this.#customMappings = opts.customMappings; this.#compilerFactory = compilerFactory; } handleNode(currentNode, newNode, newSourceFile) { const [currentChildren, newChildren] = this.#helper.getCompilerChildrenAsIterators(currentNode, newNode, newSourceFile); let count = this.#childCount; this.#handleCustomMappings(newNode); while (!currentChildren.done && !newChildren.done && !this.#isFirstChild(currentChildren.peek, newChildren.peek)) this.#helper.handleForValues(this.#straightReplacementNodeHandler, currentChildren.next(), newChildren.next(), newSourceFile); while (!currentChildren.done && this.#tryReplaceNode(currentChildren.peek)) currentChildren.next(); if (count > 0) { while (count > 0) { newChildren.next(); count--; } } else if (count < 0) { while (count < 0) { this.#helper.forgetNodeIfNecessary(currentChildren.next()); count++; } } while (!currentChildren.done) this.#helper.handleForValues(this.#straightReplacementNodeHandler, currentChildren.next(), newChildren.next(), newSourceFile); if (!newChildren.done) throw new Error("Error replacing tree: Should not have children left over."); this.#compilerFactory.replaceCompilerNode(currentNode, newNode); } #handleCustomMappings(newParentNode) { if (this.#customMappings == null) return; const customMappings = this.#customMappings(newParentNode); for (const mapping of customMappings) this.#compilerFactory.replaceCompilerNode(mapping.currentNode, mapping.newNode); } #tryReplaceNode(currentCompilerNode) { if (this.#replacingNodes == null || this.#replacingNodes.length === 0) return false; const index = this.#replacingNodes.indexOf(currentCompilerNode); if (index === -1) return false; this.#replacingNodes.splice(index, 1); this.#helper.forgetNodeIfNecessary(currentCompilerNode); return true; } } class ForgetChangedNodeHandler { #compilerFactory; #helper; constructor(compilerFactory) { this.#helper = new NodeHandlerHelper(compilerFactory); this.#compilerFactory = compilerFactory; } handleNode(currentNode, newNode, newSourceFile) { if (currentNode.getKind() !== newNode.kind) { currentNode.forget(); return; } if (currentNode._hasWrappedChildren()) this.#handleChildren(currentNode, newNode, newSourceFile); this.#compilerFactory.replaceCompilerNode(currentNode, newNode); } #handleChildren(currentNode, newNode, newSourceFile) { const [currentNodeChildren, newNodeChildrenArray] = this.#helper.getChildrenFast(currentNode, newNode, newSourceFile); const newNodeChildren = common.ArrayUtils.toIterator(newNodeChildrenArray); for (const currentNodeChild of currentNodeChildren) { const nextNodeChildResult = newNodeChildren.next(); if (nextNodeChildResult.done) { const existingNode = this.#compilerFactory.getExistingNodeFromCompilerNode(currentNodeChild); if (existingNode != null) existingNode.forget(); } else { this.#helper.handleForValues(this, currentNodeChild, nextNodeChildResult.value, newSourceFile); } } } } class ParentFinderReplacementNodeHandler extends StraightReplacementNodeHandler { #changingParent; #parentNodeHandler; #changingParentParent; #foundParent = false; #parentsAtSamePos; constructor(compilerFactory, parentNodeHandler, changingParent) { super(compilerFactory); this.#changingParentParent = changingParent.getParentSyntaxList() ?? changingParent.getParent(); this.#parentsAtSamePos = this.#changingParentParent != null && this.#changingParentParent.getPos() === changingParent.getPos(); this.#parentNodeHandler = parentNodeHandler; this.#changingParent = changingParent; } handleNode(currentNode, newNode, newSourceFile) { if (!this.#foundParent && this.#isParentNode(newNode, newSourceFile)) { this.#foundParent = true; this.#parentNodeHandler.handleNode(currentNode, newNode, newSourceFile); } else { super.handleNode(currentNode, newNode, newSourceFile); } } #isParentNode(newNode, newSourceFile) { const positionsAndKindsEqual = areNodesEqual(newNode, this.#changingParent) && areNodesEqual(getParentSyntaxList(newNode, newSourceFile) || newNode.parent, this.#changingParentParent); if (!positionsAndKindsEqual) return false; if (!this.#parentsAtSamePos) return true; return getAncestorLength(this.#changingParent.compilerNode) === getAncestorLength(newNode); function getAncestorLength(nodeToCheck) { let node = nodeToCheck; let count = 0; while (node.parent != null) { count++; node = node.parent; } return count; } } } function areNodesEqual(a, b) { if (a == null && b == null) return true; if (a == null || b == null) return false; if (a.pos === b.getPos() && a.kind === b.getKind()) return true; return false; } class RangeHandler { #compilerFactory; #straightReplacementNodeHandler; #helper; #start; #end; constructor(compilerFactory, opts) { this.#straightReplacementNodeHandler = new StraightReplacementNodeHandler(compilerFactory); this.#helper = new NodeHandlerHelper(compilerFactory); this.#start = opts.start; this.#end = opts.end; this.#compilerFactory = compilerFactory; } handleNode(currentNode, newNode, newSourceFile) { const currentSourceFile = currentNode._sourceFile.compilerNode; const children = this.#helper.getChildrenFast(currentNode, newNode, newSourceFile); const currentNodeChildren = new AdvancedIterator(common.ArrayUtils.toIterator(children[0])); const newNodeChildren = new AdvancedIterator(common.ArrayUtils.toIterator(children[1])); while (!currentNodeChildren.done && !newNodeChildren.done && newNodeChildren.peek.getEnd() <= this.#start) this.#straightReplace(currentNodeChildren.next(), newNodeChildren.next(), newSourceFile); while (!currentNodeChildren.done && !newNodeChildren.done && (currentNodeChildren.peek.getStart(currentSourceFile) < this.#start || currentNodeChildren.peek.getStart(currentSourceFile) === this.#start && newNodeChildren.peek.end > this.#end)) { this.#rangeHandlerReplace(currentNodeChildren.next(), newNodeChildren.next(), newSourceFile); } while (!newNodeChildren.done && newNodeChildren.peek.getEnd() <= this.#end) newNodeChildren.next(); while (!currentNodeChildren.done) this.#straightReplace(currentNodeChildren.next(), newNodeChildren.next(), newSourceFile); if (!newNodeChildren.done) throw new Error("Error replacing tree: Should not have children left over."); this.#compilerFactory.replaceCompilerNode(currentNode, newNode); } #straightReplace(currentNode, nextNode, newSourceFile) { this.#helper.handleForValues(this.#straightReplacementNodeHandler, currentNode, nextNode, newSourceFile); } #rangeHandlerReplace(currentNode, nextNode, newSourceFile) { this.#helper.handleForValues(this, currentNode, nextNode, newSourceFile); } } class RangeParentHandler { #compilerFactory; #straightReplacementNodeHandler; #helper; #start; #end; #replacingLength; #replacingNodes; #customMappings; constructor(compilerFactory, opts) { this.#straightReplacementNodeHandler = new StraightReplacementNodeHandler(compilerFactory); this.#helper = new NodeHandlerHelper(compilerFactory); this.#start = opts.start; this.#end = opts.end; this.#replacingLength = opts.replacingLength; this.#replacingNodes = opts.replacingNodes?.map(n => n.compilerNode); this.#customMappings = opts.customMappings; this.#compilerFactory = compilerFactory; } handleNode(currentNode, newNode, newSourceFile) { const currentSourceFile = currentNode._sourceFile.compilerNode; const [currentNodeChildren, newNodeChildren] = this.#helper.getCompilerChildrenAsIterators(currentNode, newNode, newSourceFile); this.#handleCustomMappings(newNode, newSourceFile); while (!currentNodeChildren.done && !newNodeChildren.done && newNodeChildren.peek.getStart(newSourceFile) < this.#start) this.#straightReplace(currentNodeChildren.next(), newNodeChildren.next(), newSourceFile); const newNodes = []; while (!newNodeChildren.done && newNodeChildren.peek.getStart(newSourceFile) >= this.#start && getRealEnd(newNodeChildren.peek, newSourceFile) <= this.#end) { newNodes.push(newNodeChildren.next()); } if (this.#replacingLength != null) { const replacingEnd = this.#start + this.#replacingLength; const oldNodes = []; while (!currentNodeChildren.done && (getRealEnd(currentNodeChildren.peek, currentSourceFile) <= replacingEnd || currentNodeChildren.peek.getStart(currentSourceFile) < replacingEnd)) { oldNodes.push(currentNodeChildren.next()); } if (oldNodes.length === newNodes.length && oldNodes.every((node, i) => node.kind === newNodes[i].kind)) { for (let i = 0; i < oldNodes.length; i++) { const node = this.#compilerFactory.getExistingNodeFromCompilerNode(oldNodes[i]); if (node != null) { node.forgetDescendants(); this.#compilerFactory.replaceCompilerNode(oldNodes[i], newNodes[i]); } } } else { oldNodes.forEach(node => this.#helper.forgetNodeIfNecessary(node)); } } while (!currentNodeChildren.done) this.#straightReplace(currentNodeChildren.next(), newNodeChildren.next(), newSourceFile); if (!newNodeChildren.done) throw new Error("Error replacing tree: Should not have children left over."); this.#compilerFactory.replaceCompilerNode(currentNode, newNode); } #handleCustomMappings(newParentNode, newSourceFile) { if (this.#customMappings == null) return; const customMappings = this.#customMappings(newParentNode, newSourceFile); for (const mapping of customMappings) mapping.currentNode._context.compilerFactory.replaceCompilerNode(mapping.currentNode, mapping.newNode); } #straightReplace(currentNode, nextNode, newSourceFile) { if (!this.#tryReplaceNode(currentNode)) this.#helper.handleForValues(this.#straightReplacementNodeHandler, currentNode, nextNode, newSourceFile); } #tryReplaceNode(currentCompilerNode) { if (this.#replacingNodes == null || this.#replacingNodes.length === 0) return false; const index = this.#replacingNodes.indexOf(currentCompilerNode); if (index === -1) return false; this.#replacingNodes.splice(index, 1); this.#helper.forgetNodeIfNecessary(currentCompilerNode); return true; } } function getRealEnd(node, sourceFile) { if (node.kind >= common.ts.SyntaxKind.FirstJSDocNode && node.kind <= common.ts.SyntaxKind.LastJSDocNode) { return getPreviousMatchingPos(sourceFile.text, node.end, charCode => charCode !== CharCodes.ASTERISK && !common.StringUtils.isWhitespaceCharCode(charCode)); } return node.end; } class RenameNodeHandler extends StraightReplacementNodeHandler { handleNode(currentNode, newNode, newSourceFile) { const currentNodeKind = currentNode.getKind(); const newNodeKind = newNode.kind; if (currentNodeKind === common.SyntaxKind.ShorthandPropertyAssignment && newNodeKind === common.SyntaxKind.PropertyAssignment) { const currentSourceFile = currentNode.getSourceFile(); const currentIdentifier = currentNode.getNameNode(); const newIdentifier = newNode.initializer; this.compilerFactory.replaceCompilerNode(currentIdentifier, newIdentifier); currentNode.forget(); this.compilerFactory.getNodeFromCompilerNode(newNode, currentSourceFile); return; } else if (currentNodeKind === common.SyntaxKind.ExportSpecifier && newNodeKind === common.SyntaxKind.ExportSpecifier && currentNode.compilerNode.propertyName == null && newNode.propertyName != null) { handleImportOrExportSpecifier(this.compilerFactory); return; } else if (currentNodeKind === common.SyntaxKind.ImportSpecifier && newNodeKind === common.SyntaxKind.ImportSpecifier && currentNode.compilerNode.propertyName == null && newNode.propertyName != null) { handleImportOrExportSpecifier(this.compilerFactory); return; } super.handleNode(currentNode, newNode, newSourceFile); return; function handleImportOrExportSpecifier(compilerFactory) { function getNameText(node) { return node.kind === common.SyntaxKind.Identifier ? node.escapedText : node.text; } const currentName = currentNode.getNameNode(); const newSpecifier = newNode; const newPropertyName = newSpecifier.propertyName; const newName = newSpecifier.name; const newIdentifier = getNameText(newPropertyName) === getNameText(currentName.compilerNode) ? newName : newPropertyName; compilerFactory.replaceCompilerNode(currentName, newIdentifier); compilerFactory.replaceCompilerNode(currentNode, newNode); } } } class TryOrForgetNodeHandler { #handler; constructor(handler) { this.#handler = handler; } handleNode(currentNode, newNode, newSourceFile) { if (!Node.isSourceFile(currentNode)) throw new common.errors.InvalidOperationError(`Can only use a TryOrForgetNodeHandler with a source file.`); try { this.#handler.handleNode(currentNode, newNode, newSourceFile); } catch (ex) { currentNode._context.logger.warn("Could not replace tree, so forgetting all nodes instead. Message: " + ex); currentNode.getChildSyntaxListOrThrow().forget(); currentNode._context.compilerFactory.replaceCompilerNode(currentNode, newNode); } } } class UnwrapParentHandler { #childIndex; #compilerFactory; #straightReplacementNodeHandler; #helper; constructor(compilerFactory, childIndex) { this.#straightReplacementNodeHandler = new StraightReplacementNodeHandler(compilerFactory); this.#helper = new NodeHandlerHelper(compilerFactory); this.#compilerFactory = compilerFactory; this.#childIndex = childIndex; } handleNode(currentNode, newNode, newSourceFile) { const [currentChildren, newChildren] = this.#helper.getCompilerChildrenAsIterators(currentNode, newNode, newSourceFile); let index = 0; while (!currentChildren.done && !newChildren.done && index++ < this.#childIndex) this.#helper.handleForValues(this.#straightReplacementNodeHandler, currentChildren.next(), newChildren.next(), newSourceFile); const currentChild = this.#compilerFactory.getExistingNodeFromCompilerNode(currentChildren.next()); const childSyntaxList = currentChild.getChildSyntaxListOrThrow(); for (const child of ExtendedParser.getCompilerChildren(childSyntaxList.compilerNode, childSyntaxList._sourceFile.compilerNode)) this.#helper.handleForValues(this.#straightReplacementNodeHandler, child, newChildren.next(), newSourceFile); forgetNodes(currentChild); function forgetNodes(node) { if (node === childSyntaxList) { node._forgetOnlyThis(); return; } for (const child of node._getChildrenInCacheIterator()) forgetNodes(child); node._forgetOnlyThis(); } while (!currentChildren.done) this.#helper.handleForValues(this.#straightReplacementNodeHandler, currentChildren.next(), newChildren.next(), newSourceFile); if (!newChildren.done) throw new Error("Error replacing tree: Should not have children left over."); this.#compilerFactory.replaceCompilerNode(currentNode, newNode); } } class NodeHandlerFactory { getDefault(opts) { const { parent: changingParent, isFirstChild, childCount, customMappings } = opts; const sourceFile = changingParent.getSourceFile(); const compilerFactory = sourceFile._context.compilerFactory; const replacingNodes = opts.replacingNodes == null ? undefined : [...opts.replacingNodes]; const parentHandler = new DefaultParentHandler(compilerFactory, { childCount, isFirstChild, replacingNodes, customMappings }); if (changingParent === sourceFile) return parentHandler; else return new ParentFinderReplacementNodeHandler(compilerFactory, parentHandler, changingParent); } getForParentRange(opts) { const { parent: changingParent, start, end, replacingLength, replacingNodes, customMappings } = opts; const sourceFile = changingParent.getSourceFile(); const compilerFactory = sourceFile._context.compilerFactory; const parentHandler = new RangeParentHandler(compilerFactory, { start, end, replacingLength, replacingNodes, customMappings }); if (changingParent === sourceFile) return parentHandler; else return new ParentFinderReplacementNodeHandler(compilerFactory, parentHandler, changingParent); } getForRange(opts) { const { sourceFile, start, end } = opts; const compilerFactory = sourceFile._context.compilerFactory; return new RangeHandler(compilerFactory, { start, end }); } getForChildIndex(opts) { const { parent, childIndex, childCount, replacingNodes, customMappings } = opts; const parentChildren = parent.getChildren(); common.errors.throwIfOutOfRange(childIndex, [0, parentChildren.length], "opts.childIndex"); if (childCount < 0) common.errors.throwIfOutOfRange(childCount, [childIndex - parentChildren.length, 0], "opts.childCount"); let i = 0; const isFirstChild = () => i++ === childIndex; return this.getDefault({ parent, isFirstChild, childCount, replacingNodes, customMappings, }); } getForStraightReplacement(compilerFactory) { return new StraightReplacementNodeHandler(compilerFactory); } getForForgetChanged(compilerFactory) { return new ForgetChangedNodeHandler(compilerFactory); } getForRename(compilerFactory) { return new RenameNodeHandler(compilerFactory); } getForTryOrForget(handler) { return new TryOrForgetNodeHandler(handler); } getForChangingChildOrder(opts) { const { parent: changingParent, oldIndex, newIndex } = opts; const sourceFile = changingParent.getSourceFile(); const compilerFactory = sourceFile._context.compilerFactory; const changeChildOrderParentHandler = new ChangeChildOrderParentHandler(compilerFactory, { oldIndex, newIndex }); if (changingParent === sourceFile) return changeChildOrderParentHandler; else return new ParentFinderReplacementNodeHandler(compilerFactory, changeChildOrderParentHandler, changingParent); } getForUnwrappingNode(unwrappingNode) { const changingParent = unwrappingNode.getParentSyntaxList() || unwrappingNode.getParentOrThrow(); const childIndex = unwrappingNode.getChildIndex(); const sourceFile = changingParent.getSourceFile(); const compilerFactory = sourceFile._context.compilerFactory; const unwrapParentHandler = new UnwrapParentHandler(compilerFactory, childIndex); if (changingParent === sourceFile) return unwrapParentHandler; else return new ParentFinderReplacementNodeHandler(compilerFactory, unwrapParentHandler, changingParent); } } function getSpacingBetweenNodes(opts) { const { parent, previousSibling, nextSibling, newLineKind, getSiblingFormatting } = opts; if (previousSibling == null || nextSibling == null) return ""; const previousSiblingFormatting = getSiblingFormatting(parent, previousSibling); const nextSiblingFormatting = getSiblingFormatting(parent, nextSibling); if (previousSiblingFormatting === FormattingKind.Blankline || nextSiblingFormatting === FormattingKind.Blankline) return newLineKind + newLineKind; else if (previousSiblingFormatting === FormattingKind.Newline || nextSiblingFormatting === FormattingKind.Newline) return newLineKind; else if (previousSiblingFormatting === FormattingKind.Space || nextSiblingFormatting === FormattingKind.Space) return " "; else return ""; } class ChangingChildOrderTextManipulator { #opts; constructor(opts) { this.#opts = opts; } getNewText(inputText) { const { parent, oldIndex, newIndex, getSiblingFormatting } = this.#opts; const children = parent.getChildren(); const newLineKind = parent._context.manipulationSettings.getNewLineKindAsString(); const movingNode = children[oldIndex]; const fullText = parent._sourceFile.getFullText(); const movingNodeStart = getPosAtNextNonBlankLine(fullText, movingNode.getPos()); const movingNodeText = fullText.substring(movingNodeStart, movingNode.getEnd()); const lowerIndex = Math.min(newIndex, oldIndex); const upperIndex = Math.max(newIndex, oldIndex); const childrenInNewOrder = getChildrenInNewOrder(); const isParentSourceFile = Node.isSourceFile(parent.getParentOrThrow()); let finalText = ""; fillPrefixText(); fillTextForIndex(lowerIndex); fillMiddleText(); fillTextForIndex(upperIndex); fillSuffixText(); return finalText; function getChildrenInNewOrder() { const result = [...children]; result.splice(oldIndex, 1); result.splice(newIndex, 0, movingNode); return result; } function fillPrefixText() { finalText += fullText.substring(0, children[lowerIndex].getPos()); if (lowerIndex === 0 && !isParentSourceFile) finalText += newLineKind; } function fillMiddleText() { let startPos; let endPos; if (lowerIndex === oldIndex) { startPos = getPosAtNextNonBlankLine(fullText, children[lowerIndex].getEnd()); endPos = children[upperIndex].getEnd(); } else { startPos = getPosAtNextNonBlankLine(fullText, children[lowerIndex].getPos()); endPos = children[upperIndex].getPos(); } finalText += fullText.substring(startPos, endPos); } function fillSuffixText() { if (children.length - 1 === upperIndex && !isParentSourceFile) finalText += newLineKind; finalText += fullText.substring(getPosAtNextNonBlankLine(fullText, children[upperIndex].getEnd())); } function fillTextForIndex(index) { if (index === oldIndex) fillSpacingForRemoval(); else { fillSpacingBeforeInsertion(); finalText += movingNodeText; fillSpacingAfterInsertion(); } } function fillSpacingForRemoval() { if (oldIndex === 0 || oldIndex === children.length - 1) return; fillSpacingCommon({ previousSibling: childrenInNewOrder[oldIndex - 1], nextSibling: childrenInNewOrder[oldIndex], }); } function fillSpacingBeforeInsertion() { if (newIndex === 0) return; fillSpacingCommon({ previousSibling: childrenInNewOrder[newIndex - 1], nextSibling: childrenInNewOrder[newIndex], }); } function fillSpacingAfterInsertion() { fillSpacingCommon({ previousSibling: childrenInNewOrder[newIndex], nextSibling: childrenInNewOrder[newIndex + 1], }); } function fillSpacingCommon(spacingOpts) { const spacing = getSpacingBetweenNodes({ parent, getSiblingFormatting, newLineKind, previousSibling: spacingOpts.previousSibling, nextSibling: spacingOpts.nextSibling, }); const twoNewLines = newLineKind + newLineKind; if (spacing === twoNewLines) { if (finalText.endsWith(twoNewLines)) return; else if (finalText.endsWith(newLineKind)) finalText += newLineKind; else finalText += twoNewLines; } else if (spacing === newLineKind) { if (finalText.endsWith(newLineKind)) return; else finalText += newLineKind; } else if (spacing === " ") { if (finalText.endsWith(" ")) return; else finalText += " "; } else { finalText += spacing; } } } getTextForError(newText) { return newText; } } class FullReplacementTextManipulator { #newText; constructor(newText) { this.#newText = newText; } getNewText(inputText) { return this.#newText; } getTextForError(newText) { return newText; } } function getTextForError(newText, pos, length = 0) { const startPos = Math.max(0, newText.lastIndexOf("\n", pos) - 100); let endPos = Math.min(newText.length, newText.indexOf("\n", pos + length)); endPos = endPos === -1 ? newText.length : Math.min(newText.length, endPos + 100); let text = ""; text += newText.substring(startPos, endPos); if (startPos !== 0) text = "..." + text; if (endPos !== newText.length) text += "..."; return text; } class InsertionTextManipulator { #opts; constructor(opts) { this.#opts = opts; } getNewText(inputText) { const { insertPos, newText, replacingLength = 0 } = this.#opts; return inputText.substring(0, insertPos) + newText + inputText.substring(insertPos + replacingLength); } getTextForError(newText) { return getTextForError(newText, this.#opts.insertPos, this.#opts.newText.length); } } class RemoveChildrenTextManipulator { #opts; #removalPos; constructor(opts) { this.#opts = opts; } getNewText(inputText) { const opts = this.#opts; const { children, removePrecedingSpaces = false, removeFollowingSpaces = false, removePrecedingNewLines = false, removeFollowingNewLines = false, replaceTrivia = "", } = opts; const sourceFile = children[0].getSourceFile(); const fullText = sourceFile.getFullText(); const removalPos = getRemovalPos(); this.#removalPos = removalPos; return getPrefix() + replaceTrivia + getSuffix(); function getPrefix() { return fullText.substring(0, removalPos); } function getSuffix() { return fullText.substring(getRemovalEnd()); } function getRemovalPos() { if (opts.customRemovalPos != null) return opts.customRemovalPos; const pos = children[0].getNonWhitespaceStart(); if (removePrecedingSpaces || removePrecedingNewLines) return getPreviousMatchingPos(fullText, pos, getCharRemovalFunction(removePrecedingSpaces, removePrecedingNewLines)); return pos; } function getRemovalEnd() { if (opts.customRemovalEnd != null) return opts.customRemovalEnd; const end = children[children.length - 1].getEnd(); if (removeFollowingSpaces || removeFollowingNewLines) return getNextMatchingPos(fullText, end, getCharRemovalFunction(removeFollowingSpaces, removeFollowingNewLines)); return end; } function getCharRemovalFunction(removeSpaces, removeNewLines) { return (char) => { if (removeNewLines && (char === CharCodes.CARRIAGE_RETURN || char === CharCodes.NEWLINE)) return false; if (removeSpaces && !charNotSpaceOrTab(char)) return false; return true; }; } function charNotSpaceOrTab(charCode) { return charCode !== CharCodes.SPACE && charCode !== CharCodes.TAB; } } getTextForError(newText) { return getTextForError(newText, this.#removalPos); } } function isNewLineAtPos(fullText, pos) { return fullText[pos] === "\n" || (fullText[pos] === "\r" && fullText[pos + 1] === "\n"); } function hasNewLineInRange(fullText, range) { for (let i = range[0]; i < range[1]; i++) { if (fullText[i] === "\n") return true; } return false; } class RemoveChildrenWithFormattingTextManipulator { #opts; #removalPos; constructor(opts) { this.#opts = opts; } getNewText(inputText) { const { children, getSiblingFormatting } = this.#opts; const firstChild = children[0]; const lastChild = children[children.length - 1]; const parent = firstChild.getParentOrThrow(); const sourceFile = parent.getSourceFile(); const fullText = sourceFile.getFullText(); const newLineKind = sourceFile._context.manipulationSettings.getNewLineKindAsString(); const previousSibling = firstChild.getPreviousSibling(); const nextSibling = lastChild.getNextSibling(); const removalPos = getRemovalPos(); this.#removalPos = removalPos; return getPrefix() + getSpacing() + getSuffix(); function getPrefix() { return fullText.substring(0, removalPos); } function getSpacing() { return getSpacingBetweenNodes({ parent, previousSibling, nextSibling, newLineKind, getSiblingFormatting, }); } function getSuffix() { return fullText.substring(getRemovalEnd()); } function getRemovalPos() { if (previousSibling != null) { const trailingEnd = previousSibling.getTrailingTriviaEnd(); return isNewLineAtPos(fullText, trailingEnd) ? trailingEnd : previousSibling.getEnd(); } const firstPos = getPreviousNonWhitespacePos(fullText, firstChild.getPos()); if (parent.getPos() === firstPos) return firstChild.getNonWhitespaceStart(); return firstChild.isFirstNodeOnLine() ? firstPos : firstChild.getNonWhitespaceStart(); } function getRemovalEnd() { const triviaEnd = lastChild.getTrailingTriviaEnd(); if (previousSibling != null && nextSibling != null) { const nextSiblingFormatting = getSiblingFormatting(parent, nextSibling); if (nextSiblingFormatting === FormattingKind.Blankline || nextSiblingFormatting === FormattingKind.Newline) return getPosAtStartOfLineOrNonWhitespace(fullText, nextSibling.getNonWhitespaceStart()); return nextSibling.getNonWhitespaceStart(); } if (parent.getEnd() === lastChild.getEnd()) return lastChild.getEnd(); if (isNewLineAtPos(fullText, triviaEnd)) { if (previousSibling == null && firstChild.getPos() === 0) return getPosAtNextNonBlankLine(fullText, triviaEnd); return getPosAtEndOfPreviousLine(fullText, getPosAtNextNonBlankLine(fullText, triviaEnd)); } if (previousSibling == null) return triviaEnd; else return lastChild.getEnd(); } } getTextForError(newText) { return getTextForError(newText, this.#removalPos); } } class RenameLocationTextManipulator { #newName; #renameLocations; constructor(renameLocations, newName) { this.#renameLocations = renameLocations; this.#newName = newName; } getNewText(inputText) { const renameLocations = [...this.#renameLocations].sort((a, b) => b.getTextSpan().getStart() - a.getTextSpan().getStart()); let currentPos = inputText.length; let result = ""; for (let i = 0; i < renameLocations.length; i++) { const renameLocation = renameLocations[i]; const textSpan = renameLocation.getTextSpan(); result = (renameLocation.getPrefixText() || "") + this.#newName + (renameLocation.getSuffixText() || "") + inputText.substring(textSpan.getEnd(), currentPos) + result; currentPos = textSpan.getStart(); } return inputText.substring(0, currentPos) + result; } getTextForError(newText) { if (this.#renameLocations.length === 0) return newText; return "..." + newText.substring(this.#renameLocations[0].getTextSpan().getStart()); } } class UnchangedTextManipulator { getNewText(inputText) { return inputText; } getTextForError(newText) { return newText; } } class UnwrapTextManipulator extends InsertionTextManipulator { constructor(node) { super({ insertPos: node.getStart(true), newText: getReplacementText(node), replacingLength: node.getWidth(true), }); } } function getReplacementText(node) { const sourceFile = node._sourceFile; const range = getInnerBraceRange(); const startPos = range[0]; const text = sourceFile.getFullText().substring(range[0], range[1]); return common.StringUtils.indent(text, -1, { indentText: sourceFile._context.manipulationSettings.getIndentationText(), indentSizeInSpaces: sourceFile._context.manipulationSettings._getIndentSizeInSpaces(), isInStringAtPos: pos => sourceFile.isInStringAtPos(startPos + pos), }).trim(); function getInnerBraceRange() { const bodyNode = getBodyNodeOrThrow(); return [bodyNode.getStart() + 1, bodyNode.getEnd() - 1]; function getBodyNodeOrThrow() { if (Node.isModuleDeclaration(node)) { const bodyNode = node._getInnerBody(); if (bodyNode == null) throw new common.errors.InvalidOperationError("This operation requires the module to have a body."); return bodyNode; } else if (Node.isBodied(node)) return node.getBody(); else if (Node.isBodyable(node)) return node.getBodyOrThrow(); else common.errors.throwNotImplementedForSyntaxKindError(node.getKind(), node); } } } class ManipulationError extends common.errors.InvalidOperationError { filePath; oldText; newText; constructor(filePath, oldText, newText, errorMessage) { super(errorMessage); this.filePath = filePath; this.oldText = oldText; this.newText = newText; } } function doManipulation(sourceFile, textManipulator, nodeHandler, newFilePath) { sourceFile._firePreModified(); const oldFileText = sourceFile.getFullText(); const newFileText = textManipulator.getNewText(oldFileText); try { const replacementSourceFile = sourceFile._context.compilerFactory.createCompilerSourceFileFromText(newFilePath || sourceFile.getFilePath(), newFileText, sourceFile.getScriptKind()); nodeHandler.handleNode(sourceFile, replacementSourceFile, replacementSourceFile); } catch (err) { const diagnostics = getSyntacticDiagnostics(sourceFile, newFileText); const errorDetails = err.message + "\n\n" + `-- Details --\n` + "Path: " + sourceFile.getFilePath() + "\n" + "Text: " + JSON.stringify(textManipulator.getTextForError(newFileText)) + "\n" + "Stack: " + err.stack; if (diagnostics.length > 0) { throwError("Manipulation error: " + "A syntax error was inserted." + "\n\n" + sourceFile._context.project.formatDiagnosticsWithColorAndContext(diagnostics, { newLineChar: "\n" }) + "\n" + errorDetails); } throwError("Manipulation error: " + errorDetails); function throwError(message) { throw new ManipulationError(sourceFile.getFilePath(), oldFileText, newFileText, message); } } } function getSyntacticDiagnostics(sourceFile, newText) { try { const projectOptions = { useInMemoryFileSystem: true }; const project = new sourceFile._context.project.constructor(projectOptions); const newFile = project.createSourceFile(sourceFile.getFilePath(), newText); return project.getProgram().getSyntacticDiagnostics(newFile); } catch (err) { return []; } } function insertIntoParentTextRange(opts) { const { insertPos, newText, parent } = opts; doManipulation(parent._sourceFile, new InsertionTextManipulator({ insertPos, newText, replacingLength: opts.replacing?.textLength, }), new NodeHandlerFactory().getForParentRange({ parent, start: insertPos, end: insertPos + newText.length, replacingLength: opts.replacing?.textLength, replacingNodes: opts.replacing?.nodes, customMappings: opts.customMappings, })); } function insertIntoTextRange(opts) { const { insertPos, newText, sourceFile } = opts; doManipulation(sourceFile, new InsertionTextManipulator({ insertPos, newText, }), new NodeHandlerFactory().getForRange({ sourceFile, start: insertPos, end: insertPos + newText.length, })); } function insertIntoCommaSeparatedNodes(opts) { const { currentNodes, insertIndex, parent } = opts; const previousNode = currentNodes[insertIndex - 1]; const previousNonCommentNode = getPreviousNonCommentNode(); const nextNode = currentNodes[insertIndex]; const nextNonCommentNode = getNextNonCommentNode(); const separator = opts.useNewLines ? parent._context.manipulationSettings.getNewLineKindAsString() : " "; const parentNextSibling = parent.getNextSibling(); const isContained = parentNextSibling != null && (parentNextSibling.getKind() === common.SyntaxKind.CloseBraceToken || parentNextSibling.getKind() === common.SyntaxKind.CloseBracketToken); let { newText } = opts; if (previousNode != null) { prependCommaAndSeparator(); if (nextNonCommentNode != null || opts.useTrailingCommas) appendCommaAndSeparator(); else if (opts.useNewLines || opts.surroundWithSpaces) appendSeparator(); else appendIndentation(); const nextEndStart = nextNode == null ? (isContained ? parentNextSibling.getStart(true) : parent.getEnd()) : nextNode.getStart(true); const insertPos = (previousNonCommentNode || previousNode).getEnd(); insertIntoParentTextRange({ insertPos, newText, parent, replacing: { textLength: nextEndStart - insertPos }, }); } else if (nextNode != null) { if (opts.useNewLines || opts.surroundWithSpaces) prependSeparator(); if (nextNonCommentNode != null || opts.useTrailingCommas) appendCommaAndSeparator(); else appendSeparator(); const insertPos = isContained ? parent.getPos() : parent.getStart(true); insertIntoParentTextRange({ insertPos, newText, parent, replacing: { textLength: nextNode.getStart(true) - insertPos }, }); } else { if (opts.useNewLines || opts.surroundWithSpaces) { prependSeparator(); if (opts.useTrailingCommas) appendCommaAndSeparator(); else appendSeparator(); } else { appendIndentation(); } insertIntoParentTextRange({ insertPos: parent.getPos(), newText, parent, replacing: { textLength: parent.getNextSiblingOrThrow().getStart() - parent.getPos() }, }); } function prependCommaAndSeparator() { if (previousNonCommentNode == null) { prependSeparator(); return; } const originalSourceFileText = parent.getSourceFile().getFullText(); const previousNodeNextSibling = previousNonCommentNode.getNextSibling(); let text = ""; if (previousNodeNextSibling != null && previousNodeNextSibling.getKind() === common.SyntaxKind.CommaToken) { appendNodeTrailingCommentRanges(previousNonCommentNode); text += ","; if (previousNonCommentNode === previousNode) appendNodeTrailingCommentRanges(previousNodeNextSibling); else appendCommentNodeTexts(); } else { text += ","; if (previousNonCommentNode === previousNode) appendNodeTrailingCommentRanges(previousNonCommentNode); else appendCommentNodeTexts(); } prependSeparator(); newText = text + newText; function appendCommentNodeTexts() { const lastCommentRangeEnd = getLastCommentRangeEnd(previousNode) || previousNode.getEnd(); text += originalSourceFileText.substring(previousNonCommentNode.getEnd(), lastCommentRangeEnd); } function appendNodeTrailingCommentRanges(node) { const lastCommentRangeEnd = getLastCommentRangeEnd(node); if (lastCommentRangeEnd == null) return; text += originalSourceFileText.substring(node.getEnd(), lastCommentRangeEnd); } function getLastCommentRangeEnd(node) { const commentRanges = node.getTrailingCommentRanges(); const lastCommentRange = commentRanges[commentRanges.length - 1]; return lastCommentRange?.getEnd(); } } function getPreviousNonCommentNode() { for (let i = insertIndex - 1; i >= 0; i--) { if (!Node.isCommentNode(currentNodes[i])) return currentNodes[i]; } return undefined; } function getNextNonCommentNode() { for (let i = insertIndex; i < currentNodes.length; i++) { if (!Node.isCommentNode(currentNodes[i])) return currentNodes[i]; } return undefined; } function prependSeparator() { if (!common.StringUtils.startsWithNewLine(newText)) newText = separator + newText; } function appendCommaAndSeparator() { newText = appendCommaToText(newText); appendSeparator(); } function appendSeparator() { if (!common.StringUtils.endsWithNewLine(newText)) newText += separator; appendIndentation(); } function appendIndentation() { if (opts.useNewLines || common.StringUtils.endsWithNewLine(newText)) { if (nextNode != null) newText += parent.getParentOrThrow().getChildIndentationText(); else newText += parent.getParentOrThrow().getIndentationText(); } } } function insertIntoBracesOrSourceFile(opts) { const { parent, index, children } = opts; const fullText = parent._sourceFile.getFullText(); const childSyntaxList = parent.getChildSyntaxListOrThrow(); const insertPos = getInsertPosFromIndex(index, childSyntaxList, children); const endPos = getEndPosFromIndex(index, parent, children, fullText); const replacingLength = endPos - insertPos; const newText = getNewText(); doManipulation(parent._sourceFile, new InsertionTextManipulator({ insertPos, replacingLength, newText }), new NodeHandlerFactory().getForParentRange({ parent: childSyntaxList, start: insertPos, end: insertPos + newText.length, replacingLength, })); function getNewText() { const writer = parent._getWriterWithChildIndentation(); opts.write(writer, { previousMember: getChild(children[index - 1]), nextMember: getChild(children[index]), isStartOfFile: insertPos === 0, }); return writer.toString(); function getChild(child) { if (child == null) return child; else if (Node.isOverloadable(child)) return child.getImplementation() || child; else return child; } } } function insertIntoBracesOrSourceFileWithGetChildren(opts) { if (opts.structures.length === 0) return []; const startChildren = opts.getIndexedChildren(); const parentSyntaxList = opts.parent.getChildSyntaxListOrThrow(); const index = verifyAndGetIndex(opts.index, startChildren.length); const previousJsDocCount = getPreviousJsDocCount(); insertIntoBracesOrSourceFile({ parent: opts.parent, index: getChildIndex(), children: parentSyntaxList.getChildren(), write: opts.write, }); return getRangeWithoutCommentsFromArray(opts.getIndexedChildren(), opts.index - previousJsDocCount, opts.structures.length, opts.expectedKind); function getChildIndex() { if (index === 0) return 0; return startChildren[index - 1].getChildIndex() + 1; } function getPreviousJsDocCount() { let commentCount = 0; let count = 0; for (let i = index - 1; i >= 0; i--) { const node = startChildren[i]; if (Node.isCommentNode(node)) { commentCount++; if (node.getText().startsWith("/**")) count = commentCount; } else { break; } } return count; } } function insertIntoBracesOrSourceFileWithGetChildrenWithComments(opts) { const startChildren = opts.getIndexedChildren(); const parentSyntaxList = opts.parent.getChildSyntaxListOrThrow(); const index = verifyAndGetIndex(opts.index, startChildren.length); insertIntoBracesOrSourceFile({ parent: opts.parent, index: getChildIndex(), children: parentSyntaxList.getChildren(), write: opts.write, }); return getNodesToReturn(startChildren, opts.getIndexedChildren(), index, true); function getChildIndex() { if (index === 0) return 0; return startChildren[index - 1].getChildIndex() + 1; } } function changeChildOrder(opts) { const { parent } = opts; doManipulation(parent._sourceFile, new ChangingChildOrderTextManipulator(opts), new NodeHandlerFactory().getForChangingChildOrder(opts)); } function removeChildren(opts) { const { children } = opts; if (children.length === 0) return; doManipulation(children[0].getSourceFile(), new RemoveChildrenTextManipulator(opts), new NodeHandlerFactory().getForChildIndex({ parent: children[0].getParentSyntaxList() || children[0].getParentOrThrow(), childIndex: children[0].getChildIndex(), childCount: -1 * children.length, })); } function removeChildrenWithFormattingFromCollapsibleSyntaxList(opts) { const { children } = opts; if (children.length === 0) return; const syntaxList = children[0].getParentSyntaxListOrThrow(); if (syntaxList.getChildCount() === children.length) { removeChildrenWithFormatting({ children: [syntaxList], getSiblingFormatting: () => FormattingKind.None, }); } else { removeChildrenWithFormatting(opts); } } function removeChildrenWithFormatting(opts) { const { children, getSiblingFormatting } = opts; if (children.length === 0) return; doManipulation(children[0]._sourceFile, new RemoveChildrenWithFormattingTextManipulator({ children, getSiblingFormatting, }), new NodeHandlerFactory().getForChildIndex({ parent: children[0].getParentSyntaxList() || children[0].getParentOrThrow(), childIndex: children[0].getChildIndex(), childCount: -1 * children.length, })); } function removeClassMember(classMember) { if (Node.isOverloadable(classMember)) { if (classMember.isImplementation()) removeClassMembers([...classMember.getOverloads(), classMember]); else { const parent = classMember.getParentOrThrow(); if (Node.isAmbientable(parent) && parent.isAmbient()) removeClassMembers([classMember]); else removeChildren({ children: [classMember], removeFollowingSpaces: true, removeFollowingNewLines: true }); } } else { removeClassMembers([classMember]); } } function removeClassMembers(classMembers) { removeChildrenWithFormatting({ getSiblingFormatting: getClassMemberFormatting, children: classMembers, }); } function removeInterfaceMember(interfaceMember) { removeInterfaceMembers([interfaceMember]); } function removeInterfaceMembers(interfaceMembers) { removeChildrenWithFormatting({ getSiblingFormatting: getInterfaceMemberFormatting, children: interfaceMembers, }); } function removeCommaSeparatedChild(child) { const childrenToRemove = [child]; const syntaxList = child.getParentSyntaxListOrThrow(); const isRemovingFirstChild = childrenToRemove[0] === syntaxList.getFirstChild(); addNextCommaIfAble(); addPreviousCommaIfAble(); removeChildren({ children: childrenToRemove, removePrecedingSpaces: !isRemovingFirstChild || syntaxList.getChildren().length === childrenToRemove.length && childrenToRemove[0].isFirstNodeOnLine(), removeFollowingSpaces: isRemovingFirstChild, removePrecedingNewLines: !isRemovingFirstChild, removeFollowingNewLines: isRemovingFirstChild, }); function addNextCommaIfAble() { const commaToken = child.getNextSiblingIfKind(common.SyntaxKind.CommaToken); if (commaToken != null) childrenToRemove.push(commaToken); } function addPreviousCommaIfAble() { if (syntaxList.getLastChild() !== childrenToRemove[childrenToRemove.length - 1]) return; const precedingComma = child.getPreviousSiblingIfKind(common.SyntaxKind.CommaToken); if (precedingComma != null) childrenToRemove.unshift(precedingComma); } } function removeOverloadableStatementedNodeChild(node) { if (node.isOverload()) removeChildren({ children: [node], removeFollowingSpaces: true, removeFollowingNewLines: true }); else removeStatementedNodeChildren([...node.getOverloads(), node]); } function removeStatementedNodeChild(node) { removeStatementedNodeChildren([node]); } function removeStatementedNodeChildren(nodes) { removeChildrenWithFormatting({ getSiblingFormatting: getStatementedNodeChildFormatting, children: nodes, }); } function removeClausedNodeChild(node) { removeClausedNodeChildren([node]); } function removeClausedNodeChildren(nodes) { removeChildrenWithFormatting({ getSiblingFormatting: getClausedNodeChildFormatting, children: nodes, }); } function unwrapNode(node) { doManipulation(node._sourceFile, new UnwrapTextManipulator(node), new NodeHandlerFactory().getForUnwrappingNode(node)); } function replaceNodeText(opts) { doManipulation(opts.sourceFile, new InsertionTextManipulator({ insertPos: opts.start, newText: opts.newText, replacingLength: opts.replacingLength, }), new NodeHandlerFactory().getForForgetChanged(opts.sourceFile._context.compilerFactory)); } function replaceSourceFileTextForFormatting(opts) { replaceSourceFileTextStraight(opts); } function replaceSourceFileTextStraight(opts) { const { sourceFile, newText } = opts; doManipulation(sourceFile, new FullReplacementTextManipulator(newText), new NodeHandlerFactory().getForStraightReplacement(sourceFile._context.compilerFactory)); } function replaceSourceFileTextForRename(opts) { const { sourceFile, renameLocations, newName } = opts; const nodeHandlerFactory = new NodeHandlerFactory(); doManipulation(sourceFile, new RenameLocationTextManipulator(renameLocations, newName), nodeHandlerFactory.getForTryOrForget(nodeHandlerFactory.getForRename(sourceFile._context.compilerFactory))); } function replaceTextPossiblyCreatingChildNodes(opts) { const { replacePos, replacingLength, newText, parent } = opts; doManipulation(parent._sourceFile, new InsertionTextManipulator({ insertPos: replacePos, replacingLength, newText, }), new NodeHandlerFactory().getForParentRange({ parent, start: replacePos, end: replacePos + newText.length, })); } function replaceSourceFileForFilePathMove(opts) { const { sourceFile, newFilePath } = opts; doManipulation(sourceFile, new UnchangedTextManipulator(), new NodeHandlerFactory().getForStraightReplacement(sourceFile._context.compilerFactory), newFilePath); } function replaceSourceFileForCacheUpdate(sourceFile) { replaceSourceFileForFilePathMove({ sourceFile, newFilePath: sourceFile.getFilePath() }); } function ArgumentedNode(Base) { return class extends Base { getArguments() { return this.compilerNode.arguments?.map(a => this._getNodeFromCompilerNode(a)) ?? []; } addArgument(argumentText) { return this.addArguments([argumentText])[0]; } addArguments(argumentTexts) { return this.insertArguments(this.getArguments().length, argumentTexts); } insertArgument(index, argumentText) { return this.insertArguments(index, [argumentText])[0]; } insertArguments(index, argumentTexts) { if (argumentTexts instanceof Function) argumentTexts = [argumentTexts]; if (common.ArrayUtils.isNullOrEmpty(argumentTexts)) return []; this._addParensIfNecessary(); const originalArgs = this.getArguments(); index = verifyAndGetIndex(index, originalArgs.length); const writer = this._getWriterWithQueuedChildIndentation(); for (let i = 0; i < argumentTexts.length; i++) { writer.conditionalWrite(i > 0, ", "); printTextFromStringOrWriter(writer, argumentTexts[i]); } insertIntoCommaSeparatedNodes({ parent: this.getFirstChildByKindOrThrow(common.SyntaxKind.OpenParenToken).getNextSiblingIfKindOrThrow(common.SyntaxKind.SyntaxList), currentNodes: originalArgs, insertIndex: index, newText: writer.toString(), useTrailingCommas: false, }); return getNodesToReturn(originalArgs, this.getArguments(), index, false); } removeArgument(argOrIndex) { const args = this.getArguments(); if (args.length === 0) throw new common.errors.InvalidOperationError("Cannot remove an argument when none exist."); const argToRemove = typeof argOrIndex === "number" ? getArgFromIndex(argOrIndex) : argOrIndex; removeCommaSeparatedChild(argToRemove); return this; function getArgFromIndex(index) { return args[verifyAndGetIndex(index, args.length - 1)]; } } _addParensIfNecessary() { const fullText = this.getFullText(); if (fullText[fullText.length - 1] !== ")") { insertIntoParentTextRange({ insertPos: this.getEnd(), newText: "()", parent: this, }); } } }; } function AsyncableNode(Base) { return class extends Base { isAsync() { return this.hasModifier(common.SyntaxKind.AsyncKeyword); } getAsyncKeyword() { return this.getFirstModifierByKind(common.SyntaxKind.AsyncKeyword); } getAsyncKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getAsyncKeyword(), message ?? "Expected to find an async keyword.", this); } setIsAsync(value) { this.toggleModifier("async", value); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.isAsync != null) this.setIsAsync(structure.isAsync); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { isAsync: this.isAsync(), }); } }; } function AwaitableNode(Base) { return class extends Base { isAwaited() { return this.compilerNode.awaitModifier != null; } getAwaitKeyword() { const awaitModifier = this.compilerNode.awaitModifier; return this._getNodeFromCompilerNodeIfExists(awaitModifier); } getAwaitKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getAwaitKeyword(), message ?? "Expected to find an await token."); } setIsAwaited(value) { const awaitModifier = this.getAwaitKeyword(); const isSet = awaitModifier != null; if (isSet === value) return this; if (awaitModifier == null) { insertIntoParentTextRange({ insertPos: getAwaitInsertPos(this), parent: this, newText: " await", }); } else { removeChildren({ children: [awaitModifier], removePrecedingSpaces: true, }); } return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.isAwaited != null) this.setIsAwaited(structure.isAwaited); return this; } }; } function getAwaitInsertPos(node) { if (node.getKind() === common.SyntaxKind.ForOfStatement) return node.getFirstChildByKindOrThrow(common.SyntaxKind.ForKeyword).getEnd(); throw new common.errors.NotImplementedError("Expected a for of statement node."); } function getBodyText(writer, textOrWriterFunction) { writer.newLineIfLastNot(); if (typeof textOrWriterFunction !== "string" || textOrWriterFunction.length > 0) { writer.indent(() => { printTextFromStringOrWriter(writer, textOrWriterFunction); }); } writer.newLineIfLastNot(); writer.write(""); return writer.toString(); } function getBodyTextWithoutLeadingIndentation(body) { const sourceFile = body._sourceFile; const textArea = body.getChildSyntaxList() || body; const startPos = textArea.getNonWhitespaceStart(); const endPos = Math.max(startPos, textArea._getTrailingTriviaNonWhitespaceEnd()); const width = endPos - startPos; if (width === 0) return ""; const fullText = sourceFile.getFullText().substring(startPos, endPos); return common.StringUtils.removeIndentation(fullText, { indentSizeInSpaces: body._context.manipulationSettings._getIndentSizeInSpaces(), isInStringAtPos: pos => sourceFile.isInStringAtPos(pos + startPos), }); } class TextRange { #compilerObject; #sourceFile; constructor(compilerObject, sourceFile) { this.#compilerObject = compilerObject; this.#sourceFile = sourceFile; } get compilerObject() { this.#throwIfForgotten(); return this.#compilerObject; } getSourceFile() { this.#throwIfForgotten(); return this.#sourceFile; } getPos() { return this.compilerObject.pos; } getEnd() { return this.compilerObject.end; } getWidth() { return this.getEnd() - this.getPos(); } getText() { const fullText = this.getSourceFile().getFullText(); return fullText.substring(this.compilerObject.pos, this.compilerObject.end); } _forget() { this.#compilerObject = undefined; this.#sourceFile = undefined; } wasForgotten() { return this.#compilerObject == null; } #throwIfForgotten() { if (this.#compilerObject != null) return; const message = "Attempted to get a text range that was forgotten. " + "Text ranges are forgotten after a manipulation has occurred. " + "Please re-request the text range after manipulations."; throw new common.errors.InvalidOperationError(message); } } class CommentRange extends TextRange { constructor(compilerObject, sourceFile) { super(compilerObject, sourceFile); } getKind() { return this.compilerObject.kind; } } class Node { #compilerNode; #forgottenText; #childStringRanges; #leadingCommentRanges; #trailingCommentRanges; _wrappedChildCount = 0; _context; __sourceFile; get _sourceFile() { if (this.__sourceFile == null) throw new common.errors.InvalidOperationError("Operation cannot be performed on a node that has no source file."); return this.__sourceFile; } get compilerNode() { if (this.#compilerNode == null) { let message = "Attempted to get information from a node that was removed or forgotten."; if (this.#forgottenText != null) message += `\n\nNode text: ${this.#forgottenText}`; throw new common.errors.InvalidOperationError(message); } return this.#compilerNode; } constructor(context, node, sourceFile) { if (context == null || context.compilerFactory == null) { throw new common.errors.InvalidOperationError("Constructing a node is not supported. Please create a source file from the default export " + "of the package and manipulate the source file from there."); } this._context = context; this.#compilerNode = node; this.__sourceFile = sourceFile; } forget() { if (this.wasForgotten()) return; this.forgetDescendants(); this._forgetOnlyThis(); } forgetDescendants() { for (const child of this._getChildrenInCacheIterator()) child.forget(); } _forgetOnlyThis() { if (this.wasForgotten()) return; const parent = this.getParent(); if (parent != null) parent._wrappedChildCount--; this.#storeTextForForgetting(); this._context.compilerFactory.removeNodeFromCache(this); this._clearInternals(); } wasForgotten() { return this.#compilerNode == null; } _hasWrappedChildren() { return this._wrappedChildCount > 0 || this.#compilerNode?.kind === common.SyntaxKind.SyntaxList; } _replaceCompilerNodeFromFactory(compilerNode) { if (compilerNode == null) this.#storeTextForForgetting(); this._clearInternals(); this.#compilerNode = compilerNode; } #storeTextForForgetting() { const sourceFileCompilerNode = this._sourceFile && this._sourceFile.compilerNode; const compilerNode = this.#compilerNode; if (sourceFileCompilerNode == null || compilerNode == null) return; this.#forgottenText = getText(); function getText() { const start = compilerNode.getStart(sourceFileCompilerNode); const length = compilerNode.end - start; const trimmedLength = Math.min(length, 100); const text = sourceFileCompilerNode.text.substr(start, trimmedLength); return trimmedLength !== length ? text + "..." : text; } } _clearInternals() { this.#compilerNode = undefined; this.#childStringRanges = undefined; clearTextRanges(this.#leadingCommentRanges); clearTextRanges(this.#trailingCommentRanges); this.#leadingCommentRanges = undefined; this.#trailingCommentRanges = undefined; function clearTextRanges(textRanges) { if (textRanges == null) return; textRanges.forEach(r => r._forget()); } } getKind() { return this.compilerNode.kind; } getKindName() { return common.getSyntaxKindName(this.compilerNode.kind); } getFlags() { return this.compilerNode.flags; } print(options = {}) { if (options.newLineKind == null) options.newLineKind = this._context.manipulationSettings.getNewLineKind(); if (this.getKind() === common.SyntaxKind.SourceFile) return printNode(this.compilerNode, options); else return printNode(this.compilerNode, this._sourceFile.compilerNode, options); } getSymbolOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getSymbol(), message ?? "Could not find the node's symbol.", this); } getSymbol() { const boundSymbol = this.compilerNode.symbol; if (boundSymbol != null) return this._context.compilerFactory.getSymbol(boundSymbol); const typeChecker = this._context.typeChecker; const typeCheckerSymbol = typeChecker.getSymbolAtLocation(this); if (typeCheckerSymbol != null) return typeCheckerSymbol; const nameNode = this.compilerNode.name; if (nameNode != null) return this._getNodeFromCompilerNode(nameNode).getSymbol(); return undefined; } getSymbolsInScope(meaning) { return this._context.typeChecker.getSymbolsInScope(this, meaning); } getLocalOrThrow(name, message) { return common.errors.throwIfNullOrUndefined(this.getLocal(name), message ?? (() => `Expected to find local symbol with name: ${name}`), this); } getLocal(name) { const locals = this.#getCompilerLocals(); if (locals == null) return undefined; const tsSymbol = locals.get(common.ts.escapeLeadingUnderscores(name)); return tsSymbol == null ? undefined : this._context.compilerFactory.getSymbol(tsSymbol); } getLocals() { const locals = this.#getCompilerLocals(); if (locals == null) return []; return Array.from(locals.values()).map(symbol => this._context.compilerFactory.getSymbol(symbol)); } #getCompilerLocals() { this._ensureBound(); return this.compilerNode.locals; } getType() { return this._context.typeChecker.getTypeAtLocation(this); } containsRange(pos, end) { return this.getPos() <= pos && end <= this.getEnd(); } isInStringAtPos(pos) { common.errors.throwIfOutOfRange(pos, [this.getPos(), this.getEnd()], "pos"); if (this.#childStringRanges == null) { this.#childStringRanges = []; for (const descendant of this._getCompilerDescendantsIterator()) { if (isStringKind(descendant.kind)) this.#childStringRanges.push([descendant.getStart(this._sourceFile.compilerNode), descendant.getEnd()]); } } class InStringRangeComparer { compareTo(value) { if (pos <= value[0]) return -1; if (pos >= value[1] - 1) return 1; return 0; } } return common.ArrayUtils.binarySearch(this.#childStringRanges, new InStringRangeComparer()) !== -1; } asKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.asKind(kind), message ?? (() => `Expected the node to be of kind ${common.getSyntaxKindName(kind)}, but it was ${common.getSyntaxKindName(this.getKind())}.`), this); } isKind(kind) { return this.getKind() === kind; } asKind(kind) { if (this.isKind(kind)) return this; else return undefined; } getFirstChildOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getFirstChild(condition), message ?? "Could not find a child that matched the specified condition.", this); } getFirstChild(condition) { const firstChild = this._getCompilerFirstChild(getWrappedCondition(this, condition)); return this._getNodeFromCompilerNodeIfExists(firstChild); } getLastChildOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getLastChild(condition), message ?? "Could not find a child that matched the specified condition.", this); } getLastChild(condition) { const lastChild = this._getCompilerLastChild(getWrappedCondition(this, condition)); return this._getNodeFromCompilerNodeIfExists(lastChild); } getFirstDescendantOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getFirstDescendant(condition), message ?? "Could not find a descendant that matched the specified condition.", this); } getFirstDescendant(condition) { for (const descendant of this._getDescendantsIterator()) { if (condition == null || condition(descendant)) return descendant; } return undefined; } getPreviousSiblingOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getPreviousSibling(condition), message ?? "Could not find the previous sibling.", this); } getPreviousSibling(condition) { const previousSibling = this._getCompilerPreviousSibling(getWrappedCondition(this, condition)); return this._getNodeFromCompilerNodeIfExists(previousSibling); } getNextSiblingOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getNextSibling(condition), message ?? "Could not find the next sibling.", this); } getNextSibling(condition) { const nextSibling = this._getCompilerNextSibling(getWrappedCondition(this, condition)); return this._getNodeFromCompilerNodeIfExists(nextSibling); } getPreviousSiblings() { return this._getCompilerPreviousSiblings().map(n => this._getNodeFromCompilerNode(n)); } getNextSiblings() { return this._getCompilerNextSiblings().map(n => this._getNodeFromCompilerNode(n)); } getChildren() { return this._getCompilerChildren().map(n => this._getNodeFromCompilerNode(n)); } getChildAtIndex(index) { return this._getNodeFromCompilerNode(this._getCompilerChildAtIndex(index)); } *_getChildrenIterator() { for (const compilerChild of this._getCompilerChildren()) yield this._getNodeFromCompilerNode(compilerChild); } *_getChildrenInCacheIterator() { const children = this._getCompilerChildrenFast(); for (const child of children) { if (this._context.compilerFactory.hasCompilerNode(child)) yield this._context.compilerFactory.getExistingNodeFromCompilerNode(child); else if (child.kind === common.SyntaxKind.SyntaxList) { yield this._getNodeFromCompilerNode(child); } } } getChildSyntaxListOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getChildSyntaxList(), message ?? "A child syntax list was expected.", this); } getChildSyntaxList() { let node = this; if (Node.isBodyable(node) || Node.isBodied(node)) { do { const bodyNode = Node.isBodyable(node) ? node.getBody() : node.getBody(); if (bodyNode == null) return undefined; node = bodyNode; } while ((Node.isBodyable(node) || Node.isBodied(node)) && node.compilerNode.statements == null); } if (Node.isSourceFile(node) || Node.isBodyable(this) || Node.isBodied(this) || Node.isCaseBlock(this) || Node.isCaseClause(this) || Node.isDefaultClause(this) || Node.isJsxElement(this)) { return node.getFirstChildByKind(common.SyntaxKind.SyntaxList); } let passedBrace = false; for (const child of node._getCompilerChildren()) { if (!passedBrace) passedBrace = child.kind === common.SyntaxKind.OpenBraceToken; else if (child.kind === common.SyntaxKind.SyntaxList) return this._getNodeFromCompilerNode(child); } return undefined; } forEachChild(cbNode, cbNodeArray) { const snapshots = []; this.compilerNode.forEachChild(node => { snapshots.push(this._getNodeFromCompilerNode(node)); }, cbNodeArray == null ? undefined : nodes => { snapshots.push(nodes.map(n => this._getNodeFromCompilerNode(n))); }); for (const snapshot of snapshots) { if (snapshot instanceof Array) { const filteredNodes = snapshot.filter(n => !n.wasForgotten()); if (filteredNodes.length > 0) { const returnValue = cbNodeArray(filteredNodes); if (returnValue) return returnValue; } } else if (!snapshot.wasForgotten()) { const returnValue = cbNode(snapshot); if (returnValue) return returnValue; } } return undefined; } forEachDescendant(cbNode, cbNodeArray) { const stopReturnValue = {}; const upReturnValue = {}; let stop = false; let up = false; const traversal = { stop: () => stop = true, up: () => up = true, }; const nodeCallback = (node) => { if (stop) return stopReturnValue; let skip = false; const returnValue = cbNode(node, { ...traversal, skip: () => skip = true, }); if (returnValue) return returnValue; if (stop) return stopReturnValue; if (skip || up) return undefined; if (!node.wasForgotten()) return forEachChildForNode(node); return undefined; }; const arrayCallback = cbNodeArray == null ? undefined : (nodes) => { if (stop) return stopReturnValue; let skip = false; const returnValue = cbNodeArray(nodes, { ...traversal, skip: () => skip = true, }); if (returnValue) return returnValue; if (skip) return undefined; for (const node of nodes) { if (stop) return stopReturnValue; if (up) return undefined; const innerReturnValue = forEachChildForNode(node); if (innerReturnValue) return innerReturnValue; } return undefined; }; const finalResult = forEachChildForNode(this); return finalResult === stopReturnValue ? undefined : finalResult; function forEachChildForNode(node) { const result = node.forEachChild(innerNode => { const returnValue = nodeCallback(innerNode); if (up) { up = false; return returnValue || upReturnValue; } return returnValue; }, arrayCallback == null ? undefined : nodes => { const returnValue = arrayCallback(nodes); if (up) { up = false; return returnValue || upReturnValue; } return returnValue; }); return result === upReturnValue ? undefined : result; } } forEachChildAsArray() { const children = []; this.compilerNode.forEachChild(child => { children.push(this._getNodeFromCompilerNode(child)); }); return children; } forEachDescendantAsArray() { const descendants = []; this.forEachDescendant(descendant => { descendants.push(descendant); }); return descendants; } getDescendants() { return Array.from(this._getDescendantsIterator()); } *_getDescendantsIterator() { for (const descendant of this._getCompilerDescendantsIterator()) yield this._getNodeFromCompilerNode(descendant); } getDescendantStatements() { const statements = []; handleNode(this, this.compilerNode); return statements; function handleNode(thisNode, node) { if (handleStatements(thisNode, node)) return; else if (node.kind === common.SyntaxKind.ArrowFunction) { const arrowFunction = node; if (arrowFunction.body.kind !== common.SyntaxKind.Block) statements.push(thisNode._getNodeFromCompilerNode(arrowFunction.body)); else handleNode(thisNode, arrowFunction.body); } else { handleChildren(thisNode, node); } } function handleStatements(thisNode, node) { if (node.statements == null) return false; const statementedNode = thisNode._getNodeFromCompilerNode(node); for (const statement of statementedNode.getStatements()) { statements.push(statement); handleChildren(thisNode, statement.compilerNode); } return true; } function handleChildren(thisNode, node) { common.ts.forEachChild(node, childNode => handleNode(thisNode, childNode)); } } getChildCount() { return this._getCompilerChildren().length; } getChildAtPos(pos) { if (pos < this.getPos() || pos >= this.getEnd()) return undefined; for (const child of this._getCompilerChildren()) { if (pos >= child.pos && pos < child.end) return this._getNodeFromCompilerNode(child); } return undefined; } getDescendantAtPos(pos) { let node; while (true) { const nextNode = (node || this).getChildAtPos(pos); if (nextNode == null) return node; else node = nextNode; } } getDescendantAtStartWithWidth(start, width) { let foundNode; this._context.compilerFactory.forgetNodesCreatedInBlock(remember => { let nextNode = this.getSourceFile(); do { nextNode = nextNode.getChildAtPos(start); if (nextNode != null) { if (nextNode.getStart() === start && nextNode.getWidth() === width) foundNode = nextNode; else if (foundNode != null) break; } } while (nextNode != null); if (foundNode != null) remember(foundNode); }); return foundNode; } getPos() { return this.compilerNode.pos; } getEnd() { return this.compilerNode.end; } getStart(includeJsDocComments) { return this.compilerNode.getStart(this._sourceFile.compilerNode, includeJsDocComments); } getFullStart() { return this.compilerNode.getFullStart(); } getNonWhitespaceStart() { return this._context.compilerFactory.forgetNodesCreatedInBlock(() => { const parent = this.getParent(); const pos = this.getPos(); const parentTakesPrecedence = parent != null && !Node.isSourceFile(parent) && parent.getPos() === pos; if (parentTakesPrecedence) return this.getStart(true); let startSearchPos; const sourceFileFullText = this._sourceFile.getFullText(); const previousSibling = this.getPreviousSibling(); if (previousSibling != null && Node.isCommentNode(previousSibling)) startSearchPos = previousSibling.getEnd(); else if (previousSibling != null) { if (hasNewLineInRange(sourceFileFullText, [pos, this.getStart(true)])) startSearchPos = previousSibling.getTrailingTriviaEnd(); else startSearchPos = pos; } else { startSearchPos = this.getPos(); } return getNextNonWhitespacePos(sourceFileFullText, startSearchPos); }); } _getTrailingTriviaNonWhitespaceEnd() { return getPreviousNonWhitespacePos(this._sourceFile.getFullText(), this.getTrailingTriviaEnd()); } getWidth(includeJsDocComments) { return this.getEnd() - this.getStart(includeJsDocComments); } getFullWidth() { return this.compilerNode.getFullWidth(); } getLeadingTriviaWidth() { return this.compilerNode.getLeadingTriviaWidth(this._sourceFile.compilerNode); } getTrailingTriviaWidth() { return this.getTrailingTriviaEnd() - this.getEnd(); } getTrailingTriviaEnd() { const parent = this.getParent(); const end = this.getEnd(); if (parent == null) return end; const parentEnd = parent.getEnd(); if (parentEnd === end) return end; const trailingComments = this.getTrailingCommentRanges(); const searchStart = getSearchStart(); return getNextMatchingPos(this._sourceFile.getFullText(), searchStart, char => char !== CharCodes.SPACE && char !== CharCodes.TAB); function getSearchStart() { return trailingComments.length > 0 ? trailingComments[trailingComments.length - 1].getEnd() : end; } } getText(includeJsDocCommentOrOptions) { const options = typeof includeJsDocCommentOrOptions === "object" ? includeJsDocCommentOrOptions : undefined; const includeJsDocComments = includeJsDocCommentOrOptions === true || (options != null && options.includeJsDocComments); const trimLeadingIndentation = options != null && options.trimLeadingIndentation; const startPos = this.getStart(includeJsDocComments); const text = this._sourceFile.getFullText().substring(startPos, this.getEnd()); if (trimLeadingIndentation) { return common.StringUtils.removeIndentation(text, { isInStringAtPos: pos => this._sourceFile.isInStringAtPos(pos + startPos), indentSizeInSpaces: this._context.manipulationSettings._getIndentSizeInSpaces(), }); } else { return text; } } getFullText() { return this.compilerNode.getFullText(this._sourceFile.compilerNode); } getCombinedModifierFlags() { return common.ts.getCombinedModifierFlags(this.compilerNode); } getSourceFile() { return this._sourceFile; } getProject() { return this._context.project; } getNodeProperty(propertyName) { const property = this.compilerNode[propertyName]; if (property == null) return undefined; else if (property instanceof Array) return property.map(p => isNode(p) ? this._getNodeFromCompilerNode(p) : p); else if (isNode(property)) return this._getNodeFromCompilerNode(property); else return property; function isNode(value) { return typeof value.kind === "number" && typeof value.pos === "number" && typeof value.end === "number"; } } getAncestors(includeSyntaxLists = false) { return Array.from(this._getAncestorsIterator(includeSyntaxLists)); } *_getAncestorsIterator(includeSyntaxLists) { let parent = getParent(this); while (parent != null) { yield parent; parent = getParent(parent); } function getParent(node) { return includeSyntaxLists ? node.getParentSyntaxList() || node.getParent() : node.getParent(); } } getParent() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.parent); } getParentOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getParent(), message ?? "Expected to find a parent.", this); } getParentWhileOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getParentWhile(condition), message ?? "The initial parent did not match the provided condition.", this); } getParentWhile(condition) { let node = undefined; let parent = this.getParent(); while (parent && condition(parent, node || this)) { node = parent; parent = node.getParent(); } return node; } getParentWhileKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getParentWhileKind(kind), message ?? (() => `The initial parent was not a syntax kind of ${common.getSyntaxKindName(kind)}.`), this); } getParentWhileKind(kind) { return this.getParentWhile(n => n.getKind() === kind); } getLastToken() { const lastToken = this.compilerNode.getLastToken(this._sourceFile.compilerNode); if (lastToken == null) throw new common.errors.NotImplementedError("Not implemented scenario where the last token does not exist."); return this._getNodeFromCompilerNode(lastToken); } isInSyntaxList() { return this.getParentSyntaxList() != null; } getParentSyntaxListOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getParentSyntaxList(), message ?? "Expected the parent to be a syntax list.", this); } getParentSyntaxList() { const kind = this.getKind(); if (kind === common.SyntaxKind.SingleLineCommentTrivia || kind === common.SyntaxKind.MultiLineCommentTrivia) return this.getParentOrThrow().getChildSyntaxList(); const syntaxList = getParentSyntaxList(this.compilerNode, this._sourceFile.compilerNode); return this._getNodeFromCompilerNodeIfExists(syntaxList); } _getParentSyntaxListIfWrapped() { const parent = this.getParent(); if (parent == null || !ExtendedParser.hasParsedTokens(parent.compilerNode)) return undefined; return this.getParentSyntaxList(); } getChildIndex() { const parent = this.getParentSyntaxList() || this.getParentOrThrow(); const index = parent._getCompilerChildren().indexOf(this.compilerNode); if (index === -1) throw new common.errors.NotImplementedError("For some reason the child's parent did not contain the child."); return index; } getIndentationLevel() { const indentationText = this._context.manipulationSettings.getIndentationText(); return this._context.languageService.getIdentationAtPosition(this._sourceFile, this.getStart()) / indentationText.length; } getChildIndentationLevel() { if (Node.isSourceFile(this)) return 0; return this.getIndentationLevel() + 1; } getIndentationText(offset = 0) { return this.#getIndentationTextForLevel(this.getIndentationLevel() + offset); } getChildIndentationText(offset = 0) { return this.#getIndentationTextForLevel(this.getChildIndentationLevel() + offset); } #getIndentationTextForLevel(level) { return this._context.manipulationSettings.getIndentationText().repeat(level); } getStartLinePos(includeJsDocComments) { const sourceFileText = this._sourceFile.getFullText(); return getPreviousMatchingPos(sourceFileText, this.getStart(includeJsDocComments), char => char === CharCodes.NEWLINE || char === CharCodes.CARRIAGE_RETURN); } getStartLineNumber(includeJsDocComments) { return common.StringUtils.getLineNumberAtPos(this._sourceFile.getFullText(), this.getStartLinePos(includeJsDocComments)); } getEndLineNumber() { const sourceFileText = this._sourceFile.getFullText(); const endLinePos = getPreviousMatchingPos(sourceFileText, this.getEnd(), char => char === CharCodes.NEWLINE || char === CharCodes.CARRIAGE_RETURN); return common.StringUtils.getLineNumberAtPos(this._sourceFile.getFullText(), endLinePos); } isFirstNodeOnLine() { const sourceFileText = this._sourceFile.getFullText(); const startPos = this.getNonWhitespaceStart(); for (let i = startPos - 1; i >= 0; i--) { const currentChar = sourceFileText[i]; if (currentChar === " " || currentChar === "\t") continue; if (currentChar === "\n") return true; return false; } return true; } replaceWithText(textOrWriterFunction, writer) { const newText = getTextFromStringOrWriter(writer || this._getWriterWithQueuedIndentation(), textOrWriterFunction); if (Node.isSourceFile(this)) { this.replaceText([this.getPos(), this.getEnd()], newText); return this; } const parent = this.getParentSyntaxList() || this.getParentOrThrow(); const childIndex = this.getChildIndex(); const start = this.getStart(true); insertIntoParentTextRange({ parent, insertPos: start, newText, replacing: { textLength: this.getEnd() - start, }, }); return parent.getChildren()[childIndex]; } prependWhitespace(textOrWriterFunction) { insertWhiteSpaceTextAtPos(this, this.getStart(true), textOrWriterFunction, common.nameof(this, "prependWhitespace")); } appendWhitespace(textOrWriterFunction) { insertWhiteSpaceTextAtPos(this, this.getEnd(), textOrWriterFunction, common.nameof(this, "appendWhitespace")); } formatText(settings = {}) { const formattingEdits = this._context.languageService.getFormattingEditsForRange(this._sourceFile.getFilePath(), [this.getStart(true), this.getEnd()], settings); replaceSourceFileTextForFormatting({ sourceFile: this._sourceFile, newText: getTextFromTextChanges(this._sourceFile, formattingEdits), }); } transform(visitNode) { const compilerFactory = this._context.compilerFactory; const printer = common.ts.createPrinter({ newLine: this._context.manipulationSettings.getNewLineKind(), removeComments: false, }); const transformations = []; const compilerSourceFile = this._sourceFile.compilerNode; const compilerNode = this.compilerNode; const transformerFactory = context => { return rootNode => innerVisit(rootNode, context); }; if (this.getKind() === common.ts.SyntaxKind.SourceFile) { common.ts.transform(compilerNode, [transformerFactory], this._context.compilerOptions.get()); replaceSourceFileTextStraight({ sourceFile: this._sourceFile, newText: getTransformedText([0, this.getEnd()]), }); return this; } else { const parent = this.getParentSyntaxList() || this.getParentOrThrow(); const childIndex = this.getChildIndex(); const start = this.getStart(true); const end = this.getEnd(); common.ts.transform(compilerNode, [transformerFactory], this._context.compilerOptions.get()); insertIntoParentTextRange({ parent, insertPos: start, newText: getTransformedText([start, end]), replacing: { textLength: end - start, }, }); return parent.getChildren()[childIndex]; } function innerVisit(node, context) { const traversal = { factory: context.factory, visitChildren() { node = common.ts.visitEachChild(node, child => innerVisit(child, context), context); return node; }, currentNode: node, }; const resultNode = visitNode(traversal); handleTransformation(node, resultNode); return resultNode; } function handleTransformation(oldNode, newNode) { if (oldNode === newNode && newNode.emitNode == null) return; const start = oldNode.getStart(compilerSourceFile, true); const end = oldNode.end; let lastTransformation; while ((lastTransformation = transformations[transformations.length - 1]) && lastTransformation.start > start) transformations.pop(); const wrappedNode = compilerFactory.getExistingNodeFromCompilerNode(oldNode); transformations.push({ start, end, compilerNode: newNode, }); if (wrappedNode != null) { if (oldNode.kind !== newNode.kind) wrappedNode.forget(); else wrappedNode.forgetDescendants(); } } function getTransformedText(replaceRange) { const fileText = compilerSourceFile.getFullText(); let finalText = ""; let lastPos = replaceRange[0]; for (const transform of transformations) { finalText += fileText.substring(lastPos, transform.start); finalText += printer.printNode(common.ts.EmitHint.Unspecified, transform.compilerNode, transform.compilerNode.getSourceFile() ?? compilerSourceFile); lastPos = transform.end; } finalText += fileText.substring(lastPos, replaceRange[1]); return finalText; } } getLeadingCommentRanges() { return this.#leadingCommentRanges || (this.#leadingCommentRanges = this.#getCommentsAtPos(this.getFullStart(), (text, pos) => { const comments = common.ts.getLeadingCommentRanges(text, pos) || []; if (this.getKind() === common.SyntaxKind.SingleLineCommentTrivia || this.getKind() === common.SyntaxKind.MultiLineCommentTrivia) { const thisPos = this.getPos(); return comments.filter(r => r.pos < thisPos); } else { return comments; } })); } getTrailingCommentRanges() { return this.#trailingCommentRanges ?? (this.#trailingCommentRanges = this.#getCommentsAtPos(this.getEnd(), common.ts.getTrailingCommentRanges)); } #getCommentsAtPos(pos, getComments) { if (this.getKind() === common.SyntaxKind.SourceFile) return []; return (getComments(this._sourceFile.getFullText(), pos) ?? []).map(r => new CommentRange(r, this._sourceFile)); } getChildrenOfKind(kind) { return this._getCompilerChildrenOfKind(kind).map(c => this._getNodeFromCompilerNode(c)); } getFirstChildByKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getFirstChildByKind(kind), message ?? (() => `A child of the kind ${common.getSyntaxKindName(kind)} was expected.`), this); } getFirstChildByKind(kind) { const child = this._getCompilerChildrenOfKind(kind)[0]; return child == null ? undefined : this._getNodeFromCompilerNode(child); } getFirstChildIfKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getFirstChildIfKind(kind), message ?? (() => `A first child of the kind ${common.getSyntaxKindName(kind)} was expected.`), this); } getFirstChildIfKind(kind) { const firstChild = this._getCompilerFirstChild(); return firstChild != null && firstChild.kind === kind ? this._getNodeFromCompilerNode(firstChild) : undefined; } getLastChildByKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getLastChildByKind(kind), message ?? (() => `A child of the kind ${common.getSyntaxKindName(kind)} was expected.`), this); } getLastChildByKind(kind) { const children = this._getCompilerChildrenOfKind(kind); const lastChild = children[children.length - 1]; return this._getNodeFromCompilerNodeIfExists(lastChild); } getLastChildIfKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getLastChildIfKind(kind), message ?? (() => `A last child of the kind ${common.getSyntaxKindName(kind)} was expected.`), this); } getLastChildIfKind(kind) { const lastChild = this._getCompilerLastChild(); return lastChild != null && lastChild.kind === kind ? this._getNodeFromCompilerNode(lastChild) : undefined; } getChildAtIndexIfKindOrThrow(index, kind, message) { return common.errors.throwIfNullOrUndefined(this.getChildAtIndexIfKind(index, kind), message ?? (() => `Child at index ${index} was expected to be ${common.getSyntaxKindName(kind)}`), this); } getChildAtIndexIfKind(index, kind) { const node = this._getCompilerChildAtIndex(index); return node.kind === kind ? this._getNodeFromCompilerNode(node) : undefined; } getPreviousSiblingIfKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getPreviousSiblingIfKind(kind), message ?? (() => `A previous sibling of kind ${common.getSyntaxKindName(kind)} was expected.`), this); } getNextSiblingIfKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getNextSiblingIfKind(kind), message ?? (() => `A next sibling of kind ${common.getSyntaxKindName(kind)} was expected.`), this); } getPreviousSiblingIfKind(kind) { const previousSibling = this._getCompilerPreviousSibling(); return previousSibling != null && previousSibling.kind === kind ? this._getNodeFromCompilerNode(previousSibling) : undefined; } getNextSiblingIfKind(kind) { const nextSibling = this._getCompilerNextSibling(); return nextSibling != null && nextSibling.kind === kind ? this._getNodeFromCompilerNode(nextSibling) : undefined; } getParentIfOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getParentIf(condition), message ?? "The parent did not match the provided condition.", this); } getParentIf(condition) { return condition(this.getParent(), this) ? this.getParent() : undefined; } getParentIfKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getParentIfKind(kind), message ?? (() => `The parent was not a syntax kind of ${common.getSyntaxKindName(kind)}.`), this); } getParentIfKind(kind) { return this.getParentIf(n => n !== undefined && n.getKind() === kind); } getFirstAncestorByKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getFirstAncestorByKind(kind), message ?? (() => `Expected an ancestor with a syntax kind of ${common.getSyntaxKindName(kind)}.`), this); } getFirstAncestorByKind(kind) { for (const parent of this._getAncestorsIterator(kind === common.SyntaxKind.SyntaxList)) { if (parent.getKind() === kind) return parent; } return undefined; } getFirstAncestorOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getFirstAncestor(condition), message ?? `Expected to find an ancestor that matched the provided condition.`, this); } getFirstAncestor(condition) { for (const ancestor of this._getAncestorsIterator(false)) { if (condition == null || condition(ancestor)) return ancestor; } return undefined; } getDescendantsOfKind(kind) { const descendants = []; for (const descendant of this._getCompilerDescendantsOfKindIterator(kind)) descendants.push(this._getNodeFromCompilerNode(descendant)); return descendants; } getFirstDescendantByKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getFirstDescendantByKind(kind), message ?? (() => `A descendant of kind ${common.getSyntaxKindName(kind)} was expected to be found.`), this); } getFirstDescendantByKind(kind) { for (const descendant of this._getCompilerDescendantsOfKindIterator(kind)) return this._getNodeFromCompilerNode(descendant); return undefined; } _getCompilerChildren() { return ExtendedParser.getCompilerChildren(this.compilerNode, this._sourceFile.compilerNode); } _getCompilerForEachChildren() { return ExtendedParser.getCompilerForEachChildren(this.compilerNode, this._sourceFile.compilerNode); } _getCompilerChildrenFast() { return ExtendedParser.hasParsedTokens(this.compilerNode) ? this._getCompilerChildren() : this._getCompilerForEachChildren(); } _getCompilerChildrenOfKind(kind) { const children = useParseTreeSearchForKind(this, kind) ? this._getCompilerForEachChildren() : this._getCompilerChildren(); return children.filter(c => c.kind === kind); } *_getCompilerDescendantsOfKindIterator(kind) { const children = useParseTreeSearchForKind(this, kind) ? this._getCompilerForEachChildren() : this._getCompilerChildren(); for (const child of children) { if (child.kind === kind) yield child; const descendants = useParseTreeSearchForKind(child.kind, kind) ? getCompilerForEachDescendantsIterator(child) : getCompilerDescendantsIterator(child, this._sourceFile.compilerNode); for (const descendant of descendants) { if (descendant.kind === kind) yield descendant; } } } _getCompilerDescendantsIterator() { return getCompilerDescendantsIterator(this.compilerNode, this._sourceFile.compilerNode); } _getCompilerForEachDescendantsIterator() { return getCompilerForEachDescendantsIterator(this.compilerNode); } _getCompilerFirstChild(condition) { for (const child of this._getCompilerChildren()) { if (condition == null || condition(child)) return child; } return undefined; } _getCompilerLastChild(condition) { const children = this._getCompilerChildren(); for (let i = children.length - 1; i >= 0; i--) { const child = children[i]; if (condition == null || condition(child)) return child; } return undefined; } _getCompilerPreviousSiblings() { const parent = this.getParentSyntaxList() || this.getParentOrThrow(); const previousSiblings = []; for (const child of parent._getCompilerChildren()) { if (child === this.compilerNode) break; previousSiblings.unshift(child); } return previousSiblings; } _getCompilerNextSiblings() { let foundChild = false; const parent = this.getParentSyntaxList() || this.getParentOrThrow(); const nextSiblings = []; for (const child of parent._getCompilerChildren()) { if (!foundChild) { foundChild = child === this.compilerNode; continue; } nextSiblings.push(child); } return nextSiblings; } _getCompilerPreviousSibling(condition) { for (const sibling of this._getCompilerPreviousSiblings()) { if (condition == null || condition(sibling)) return sibling; } return undefined; } _getCompilerNextSibling(condition) { for (const sibling of this._getCompilerNextSiblings()) { if (condition == null || condition(sibling)) return sibling; } return undefined; } _getCompilerChildAtIndex(index) { const children = this._getCompilerChildren(); common.errors.throwIfOutOfRange(index, [0, children.length - 1], "index"); return children[index]; } _getWriterWithIndentation() { const writer = this._getWriter(); writer.setIndentationLevel(this.getIndentationLevel()); return writer; } _getWriterWithQueuedIndentation() { const writer = this._getWriter(); writer.queueIndentationLevel(this.getIndentationLevel()); return writer; } _getWriterWithChildIndentation() { const writer = this._getWriter(); writer.setIndentationLevel(this.getChildIndentationLevel()); return writer; } _getWriterWithQueuedChildIndentation() { const writer = this._getWriter(); writer.queueIndentationLevel(this.getChildIndentationLevel()); return writer; } _getTextWithQueuedChildIndentation(textOrWriterFunc) { const writer = this._getWriterWithQueuedChildIndentation(); if (typeof textOrWriterFunc === "string") writer.write(textOrWriterFunc); else textOrWriterFunc(writer); return writer.toString(); } _getWriter() { return this._context.createWriter(); } _getNodeFromCompilerNode(compilerNode) { return this._context.compilerFactory.getNodeFromCompilerNode(compilerNode, this._sourceFile); } _getNodeFromCompilerNodeIfExists(compilerNode) { return compilerNode == null ? undefined : this._getNodeFromCompilerNode(compilerNode); } _ensureBound() { if (this.compilerNode.symbol != null) return; this.getSymbol(); } static hasExpression(node) { return node.getExpression?.() != null; } static hasName(node) { return typeof node.getName?.() === "string"; } static hasBody(node) { return node.getBody?.() != null; } static hasStructure(node) { return typeof node.getStructure === "function"; } static is(kind) { return (node) => { return node?.getKind() == kind; }; } static isNode(value) { return value != null && value.compilerNode != null; } static isCommentNode(node) { const kind = node?.getKind(); return kind === common.SyntaxKind.SingleLineCommentTrivia || kind === common.SyntaxKind.MultiLineCommentTrivia; } static isCommentStatement(node) { return node?.compilerNode?._commentKind === exports.CommentNodeKind.Statement; } static isCommentClassElement(node) { return node?.compilerNode?._commentKind === exports.CommentNodeKind.ClassElement; } static isCommentTypeElement(node) { return node?.compilerNode?._commentKind === exports.CommentNodeKind.TypeElement; } static isCommentObjectLiteralElement(node) { return node?.compilerNode?._commentKind === exports.CommentNodeKind.ObjectLiteralElement; } static isCommentEnumMember(node) { return node?.compilerNode?._commentKind == exports.CommentNodeKind.EnumMember; } static isAbstractable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.ConstructorType: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isAmbientable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.VariableStatement: return true; default: return false; } } static isAnyKeyword = Node.is(common.SyntaxKind.AnyKeyword); static isArgumented(node) { switch (node?.getKind()) { case common.SyntaxKind.CallExpression: case common.SyntaxKind.NewExpression: return true; default: return false; } } static isArrayBindingPattern = Node.is(common.SyntaxKind.ArrayBindingPattern); static isArrayLiteralExpression = Node.is(common.SyntaxKind.ArrayLiteralExpression); static isArrayTypeNode(node) { return node?.getKind() === common.SyntaxKind.ArrayType; } static isArrowFunction = Node.is(common.SyntaxKind.ArrowFunction); static isAsExpression = Node.is(common.SyntaxKind.AsExpression); static isAsyncable(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.MethodDeclaration: return true; default: return false; } } static isAwaitable(node) { return node?.getKind() === common.SyntaxKind.ForOfStatement; } static isAwaitExpression = Node.is(common.SyntaxKind.AwaitExpression); static isBigIntLiteral = Node.is(common.SyntaxKind.BigIntLiteral); static isBinaryExpression = Node.is(common.SyntaxKind.BinaryExpression); static isBindingElement = Node.is(common.SyntaxKind.BindingElement); static isBindingNamed(node) { switch (node?.getKind()) { case common.SyntaxKind.BindingElement: case common.SyntaxKind.Parameter: case common.SyntaxKind.VariableDeclaration: return true; default: return false; } } static isBlock = Node.is(common.SyntaxKind.Block); static isBodied(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.ClassStaticBlockDeclaration: case common.SyntaxKind.FunctionExpression: return true; default: return false; } } static isBodyable(node) { switch (node?.getKind()) { case common.SyntaxKind.Constructor: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isBooleanKeyword = Node.is(common.SyntaxKind.BooleanKeyword); static isBreakStatement = Node.is(common.SyntaxKind.BreakStatement); static isCallExpression = Node.is(common.SyntaxKind.CallExpression); static isCallSignatureDeclaration(node) { return node?.getKind() === common.SyntaxKind.CallSignature; } static isCaseBlock = Node.is(common.SyntaxKind.CaseBlock); static isCaseClause = Node.is(common.SyntaxKind.CaseClause); static isCatchClause = Node.is(common.SyntaxKind.CatchClause); static isChildOrderable(node) { switch (node?.getKind()) { case common.SyntaxKind.Block: case common.SyntaxKind.BreakStatement: case common.SyntaxKind.CallSignature: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassStaticBlockDeclaration: case common.SyntaxKind.Constructor: case common.SyntaxKind.ConstructSignature: case common.SyntaxKind.ContinueStatement: case common.SyntaxKind.DebuggerStatement: case common.SyntaxKind.DoStatement: case common.SyntaxKind.EmptyStatement: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.ExportAssignment: case common.SyntaxKind.ExportDeclaration: case common.SyntaxKind.ExpressionStatement: case common.SyntaxKind.ForInStatement: case common.SyntaxKind.ForOfStatement: case common.SyntaxKind.ForStatement: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.IfStatement: case common.SyntaxKind.ImportDeclaration: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.IndexSignature: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.LabeledStatement: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.ModuleBlock: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.NotEmittedStatement: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.ReturnStatement: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.SwitchStatement: case common.SyntaxKind.ThrowStatement: case common.SyntaxKind.TryStatement: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.VariableStatement: case common.SyntaxKind.WhileStatement: case common.SyntaxKind.WithStatement: return true; default: return false; } } static isClassDeclaration = Node.is(common.SyntaxKind.ClassDeclaration); static isClassExpression = Node.is(common.SyntaxKind.ClassExpression); static isClassLikeDeclarationBase(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: return true; default: return false; } } static isClassStaticBlockDeclaration = Node.is(common.SyntaxKind.ClassStaticBlockDeclaration); static isCommaListExpression = Node.is(common.SyntaxKind.CommaListExpression); static isComputedPropertyName = Node.is(common.SyntaxKind.ComputedPropertyName); static isConditionalExpression = Node.is(common.SyntaxKind.ConditionalExpression); static isConditionalTypeNode(node) { return node?.getKind() === common.SyntaxKind.ConditionalType; } static isConstructorDeclaration(node) { return node?.getKind() === common.SyntaxKind.Constructor; } static isConstructorTypeNode(node) { return node?.getKind() === common.SyntaxKind.ConstructorType; } static isConstructSignatureDeclaration(node) { return node?.getKind() === common.SyntaxKind.ConstructSignature; } static isContinueStatement = Node.is(common.SyntaxKind.ContinueStatement); static isDebuggerStatement = Node.is(common.SyntaxKind.DebuggerStatement); static isDecoratable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isDecorator = Node.is(common.SyntaxKind.Decorator); static isDefaultClause = Node.is(common.SyntaxKind.DefaultClause); static isDeleteExpression = Node.is(common.SyntaxKind.DeleteExpression); static isDoStatement = Node.is(common.SyntaxKind.DoStatement); static isDotDotDotTokenable(node) { switch (node?.getKind()) { case common.SyntaxKind.BindingElement: case common.SyntaxKind.JsxExpression: case common.SyntaxKind.NamedTupleMember: case common.SyntaxKind.Parameter: return true; default: return false; } } static isElementAccessExpression = Node.is(common.SyntaxKind.ElementAccessExpression); static isEmptyStatement = Node.is(common.SyntaxKind.EmptyStatement); static isEnumDeclaration = Node.is(common.SyntaxKind.EnumDeclaration); static isEnumMember = Node.is(common.SyntaxKind.EnumMember); static isExclamationTokenable(node) { switch (node?.getKind()) { case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.VariableDeclaration: return true; default: return false; } } static isExportable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.VariableStatement: return true; default: return false; } } static isExportAssignment = Node.is(common.SyntaxKind.ExportAssignment); static isExportDeclaration = Node.is(common.SyntaxKind.ExportDeclaration); static isExportGetable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.VariableDeclaration: case common.SyntaxKind.VariableStatement: return true; default: return false; } } static isExportSpecifier = Node.is(common.SyntaxKind.ExportSpecifier); static isExpression(node) { switch (node?.getKind()) { case common.SyntaxKind.AnyKeyword: case common.SyntaxKind.BooleanKeyword: case common.SyntaxKind.NumberKeyword: case common.SyntaxKind.ObjectKeyword: case common.SyntaxKind.StringKeyword: case common.SyntaxKind.SymbolKeyword: case common.SyntaxKind.UndefinedKeyword: case common.SyntaxKind.ArrayLiteralExpression: case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.AsExpression: case common.SyntaxKind.AwaitExpression: case common.SyntaxKind.BigIntLiteral: case common.SyntaxKind.BinaryExpression: case common.SyntaxKind.CallExpression: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.CommaListExpression: case common.SyntaxKind.ConditionalExpression: case common.SyntaxKind.DeleteExpression: case common.SyntaxKind.ElementAccessExpression: case common.SyntaxKind.FalseKeyword: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.Identifier: case common.SyntaxKind.ImportKeyword: case common.SyntaxKind.JsxClosingFragment: case common.SyntaxKind.JsxElement: case common.SyntaxKind.JsxExpression: case common.SyntaxKind.JsxFragment: case common.SyntaxKind.JsxOpeningElement: case common.SyntaxKind.JsxOpeningFragment: case common.SyntaxKind.JsxSelfClosingElement: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.NewExpression: case common.SyntaxKind.NonNullExpression: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.NullKeyword: case common.SyntaxKind.NumericLiteral: case common.SyntaxKind.ObjectLiteralExpression: case common.SyntaxKind.OmittedExpression: case common.SyntaxKind.ParenthesizedExpression: case common.SyntaxKind.PartiallyEmittedExpression: case common.SyntaxKind.PostfixUnaryExpression: case common.SyntaxKind.PrefixUnaryExpression: case common.SyntaxKind.PropertyAccessExpression: case common.SyntaxKind.RegularExpressionLiteral: case common.SyntaxKind.SatisfiesExpression: case common.SyntaxKind.SpreadElement: case common.SyntaxKind.StringLiteral: case common.SyntaxKind.SuperKeyword: case common.SyntaxKind.TaggedTemplateExpression: case common.SyntaxKind.TemplateExpression: case common.SyntaxKind.ThisKeyword: case common.SyntaxKind.TrueKeyword: case common.SyntaxKind.TypeAssertionExpression: case common.SyntaxKind.TypeOfExpression: case common.SyntaxKind.VoidExpression: case common.SyntaxKind.YieldExpression: return true; default: return false; } } static isExpressionable(node) { switch (node?.getKind()) { case common.SyntaxKind.ExternalModuleReference: case common.SyntaxKind.JsxExpression: case common.SyntaxKind.ReturnStatement: case common.SyntaxKind.YieldExpression: return true; default: return false; } } static isExpressioned(node) { switch (node?.getKind()) { case common.SyntaxKind.AsExpression: case common.SyntaxKind.CaseClause: case common.SyntaxKind.ComputedPropertyName: case common.SyntaxKind.DoStatement: case common.SyntaxKind.ExportAssignment: case common.SyntaxKind.ExpressionStatement: case common.SyntaxKind.ForInStatement: case common.SyntaxKind.ForOfStatement: case common.SyntaxKind.IfStatement: case common.SyntaxKind.JsxSpreadAttribute: case common.SyntaxKind.NonNullExpression: case common.SyntaxKind.ParenthesizedExpression: case common.SyntaxKind.PartiallyEmittedExpression: case common.SyntaxKind.SatisfiesExpression: case common.SyntaxKind.SpreadAssignment: case common.SyntaxKind.SpreadElement: case common.SyntaxKind.SwitchStatement: case common.SyntaxKind.TemplateSpan: case common.SyntaxKind.ThrowStatement: case common.SyntaxKind.WhileStatement: case common.SyntaxKind.WithStatement: return true; default: return false; } } static isExpressionStatement = Node.is(common.SyntaxKind.ExpressionStatement); static isExpressionWithTypeArguments = Node.is(common.SyntaxKind.ExpressionWithTypeArguments); static isExtendsClauseable(node) { return node?.getKind() === common.SyntaxKind.InterfaceDeclaration; } static isExternalModuleReference = Node.is(common.SyntaxKind.ExternalModuleReference); static isFalseLiteral(node) { return node?.getKind() === common.SyntaxKind.FalseKeyword; } static isForInStatement = Node.is(common.SyntaxKind.ForInStatement); static isForOfStatement = Node.is(common.SyntaxKind.ForOfStatement); static isForStatement = Node.is(common.SyntaxKind.ForStatement); static isFunctionDeclaration = Node.is(common.SyntaxKind.FunctionDeclaration); static isFunctionExpression = Node.is(common.SyntaxKind.FunctionExpression); static isFunctionLikeDeclaration(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.Constructor: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isFunctionTypeNode(node) { return node?.getKind() === common.SyntaxKind.FunctionType; } static isGeneratorable(node) { switch (node?.getKind()) { case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.YieldExpression: return true; default: return false; } } static isGetAccessorDeclaration(node) { return node?.getKind() === common.SyntaxKind.GetAccessor; } static isHeritageClause = Node.is(common.SyntaxKind.HeritageClause); static isHeritageClauseable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.InterfaceDeclaration: return true; default: return false; } } static isIdentifier = Node.is(common.SyntaxKind.Identifier); static isIfStatement = Node.is(common.SyntaxKind.IfStatement); static isImplementsClauseable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: return true; default: return false; } } static isImportAttribute = Node.is(common.SyntaxKind.ImportAttribute); static isImportAttributeNamed(node) { return node?.getKind() === common.SyntaxKind.ImportAttribute; } static isImportAttributes = Node.is(common.SyntaxKind.ImportAttributes); static isImportClause = Node.is(common.SyntaxKind.ImportClause); static isImportDeclaration = Node.is(common.SyntaxKind.ImportDeclaration); static isImportEqualsDeclaration = Node.is(common.SyntaxKind.ImportEqualsDeclaration); static isImportExpression(node) { return node?.getKind() === common.SyntaxKind.ImportKeyword; } static isImportSpecifier = Node.is(common.SyntaxKind.ImportSpecifier); static isImportTypeNode(node) { return node?.getKind() === common.SyntaxKind.ImportType; } static isIndexedAccessTypeNode(node) { return node?.getKind() === common.SyntaxKind.IndexedAccessType; } static isIndexSignatureDeclaration(node) { return node?.getKind() === common.SyntaxKind.IndexSignature; } static isInferKeyword = Node.is(common.SyntaxKind.InferKeyword); static isInferTypeNode(node) { return node?.getKind() === common.SyntaxKind.InferType; } static isInitializerExpressionable(node) { switch (node?.getKind()) { case common.SyntaxKind.BindingElement: case common.SyntaxKind.EnumMember: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.VariableDeclaration: return true; default: return false; } } static isInitializerExpressionGetable(node) { switch (node?.getKind()) { case common.SyntaxKind.BindingElement: case common.SyntaxKind.EnumMember: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyAssignment: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.ShorthandPropertyAssignment: case common.SyntaxKind.VariableDeclaration: return true; default: return false; } } static isInterfaceDeclaration = Node.is(common.SyntaxKind.InterfaceDeclaration); static isIntersectionTypeNode(node) { return node?.getKind() === common.SyntaxKind.IntersectionType; } static isIterationStatement(node) { switch (node?.getKind()) { case common.SyntaxKind.DoStatement: case common.SyntaxKind.ForInStatement: case common.SyntaxKind.ForOfStatement: case common.SyntaxKind.ForStatement: case common.SyntaxKind.WhileStatement: return true; default: return false; } } static isJSDoc = Node.is(common.SyntaxKind.JSDoc); static isJSDocable(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.CallSignature: case common.SyntaxKind.CaseClause: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.ClassStaticBlockDeclaration: case common.SyntaxKind.Constructor: case common.SyntaxKind.ConstructSignature: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.EnumMember: case common.SyntaxKind.ExportAssignment: case common.SyntaxKind.ExpressionStatement: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.IndexSignature: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.LabeledStatement: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.NamedTupleMember: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.VariableStatement: return true; default: return false; } } static isJSDocAllType = Node.is(common.SyntaxKind.JSDocAllType); static isJSDocAugmentsTag = Node.is(common.SyntaxKind.JSDocAugmentsTag); static isJSDocAuthorTag = Node.is(common.SyntaxKind.JSDocAuthorTag); static isJSDocCallbackTag = Node.is(common.SyntaxKind.JSDocCallbackTag); static isJSDocClassTag = Node.is(common.SyntaxKind.JSDocClassTag); static isJSDocDeprecatedTag = Node.is(common.SyntaxKind.JSDocDeprecatedTag); static isJSDocEnumTag = Node.is(common.SyntaxKind.JSDocEnumTag); static isJSDocFunctionType = Node.is(common.SyntaxKind.JSDocFunctionType); static isJSDocImplementsTag = Node.is(common.SyntaxKind.JSDocImplementsTag); static isJSDocLink = Node.is(common.SyntaxKind.JSDocLink); static isJSDocLinkCode = Node.is(common.SyntaxKind.JSDocLinkCode); static isJSDocLinkPlain = Node.is(common.SyntaxKind.JSDocLinkPlain); static isJSDocMemberName = Node.is(common.SyntaxKind.JSDocMemberName); static isJSDocNamepathType = Node.is(common.SyntaxKind.JSDocNamepathType); static isJSDocNameReference = Node.is(common.SyntaxKind.JSDocNameReference); static isJSDocNonNullableType = Node.is(common.SyntaxKind.JSDocNonNullableType); static isJSDocNullableType = Node.is(common.SyntaxKind.JSDocNullableType); static isJSDocOptionalType = Node.is(common.SyntaxKind.JSDocOptionalType); static isJSDocOverloadTag = Node.is(common.SyntaxKind.JSDocOverloadTag); static isJSDocOverrideTag = Node.is(common.SyntaxKind.JSDocOverrideTag); static isJSDocParameterTag = Node.is(common.SyntaxKind.JSDocParameterTag); static isJSDocPrivateTag = Node.is(common.SyntaxKind.JSDocPrivateTag); static isJSDocPropertyLikeTag(node) { switch (node?.getKind()) { case common.SyntaxKind.JSDocParameterTag: case common.SyntaxKind.JSDocPropertyTag: return true; default: return false; } } static isJSDocPropertyTag = Node.is(common.SyntaxKind.JSDocPropertyTag); static isJSDocProtectedTag = Node.is(common.SyntaxKind.JSDocProtectedTag); static isJSDocPublicTag = Node.is(common.SyntaxKind.JSDocPublicTag); static isJSDocReadonlyTag = Node.is(common.SyntaxKind.JSDocReadonlyTag); static isJSDocReturnTag = Node.is(common.SyntaxKind.JSDocReturnTag); static isJSDocSatisfiesTag = Node.is(common.SyntaxKind.JSDocSatisfiesTag); static isJSDocSeeTag = Node.is(common.SyntaxKind.JSDocSeeTag); static isJSDocSignature = Node.is(common.SyntaxKind.JSDocSignature); static isJSDocTag(node) { switch (node?.getKind()) { case common.SyntaxKind.JSDocAugmentsTag: case common.SyntaxKind.JSDocAuthorTag: case common.SyntaxKind.JSDocCallbackTag: case common.SyntaxKind.JSDocClassTag: case common.SyntaxKind.JSDocDeprecatedTag: case common.SyntaxKind.JSDocEnumTag: case common.SyntaxKind.JSDocImplementsTag: case common.SyntaxKind.JSDocOverloadTag: case common.SyntaxKind.JSDocOverrideTag: case common.SyntaxKind.JSDocParameterTag: case common.SyntaxKind.JSDocPrivateTag: case common.SyntaxKind.JSDocPropertyTag: case common.SyntaxKind.JSDocProtectedTag: case common.SyntaxKind.JSDocPublicTag: case common.SyntaxKind.JSDocReadonlyTag: case common.SyntaxKind.JSDocReturnTag: case common.SyntaxKind.JSDocSatisfiesTag: case common.SyntaxKind.JSDocSeeTag: case common.SyntaxKind.JSDocTemplateTag: case common.SyntaxKind.JSDocThisTag: case common.SyntaxKind.JSDocThrowsTag: case common.SyntaxKind.JSDocTypedefTag: case common.SyntaxKind.JSDocTypeTag: case common.SyntaxKind.JSDocTag: return true; default: return false; } } static isJSDocTemplateTag = Node.is(common.SyntaxKind.JSDocTemplateTag); static isJSDocText = Node.is(common.SyntaxKind.JSDocText); static isJSDocThisTag = Node.is(common.SyntaxKind.JSDocThisTag); static isJSDocThrowsTag = Node.is(common.SyntaxKind.JSDocThrowsTag); static isJSDocType(node) { switch (node?.getKind()) { case common.SyntaxKind.JSDocAllType: case common.SyntaxKind.JSDocFunctionType: case common.SyntaxKind.JSDocNamepathType: case common.SyntaxKind.JSDocNonNullableType: case common.SyntaxKind.JSDocNullableType: case common.SyntaxKind.JSDocOptionalType: case common.SyntaxKind.JSDocSignature: case common.SyntaxKind.JSDocTypeLiteral: case common.SyntaxKind.JSDocUnknownType: case common.SyntaxKind.JSDocVariadicType: return true; default: return false; } } static isJSDocTypedefTag = Node.is(common.SyntaxKind.JSDocTypedefTag); static isJSDocTypeExpression = Node.is(common.SyntaxKind.JSDocTypeExpression); static isJSDocTypeExpressionableTag(node) { switch (node?.getKind()) { case common.SyntaxKind.JSDocOverloadTag: case common.SyntaxKind.JSDocReturnTag: case common.SyntaxKind.JSDocSatisfiesTag: case common.SyntaxKind.JSDocSeeTag: case common.SyntaxKind.JSDocThisTag: case common.SyntaxKind.JSDocThrowsTag: return true; default: return false; } } static isJSDocTypeLiteral = Node.is(common.SyntaxKind.JSDocTypeLiteral); static isJSDocTypeParameteredTag(node) { return node?.getKind() === common.SyntaxKind.JSDocTemplateTag; } static isJSDocTypeTag = Node.is(common.SyntaxKind.JSDocTypeTag); static isJSDocUnknownTag(node) { return node?.getKind() === common.SyntaxKind.JSDocTag; } static isJSDocUnknownType = Node.is(common.SyntaxKind.JSDocUnknownType); static isJSDocVariadicType = Node.is(common.SyntaxKind.JSDocVariadicType); static isJsxAttribute = Node.is(common.SyntaxKind.JsxAttribute); static isJsxAttributed(node) { switch (node?.getKind()) { case common.SyntaxKind.JsxOpeningElement: case common.SyntaxKind.JsxSelfClosingElement: return true; default: return false; } } static isJsxClosingElement = Node.is(common.SyntaxKind.JsxClosingElement); static isJsxClosingFragment = Node.is(common.SyntaxKind.JsxClosingFragment); static isJsxElement = Node.is(common.SyntaxKind.JsxElement); static isJsxExpression = Node.is(common.SyntaxKind.JsxExpression); static isJsxFragment = Node.is(common.SyntaxKind.JsxFragment); static isJsxNamespacedName = Node.is(common.SyntaxKind.JsxNamespacedName); static isJsxOpeningElement = Node.is(common.SyntaxKind.JsxOpeningElement); static isJsxOpeningFragment = Node.is(common.SyntaxKind.JsxOpeningFragment); static isJsxSelfClosingElement = Node.is(common.SyntaxKind.JsxSelfClosingElement); static isJsxSpreadAttribute = Node.is(common.SyntaxKind.JsxSpreadAttribute); static isJsxTagNamed(node) { switch (node?.getKind()) { case common.SyntaxKind.JsxClosingElement: case common.SyntaxKind.JsxOpeningElement: case common.SyntaxKind.JsxSelfClosingElement: return true; default: return false; } } static isJsxText = Node.is(common.SyntaxKind.JsxText); static isLabeledStatement = Node.is(common.SyntaxKind.LabeledStatement); static isLeftHandSideExpression(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrayLiteralExpression: case common.SyntaxKind.BigIntLiteral: case common.SyntaxKind.CallExpression: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.ElementAccessExpression: case common.SyntaxKind.FalseKeyword: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.Identifier: case common.SyntaxKind.ImportKeyword: case common.SyntaxKind.JsxElement: case common.SyntaxKind.JsxFragment: case common.SyntaxKind.JsxSelfClosingElement: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.NewExpression: case common.SyntaxKind.NonNullExpression: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.NullKeyword: case common.SyntaxKind.NumericLiteral: case common.SyntaxKind.ObjectLiteralExpression: case common.SyntaxKind.PropertyAccessExpression: case common.SyntaxKind.RegularExpressionLiteral: case common.SyntaxKind.StringLiteral: case common.SyntaxKind.SuperKeyword: case common.SyntaxKind.TaggedTemplateExpression: case common.SyntaxKind.TemplateExpression: case common.SyntaxKind.ThisKeyword: case common.SyntaxKind.TrueKeyword: return true; default: return false; } } static isLeftHandSideExpressioned(node) { switch (node?.getKind()) { case common.SyntaxKind.CallExpression: case common.SyntaxKind.Decorator: case common.SyntaxKind.ElementAccessExpression: case common.SyntaxKind.ExpressionWithTypeArguments: case common.SyntaxKind.NewExpression: case common.SyntaxKind.PropertyAccessExpression: return true; default: return false; } } static isLiteralExpression(node) { switch (node?.getKind()) { case common.SyntaxKind.BigIntLiteral: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.NumericLiteral: case common.SyntaxKind.RegularExpressionLiteral: case common.SyntaxKind.StringLiteral: return true; default: return false; } } static isLiteralLike(node) { switch (node?.getKind()) { case common.SyntaxKind.BigIntLiteral: case common.SyntaxKind.JsxText: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.NumericLiteral: case common.SyntaxKind.RegularExpressionLiteral: case common.SyntaxKind.StringLiteral: case common.SyntaxKind.TemplateHead: case common.SyntaxKind.TemplateMiddle: case common.SyntaxKind.TemplateTail: return true; default: return false; } } static isLiteralTypeNode(node) { return node?.getKind() === common.SyntaxKind.LiteralType; } static isMappedTypeNode(node) { return node?.getKind() === common.SyntaxKind.MappedType; } static isMemberExpression(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrayLiteralExpression: case common.SyntaxKind.BigIntLiteral: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.ElementAccessExpression: case common.SyntaxKind.FalseKeyword: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.Identifier: case common.SyntaxKind.ImportKeyword: case common.SyntaxKind.JsxElement: case common.SyntaxKind.JsxFragment: case common.SyntaxKind.JsxSelfClosingElement: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.NewExpression: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.NullKeyword: case common.SyntaxKind.NumericLiteral: case common.SyntaxKind.ObjectLiteralExpression: case common.SyntaxKind.PropertyAccessExpression: case common.SyntaxKind.RegularExpressionLiteral: case common.SyntaxKind.StringLiteral: case common.SyntaxKind.SuperKeyword: case common.SyntaxKind.TaggedTemplateExpression: case common.SyntaxKind.TemplateExpression: case common.SyntaxKind.ThisKeyword: case common.SyntaxKind.TrueKeyword: return true; default: return false; } } static isMetaProperty = Node.is(common.SyntaxKind.MetaProperty); static isMethodDeclaration = Node.is(common.SyntaxKind.MethodDeclaration); static isMethodSignature = Node.is(common.SyntaxKind.MethodSignature); static isModifierable(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.Constructor: case common.SyntaxKind.ConstructorType: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.IndexSignature: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.TypeParameter: case common.SyntaxKind.VariableDeclarationList: case common.SyntaxKind.VariableStatement: return true; default: return false; } } static isModuleBlock = Node.is(common.SyntaxKind.ModuleBlock); static isModuleChildable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.VariableStatement: return true; default: return false; } } static isModuleDeclaration = Node.is(common.SyntaxKind.ModuleDeclaration); static isModuled(node) { switch (node?.getKind()) { case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.SourceFile: return true; default: return false; } } static isModuleNamed(node) { return node?.getKind() === common.SyntaxKind.ModuleDeclaration; } static isNameable(node) { switch (node?.getKind()) { case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: return true; default: return false; } } static isNamedExports = Node.is(common.SyntaxKind.NamedExports); static isNamedImports = Node.is(common.SyntaxKind.NamedImports); static isNamed(node) { switch (node?.getKind()) { case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.NamedTupleMember: case common.SyntaxKind.PropertyAccessExpression: case common.SyntaxKind.ShorthandPropertyAssignment: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.TypeParameter: return true; default: return false; } } static isNamedTupleMember = Node.is(common.SyntaxKind.NamedTupleMember); static isNamespaceExport = Node.is(common.SyntaxKind.NamespaceExport); static isNamespaceImport = Node.is(common.SyntaxKind.NamespaceImport); static isNeverKeyword = Node.is(common.SyntaxKind.NeverKeyword); static isNewExpression = Node.is(common.SyntaxKind.NewExpression); static isNodeWithTypeArguments(node) { switch (node?.getKind()) { case common.SyntaxKind.ExpressionWithTypeArguments: case common.SyntaxKind.ImportType: case common.SyntaxKind.TypeQuery: case common.SyntaxKind.TypeReference: return true; default: return false; } } static isNonNullExpression = Node.is(common.SyntaxKind.NonNullExpression); static isNoSubstitutionTemplateLiteral = Node.is(common.SyntaxKind.NoSubstitutionTemplateLiteral); static isNotEmittedStatement = Node.is(common.SyntaxKind.NotEmittedStatement); static isNullLiteral(node) { return node?.getKind() === common.SyntaxKind.NullKeyword; } static isNumberKeyword = Node.is(common.SyntaxKind.NumberKeyword); static isNumericLiteral = Node.is(common.SyntaxKind.NumericLiteral); static isObjectBindingPattern = Node.is(common.SyntaxKind.ObjectBindingPattern); static isObjectKeyword = Node.is(common.SyntaxKind.ObjectKeyword); static isObjectLiteralExpression = Node.is(common.SyntaxKind.ObjectLiteralExpression); static isOmittedExpression = Node.is(common.SyntaxKind.OmittedExpression); static isOverloadable(node) { switch (node?.getKind()) { case common.SyntaxKind.Constructor: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.MethodDeclaration: return true; default: return false; } } static isOverrideable(node) { switch (node?.getKind()) { case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyDeclaration: return true; default: return false; } } static isParameterDeclaration(node) { return node?.getKind() === common.SyntaxKind.Parameter; } static isParametered(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.CallSignature: case common.SyntaxKind.Constructor: case common.SyntaxKind.ConstructorType: case common.SyntaxKind.ConstructSignature: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.FunctionType: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.JSDocFunctionType: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isParenthesizedExpression = Node.is(common.SyntaxKind.ParenthesizedExpression); static isParenthesizedTypeNode(node) { return node?.getKind() === common.SyntaxKind.ParenthesizedType; } static isPartiallyEmittedExpression = Node.is(common.SyntaxKind.PartiallyEmittedExpression); static isPostfixUnaryExpression = Node.is(common.SyntaxKind.PostfixUnaryExpression); static isPrefixUnaryExpression = Node.is(common.SyntaxKind.PrefixUnaryExpression); static isPrimaryExpression(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrayLiteralExpression: case common.SyntaxKind.BigIntLiteral: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.FalseKeyword: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.Identifier: case common.SyntaxKind.ImportKeyword: case common.SyntaxKind.JsxElement: case common.SyntaxKind.JsxFragment: case common.SyntaxKind.JsxSelfClosingElement: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.NewExpression: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.NullKeyword: case common.SyntaxKind.NumericLiteral: case common.SyntaxKind.ObjectLiteralExpression: case common.SyntaxKind.RegularExpressionLiteral: case common.SyntaxKind.StringLiteral: case common.SyntaxKind.SuperKeyword: case common.SyntaxKind.TemplateExpression: case common.SyntaxKind.ThisKeyword: case common.SyntaxKind.TrueKeyword: return true; default: return false; } } static isPrivateIdentifier = Node.is(common.SyntaxKind.PrivateIdentifier); static isPropertyAccessExpression = Node.is(common.SyntaxKind.PropertyAccessExpression); static isPropertyAssignment = Node.is(common.SyntaxKind.PropertyAssignment); static isPropertyDeclaration = Node.is(common.SyntaxKind.PropertyDeclaration); static isPropertyNamed(node) { switch (node?.getKind()) { case common.SyntaxKind.EnumMember: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.PropertyAssignment: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isPropertySignature = Node.is(common.SyntaxKind.PropertySignature); static isQualifiedName = Node.is(common.SyntaxKind.QualifiedName); static isQuestionDotTokenable(node) { switch (node?.getKind()) { case common.SyntaxKind.CallExpression: case common.SyntaxKind.ElementAccessExpression: case common.SyntaxKind.PropertyAccessExpression: return true; default: return false; } } static isQuestionTokenable(node) { switch (node?.getKind()) { case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.NamedTupleMember: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyAssignment: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.ShorthandPropertyAssignment: return true; default: return false; } } static isReadonlyable(node) { switch (node?.getKind()) { case common.SyntaxKind.IndexSignature: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: return true; default: return false; } } static isReferenceFindable(node) { switch (node?.getKind()) { case common.SyntaxKind.BindingElement: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.Constructor: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.EnumMember: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.Identifier: case common.SyntaxKind.ImportAttribute: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.NamedTupleMember: case common.SyntaxKind.Parameter: case common.SyntaxKind.PrivateIdentifier: case common.SyntaxKind.PropertyAccessExpression: case common.SyntaxKind.PropertyAssignment: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.ShorthandPropertyAssignment: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.TypeParameter: case common.SyntaxKind.VariableDeclaration: return true; default: return false; } } static isRegularExpressionLiteral = Node.is(common.SyntaxKind.RegularExpressionLiteral); static isRenameable(node) { switch (node?.getKind()) { case common.SyntaxKind.BindingElement: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.EnumMember: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.Identifier: case common.SyntaxKind.ImportAttribute: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.NamedTupleMember: case common.SyntaxKind.NamespaceExport: case common.SyntaxKind.NamespaceImport: case common.SyntaxKind.Parameter: case common.SyntaxKind.PrivateIdentifier: case common.SyntaxKind.PropertyAccessExpression: case common.SyntaxKind.PropertyAssignment: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.ShorthandPropertyAssignment: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.TypeParameter: case common.SyntaxKind.VariableDeclaration: return true; default: return false; } } static isRestTypeNode(node) { return node?.getKind() === common.SyntaxKind.RestType; } static isReturnStatement = Node.is(common.SyntaxKind.ReturnStatement); static isReturnTyped(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.CallSignature: case common.SyntaxKind.Constructor: case common.SyntaxKind.ConstructorType: case common.SyntaxKind.ConstructSignature: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.FunctionType: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.IndexSignature: case common.SyntaxKind.JSDocFunctionType: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isSatisfiesExpression = Node.is(common.SyntaxKind.SatisfiesExpression); static isScopeable(node) { return node?.getKind() === common.SyntaxKind.Parameter; } static isScoped(node) { switch (node?.getKind()) { case common.SyntaxKind.Constructor: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isSemicolonToken = Node.is(common.SyntaxKind.SemicolonToken); static isSetAccessorDeclaration(node) { return node?.getKind() === common.SyntaxKind.SetAccessor; } static isShorthandPropertyAssignment = Node.is(common.SyntaxKind.ShorthandPropertyAssignment); static isSignaturedDeclaration(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.CallSignature: case common.SyntaxKind.Constructor: case common.SyntaxKind.ConstructorType: case common.SyntaxKind.ConstructSignature: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.FunctionType: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.JSDocFunctionType: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isSourceFile = Node.is(common.SyntaxKind.SourceFile); static isSpreadAssignment = Node.is(common.SyntaxKind.SpreadAssignment); static isSpreadElement = Node.is(common.SyntaxKind.SpreadElement); static isStatement(node) { switch (node?.getKind()) { case common.SyntaxKind.Block: case common.SyntaxKind.BreakStatement: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ContinueStatement: case common.SyntaxKind.DebuggerStatement: case common.SyntaxKind.DoStatement: case common.SyntaxKind.EmptyStatement: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.ExportAssignment: case common.SyntaxKind.ExportDeclaration: case common.SyntaxKind.ExpressionStatement: case common.SyntaxKind.ForInStatement: case common.SyntaxKind.ForOfStatement: case common.SyntaxKind.ForStatement: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.IfStatement: case common.SyntaxKind.ImportDeclaration: case common.SyntaxKind.ImportEqualsDeclaration: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.LabeledStatement: case common.SyntaxKind.ModuleBlock: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.NotEmittedStatement: case common.SyntaxKind.ReturnStatement: case common.SyntaxKind.SwitchStatement: case common.SyntaxKind.ThrowStatement: case common.SyntaxKind.TryStatement: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.VariableStatement: case common.SyntaxKind.WhileStatement: case common.SyntaxKind.WithStatement: return true; default: return false; } } static isStatemented(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.Block: case common.SyntaxKind.CaseClause: case common.SyntaxKind.ClassStaticBlockDeclaration: case common.SyntaxKind.Constructor: case common.SyntaxKind.DefaultClause: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.ModuleBlock: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.SourceFile: return true; default: return false; } } static isStaticable(node) { switch (node?.getKind()) { case common.SyntaxKind.GetAccessor: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.SetAccessor: return true; default: return false; } } static isStringKeyword = Node.is(common.SyntaxKind.StringKeyword); static isStringLiteral = Node.is(common.SyntaxKind.StringLiteral); static isSuperExpression(node) { return node?.getKind() === common.SyntaxKind.SuperKeyword; } static isSwitchStatement = Node.is(common.SyntaxKind.SwitchStatement); static isSymbolKeyword = Node.is(common.SyntaxKind.SymbolKeyword); static isSyntaxList = Node.is(common.SyntaxKind.SyntaxList); static isTaggedTemplateExpression = Node.is(common.SyntaxKind.TaggedTemplateExpression); static isTemplateExpression = Node.is(common.SyntaxKind.TemplateExpression); static isTemplateHead = Node.is(common.SyntaxKind.TemplateHead); static isTemplateLiteralTypeNode(node) { return node?.getKind() === common.SyntaxKind.TemplateLiteralType; } static isTemplateMiddle = Node.is(common.SyntaxKind.TemplateMiddle); static isTemplateSpan = Node.is(common.SyntaxKind.TemplateSpan); static isTemplateTail = Node.is(common.SyntaxKind.TemplateTail); static isTextInsertable(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.Block: case common.SyntaxKind.CaseBlock: case common.SyntaxKind.CaseClause: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.ClassStaticBlockDeclaration: case common.SyntaxKind.Constructor: case common.SyntaxKind.DefaultClause: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.SourceFile: return true; default: return false; } } static isThisExpression(node) { return node?.getKind() === common.SyntaxKind.ThisKeyword; } static isThisTypeNode(node) { return node?.getKind() === common.SyntaxKind.ThisType; } static isThrowStatement = Node.is(common.SyntaxKind.ThrowStatement); static isTrueLiteral(node) { return node?.getKind() === common.SyntaxKind.TrueKeyword; } static isTryStatement = Node.is(common.SyntaxKind.TryStatement); static isTupleTypeNode(node) { return node?.getKind() === common.SyntaxKind.TupleType; } static isTypeAliasDeclaration = Node.is(common.SyntaxKind.TypeAliasDeclaration); static isTypeArgumented(node) { switch (node?.getKind()) { case common.SyntaxKind.CallExpression: case common.SyntaxKind.ExpressionWithTypeArguments: case common.SyntaxKind.ImportType: case common.SyntaxKind.NewExpression: case common.SyntaxKind.TypeQuery: case common.SyntaxKind.TypeReference: return true; default: return false; } } static isTypeAssertion(node) { return node?.getKind() === common.SyntaxKind.TypeAssertionExpression; } static isTyped(node) { switch (node?.getKind()) { case common.SyntaxKind.AsExpression: case common.SyntaxKind.NamedTupleMember: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.SatisfiesExpression: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.TypeAssertionExpression: case common.SyntaxKind.VariableDeclaration: return true; default: return false; } } static isTypeElement(node) { switch (node?.getKind()) { case common.SyntaxKind.CallSignature: case common.SyntaxKind.ConstructSignature: case common.SyntaxKind.IndexSignature: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.PropertySignature: return true; default: return false; } } static isTypeElementMembered(node) { switch (node?.getKind()) { case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.TypeLiteral: return true; default: return false; } } static isTypeLiteral(node) { return node?.getKind() === common.SyntaxKind.TypeLiteral; } static isTypeNode(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrayType: case common.SyntaxKind.ConditionalType: case common.SyntaxKind.ConstructorType: case common.SyntaxKind.ExpressionWithTypeArguments: case common.SyntaxKind.FunctionType: case common.SyntaxKind.ImportType: case common.SyntaxKind.IndexedAccessType: case common.SyntaxKind.InferType: case common.SyntaxKind.IntersectionType: case common.SyntaxKind.JSDocAllType: case common.SyntaxKind.JSDocFunctionType: case common.SyntaxKind.JSDocNamepathType: case common.SyntaxKind.JSDocNonNullableType: case common.SyntaxKind.JSDocNullableType: case common.SyntaxKind.JSDocOptionalType: case common.SyntaxKind.JSDocSignature: case common.SyntaxKind.JSDocTypeExpression: case common.SyntaxKind.JSDocTypeLiteral: case common.SyntaxKind.JSDocUnknownType: case common.SyntaxKind.JSDocVariadicType: case common.SyntaxKind.LiteralType: case common.SyntaxKind.MappedType: case common.SyntaxKind.NamedTupleMember: case common.SyntaxKind.ParenthesizedType: case common.SyntaxKind.RestType: case common.SyntaxKind.TemplateLiteralType: case common.SyntaxKind.ThisType: case common.SyntaxKind.TupleType: case common.SyntaxKind.TypeLiteral: case common.SyntaxKind.TypeOperator: case common.SyntaxKind.TypePredicate: case common.SyntaxKind.TypeQuery: case common.SyntaxKind.TypeReference: case common.SyntaxKind.UnionType: return true; default: return false; } } static isTypeOfExpression = Node.is(common.SyntaxKind.TypeOfExpression); static isTypeOperatorTypeNode(node) { return node?.getKind() === common.SyntaxKind.TypeOperator; } static isTypeParameterDeclaration(node) { return node?.getKind() === common.SyntaxKind.TypeParameter; } static isTypeParametered(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrowFunction: case common.SyntaxKind.CallSignature: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.Constructor: case common.SyntaxKind.ConstructSignature: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.FunctionType: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.TypeAliasDeclaration: return true; default: return false; } } static isTypePredicate(node) { return node?.getKind() === common.SyntaxKind.TypePredicate; } static isTypeQuery(node) { return node?.getKind() === common.SyntaxKind.TypeQuery; } static isTypeReference(node) { return node?.getKind() === common.SyntaxKind.TypeReference; } static isUnaryExpression(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrayLiteralExpression: case common.SyntaxKind.AwaitExpression: case common.SyntaxKind.BigIntLiteral: case common.SyntaxKind.CallExpression: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.DeleteExpression: case common.SyntaxKind.ElementAccessExpression: case common.SyntaxKind.FalseKeyword: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.Identifier: case common.SyntaxKind.ImportKeyword: case common.SyntaxKind.JsxElement: case common.SyntaxKind.JsxFragment: case common.SyntaxKind.JsxSelfClosingElement: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.NewExpression: case common.SyntaxKind.NonNullExpression: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.NullKeyword: case common.SyntaxKind.NumericLiteral: case common.SyntaxKind.ObjectLiteralExpression: case common.SyntaxKind.PostfixUnaryExpression: case common.SyntaxKind.PrefixUnaryExpression: case common.SyntaxKind.PropertyAccessExpression: case common.SyntaxKind.RegularExpressionLiteral: case common.SyntaxKind.StringLiteral: case common.SyntaxKind.SuperKeyword: case common.SyntaxKind.TaggedTemplateExpression: case common.SyntaxKind.TemplateExpression: case common.SyntaxKind.ThisKeyword: case common.SyntaxKind.TrueKeyword: case common.SyntaxKind.TypeAssertionExpression: case common.SyntaxKind.TypeOfExpression: case common.SyntaxKind.VoidExpression: return true; default: return false; } } static isUnaryExpressioned(node) { switch (node?.getKind()) { case common.SyntaxKind.AwaitExpression: case common.SyntaxKind.DeleteExpression: case common.SyntaxKind.TypeAssertionExpression: case common.SyntaxKind.TypeOfExpression: case common.SyntaxKind.VoidExpression: return true; default: return false; } } static isUndefinedKeyword = Node.is(common.SyntaxKind.UndefinedKeyword); static isUnionTypeNode(node) { return node?.getKind() === common.SyntaxKind.UnionType; } static isUnwrappable(node) { switch (node?.getKind()) { case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.ModuleDeclaration: return true; default: return false; } } static isUpdateExpression(node) { switch (node?.getKind()) { case common.SyntaxKind.ArrayLiteralExpression: case common.SyntaxKind.BigIntLiteral: case common.SyntaxKind.CallExpression: case common.SyntaxKind.ClassExpression: case common.SyntaxKind.ElementAccessExpression: case common.SyntaxKind.FalseKeyword: case common.SyntaxKind.FunctionExpression: case common.SyntaxKind.Identifier: case common.SyntaxKind.ImportKeyword: case common.SyntaxKind.JsxElement: case common.SyntaxKind.JsxFragment: case common.SyntaxKind.JsxSelfClosingElement: case common.SyntaxKind.MetaProperty: case common.SyntaxKind.NewExpression: case common.SyntaxKind.NonNullExpression: case common.SyntaxKind.NoSubstitutionTemplateLiteral: case common.SyntaxKind.NullKeyword: case common.SyntaxKind.NumericLiteral: case common.SyntaxKind.ObjectLiteralExpression: case common.SyntaxKind.PropertyAccessExpression: case common.SyntaxKind.RegularExpressionLiteral: case common.SyntaxKind.StringLiteral: case common.SyntaxKind.SuperKeyword: case common.SyntaxKind.TaggedTemplateExpression: case common.SyntaxKind.TemplateExpression: case common.SyntaxKind.ThisKeyword: case common.SyntaxKind.TrueKeyword: return true; default: return false; } } static isVariableDeclaration = Node.is(common.SyntaxKind.VariableDeclaration); static isVariableDeclarationList = Node.is(common.SyntaxKind.VariableDeclarationList); static isVariableStatement = Node.is(common.SyntaxKind.VariableStatement); static isVoidExpression = Node.is(common.SyntaxKind.VoidExpression); static isWhileStatement = Node.is(common.SyntaxKind.WhileStatement); static isWithStatement = Node.is(common.SyntaxKind.WithStatement); static isYieldExpression = Node.is(common.SyntaxKind.YieldExpression); static _hasStructure(node) { switch (node?.getKind()) { case common.SyntaxKind.CallSignature: case common.SyntaxKind.ClassDeclaration: case common.SyntaxKind.ClassStaticBlockDeclaration: case common.SyntaxKind.Constructor: case common.SyntaxKind.ConstructSignature: case common.SyntaxKind.Decorator: case common.SyntaxKind.EnumDeclaration: case common.SyntaxKind.EnumMember: case common.SyntaxKind.ExportAssignment: case common.SyntaxKind.ExportDeclaration: case common.SyntaxKind.ExportSpecifier: case common.SyntaxKind.FunctionDeclaration: case common.SyntaxKind.GetAccessor: case common.SyntaxKind.ImportAttribute: case common.SyntaxKind.ImportDeclaration: case common.SyntaxKind.ImportSpecifier: case common.SyntaxKind.IndexSignature: case common.SyntaxKind.InterfaceDeclaration: case common.SyntaxKind.JSDoc: case common.SyntaxKind.JsxAttribute: case common.SyntaxKind.JsxElement: case common.SyntaxKind.JsxNamespacedName: case common.SyntaxKind.JsxSelfClosingElement: case common.SyntaxKind.JsxSpreadAttribute: case common.SyntaxKind.MethodDeclaration: case common.SyntaxKind.MethodSignature: case common.SyntaxKind.ModuleDeclaration: case common.SyntaxKind.Parameter: case common.SyntaxKind.PropertyAssignment: case common.SyntaxKind.PropertyDeclaration: case common.SyntaxKind.PropertySignature: case common.SyntaxKind.SetAccessor: case common.SyntaxKind.ShorthandPropertyAssignment: case common.SyntaxKind.SourceFile: case common.SyntaxKind.SpreadAssignment: case common.SyntaxKind.TypeAliasDeclaration: case common.SyntaxKind.TypeParameter: case common.SyntaxKind.VariableDeclaration: case common.SyntaxKind.VariableStatement: return true; default: return false; } } } function getWrappedCondition(thisNode, condition) { return condition == null ? undefined : ((c) => condition(thisNode._getNodeFromCompilerNode(c))); } function insertWhiteSpaceTextAtPos(node, insertPos, textOrWriterFunction, methodName) { const parent = Node.isSourceFile(node) ? node.getChildSyntaxListOrThrow() : node.getParentSyntaxList() || node.getParentOrThrow(); const newText = getTextFromStringOrWriter(node._getWriterWithQueuedIndentation(), textOrWriterFunction); if (!/^[\s\r\n]*$/.test(newText)) throw new common.errors.InvalidOperationError(`Cannot insert non-whitespace into ${methodName}.`); insertIntoParentTextRange({ parent, insertPos, newText, }); } function* getCompilerForEachDescendantsIterator(node) { for (const child of getForEachChildren()) { yield child; yield* getCompilerForEachDescendantsIterator(child); } function getForEachChildren() { const children = []; node.forEachChild(child => { children.push(child); }); return children; } } function* getCompilerDescendantsIterator(node, sourceFile) { for (const child of ExtendedParser.getCompilerChildren(node, sourceFile)) { yield child; yield* getCompilerDescendantsIterator(child, sourceFile); } } function useParseTreeSearchForKind(thisNodeOrSyntaxKind, searchingKind) { return searchingKind >= common.SyntaxKind.FirstNode && searchingKind < common.SyntaxKind.FirstJSDocNode && getThisKind() !== common.SyntaxKind.SyntaxList; function getThisKind() { if (typeof thisNodeOrSyntaxKind === "number") return thisNodeOrSyntaxKind; return thisNodeOrSyntaxKind.compilerNode.kind; } } exports.Scope = void 0; (function (Scope) { Scope["Public"] = "public"; Scope["Protected"] = "protected"; Scope["Private"] = "private"; })(exports.Scope || (exports.Scope = {})); class SyntaxList extends Node { addChildText(textOrWriterFunction) { return this.insertChildText(this.getChildCount(), textOrWriterFunction); } insertChildText(index, textOrWriterFunction) { const initialChildCount = this.getChildCount(); const newLineKind = this._context.manipulationSettings.getNewLineKindAsString(); const parent = this.getParentOrThrow(); index = verifyAndGetIndex(index, initialChildCount); const isInline = this !== parent.getChildSyntaxList(); let insertText = getTextFromStringOrWriter(isInline ? parent._getWriterWithQueuedChildIndentation() : parent._getWriterWithChildIndentation(), textOrWriterFunction); if (insertText.length === 0) return []; if (isInline) { if (index === 0) insertText += " "; else insertText = " " + insertText; } else { if (index === 0 && Node.isSourceFile(parent)) { if (!insertText.endsWith("\n")) insertText += newLineKind; } else { insertText = newLineKind + insertText; if (!Node.isSourceFile(parent) && index === initialChildCount && insertText.endsWith("\n")) insertText = insertText.replace(/\r?\n$/, ""); } } const insertPos = getInsertPosFromIndex(index, this, this.getChildren()); insertIntoParentTextRange({ insertPos, newText: insertText, parent: this, }); const finalChildren = this.getChildren(); return getNodesToReturn(initialChildCount, finalChildren, index, true); } } function renameNode(node, newName, options) { common.errors.throwIfWhitespaceOrNotString(newName, "newName"); if (node.getText() === newName) return; const renameLocations = node._context.languageService.findRenameLocations(node, options); const renameLocationsBySourceFile = new common.KeyValueCache(); for (const renameLocation of renameLocations) { const locations = renameLocationsBySourceFile.getOrCreate(renameLocation.getSourceFile(), () => []); locations.push(renameLocation); } for (const [sourceFile, locations] of renameLocationsBySourceFile.getEntries()) { replaceSourceFileTextForRename({ sourceFile, renameLocations: locations, newName, }); } } function setBodyTextForNode(body, textOrWriterFunction) { const newText = getBodyText(body._getWriterWithIndentation(), textOrWriterFunction); const openBrace = body.getFirstChildByKindOrThrow(common.SyntaxKind.OpenBraceToken); const closeBrace = body.getFirstChildByKindOrThrow(common.SyntaxKind.CloseBraceToken); insertIntoParentTextRange({ insertPos: openBrace.getEnd(), newText, parent: body, replacing: { textLength: closeBrace.getStart() - openBrace.getEnd(), }, }); } function BodiedNode(Base) { return class extends Base { getBody() { const body = this.compilerNode.body; if (body == null) throw new common.errors.InvalidOperationError("Bodied node should have a body."); return this._getNodeFromCompilerNode(body); } setBodyText(textOrWriterFunction) { const body = this.getBody(); setBodyTextForNode(body, textOrWriterFunction); return this; } getBodyText() { return getBodyTextWithoutLeadingIndentation(this.getBody()); } }; } function BodyableNode(Base) { return class extends Base { getBodyOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getBody(), message ?? "Expected to find the node's body.", this); } getBody() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.body); } getBodyText() { const body = this.getBody(); return body == null ? undefined : getBodyTextWithoutLeadingIndentation(body); } setBodyText(textOrWriterFunction) { this.addBody(); setBodyTextForNode(this.getBodyOrThrow(), textOrWriterFunction); return this; } hasBody() { return this.compilerNode.body != null; } addBody() { if (this.hasBody()) return this; const semiColon = this.getLastChildByKind(common.SyntaxKind.SemicolonToken); insertIntoParentTextRange({ parent: this, insertPos: semiColon == null ? this.getEnd() : semiColon.getStart(), newText: this._getWriterWithQueuedIndentation().space().block().toString(), replacing: { textLength: semiColon?.getFullWidth() ?? 0, }, }); return this; } removeBody() { const body = this.getBody(); if (body == null) return this; insertIntoParentTextRange({ parent: this, insertPos: body.getPos(), newText: ";", replacing: { textLength: body.getFullWidth(), }, }); return this; } }; } function ChildOrderableNode(Base) { return class extends Base { setOrder(order) { const childIndex = this.getChildIndex(); const parent = this.getParentSyntaxList() || this.getParentSyntaxListOrThrow(); common.errors.throwIfOutOfRange(order, [0, parent.getChildCount() - 1], "order"); if (childIndex === order) return this; changeChildOrder({ parent, getSiblingFormatting: getGeneralFormatting, oldIndex: childIndex, newIndex: order, }); return this; } }; } function DecoratableNode(Base) { return class extends Base { getDecorator(nameOrFindFunction) { return getNodeByNameOrFindFunction(this.getDecorators(), nameOrFindFunction); } getDecoratorOrThrow(nameOrFindFunction, message) { return common.errors.throwIfNullOrUndefined(this.getDecorator(nameOrFindFunction), message ?? (() => getNotFoundErrorMessageForNameOrFindFunction("decorator", nameOrFindFunction)), this); } getDecorators() { return getCompilerNodeDecorators(this.compilerNode).map(d => this._getNodeFromCompilerNode(d)); } addDecorator(structure) { return this.insertDecorator(getEndIndexFromArray(getCompilerNodeDecorators(this.compilerNode)), structure); } addDecorators(structures) { return this.insertDecorators(getEndIndexFromArray(getCompilerNodeDecorators(this.compilerNode)), structures); } insertDecorator(index, structure) { return this.insertDecorators(index, [structure])[0]; } insertDecorators(index, structures) { if (common.ArrayUtils.isNullOrEmpty(structures)) return []; const decoratorLines = getDecoratorLines(this, structures); const decorators = this.getDecorators(); index = verifyAndGetIndex(index, decorators.length); const formattingKind = getDecoratorFormattingKind(this, decorators); const previousDecorator = decorators[index - 1]; const decoratorCode = getNewInsertCode({ structures, newCodes: decoratorLines, parent: this, indentationText: this.getIndentationText(), getSeparator: () => formattingKind, previousFormattingKind: previousDecorator == null ? FormattingKind.None : formattingKind, nextFormattingKind: previousDecorator == null ? formattingKind : FormattingKind.None, }); insertIntoParentTextRange({ parent: decorators[0]?.getParentSyntaxListOrThrow() ?? this.getModifiers()[0]?.getParentSyntaxListOrThrow() ?? this, insertPos: index === 0 ? (decorators[0] ?? this).getStart() : decorators[index - 1].getEnd(), newText: decoratorCode, }); return getNodesToReturn(decorators, this.getDecorators(), index, false); } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.decorators != null) { this.getDecorators().forEach(d => d.remove()); this.addDecorators(structure.decorators); } return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { decorators: this.getDecorators().map(d => d.getStructure()), }); } }; } function getCompilerNodeDecorators(node) { return common.ts.canHaveDecorators(node) ? common.ts.getDecorators(node) ?? [] : []; } function getDecoratorLines(node, structures) { const lines = []; for (const structure of structures) { const writer = node._getWriter(); const structurePrinter = node._context.structurePrinterFactory.forDecorator(); structurePrinter.printText(writer, structure); lines.push(writer.toString()); } return lines; } function getDecoratorFormattingKind(parent, currentDecorators) { const sameLine = areDecoratorsOnSameLine(parent, currentDecorators); return sameLine ? FormattingKind.Space : FormattingKind.Newline; } function areDecoratorsOnSameLine(parent, currentDecorators) { if (currentDecorators.length === 1) { const previousNode = currentDecorators[0].getPreviousSibling(); if (previousNode != null && previousNode.getStartLinePos() === currentDecorators[0].getStartLinePos()) return true; } if (currentDecorators.length <= 1) return parent.getKind() === common.SyntaxKind.Parameter; const startLinePos = currentDecorators[0].getStartLinePos(); for (let i = 1; i < currentDecorators.length; i++) { if (currentDecorators[i].getStartLinePos() !== startLinePos) return false; } return true; } function DotDotDotTokenableNode(Base) { return class extends Base { getDotDotDotTokenOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getDotDotDotToken(), message ?? "Expected to find a dot dot dot token (...).", this); } getDotDotDotToken() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.dotDotDotToken); } }; } function ExclamationTokenableNode(Base) { return class extends Base { hasExclamationToken() { return this.compilerNode.exclamationToken != null; } getExclamationTokenNode() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.exclamationToken); } getExclamationTokenNodeOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getExclamationTokenNode(), message ?? "Expected to find an exclamation token.", this); } setHasExclamationToken(value) { const exclamationTokenNode = this.getExclamationTokenNode(); const hasExclamationToken = exclamationTokenNode != null; if (value === hasExclamationToken) return this; if (value) { if (Node.isQuestionTokenable(this)) this.setHasQuestionToken(false); const colonNode = this.getFirstChildByKind(common.SyntaxKind.ColonToken); if (colonNode == null) throw new common.errors.InvalidOperationError("Cannot add an exclamation token to a node that does not have a type."); insertIntoParentTextRange({ insertPos: colonNode.getStart(), parent: this, newText: "!", }); } else { removeChildren({ children: [exclamationTokenNode] }); } return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.hasExclamationToken != null) this.setHasExclamationToken(structure.hasExclamationToken); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { hasExclamationToken: this.hasExclamationToken(), }); } }; } function ExportGetableNode(Base) { return class extends Base { hasExportKeyword() { return this.getExportKeyword() != null; } getExportKeyword() { if (Node.isVariableDeclaration(this)) { const variableStatement = this.getVariableStatement(); return variableStatement?.getExportKeyword(); } if (!Node.isModifierable(this)) return throwForNotModifierableNode(); return this.getFirstModifierByKind(common.SyntaxKind.ExportKeyword); } getExportKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getExportKeyword(), message ?? "Expected to find an export keyword.", this); } hasDefaultKeyword() { return this.getDefaultKeyword() != null; } getDefaultKeyword() { if (Node.isVariableDeclaration(this)) { const variableStatement = this.getVariableStatement(); return variableStatement?.getDefaultKeyword(); } if (!Node.isModifierable(this)) return throwForNotModifierableNode(); return this.getFirstModifierByKind(common.SyntaxKind.DefaultKeyword); } getDefaultKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getDefaultKeyword(), message ?? "Expected to find a default keyword.", this); } isExported() { if (this.hasExportKeyword()) return true; const thisSymbol = this.getSymbol(); const sourceFileSymbol = this.getSourceFile().getSymbol(); if (thisSymbol == null || sourceFileSymbol == null) return false; return sourceFileSymbol.getExports().some(e => e === thisSymbol || e.getAliasedSymbol() === thisSymbol); } isDefaultExport() { if (this.hasDefaultKeyword()) return true; const thisSymbol = this.getSymbol(); if (thisSymbol == null) return false; const defaultExportSymbol = this.getSourceFile().getDefaultExportSymbol(); if (defaultExportSymbol == null) return false; if (thisSymbol === defaultExportSymbol) return true; const aliasedSymbol = defaultExportSymbol.getAliasedSymbol(); return thisSymbol === aliasedSymbol; } isNamedExport() { const thisSymbol = this.getSymbol(); const sourceFileSymbol = this.getSourceFile().getSymbol(); if (thisSymbol == null || sourceFileSymbol == null) return false; return !isDefaultExport() && sourceFileSymbol.getExports().some(e => e === thisSymbol || e.getAliasedSymbol() === thisSymbol); function isDefaultExport() { const defaultExportSymbol = sourceFileSymbol.getExport("default"); if (defaultExportSymbol == null) return false; return thisSymbol === defaultExportSymbol || thisSymbol === defaultExportSymbol.getAliasedSymbol(); } } }; } function throwForNotModifierableNode() { throw new common.errors.NotImplementedError(`Not implemented situation where node was not a ModifierableNode.`); } function ExportableNode(Base) { return apply$1(ExportGetableNode(Base)); } function apply$1(Base) { return class extends Base { setIsDefaultExport(value) { if (value === this.isDefaultExport()) return this; if (value && !Node.isSourceFile(this.getParentOrThrow())) throw new common.errors.InvalidOperationError("The parent must be a source file in order to set this node as a default export."); const sourceFile = this.getSourceFile(); const fileDefaultExportSymbol = sourceFile.getDefaultExportSymbol(); if (fileDefaultExportSymbol != null) sourceFile.removeDefaultExport(fileDefaultExportSymbol); if (!value) return this; if (Node.hasName(this) && shouldWriteAsSeparateStatement.call(this)) { const parentSyntaxList = this.getFirstAncestorByKindOrThrow(common.SyntaxKind.SyntaxList); const name = this.getName(); parentSyntaxList.insertChildText(this.getChildIndex() + 1, writer => { writer.newLine().write(`export default ${name};`); }); } else { this.addModifier("export"); this.addModifier("default"); } return this; function shouldWriteAsSeparateStatement() { if (Node.isEnumDeclaration(this) || Node.isModuleDeclaration(this) || Node.isTypeAliasDeclaration(this)) return true; if (Node.isAmbientable(this) && this.isAmbient()) return true; return false; } } setIsExported(value) { if (Node.isSourceFile(this.getParentOrThrow())) this.toggleModifier("default", false); this.toggleModifier("export", value); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.isExported != null) this.setIsExported(structure.isExported); if (structure.isDefaultExport != null) this.setIsDefaultExport(structure.isDefaultExport); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { isExported: this.hasExportKeyword(), isDefaultExport: this.hasDefaultKeyword(), }); } }; } class Printer { printTextOrWriterFunc(writer, textOrWriterFunc) { if (typeof textOrWriterFunc === "string") writer.write(textOrWriterFunc); else if (textOrWriterFunc != null) textOrWriterFunc(writer); } getNewWriter(writer) { return new CodeBlockWriter__default.default(writer.getOptions()); } getNewWriterWithQueuedChildIndentation(writer) { const newWriter = new CodeBlockWriter__default.default(writer.getOptions()); newWriter.queueIndentationLevel(1); return newWriter; } getText(writer, textOrWriterFunc) { const newWriter = this.getNewWriter(writer); this.printTextOrWriterFunc(newWriter, textOrWriterFunc); return newWriter.toString(); } getTextWithQueuedChildIndentation(writer, textOrWriterFunc) { const queuedChildIndentationWriter = this.getNewWriterWithQueuedChildIndentation(writer); this.printTextOrWriterFunc(queuedChildIndentationWriter, textOrWriterFunc); return queuedChildIndentationWriter.toString(); } } class InitializerExpressionableNodeStructurePrinter extends Printer { printText(writer, structure) { const { initializer } = structure; if (initializer == null) return; const initializerText = this.getText(writer, initializer); if (!common.StringUtils.isNullOrWhitespace(initializerText)) { writer.hangingIndent(() => { writer.spaceIfLastNot(); writer.write(`= ${initializerText}`); }); } } } class ModifierableNodeStructurePrinter extends Printer { printText(writer, structure) { const scope = structure.scope; if (structure.isDefaultExport) writer.write("export default "); else if (structure.isExported) writer.write("export "); if (structure.hasDeclareKeyword) writer.write("declare "); if (scope != null) writer.write(`${scope} `); if (structure.isStatic) writer.write("static "); if (structure.hasOverrideKeyword) writer.write("override "); if (structure.isAbstract) writer.write("abstract "); if (structure.isAsync) writer.write("async "); if (structure.isReadonly) writer.write("readonly "); if (structure.hasAccessorKeyword) writer.write("accessor "); } } class ReturnTypedNodeStructurePrinter extends Printer { #alwaysWrite; constructor(alwaysWrite = false) { super(); this.#alwaysWrite = alwaysWrite; } printText(writer, structure) { let { returnType } = structure; if (returnType == null && this.#alwaysWrite === false) return; returnType = returnType ?? "void"; const returnTypeText = this.getText(writer, returnType); if (!common.StringUtils.isNullOrWhitespace(returnTypeText)) { writer.hangingIndent(() => { writer.write(`: ${returnTypeText}`); }); } } } class TypedNodeStructurePrinter extends Printer { #separator; #alwaysWrite; constructor(separator, alwaysWrite = false) { super(); this.#alwaysWrite = alwaysWrite; this.#separator = separator; } printText(writer, structure) { let { type } = structure; if (type == null && this.#alwaysWrite === false) return; type = type ?? "any"; const typeText = this.getText(writer, type); if (!common.StringUtils.isNullOrWhitespace(typeText)) { writer.hangingIndent(() => { writer.write(`${this.#separator} ${typeText}`); }); } } } class BlankLineFormattingStructuresPrinter extends Printer { #printer; constructor(printer) { super(); this.#printer = printer; } printText(writer, structures) { if (structures == null) return; for (let i = 0; i < structures.length; i++) { writer.conditionalBlankLine(i > 0); this.#printer.printText(writer, structures[i]); } } } class CommaSeparatedStructuresPrinter extends Printer { #printer; constructor(printer) { super(); this.#printer = printer; } printText(writer, structures) { printTextWithSeparator(this.#printer, writer, structures, () => writer.spaceIfLastNot()); } } function printTextWithSeparator(printer, writer, structures, separator) { if (structures == null) return; if (structures instanceof Function || typeof structures === "string") printer.printText(writer, structures); else { const commaAppendPositions = new Array(structures.length); for (let i = 0; i < structures.length; i++) { if (i > 0) separator(); const structure = structures[i]; const startPos = writer.getLength(); printer.printText(writer, structure); const pos = getAppendCommaPos(WriterUtils.getLastCharactersToPos(writer, startPos)); commaAppendPositions[i] = pos === -1 ? false : pos + startPos; } let foundFirst = false; for (let i = commaAppendPositions.length - 1; i >= 0; i--) { const pos = commaAppendPositions[i]; if (pos === false) continue; else if (!foundFirst) foundFirst = true; else writer.unsafeInsert(pos, ","); } } } class CommaNewLineSeparatedStructuresPrinter extends Printer { #printer; constructor(printer) { super(); this.#printer = printer; } printText(writer, structures) { printTextWithSeparator(this.#printer, writer, structures, () => writer.newLineIfLastNot()); } } class NewLineFormattingStructuresPrinter extends Printer { #printer; constructor(printer) { super(); this.#printer = printer; } printText(writer, structures) { if (structures == null) return; for (let i = 0; i < structures.length; i++) { writer.conditionalNewLine(i > 0); this.#printer.printText(writer, structures[i]); } } } class SpaceFormattingStructuresPrinter extends Printer { #printer; constructor(printer) { super(); this.#printer = printer; } printText(writer, structures) { if (structures == null) return; for (let i = 0; i < structures.length; i++) { writer.conditionalWrite(i > 0, " "); this.#printer.printText(writer, structures[i]); } } } class NodePrinter extends Printer { factory; constructor(factory) { super(); this.factory = factory; } printTextWithoutTrivia(writer, structure) { this.printTextInternal(writer, structure); } printText(writer, structure) { this.printLeadingTrivia(writer, structure); writer.closeComment(); this.printTextInternal(writer, structure); this.printTrailingTrivia(writer, structure); } printLeadingTrivia(writer, structure) { const leadingTrivia = structure?.leadingTrivia; if (leadingTrivia) { this.#printTrivia(writer, leadingTrivia); if (writer.isInComment()) writer.closeComment(); } } printTrailingTrivia(writer, structure) { const trailingTrivia = structure?.trailingTrivia; if (trailingTrivia != null) this.#printTrivia(writer, trailingTrivia); } #printTrivia(writer, trivia) { if (trivia instanceof Array) { for (let i = 0; i < trivia.length; i++) { this.printTextOrWriterFunc(writer, trivia[i]); if (i !== trivia.length - 1) writer.newLineIfLastNot(); } } else { this.printTextOrWriterFunc(writer, trivia); } } } class GetAndSetAccessorStructurePrinter { #getAccessorPrinter; #setAccessorPrinter; constructor(getAccessorPrinter, setAccessorPrinter) { this.#getAccessorPrinter = getAccessorPrinter; this.#setAccessorPrinter = setAccessorPrinter; } printGetAndSet(writer, getAccessors, setAccessors, isAmbient) { getAccessors = [...getAccessors ?? []]; setAccessors = [...setAccessors ?? []]; for (const getAccessor of getAccessors) { this.#conditionalSeparator(writer, isAmbient); this.#getAccessorPrinter.printText(writer, getAccessor); const setAccessorIndex = setAccessors.findIndex(item => item.name === getAccessor.name); if (setAccessorIndex >= 0) { this.#conditionalSeparator(writer, isAmbient); this.#setAccessorPrinter.printText(writer, setAccessors[setAccessorIndex]); setAccessors.splice(setAccessorIndex, 1); } } for (const setAccessor of setAccessors) { this.#conditionalSeparator(writer, isAmbient); this.#setAccessorPrinter.printText(writer, setAccessor); } } #conditionalSeparator(writer, isAmbient) { if (writer.isAtStartOfFirstLineOfBlock()) return; if (isAmbient) writer.newLine(); else writer.blankLine(); } } class ClassDeclarationStructurePrinter extends NodePrinter { #options; #multipleWriter = new BlankLineFormattingStructuresPrinter(this); constructor(factory, options) { super(factory); this.#options = options; } printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { const isAmbient = structure.hasDeclareKeyword || this.#options.isAmbient; this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forDecorator().printTexts(writer, structure.decorators); this.#printHeader(writer, structure); writer.inlineBlock(() => { this.factory.forPropertyDeclaration().printTexts(writer, structure.properties); this.#printStaticBlocks(writer, structure); this.#printCtors(writer, structure, isAmbient); this.#printGetAndSet(writer, structure, isAmbient); if (!common.ArrayUtils.isNullOrEmpty(structure.methods)) { this.#conditionalSeparator(writer, isAmbient); this.factory.forMethodDeclaration({ isAmbient }).printTexts(writer, structure.methods); } }); } #printHeader(writer, structure) { this.factory.forModifierableNode().printText(writer, structure); writer.write(`class`); if (!common.StringUtils.isNullOrWhitespace(structure.name)) writer.space().write(structure.name); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); writer.space(); writer.hangingIndent(() => { if (structure.extends != null) { const extendsText = this.getText(writer, structure.extends); if (!common.StringUtils.isNullOrWhitespace(extendsText)) writer.write(`extends ${extendsText} `); } if (structure.implements != null) { const implementsText = structure.implements instanceof Array ? structure.implements.map(i => this.getText(writer, i)).join(", ") : this.getText(writer, structure.implements); if (!common.StringUtils.isNullOrWhitespace(implementsText)) writer.write(`implements ${implementsText} `); } }); } #printCtors(writer, structure, isAmbient) { if (common.ArrayUtils.isNullOrEmpty(structure.ctors)) return; for (const ctor of structure.ctors) { this.#conditionalSeparator(writer, isAmbient); this.factory.forConstructorDeclaration({ isAmbient }).printText(writer, ctor); } } #printStaticBlocks(writer, structure) { if (common.ArrayUtils.isNullOrEmpty(structure.staticBlocks)) return; for (const block of structure.staticBlocks) { this.#conditionalSeparator(writer, false); this.factory.forClassStaticBlockDeclaration().printText(writer, block); } } #printGetAndSet(writer, structure, isAmbient) { if (structure.getAccessors == null && structure.setAccessors == null) return; const getAccessorWriter = this.factory.forGetAccessorDeclaration({ isAmbient }); const setAccessorWriter = this.factory.forSetAccessorDeclaration({ isAmbient }); const combinedPrinter = new GetAndSetAccessorStructurePrinter(getAccessorWriter, setAccessorWriter); combinedPrinter.printGetAndSet(writer, structure.getAccessors, structure.setAccessors, isAmbient); } #conditionalSeparator(writer, isAmbient) { if (writer.isAtStartOfFirstLineOfBlock()) return; if (isAmbient) writer.newLine(); else writer.blankLine(); } } exports.StructureKind = void 0; (function (StructureKind) { StructureKind[StructureKind["ImportAttribute"] = 0] = "ImportAttribute"; StructureKind[StructureKind["CallSignature"] = 1] = "CallSignature"; StructureKind[StructureKind["Class"] = 2] = "Class"; StructureKind[StructureKind["ClassStaticBlock"] = 3] = "ClassStaticBlock"; StructureKind[StructureKind["ConstructSignature"] = 4] = "ConstructSignature"; StructureKind[StructureKind["Constructor"] = 5] = "Constructor"; StructureKind[StructureKind["ConstructorOverload"] = 6] = "ConstructorOverload"; StructureKind[StructureKind["Decorator"] = 7] = "Decorator"; StructureKind[StructureKind["Enum"] = 8] = "Enum"; StructureKind[StructureKind["EnumMember"] = 9] = "EnumMember"; StructureKind[StructureKind["ExportAssignment"] = 10] = "ExportAssignment"; StructureKind[StructureKind["ExportDeclaration"] = 11] = "ExportDeclaration"; StructureKind[StructureKind["ExportSpecifier"] = 12] = "ExportSpecifier"; StructureKind[StructureKind["Function"] = 13] = "Function"; StructureKind[StructureKind["FunctionOverload"] = 14] = "FunctionOverload"; StructureKind[StructureKind["GetAccessor"] = 15] = "GetAccessor"; StructureKind[StructureKind["ImportDeclaration"] = 16] = "ImportDeclaration"; StructureKind[StructureKind["ImportSpecifier"] = 17] = "ImportSpecifier"; StructureKind[StructureKind["IndexSignature"] = 18] = "IndexSignature"; StructureKind[StructureKind["Interface"] = 19] = "Interface"; StructureKind[StructureKind["JsxAttribute"] = 20] = "JsxAttribute"; StructureKind[StructureKind["JsxSpreadAttribute"] = 21] = "JsxSpreadAttribute"; StructureKind[StructureKind["JsxElement"] = 22] = "JsxElement"; StructureKind[StructureKind["JsxSelfClosingElement"] = 23] = "JsxSelfClosingElement"; StructureKind[StructureKind["JSDoc"] = 24] = "JSDoc"; StructureKind[StructureKind["JSDocTag"] = 25] = "JSDocTag"; StructureKind[StructureKind["Method"] = 26] = "Method"; StructureKind[StructureKind["MethodOverload"] = 27] = "MethodOverload"; StructureKind[StructureKind["MethodSignature"] = 28] = "MethodSignature"; StructureKind[StructureKind["Module"] = 29] = "Module"; StructureKind[StructureKind["Parameter"] = 30] = "Parameter"; StructureKind[StructureKind["Property"] = 31] = "Property"; StructureKind[StructureKind["PropertyAssignment"] = 32] = "PropertyAssignment"; StructureKind[StructureKind["PropertySignature"] = 33] = "PropertySignature"; StructureKind[StructureKind["SetAccessor"] = 34] = "SetAccessor"; StructureKind[StructureKind["ShorthandPropertyAssignment"] = 35] = "ShorthandPropertyAssignment"; StructureKind[StructureKind["SourceFile"] = 36] = "SourceFile"; StructureKind[StructureKind["SpreadAssignment"] = 37] = "SpreadAssignment"; StructureKind[StructureKind["TypeAlias"] = 38] = "TypeAlias"; StructureKind[StructureKind["TypeParameter"] = 39] = "TypeParameter"; StructureKind[StructureKind["VariableDeclaration"] = 40] = "VariableDeclaration"; StructureKind[StructureKind["VariableStatement"] = 41] = "VariableStatement"; })(exports.StructureKind || (exports.StructureKind = {})); const Structure = { hasName(structure) { return typeof structure.name === "string"; }, isCallSignature(structure) { return structure?.kind === exports.StructureKind.CallSignature; }, isJSDocable(structure) { switch (structure?.kind) { case exports.StructureKind.CallSignature: case exports.StructureKind.Class: case exports.StructureKind.ClassStaticBlock: case exports.StructureKind.ConstructorOverload: case exports.StructureKind.Constructor: case exports.StructureKind.ConstructSignature: case exports.StructureKind.Enum: case exports.StructureKind.EnumMember: case exports.StructureKind.ExportAssignment: case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.GetAccessor: case exports.StructureKind.IndexSignature: case exports.StructureKind.Interface: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.MethodSignature: case exports.StructureKind.Module: case exports.StructureKind.Property: case exports.StructureKind.PropertySignature: case exports.StructureKind.SetAccessor: case exports.StructureKind.TypeAlias: case exports.StructureKind.VariableStatement: return true; default: return false; } }, isSignatured(structure) { switch (structure?.kind) { case exports.StructureKind.CallSignature: case exports.StructureKind.ConstructorOverload: case exports.StructureKind.Constructor: case exports.StructureKind.ConstructSignature: case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.GetAccessor: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.MethodSignature: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isParametered(structure) { switch (structure?.kind) { case exports.StructureKind.CallSignature: case exports.StructureKind.ConstructorOverload: case exports.StructureKind.Constructor: case exports.StructureKind.ConstructSignature: case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.GetAccessor: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.MethodSignature: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isReturnTyped(structure) { switch (structure?.kind) { case exports.StructureKind.CallSignature: case exports.StructureKind.ConstructorOverload: case exports.StructureKind.Constructor: case exports.StructureKind.ConstructSignature: case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.GetAccessor: case exports.StructureKind.IndexSignature: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.MethodSignature: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isTypeParametered(structure) { switch (structure?.kind) { case exports.StructureKind.CallSignature: case exports.StructureKind.Class: case exports.StructureKind.ConstructorOverload: case exports.StructureKind.Constructor: case exports.StructureKind.ConstructSignature: case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.GetAccessor: case exports.StructureKind.Interface: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.MethodSignature: case exports.StructureKind.SetAccessor: case exports.StructureKind.TypeAlias: return true; default: return false; } }, isClass(structure) { return structure?.kind === exports.StructureKind.Class; }, isClassLikeDeclarationBase(structure) { return structure?.kind === exports.StructureKind.Class; }, isNameable(structure) { switch (structure?.kind) { case exports.StructureKind.Class: case exports.StructureKind.Function: return true; default: return false; } }, isImplementsClauseable(structure) { return structure?.kind === exports.StructureKind.Class; }, isDecoratable(structure) { switch (structure?.kind) { case exports.StructureKind.Class: case exports.StructureKind.GetAccessor: case exports.StructureKind.Method: case exports.StructureKind.Parameter: case exports.StructureKind.Property: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isAbstractable(structure) { switch (structure?.kind) { case exports.StructureKind.Class: case exports.StructureKind.GetAccessor: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.Property: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isAmbientable(structure) { switch (structure?.kind) { case exports.StructureKind.Class: case exports.StructureKind.Enum: case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.Interface: case exports.StructureKind.Module: case exports.StructureKind.Property: case exports.StructureKind.TypeAlias: case exports.StructureKind.VariableStatement: return true; default: return false; } }, isExportable(structure) { switch (structure?.kind) { case exports.StructureKind.Class: case exports.StructureKind.Enum: case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.Interface: case exports.StructureKind.Module: case exports.StructureKind.TypeAlias: case exports.StructureKind.VariableStatement: return true; default: return false; } }, isClassStaticBlock(structure) { return structure?.kind === exports.StructureKind.ClassStaticBlock; }, isStatemented(structure) { switch (structure?.kind) { case exports.StructureKind.ClassStaticBlock: case exports.StructureKind.Constructor: case exports.StructureKind.Function: case exports.StructureKind.GetAccessor: case exports.StructureKind.Method: case exports.StructureKind.Module: case exports.StructureKind.SetAccessor: case exports.StructureKind.SourceFile: return true; default: return false; } }, isConstructorDeclarationOverload(structure) { return structure?.kind === exports.StructureKind.ConstructorOverload; }, isScoped(structure) { switch (structure?.kind) { case exports.StructureKind.ConstructorOverload: case exports.StructureKind.Constructor: case exports.StructureKind.GetAccessor: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.Property: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isConstructor(structure) { return structure?.kind === exports.StructureKind.Constructor; }, isFunctionLike(structure) { switch (structure?.kind) { case exports.StructureKind.Constructor: case exports.StructureKind.Function: case exports.StructureKind.GetAccessor: case exports.StructureKind.Method: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isConstructSignature(structure) { return structure?.kind === exports.StructureKind.ConstructSignature; }, isDecorator(structure) { return structure?.kind === exports.StructureKind.Decorator; }, isEnum(structure) { return structure?.kind === exports.StructureKind.Enum; }, isNamed(structure) { switch (structure?.kind) { case exports.StructureKind.Enum: case exports.StructureKind.Interface: case exports.StructureKind.ShorthandPropertyAssignment: case exports.StructureKind.TypeAlias: case exports.StructureKind.TypeParameter: return true; default: return false; } }, isEnumMember(structure) { return structure?.kind === exports.StructureKind.EnumMember; }, isPropertyNamed(structure) { switch (structure?.kind) { case exports.StructureKind.EnumMember: case exports.StructureKind.GetAccessor: case exports.StructureKind.Method: case exports.StructureKind.MethodSignature: case exports.StructureKind.PropertyAssignment: case exports.StructureKind.Property: case exports.StructureKind.PropertySignature: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isInitializerExpressionable(structure) { switch (structure?.kind) { case exports.StructureKind.EnumMember: case exports.StructureKind.Parameter: case exports.StructureKind.Property: case exports.StructureKind.PropertySignature: case exports.StructureKind.VariableDeclaration: return true; default: return false; } }, isExportAssignment(structure) { return structure?.kind === exports.StructureKind.ExportAssignment; }, isExportDeclaration(structure) { return structure?.kind === exports.StructureKind.ExportDeclaration; }, isExportSpecifier(structure) { return structure?.kind === exports.StructureKind.ExportSpecifier; }, isFunctionDeclarationOverload(structure) { return structure?.kind === exports.StructureKind.FunctionOverload; }, isAsyncable(structure) { switch (structure?.kind) { case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: return true; default: return false; } }, isGeneratorable(structure) { switch (structure?.kind) { case exports.StructureKind.FunctionOverload: case exports.StructureKind.Function: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: return true; default: return false; } }, isFunction(structure) { return structure?.kind === exports.StructureKind.Function; }, isGetAccessor(structure) { return structure?.kind === exports.StructureKind.GetAccessor; }, isStaticable(structure) { switch (structure?.kind) { case exports.StructureKind.GetAccessor: case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.Property: case exports.StructureKind.SetAccessor: return true; default: return false; } }, isImportAttribute(structure) { return structure?.kind === exports.StructureKind.ImportAttribute; }, isImportAttributeNamed(structure) { return structure?.kind === exports.StructureKind.ImportAttribute; }, isImportDeclaration(structure) { return structure?.kind === exports.StructureKind.ImportDeclaration; }, isImportSpecifier(structure) { return structure?.kind === exports.StructureKind.ImportSpecifier; }, isIndexSignature(structure) { return structure?.kind === exports.StructureKind.IndexSignature; }, isReadonlyable(structure) { switch (structure?.kind) { case exports.StructureKind.IndexSignature: case exports.StructureKind.Parameter: case exports.StructureKind.Property: case exports.StructureKind.PropertySignature: return true; default: return false; } }, isInterface(structure) { return structure?.kind === exports.StructureKind.Interface; }, isExtendsClauseable(structure) { return structure?.kind === exports.StructureKind.Interface; }, isTypeElementMembered(structure) { return structure?.kind === exports.StructureKind.Interface; }, isJSDoc(structure) { return structure?.kind === exports.StructureKind.JSDoc; }, isJSDocTag(structure) { return structure?.kind === exports.StructureKind.JSDocTag; }, isJsxAttribute(structure) { return structure?.kind === exports.StructureKind.JsxAttribute; }, isJsxElement(structure) { return structure?.kind === exports.StructureKind.JsxElement; }, isJsxSelfClosingElement(structure) { return structure?.kind === exports.StructureKind.JsxSelfClosingElement; }, isJsxTagNamed(structure) { return structure?.kind === exports.StructureKind.JsxSelfClosingElement; }, isJsxAttributed(structure) { return structure?.kind === exports.StructureKind.JsxSelfClosingElement; }, isJsxSpreadAttribute(structure) { return structure?.kind === exports.StructureKind.JsxSpreadAttribute; }, isMethodDeclarationOverload(structure) { return structure?.kind === exports.StructureKind.MethodOverload; }, isQuestionTokenable(structure) { switch (structure?.kind) { case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.MethodSignature: case exports.StructureKind.Parameter: case exports.StructureKind.Property: case exports.StructureKind.PropertySignature: return true; default: return false; } }, isOverrideable(structure) { switch (structure?.kind) { case exports.StructureKind.MethodOverload: case exports.StructureKind.Method: case exports.StructureKind.Parameter: case exports.StructureKind.Property: return true; default: return false; } }, isMethod(structure) { return structure?.kind === exports.StructureKind.Method; }, isMethodSignature(structure) { return structure?.kind === exports.StructureKind.MethodSignature; }, isModule(structure) { return structure?.kind === exports.StructureKind.Module; }, isModuleNamed(structure) { return structure?.kind === exports.StructureKind.Module; }, isParameter(structure) { return structure?.kind === exports.StructureKind.Parameter; }, isBindingNamed(structure) { switch (structure?.kind) { case exports.StructureKind.Parameter: case exports.StructureKind.VariableDeclaration: return true; default: return false; } }, isTyped(structure) { switch (structure?.kind) { case exports.StructureKind.Parameter: case exports.StructureKind.Property: case exports.StructureKind.PropertySignature: case exports.StructureKind.TypeAlias: case exports.StructureKind.VariableDeclaration: return true; default: return false; } }, isScopeable(structure) { return structure?.kind === exports.StructureKind.Parameter; }, isPropertyAssignment(structure) { return structure?.kind === exports.StructureKind.PropertyAssignment; }, isProperty(structure) { return structure?.kind === exports.StructureKind.Property; }, isExclamationTokenable(structure) { switch (structure?.kind) { case exports.StructureKind.Property: case exports.StructureKind.VariableDeclaration: return true; default: return false; } }, isPropertySignature(structure) { return structure?.kind === exports.StructureKind.PropertySignature; }, isSetAccessor(structure) { return structure?.kind === exports.StructureKind.SetAccessor; }, isShorthandPropertyAssignment(structure) { return structure?.kind === exports.StructureKind.ShorthandPropertyAssignment; }, isSourceFile(structure) { return structure?.kind === exports.StructureKind.SourceFile; }, isSpreadAssignment(structure) { return structure?.kind === exports.StructureKind.SpreadAssignment; }, isExpressioned(structure) { return structure?.kind === exports.StructureKind.SpreadAssignment; }, isTypeAlias(structure) { return structure?.kind === exports.StructureKind.TypeAlias; }, isTypeParameter(structure) { return structure?.kind === exports.StructureKind.TypeParameter; }, isVariableDeclaration(structure) { return structure?.kind === exports.StructureKind.VariableDeclaration; }, isVariableStatement(structure) { return structure?.kind === exports.StructureKind.VariableStatement; } }; function forEachStructureChild(structure, callback) { if (common.ArrayUtils.isReadonlyArray(structure)) { for (const item of structure) { const result = callback(item); if (result) return result; } return undefined; } switch (structure.kind) { case exports.StructureKind.CallSignature: return forCallSignatureDeclaration(structure, callback); case exports.StructureKind.Class: return forClassDeclaration(structure, callback); case exports.StructureKind.ClassStaticBlock: return forClassStaticBlockDeclaration(structure, callback); case exports.StructureKind.ConstructorOverload: return forConstructorDeclarationOverload(structure, callback); case exports.StructureKind.Constructor: return forConstructorDeclaration(structure, callback); case exports.StructureKind.ConstructSignature: return forConstructSignatureDeclaration(structure, callback); case exports.StructureKind.Enum: return forEnumDeclaration(structure, callback); case exports.StructureKind.EnumMember: return forEnumMember(structure, callback); case exports.StructureKind.ExportAssignment: return forExportAssignment(structure, callback); case exports.StructureKind.ExportDeclaration: return forExportDeclaration(structure, callback); case exports.StructureKind.FunctionOverload: return forFunctionDeclarationOverload(structure, callback); case exports.StructureKind.Function: return forFunctionDeclaration(structure, callback); case exports.StructureKind.GetAccessor: return forGetAccessorDeclaration(structure, callback); case exports.StructureKind.ImportDeclaration: return forImportDeclaration(structure, callback); case exports.StructureKind.IndexSignature: return forIndexSignatureDeclaration(structure, callback); case exports.StructureKind.Interface: return forInterfaceDeclaration(structure, callback); case exports.StructureKind.JSDoc: return forJSDoc(structure, callback); case exports.StructureKind.JsxElement: return forJsxElement(structure, callback); case exports.StructureKind.JsxSelfClosingElement: return forJsxSelfClosingElement(structure, callback); case exports.StructureKind.MethodOverload: return forMethodDeclarationOverload(structure, callback); case exports.StructureKind.Method: return forMethodDeclaration(structure, callback); case exports.StructureKind.MethodSignature: return forMethodSignature(structure, callback); case exports.StructureKind.Module: return forModuleDeclaration(structure, callback); case exports.StructureKind.Parameter: return forParameterDeclaration(structure, callback); case exports.StructureKind.Property: return forPropertyDeclaration(structure, callback); case exports.StructureKind.PropertySignature: return forPropertySignature(structure, callback); case exports.StructureKind.SetAccessor: return forSetAccessorDeclaration(structure, callback); case exports.StructureKind.SourceFile: return forSourceFile(structure, callback); case exports.StructureKind.TypeAlias: return forTypeAliasDeclaration(structure, callback); case exports.StructureKind.VariableStatement: return forVariableStatement(structure, callback); default: return undefined; } } function forCallSignatureDeclaration(structure, callback) { return forJSDocableNode(structure, callback) || forSignaturedDeclaration(structure, callback) || forTypeParameteredNode(structure, callback); } function forJSDocableNode(structure, callback) { return forAllIfStructure(structure.docs, callback, exports.StructureKind.JSDoc); } function forSignaturedDeclaration(structure, callback) { return forParameteredNode(structure, callback); } function forParameteredNode(structure, callback) { return forAll(structure.parameters, callback, exports.StructureKind.Parameter); } function forTypeParameteredNode(structure, callback) { return forAllIfStructure(structure.typeParameters, callback, exports.StructureKind.TypeParameter); } function forClassDeclaration(structure, callback) { return forClassLikeDeclarationBase(structure, callback); } function forClassLikeDeclarationBase(structure, callback) { return forDecoratableNode(structure, callback) || forTypeParameteredNode(structure, callback) || forJSDocableNode(structure, callback) || forAll(structure.ctors, callback, exports.StructureKind.Constructor) || forAll(structure.staticBlocks, callback, exports.StructureKind.ClassStaticBlock) || forAll(structure.properties, callback, exports.StructureKind.Property) || forAll(structure.getAccessors, callback, exports.StructureKind.GetAccessor) || forAll(structure.setAccessors, callback, exports.StructureKind.SetAccessor) || forAll(structure.methods, callback, exports.StructureKind.Method); } function forDecoratableNode(structure, callback) { return forAll(structure.decorators, callback, exports.StructureKind.Decorator); } function forClassStaticBlockDeclaration(structure, callback) { return forJSDocableNode(structure, callback) || forStatementedNode(structure, callback); } function forStatementedNode(structure, callback) { return forAllUnknownKindIfStructure(structure.statements, callback); } function forConstructorDeclarationOverload(structure, callback) { return forSignaturedDeclaration(structure, callback) || forTypeParameteredNode(structure, callback) || forJSDocableNode(structure, callback); } function forConstructorDeclaration(structure, callback) { return forFunctionLikeDeclaration(structure, callback) || forAll(structure.overloads, callback, exports.StructureKind.ConstructorOverload); } function forFunctionLikeDeclaration(structure, callback) { return forSignaturedDeclaration(structure, callback) || forTypeParameteredNode(structure, callback) || forJSDocableNode(structure, callback) || forStatementedNode(structure, callback); } function forConstructSignatureDeclaration(structure, callback) { return forJSDocableNode(structure, callback) || forSignaturedDeclaration(structure, callback) || forTypeParameteredNode(structure, callback); } function forEnumDeclaration(structure, callback) { return forJSDocableNode(structure, callback) || forAll(structure.members, callback, exports.StructureKind.EnumMember); } function forEnumMember(structure, callback) { return forJSDocableNode(structure, callback); } function forExportAssignment(structure, callback) { return forJSDocableNode(structure, callback); } function forExportDeclaration(structure, callback) { return forAllIfStructure(structure.namedExports, callback, exports.StructureKind.ExportSpecifier) || forAll(structure.attributes, callback, exports.StructureKind.ImportAttribute); } function forFunctionDeclarationOverload(structure, callback) { return forSignaturedDeclaration(structure, callback) || forTypeParameteredNode(structure, callback) || forJSDocableNode(structure, callback); } function forFunctionDeclaration(structure, callback) { return forFunctionLikeDeclaration(structure, callback) || forAll(structure.overloads, callback, exports.StructureKind.FunctionOverload); } function forGetAccessorDeclaration(structure, callback) { return forDecoratableNode(structure, callback) || forFunctionLikeDeclaration(structure, callback); } function forImportDeclaration(structure, callback) { return forAllIfStructure(structure.namedImports, callback, exports.StructureKind.ImportSpecifier) || forAll(structure.attributes, callback, exports.StructureKind.ImportAttribute); } function forIndexSignatureDeclaration(structure, callback) { return forJSDocableNode(structure, callback); } function forInterfaceDeclaration(structure, callback) { return forTypeParameteredNode(structure, callback) || forJSDocableNode(structure, callback) || forTypeElementMemberedNode(structure, callback); } function forTypeElementMemberedNode(structure, callback) { return forAll(structure.callSignatures, callback, exports.StructureKind.CallSignature) || forAll(structure.constructSignatures, callback, exports.StructureKind.ConstructSignature) || forAll(structure.getAccessors, callback, exports.StructureKind.GetAccessor) || forAll(structure.indexSignatures, callback, exports.StructureKind.IndexSignature) || forAll(structure.methods, callback, exports.StructureKind.MethodSignature) || forAll(structure.properties, callback, exports.StructureKind.PropertySignature) || forAll(structure.setAccessors, callback, exports.StructureKind.SetAccessor); } function forJSDoc(structure, callback) { return forAll(structure.tags, callback, exports.StructureKind.JSDocTag); } function forJsxElement(structure, callback) { return forAllUnknownKindIfStructure(structure.attributes, callback) || forAllUnknownKindIfStructure(structure.children, callback); } function forJsxSelfClosingElement(structure, callback) { return forJsxAttributedNode(structure, callback); } function forJsxAttributedNode(structure, callback) { return forAllUnknownKindIfStructure(structure.attributes, callback); } function forMethodDeclarationOverload(structure, callback) { return forSignaturedDeclaration(structure, callback) || forTypeParameteredNode(structure, callback) || forJSDocableNode(structure, callback); } function forMethodDeclaration(structure, callback) { return forDecoratableNode(structure, callback) || forFunctionLikeDeclaration(structure, callback) || forAll(structure.overloads, callback, exports.StructureKind.MethodOverload); } function forMethodSignature(structure, callback) { return forJSDocableNode(structure, callback) || forSignaturedDeclaration(structure, callback) || forTypeParameteredNode(structure, callback); } function forModuleDeclaration(structure, callback) { return forJSDocableNode(structure, callback) || forStatementedNode(structure, callback); } function forParameterDeclaration(structure, callback) { return forDecoratableNode(structure, callback); } function forPropertyDeclaration(structure, callback) { return forJSDocableNode(structure, callback) || forDecoratableNode(structure, callback); } function forPropertySignature(structure, callback) { return forJSDocableNode(structure, callback); } function forSetAccessorDeclaration(structure, callback) { return forDecoratableNode(structure, callback) || forFunctionLikeDeclaration(structure, callback); } function forSourceFile(structure, callback) { return forStatementedNode(structure, callback); } function forTypeAliasDeclaration(structure, callback) { return forTypeParameteredNode(structure, callback) || forJSDocableNode(structure, callback); } function forVariableStatement(structure, callback) { return forJSDocableNode(structure, callback) || forAll(structure.declarations, callback, exports.StructureKind.VariableDeclaration); } function forAll(structures, callback, kind) { if (structures == null) return; for (const structure of structures) { const result = callback(ensureKind(structure, kind)); if (result) return result; } return undefined; } function forAllIfStructure(values, callback, kind) { if (values == null || !(values instanceof Array)) return; for (const value of values) { if (isStructure(value)) { const result = callback(ensureKind(value, kind)); if (result) return result; } } return undefined; } function forAllUnknownKindIfStructure(values, callback) { if (values == null || !(values instanceof Array)) return; for (const value of values) { if (isStructure(value)) { const result = callback(value); if (result) return result; } } return undefined; } function ensureKind(structure, kind) { if (structure.kind == null) structure.kind = kind; return structure; } function isStructure(value) { return value != null && typeof value.kind === "number"; } function isLastNonWhitespaceCharCloseBrace(writer) { return writer.iterateLastCharCodes(charCode => { if (charCode === CharCodes.CLOSE_BRACE) return true; else if (common.StringUtils.isWhitespaceCharCode(charCode)) return undefined; else return false; }) || false; } class ClassMemberStructurePrinter extends Printer { #options; #factory; constructor(factory, options) { super(); this.#factory = factory; this.#options = options; } printTexts(writer, members) { if (members == null) return; if (typeof members === "string" || members instanceof Function) this.printText(writer, members); else { for (const member of members) { if (isLastNonWhitespaceCharCloseBrace(writer)) writer.blankLineIfLastNot(); else if (!writer.isAtStartOfFirstLineOfBlock()) writer.newLineIfLastNot(); this.printText(writer, member); } } } printText(writer, member) { if (typeof member === "string" || member instanceof Function || member == null) { this.printTextOrWriterFunc(writer, member); return; } switch (member.kind) { case exports.StructureKind.Method: if (!this.#options.isAmbient) ensureBlankLine(); this.#factory.forMethodDeclaration(this.#options).printText(writer, member); break; case exports.StructureKind.Property: this.#factory.forPropertyDeclaration().printText(writer, member); break; case exports.StructureKind.GetAccessor: if (!this.#options.isAmbient) ensureBlankLine(); this.#factory.forGetAccessorDeclaration(this.#options).printText(writer, member); break; case exports.StructureKind.SetAccessor: if (!this.#options.isAmbient) ensureBlankLine(); this.#factory.forSetAccessorDeclaration(this.#options).printText(writer, member); break; case exports.StructureKind.Constructor: if (!this.#options.isAmbient) ensureBlankLine(); this.#factory.forConstructorDeclaration(this.#options).printText(writer, member); break; case exports.StructureKind.ClassStaticBlock: ensureBlankLine(); this.#factory.forClassStaticBlockDeclaration().printText(writer, member); break; default: common.errors.throwNotImplementedForNeverValueError(member); } function ensureBlankLine() { if (!writer.isAtStartOfFirstLineOfBlock()) writer.blankLineIfLastNot(); } } } class ClassStaticBlockDeclarationStructurePrinter extends NodePrinter { constructor(factory) { super(factory); } printTexts(writer, structures) { if (structures == null) return; for (let i = 0; i < structures.length; i++) { if (i > 0) writer.blankLine(); this.printText(writer, structures[i]); } } printTextInternal(writer, structure) { writer.write("static"); writer.space().inlineBlock(() => { this.factory.forStatementedNode({ isAmbient: false }).printText(writer, structure); }); } } class ConstructorDeclarationStructurePrinter extends NodePrinter { #options; constructor(factory, options) { super(factory); this.#options = options; } printTexts(writer, structures) { if (structures == null) return; for (let i = 0; i < structures.length; i++) { if (i > 0) { if (this.#options.isAmbient) writer.newLine(); else writer.blankLine(); } this.printText(writer, structures[i]); } } printTextInternal(writer, structure) { this.#printOverloads(writer, getOverloadStructures()); this.#printHeader(writer, structure); if (this.#options.isAmbient) writer.write(";"); else { writer.space().inlineBlock(() => { this.factory.forStatementedNode(this.#options).printText(writer, structure); }); } function getOverloadStructures() { const overloads = common.ObjectUtils.clone(structure.overloads); if (overloads == null || overloads.length === 0) return; for (const overload of overloads) setValueIfUndefined(overload, "scope", structure.scope); return overloads; } } #printOverloads(writer, structures) { if (structures == null || structures.length === 0) return; for (const structure of structures) { this.printOverload(writer, structure); writer.newLine(); } } printOverload(writer, structure) { this.printLeadingTrivia(writer, structure); this.#printHeader(writer, structure); writer.write(";"); this.printTrailingTrivia(writer, structure); } #printHeader(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forModifierableNode().printText(writer, structure); writer.write("constructor"); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters); } } class GetAccessorDeclarationStructurePrinter extends NodePrinter { #options; #multipleWriter; constructor(factory, options) { super(factory); this.#options = options; this.#multipleWriter = this.#options.isAmbient ? new NewLineFormattingStructuresPrinter(this) : new BlankLineFormattingStructuresPrinter(this); } printTexts(writer, structures) { if (structures != null) this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forDecorator().printTexts(writer, structure.decorators); this.factory.forModifierableNode().printText(writer, structure); writer.write(`get ${structure.name}`); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters); this.factory.forReturnTypedNode().printText(writer, structure); if (this.#options.isAmbient || structure.isAbstract) writer.write(";"); else { writer.spaceIfLastNot().inlineBlock(() => { this.factory.forStatementedNode(this.#options).printText(writer, structure); }); } } } class MethodDeclarationStructurePrinter extends NodePrinter { #options; constructor(factory, options) { super(factory); this.#options = options; } printTexts(writer, structures) { if (structures == null) return; for (let i = 0; i < structures.length; i++) { if (i > 0) { if (this.#options.isAmbient) writer.newLine(); else writer.blankLine(); } this.printText(writer, structures[i]); } } printTextInternal(writer, structure) { this.#printOverloads(writer, structure.name, getOverloadStructures()); this.#printHeader(writer, structure.name, structure); if (this.#options.isAmbient || structure.isAbstract) writer.write(";"); else { writer.spaceIfLastNot().inlineBlock(() => { this.factory.forStatementedNode(this.#options).printText(writer, structure); }); } function getOverloadStructures() { const overloads = common.ObjectUtils.clone(structure.overloads); if (overloads == null || overloads.length === 0) return; for (const overload of overloads) { setValueIfUndefined(overload, "scope", structure.scope); setValueIfUndefined(overload, "isStatic", structure.isStatic); setValueIfUndefined(overload, "isAbstract", structure.isAbstract); setValueIfUndefined(overload, "hasQuestionToken", structure.hasQuestionToken); } return overloads; } } #printOverloads(writer, name, structures) { if (structures == null || structures.length === 0) return; for (const structure of structures) { this.printOverload(writer, name, structure); writer.newLine(); } } printOverload(writer, name, structure) { this.printLeadingTrivia(writer, structure); this.#printHeader(writer, name, structure); writer.write(";"); this.printTrailingTrivia(writer, structure); } #printHeader(writer, name, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); if (structure.decorators != null) this.factory.forDecorator().printTexts(writer, structure.decorators); this.factory.forModifierableNode().printText(writer, structure); writer.conditionalWrite(structure.isGenerator, "*"); writer.write(name); writer.conditionalWrite(structure.hasQuestionToken, "?"); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters); this.factory.forReturnTypedNode().printText(writer, structure); } } class PropertyDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forDecorator().printTexts(writer, structure.decorators); this.factory.forModifierableNode().printText(writer, structure); writer.write(structure.name); writer.conditionalWrite(structure.hasQuestionToken, "?"); writer.conditionalWrite(structure.hasExclamationToken && !structure.hasQuestionToken, "!"); this.factory.forTypedNode(":").printText(writer, structure); this.factory.forInitializerExpressionableNode().printText(writer, structure); writer.write(";"); } } class SetAccessorDeclarationStructurePrinter extends NodePrinter { #options; #multipleWriter; constructor(factory, options) { super(factory); this.#options = options; this.#multipleWriter = this.#options.isAmbient ? new NewLineFormattingStructuresPrinter(this) : new BlankLineFormattingStructuresPrinter(this); } printTexts(writer, structures) { if (structures != null) this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forDecorator().printTexts(writer, structure.decorators); this.factory.forModifierableNode().printText(writer, structure); writer.write(`set ${structure.name}`); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters); this.factory.forReturnTypedNode().printText(writer, structure); if (this.#options.isAmbient || structure.isAbstract) writer.write(";"); else { writer.spaceIfLastNot().inlineBlock(() => { this.factory.forStatementedNode(this.#options).printText(writer, structure); }); } } } class StringStructurePrinter extends Printer { printText(writer, textOrWriterFunc) { if (typeof textOrWriterFunc === "string") writer.write(textOrWriterFunc); else textOrWriterFunc(writer); } } class DecoratorStructurePrinter extends NodePrinter { printTexts(writer, structures) { this.#printMultiple(writer, structures, () => writer.newLine()); } printTextsInline(writer, structures) { this.#printMultiple(writer, structures, () => writer.space()); } printTextInternal(writer, structure) { writer.write(`@${structure.name}`); this.#printTypeArguments(writer, structure); this.#printArguments(writer, structure); } #printTypeArguments(writer, structure) { if (structure.typeArguments == null || structure.typeArguments.length === 0) return; writer.write("<"); for (let i = 0; i < structure.typeArguments.length; i++) { writer.conditionalWrite(i > 0, ", "); writer.write(this.getTextWithQueuedChildIndentation(writer, structure.typeArguments[i])); } writer.write(">"); } #printArguments(writer, structure) { if (structure.arguments == null) return; writer.write("("); const args = structure.arguments instanceof Array ? structure.arguments : [structure.arguments]; for (let i = 0; i < args.length; i++) { writer.conditionalWrite(i > 0, ", "); writer.write(this.getTextWithQueuedChildIndentation(writer, args[i])); } writer.write(")"); } #printMultiple(writer, structures, separator) { if (structures == null || structures.length === 0) return; for (const structure of structures) { this.printText(writer, structure); separator(); } } } class JSDocStructurePrinter extends NodePrinter { printDocs(writer, structures) { if (structures == null) return; for (const structure of structures) { this.printText(writer, structure); writer.newLine(); } } printTextInternal(writer, structure) { const text = getText(this); const lines = text.split(/\r?\n/); const startsWithNewLine = lines[0].length === 0; const isSingleLine = lines.length <= 1; const startIndex = startsWithNewLine ? 1 : 0; writer.write("/**"); if (isSingleLine) writer.space(); else writer.newLine(); if (isSingleLine) writer.write(lines[startIndex]); else { for (let i = startIndex; i < lines.length; i++) { writer.write(` *`); if (lines[i].length > 0) writer.write(` ${lines[i]}`); writer.newLine(); } } writer.spaceIfLastNot(); writer.write("*/"); function getText(jsdocPrinter) { if (typeof structure === "string") return structure; const tempWriter = jsdocPrinter.getNewWriter(writer); if (typeof structure === "function") structure(tempWriter); else { if (structure.description) printTextFromStringOrWriter(tempWriter, structure.description); if (structure.tags && structure.tags.length > 0) { if (tempWriter.getLength() > 0) tempWriter.newLine(); jsdocPrinter.factory.forJSDocTag({ printStarsOnNewLine: false }).printTexts(tempWriter, structure.tags); } } return tempWriter.toString(); } } } class JSDocTagStructurePrinter extends NodePrinter { #options; constructor(factory, options) { super(factory); this.#options = options; } printTexts(writer, structures) { if (structures == null) return; for (let i = 0; i < structures.length; i++) { if (i > 0) { writer.newLine(); writer.conditionalWrite(this.#options.printStarsOnNewLine, " * "); } this.printText(writer, structures[i]); } } printTextInternal(writer, structure) { const text = getText(this); const lines = text.split(/\r?\n/); for (let i = 0; i < lines.length; i++) { if (i > 0) { writer.newLine(); if (this.#options.printStarsOnNewLine) writer.write(` *`); } if (lines[i].length > 0) { if (this.#options.printStarsOnNewLine && i > 0) writer.space(); writer.write(lines[i]); } } function getText(tagPrinter) { if (typeof structure === "string") return structure; const tempWriter = tagPrinter.getNewWriter(writer); if (typeof structure === "function") structure(tempWriter); else { if (structure.text) printTextFromStringOrWriter(tempWriter, structure.text); const currentText = tempWriter.toString(); tempWriter.unsafeInsert(0, `@${structure.tagName}` + (currentText.length > 0 && !common.StringUtils.startsWithNewLine(currentText) ? " " : "")); } return tempWriter.toString(); } } } class EnumDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new BlankLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forModifierableNode().printText(writer, structure); writer.conditionalWrite(structure.isConst, "const "); writer.write(`enum ${structure.name} `).inlineBlock(() => { this.factory.forEnumMember().printTexts(writer, structure.members); }); } } class EnumMemberStructurePrinter extends NodePrinter { #multipleWriter = new CommaNewLineSeparatedStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { if (structure instanceof Function) { structure(writer); return; } else if (typeof structure === "string") { writer.write(structure); return; } this.factory.forJSDoc().printDocs(writer, structure.docs); if (isValidVariableName(structure.name) || common.StringUtils.isQuoted(structure.name)) writer.write(structure.name); else writer.quote(structure.name); if (typeof structure.value === "string") { const { value } = structure; writer.hangingIndent(() => writer.write(` = `).quote(value)); } else if (typeof structure.value === "number") writer.write(` = ${structure.value}`); else this.factory.forInitializerExpressionableNode().printText(writer, structure); } } class ObjectLiteralExpressionPropertyStructurePrinter extends Printer { #factory; #multipleWriter = new CommaNewLineSeparatedStructuresPrinter(this); #options = { isAmbient: false }; constructor(factory) { super(); this.#factory = factory; } printTexts(writer, members) { this.#multipleWriter.printText(writer, members); } printText(writer, member) { if (typeof member === "string" || member instanceof Function || member == null) { this.printTextOrWriterFunc(writer, member); return; } switch (member.kind) { case exports.StructureKind.PropertyAssignment: this.#factory.forPropertyAssignment().printText(writer, member); break; case exports.StructureKind.ShorthandPropertyAssignment: this.#factory.forShorthandPropertyAssignment().printText(writer, member); break; case exports.StructureKind.SpreadAssignment: this.#factory.forSpreadAssignment().printText(writer, member); break; case exports.StructureKind.Method: this.#factory.forMethodDeclaration(this.#options).printText(writer, member); break; case exports.StructureKind.GetAccessor: this.#factory.forGetAccessorDeclaration(this.#options).printText(writer, member); break; case exports.StructureKind.SetAccessor: this.#factory.forSetAccessorDeclaration(this.#options).printText(writer, member); break; default: common.errors.throwNotImplementedForNeverValueError(member); } } } class PropertyAssignmentStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { writer.hangingIndent(() => { writer.write(`${structure.name}: `); printTextFromStringOrWriter(writer, structure.initializer); }); } } class ShorthandPropertyAssignmentStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { writer.write(`${structure.name}`); } } class SpreadAssignmentStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { writer.hangingIndent(() => { writer.write("..."); printTextFromStringOrWriter(writer, structure.expression); }); } } class FunctionDeclarationStructurePrinter extends NodePrinter { #options; constructor(factory, options) { super(factory); this.#options = options; } printTexts(writer, structures) { if (structures == null) return; for (let i = 0; i < structures.length; i++) { const currentStructure = structures[i]; if (i > 0) { const previousStructure = structures[i - 1]; if (this.#options.isAmbient || previousStructure.hasDeclareKeyword && currentStructure.hasDeclareKeyword) writer.newLine(); else writer.blankLine(); } this.printText(writer, currentStructure); } } printTextInternal(writer, structure) { this.#printOverloads(writer, structure.name, getOverloadStructures()); this.#printHeader(writer, structure.name, structure); if (this.#options.isAmbient || structure.hasDeclareKeyword) writer.write(";"); else { writer.space().inlineBlock(() => { this.factory.forStatementedNode({ isAmbient: false }).printText(writer, structure); }); } function getOverloadStructures() { const overloads = common.ObjectUtils.clone(structure.overloads); if (overloads == null || overloads.length === 0) return; for (const overload of overloads) { setValueIfUndefined(overload, "hasDeclareKeyword", structure.hasDeclareKeyword); setValueIfUndefined(overload, "isExported", structure.isExported); setValueIfUndefined(overload, "isDefaultExport", structure.isDefaultExport); } return overloads; } } #printOverloads(writer, name, structures) { if (structures == null || structures.length === 0) return; for (const structure of structures) { this.printOverload(writer, name, structure); writer.newLine(); } } printOverload(writer, name, structure) { this.printLeadingTrivia(writer, structure); this.#printHeader(writer, name, structure); writer.write(";"); this.printTrailingTrivia(writer, structure); } #printHeader(writer, name, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forModifierableNode().printText(writer, structure); writer.write(`function`); writer.conditionalWrite(structure.isGenerator, "*"); if (!common.StringUtils.isNullOrWhitespace(name)) writer.write(` ${name}`); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters); this.factory.forReturnTypedNode().printText(writer, structure); } } class ParameterDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new CommaSeparatedStructuresPrinter(this); printTextsWithParenthesis(writer, structures) { writer.write("("); if (structures != null) this.factory.forParameterDeclaration().printTexts(writer, structures); writer.write(`)`); } printTexts(writer, structures) { if (structures == null || structures.length === 0) return; writer.hangingIndent(() => { this.#multipleWriter.printText(writer, structures); }); } printTextInternal(writer, structure) { if (structure.name == null) { throw new common.errors .NotImplementedError("Not implemented scenario where parameter declaration structure doesn't have a name. Please open an issue if you need this."); } this.factory.forDecorator().printTextsInline(writer, structure.decorators); this.factory.forModifierableNode().printText(writer, structure); writer.conditionalWrite(structure.isRestParameter, "..."); writer.write(structure.name); writer.conditionalWrite(structure.hasQuestionToken, "?"); this.factory.forTypedNode(":", structure.hasQuestionToken).printText(writer, structure); this.factory.forInitializerExpressionableNode().printText(writer, structure); } } class CallSignatureDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters); this.factory.forReturnTypedNode(true).printText(writer, structure); writer.write(";"); } } class ConstructSignatureDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); writer.write("new"); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters); this.factory.forReturnTypedNode().printText(writer, structure); writer.write(";"); } } class IndexSignatureDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forModifierableNode().printText(writer, structure); writer.write(`[${structure.keyName || "key"}: ${structure.keyType || "string"}]`); this.factory.forReturnTypedNode().printText(writer, structure); writer.write(";"); } } class InterfaceDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new BlankLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forModifierableNode().printText(writer, structure); writer.write(`interface ${structure.name}`); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); writer.space(); if (structure.extends != null) { const extendsText = structure.extends instanceof Array ? structure.extends.map(i => this.getText(writer, i)).join(", ") : this.getText(writer, structure.extends); if (!common.StringUtils.isNullOrWhitespace(extendsText)) writer.hangingIndent(() => writer.write(`extends ${extendsText} `)); } writer.inlineBlock(() => { this.factory.forTypeElementMemberedNode().printText(writer, structure); }); } } class MethodSignatureStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); writer.write(structure.name); writer.conditionalWrite(structure.hasQuestionToken, "?"); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters); this.factory.forReturnTypedNode().printText(writer, structure); writer.write(";"); } } class PropertySignatureStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forModifierableNode().printText(writer, structure); writer.write(structure.name); writer.conditionalWrite(structure.hasQuestionToken, "?"); this.factory.forTypedNode(":").printText(writer, structure); this.factory.forInitializerExpressionableNode().printText(writer, structure); writer.write(";"); } } class TypeElementMemberedNodeStructurePrinter extends Printer { #factory; constructor(factory) { super(); this.#factory = factory; } printText(writer, structure) { this.#factory.forCallSignatureDeclaration().printTexts(writer, structure.callSignatures); this.#conditionalSeparator(writer, structure.constructSignatures); this.#factory.forConstructSignatureDeclaration().printTexts(writer, structure.constructSignatures); this.#conditionalSeparator(writer, structure.indexSignatures); this.#factory.forIndexSignatureDeclaration().printTexts(writer, structure.indexSignatures); this.#printGetAndSet(writer, structure); this.#conditionalSeparator(writer, structure.properties); this.#factory.forPropertySignature().printTexts(writer, structure.properties); this.#conditionalSeparator(writer, structure.methods); this.#factory.forMethodSignature().printTexts(writer, structure.methods); } #printGetAndSet(writer, structure) { if (structure.getAccessors == null && structure.setAccessors == null) return; const getAccessorWriter = this.#factory.forGetAccessorDeclaration({ isAmbient: true }); const setAccessorWriter = this.#factory.forSetAccessorDeclaration({ isAmbient: true }); const combinedPrinter = new GetAndSetAccessorStructurePrinter(getAccessorWriter, setAccessorWriter); combinedPrinter.printGetAndSet(writer, structure.getAccessors, structure.setAccessors, true); } #conditionalSeparator(writer, structures) { if (!common.ArrayUtils.isNullOrEmpty(structures) && !writer.isAtStartOfFirstLineOfBlock()) writer.newLine(); } } class TypeElementMemberStructurePrinter extends Printer { #factory; constructor(factory) { super(); this.#factory = factory; } printTexts(writer, members) { if (members == null) return; if (typeof members === "string" || members instanceof Function) this.printText(writer, members); else { for (const member of members) { if (isLastNonWhitespaceCharCloseBrace(writer)) writer.blankLineIfLastNot(); else if (!writer.isAtStartOfFirstLineOfBlock()) writer.newLineIfLastNot(); this.printText(writer, member); } } } printText(writer, members) { if (typeof members === "string" || members instanceof Function || members == null) { this.printTextOrWriterFunc(writer, members); return; } switch (members.kind) { case exports.StructureKind.PropertySignature: this.#factory.forPropertySignature().printText(writer, members); break; case exports.StructureKind.MethodSignature: this.#factory.forMethodSignature().printText(writer, members); break; case exports.StructureKind.CallSignature: this.#factory.forCallSignatureDeclaration().printText(writer, members); break; case exports.StructureKind.IndexSignature: this.#factory.forIndexSignatureDeclaration().printText(writer, members); break; case exports.StructureKind.ConstructSignature: this.#factory.forConstructSignatureDeclaration().printText(writer, members); break; default: common.errors.throwNotImplementedForNeverValueError(members); } } } class JsxAttributeDeciderStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { if (isJsxAttribute()) this.factory.forJsxAttribute().printTextWithoutTrivia(writer, structure); else if (structure.kind === exports.StructureKind.JsxSpreadAttribute) this.factory.forJsxSpreadAttribute().printTextWithoutTrivia(writer, structure); else throw common.errors.throwNotImplementedForNeverValueError(structure); function isJsxAttribute(struct) { return structure.kind == null || structure.kind === exports.StructureKind.JsxAttribute; } } } class JsxAttributeStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { if (typeof structure.name === "object") this.factory.forJsxNamespacedName().printText(writer, structure.name); else writer.write(structure.name); if (structure.initializer != null) writer.write("=").write(structure.initializer); } } class JsxChildDeciderStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { if (isJsxElement(structure)) this.factory.forJsxElement().printText(writer, structure); else if (structure.kind === exports.StructureKind.JsxSelfClosingElement) this.factory.forJsxSelfClosingElement().printText(writer, structure); else common.errors.throwNotImplementedForNeverValueError(structure); function isJsxElement(struct) { return struct.kind == null || struct.kind === exports.StructureKind.JsxElement; } } } class JsxElementStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { writer.hangingIndent(() => { writer.write(`<${structure.name}`); if (structure.attributes) this.#printAttributes(writer, structure.attributes); writer.write(">"); }); this.#printChildren(writer, structure.children); writer.write(``); } #printAttributes(writer, attributes) { const attributePrinter = this.factory.forJsxAttributeDecider(); for (const attrib of attributes) { writer.space(); attributePrinter.printText(writer, attrib); } } #printChildren(writer, children) { if (children == null) return; writer.newLine(); writer.indent(() => { for (const child of children) { this.factory.forJsxChildDecider().printText(writer, child); writer.newLine(); } }); } } class JsxNamespacedNameStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { writer.write(structure.namespace).write(":").write(structure.name); } } class JsxSelfClosingElementStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { writer.hangingIndent(() => { writer.write(`<${structure.name}`); if (structure.attributes) this.#printAttributes(writer, structure.attributes); writer.write(" />"); }); } #printAttributes(writer, attributes) { const attributePrinter = this.factory.forJsxAttributeDecider(); for (const attrib of attributes) { writer.space(); attributePrinter.printText(writer, attrib); } } } class JsxSpreadAttributeStructurePrinter extends NodePrinter { printTextInternal(writer, structure) { writer.hangingIndent(() => { writer.write("{"); writer.write("..."); writer.write(structure.expression); writer.write("}"); }); } } class ExportAssignmentStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); writer.write("export"); if (structure.isExportEquals !== false) writer.write(" = "); else writer.write(" default "); writer.write(this.getTextWithQueuedChildIndentation(writer, structure.expression)).write(";"); } } class ExportDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { const hasModuleSpecifier = structure.moduleSpecifier != null && structure.moduleSpecifier.length > 0; const hasNamedImport = structure.namedExports != null && structure.namedExports.length > 0; if (hasNamedImport && structure.namespaceExport != null) throw new common.errors.InvalidOperationError("An export declaration cannot have both a namespace export and a named export."); writer.write("export"); if (structure.isTypeOnly) writer.write(" type"); if (structure.namedExports != null && structure.namedExports.length > 0) { writer.space(); this.factory.forNamedImportExportSpecifier().printTextsWithBraces(writer, structure.namedExports); } else if (structure.namespaceExport != null) { writer.write(" *"); if (!common.StringUtils.isNullOrWhitespace(structure.namespaceExport)) writer.write(` as ${structure.namespaceExport}`); } else if (!hasModuleSpecifier) { writer.write(" {") .conditionalWrite(this.factory.getFormatCodeSettings().insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces, " ") .write("}"); } else { writer.write(` *`); } if (hasModuleSpecifier) { writer.write(" from "); writer.quote(structure.moduleSpecifier); } if (structure.attributes) { writer.space(); this.factory.forImportAttribute().printAttributes(writer, structure.attributes); } writer.write(";"); } } class ImportAttributeStructurePrinter extends NodePrinter { #multipleWriter = new CommaNewLineSeparatedStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printAttributes(writer, structures) { if (!structures) return; writer.write("with "); writer.inlineBlock(() => { this.printTexts(writer, structures); }); } printTextInternal(writer, structure) { writer.write(structure.name); writer.write(": "); writer.quote(structure.value); } } class ImportDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { const hasNamedImport = structure.namedImports != null && structure.namedImports.length > 0; if (hasNamedImport && structure.namespaceImport != null) throw new common.errors.InvalidOperationError("An import declaration cannot have both a namespace import and a named import."); writer.write("import"); if (structure.isTypeOnly) writer.write(" type"); if (structure.defaultImport != null) { writer.write(` ${structure.defaultImport}`); writer.conditionalWrite(hasNamedImport || structure.namespaceImport != null, ","); } if (structure.namespaceImport != null) writer.write(` * as ${structure.namespaceImport}`); if (structure.namedImports != null && structure.namedImports.length > 0) { writer.space(); this.factory.forNamedImportExportSpecifier().printTextsWithBraces(writer, structure.namedImports); } writer.conditionalWrite(structure.defaultImport != null || hasNamedImport || structure.namespaceImport != null, " from"); writer.write(" "); writer.quote(structure.moduleSpecifier); if (structure.attributes) { writer.space(); this.factory.forImportAttribute().printAttributes(writer, structure.attributes); } writer.write(";"); } } class ModuleDeclarationStructurePrinter extends NodePrinter { #options; #blankLineFormattingWriter = new BlankLineFormattingStructuresPrinter(this); constructor(factory, options) { super(factory); this.#options = options; } printTexts(writer, structures) { this.#blankLineFormattingWriter.printText(writer, structures); } printTextInternal(writer, structure) { structure = this.#validateAndGetStructure(structure); this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forModifierableNode().printText(writer, structure); if (structure.declarationKind == null || structure.declarationKind !== exports.ModuleDeclarationKind.Global) writer.write(`${structure.declarationKind || "namespace"} ${structure.name}`); else writer.write("global"); if (structure.hasDeclareKeyword && common.StringUtils.isQuoted(structure.name.trim()) && structure.hasOwnProperty(common.nameof(structure, "statements")) && structure.statements == null) { writer.write(";"); } else { writer.write(" "); writer.inlineBlock(() => { this.factory.forStatementedNode({ isAmbient: structure.hasDeclareKeyword || this.#options.isAmbient, }).printText(writer, structure); }); } } #validateAndGetStructure(structure) { if (common.StringUtils.isQuoted(structure.name.trim())) { if (structure.declarationKind === exports.ModuleDeclarationKind.Namespace) { throw new common.errors.InvalidOperationError(`Cannot print a namespace with quotes for namespace with name ${structure.name}. ` + `Use ModuleDeclarationKind.Module instead.`); } structure = common.ObjectUtils.clone(structure); setValueIfUndefined(structure, "hasDeclareKeyword", true); setValueIfUndefined(structure, "declarationKind", exports.ModuleDeclarationKind.Module); } return structure; } } class NamedImportExportSpecifierStructurePrinter extends NodePrinter { #multipleWriter = new CommaSeparatedStructuresPrinter(this); printTextsWithBraces(writer, structures) { const formatSettings = this.factory.getFormatCodeSettings(); writer.write("{"); const specifierWriter = this.getNewWriter(writer); this.printTexts(specifierWriter, structures); const specifierText = specifierWriter.toString(); if (formatSettings.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces && !common.StringUtils.startsWithNewLine(specifierText)) writer.space(); writer.write(specifierText); if (formatSettings.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces && !common.StringUtils.endsWithNewLine(specifierText)) writer.space(); writer.write("}"); } printTexts(writer, structures) { if (structures instanceof Function) this.printText(writer, structures); else this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { const specifierWriter = this.getNewWriterWithQueuedChildIndentation(writer); if (typeof structure === "string") specifierWriter.write(structure); else if (structure instanceof Function) structure(specifierWriter); else { if (structure.isTypeOnly) writer.write("type "); specifierWriter.write(structure.name); if (!common.StringUtils.isNullOrWhitespace(structure.alias)) { if (!specifierWriter.isLastNewLine()) specifierWriter.space(); specifierWriter.write(`as ${structure.alias}`); } } writer.write(specifierWriter.toString()); } } class SourceFileStructurePrinter extends NodePrinter { #options; constructor(factory, options) { super(factory); this.#options = options; } printTextInternal(writer, structure) { this.factory.forStatementedNode(this.#options).printText(writer, structure); writer.conditionalNewLine(!writer.isAtStartOfFirstLineOfBlock() && !writer.isLastNewLine()); } } class StatementedNodeStructurePrinter extends Printer { #options; #factory; constructor(factory, options) { super(); this.#factory = factory; this.#options = options; } printText(writer, structure) { this.#factory.forStatement(this.#options).printTexts(writer, structure.statements); } } class StatementStructurePrinter extends Printer { #options; #factory; constructor(factory, options) { super(); this.#factory = factory; this.#options = options; } printTexts(writer, statements) { if (statements == null) return; if (typeof statements === "string" || statements instanceof Function) this.printText(writer, statements); else { for (const statement of statements) { if (isLastNonWhitespaceCharCloseBrace(writer)) writer.blankLineIfLastNot(); else if (!writer.isAtStartOfFirstLineOfBlock()) writer.newLineIfLastNot(); this.printText(writer, statement); } } } printText(writer, statement) { if (typeof statement === "string" || statement instanceof Function || statement == null) { this.printTextOrWriterFunc(writer, statement); return; } switch (statement.kind) { case exports.StructureKind.Function: if (!this.#options.isAmbient) ensureBlankLine(); this.#factory.forFunctionDeclaration(this.#options).printText(writer, statement); break; case exports.StructureKind.Class: ensureBlankLine(); this.#factory.forClassDeclaration(this.#options).printText(writer, statement); break; case exports.StructureKind.Interface: ensureBlankLine(); this.#factory.forInterfaceDeclaration().printText(writer, statement); break; case exports.StructureKind.TypeAlias: this.#factory.forTypeAliasDeclaration().printText(writer, statement); break; case exports.StructureKind.VariableStatement: this.#factory.forVariableStatement().printText(writer, statement); break; case exports.StructureKind.ImportDeclaration: this.#factory.forImportDeclaration().printText(writer, statement); break; case exports.StructureKind.Module: ensureBlankLine(); this.#factory.forModuleDeclaration(this.#options).printText(writer, statement); break; case exports.StructureKind.Enum: ensureBlankLine(); this.#factory.forEnumDeclaration().printText(writer, statement); break; case exports.StructureKind.ExportDeclaration: this.#factory.forExportDeclaration().printText(writer, statement); break; case exports.StructureKind.ExportAssignment: this.#factory.forExportAssignment().printText(writer, statement); break; default: common.errors.throwNotImplementedForNeverValueError(statement); } function ensureBlankLine() { if (!writer.isAtStartOfFirstLineOfBlock()) writer.blankLineIfLastNot(); } } } exports.VariableDeclarationKind = void 0; (function (VariableDeclarationKind) { VariableDeclarationKind["Var"] = "var"; VariableDeclarationKind["Let"] = "let"; VariableDeclarationKind["Const"] = "const"; VariableDeclarationKind["AwaitUsing"] = "await using"; VariableDeclarationKind["Using"] = "using"; })(exports.VariableDeclarationKind || (exports.VariableDeclarationKind = {})); class VariableStatementStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); writer.hangingIndent(() => { this.factory.forModifierableNode().printText(writer, structure); writer.write(`${structure.declarationKind || exports.VariableDeclarationKind.Let} `); this.factory.forVariableDeclaration().printTexts(writer, structure.declarations); writer.write(";"); }); } } class TypeAliasDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new NewLineFormattingStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { this.factory.forJSDoc().printDocs(writer, structure.docs); this.factory.forModifierableNode().printText(writer, structure); writer.write(`type ${structure.name}`); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); this.factory.forTypedNode(" =").printText(writer, structure); writer.write(";"); } } class TypeParameterDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new CommaSeparatedStructuresPrinter(this); printTextsWithBrackets(writer, structures) { if (structures == null || structures.length === 0) return; writer.write("<"); this.printTexts(writer, structures); writer.write(">"); } printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { if (typeof structure === "string") { writer.write(structure); return; } writer.hangingIndent(() => { if (structure.isConst) writer.write("const "); if (structure.variance != null) { if ((structure.variance & exports.TypeParameterVariance.In) !== 0) writer.write("in "); if ((structure.variance & exports.TypeParameterVariance.Out) !== 0) writer.write("out "); } writer.write(structure.name); if (structure.constraint != null) { const constraintText = this.getText(writer, structure.constraint); if (!common.StringUtils.isNullOrWhitespace(constraintText)) writer.write(` extends ${constraintText}`); } if (structure.default != null) { const defaultText = this.getText(writer, structure.default); if (!common.StringUtils.isNullOrWhitespace(defaultText)) writer.write(` = ${defaultText}`); } }); } } class VariableDeclarationStructurePrinter extends NodePrinter { #multipleWriter = new CommaSeparatedStructuresPrinter(this); printTexts(writer, structures) { this.#multipleWriter.printText(writer, structures); } printTextInternal(writer, structure) { writer.write(structure.name); writer.conditionalWrite(structure.hasExclamationToken, "!"); this.factory.forTypedNode(":").printText(writer, structure); this.factory.forInitializerExpressionableNode().printText(writer, structure); } } function ExtendsClauseableNode(Base) { return class extends Base { getExtends() { const extendsClause = this.getHeritageClauseByKind(common.SyntaxKind.ExtendsKeyword); return extendsClause?.getTypeNodes() ?? []; } addExtends(text) { return this.insertExtends(this.getExtends().length, text); } insertExtends(index, texts) { const originalExtends = this.getExtends(); const wasStringInput = typeof texts === "string"; if (typeof texts === "string") { common.errors.throwIfWhitespaceOrNotString(texts, "texts"); texts = [texts]; } else if (texts.length === 0) { return []; } const writer = this._getWriterWithQueuedChildIndentation(); const structurePrinter = new CommaSeparatedStructuresPrinter(new StringStructurePrinter()); structurePrinter.printText(writer, texts); index = verifyAndGetIndex(index, originalExtends.length); if (originalExtends.length > 0) { const extendsClause = this.getHeritageClauseByKindOrThrow(common.SyntaxKind.ExtendsKeyword); insertIntoCommaSeparatedNodes({ parent: extendsClause.getFirstChildByKindOrThrow(common.SyntaxKind.SyntaxList), currentNodes: originalExtends, insertIndex: index, newText: writer.toString(), useTrailingCommas: false, }); } else { const openBraceToken = this.getFirstChildByKindOrThrow(common.SyntaxKind.OpenBraceToken); const openBraceStart = openBraceToken.getStart(); const isLastSpace = /\s/.test(this.getSourceFile().getFullText()[openBraceStart - 1]); let insertText = `extends ${writer.toString()} `; if (!isLastSpace) insertText = " " + insertText; insertIntoParentTextRange({ parent: this, insertPos: openBraceStart, newText: insertText, }); } const newExtends = this.getExtends(); return wasStringInput ? newExtends[index] : getNodesToReturn(originalExtends, newExtends, index, false); } removeExtends(implementsNodeOrIndex) { const extendsClause = this.getHeritageClauseByKind(common.SyntaxKind.ExtendsKeyword); if (extendsClause == null) throw new common.errors.InvalidOperationError("Cannot remove an extends when none exist."); extendsClause.removeExpression(implementsNodeOrIndex); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.extends != null) { this.getExtends().forEach(e => this.removeExtends(e)); this.addExtends(structure.extends); } return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { extends: this.getExtends().map(e => e.getText()), }); } }; } function GeneratorableNode(Base) { return class extends Base { isGenerator() { return this.compilerNode.asteriskToken != null; } getAsteriskToken() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.asteriskToken); } getAsteriskTokenOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getAsteriskToken(), message ?? "Expected to find an asterisk token.", this); } setIsGenerator(value) { const asteriskToken = this.getAsteriskToken(); const isSet = asteriskToken != null; if (isSet === value) return this; if (asteriskToken == null) { insertIntoParentTextRange({ insertPos: getAsteriskInsertPos(this), parent: this, newText: "*", }); } else { removeChildrenWithFormatting({ children: [asteriskToken], getSiblingFormatting: () => FormattingKind.Space, }); } return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.isGenerator != null) this.setIsGenerator(structure.isGenerator); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { isGenerator: this.isGenerator(), }); } }; } function getAsteriskInsertPos(node) { if (node.getKind() === common.SyntaxKind.FunctionDeclaration) return node.getFirstChildByKindOrThrow(common.SyntaxKind.FunctionKeyword).getEnd(); const namedNode = node; if (namedNode.getName == null) throw new common.errors.NotImplementedError("Expected a name node for a non-function declaration."); return namedNode.getNameNode().getStart(); } function HeritageClauseableNode(Base) { return class extends Base { getHeritageClauses() { const heritageClauses = this.compilerNode.heritageClauses; return heritageClauses?.map(c => this._getNodeFromCompilerNode(c)) ?? []; } getHeritageClauseByKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getHeritageClauseByKind(kind), message ?? (() => `Expected to have heritage clause of kind ${common.getSyntaxKindName(kind)}.`), this); } getHeritageClauseByKind(kind) { return this.getHeritageClauses().find(c => c.compilerNode.token === kind); } }; } function ImplementsClauseableNode(Base) { return class extends Base { getImplements() { const implementsClause = this.getHeritageClauseByKind(common.SyntaxKind.ImplementsKeyword); return implementsClause?.getTypeNodes() ?? []; } addImplements(text) { return this.insertImplements(this.getImplements().length, text); } insertImplements(index, texts) { const originalImplements = this.getImplements(); const wasStringInput = typeof texts === "string"; if (typeof texts === "string") { common.errors.throwIfWhitespaceOrNotString(texts, "texts"); texts = [texts]; } else if (texts.length === 0) { return []; } const writer = this._getWriterWithQueuedChildIndentation(); const structurePrinter = new CommaSeparatedStructuresPrinter(new StringStructurePrinter()); structurePrinter.printText(writer, texts); const heritageClauses = this.getHeritageClauses(); index = verifyAndGetIndex(index, originalImplements.length); if (originalImplements.length > 0) { const implementsClause = this.getHeritageClauseByKindOrThrow(common.SyntaxKind.ImplementsKeyword); insertIntoCommaSeparatedNodes({ parent: implementsClause.getFirstChildByKindOrThrow(common.SyntaxKind.SyntaxList), currentNodes: originalImplements, insertIndex: index, newText: writer.toString(), useTrailingCommas: false, }); } else { const openBraceToken = this.getFirstChildByKindOrThrow(common.SyntaxKind.OpenBraceToken); const openBraceStart = openBraceToken.getStart(); const isLastSpace = /\s/.test(this.getSourceFile().getFullText()[openBraceStart - 1]); let insertText = `implements ${writer.toString()} `; if (!isLastSpace) insertText = " " + insertText; insertIntoParentTextRange({ parent: heritageClauses.length === 0 ? this : heritageClauses[0].getParentSyntaxListOrThrow(), insertPos: openBraceStart, newText: insertText, }); } const newImplements = this.getImplements(); return wasStringInput ? newImplements[0] : getNodesToReturn(originalImplements, newImplements, index, false); } removeImplements(implementsNodeOrIndex) { const implementsClause = this.getHeritageClauseByKind(common.SyntaxKind.ImplementsKeyword); if (implementsClause == null) throw new common.errors.InvalidOperationError("Cannot remove an implements when none exist."); implementsClause.removeExpression(implementsNodeOrIndex); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.implements != null) { this.getImplements().forEach(expr => this.removeImplements(expr)); this.addImplements(structure.implements); } return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { implements: this.getImplements().map(node => node.getText()), }); } }; } function InitializerExpressionGetableNode(Base) { return class extends Base { hasInitializer() { return this.compilerNode.initializer != null; } getInitializerIfKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getInitializerIfKind(kind), message ?? `Expected to find an initializer of kind '${common.getSyntaxKindName(kind)}'.`, this); } getInitializerIfKind(kind) { const initializer = this.getInitializer(); if (initializer != null && initializer.getKind() !== kind) return undefined; return initializer; } getInitializerOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getInitializer(), message ?? "Expected to find an initializer.", this); } getInitializer() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.initializer); } }; } function InitializerExpressionableNode(Base) { return apply(InitializerExpressionGetableNode(Base)); } function apply(Base) { return class extends Base { removeInitializer() { const initializer = this.getInitializer(); if (initializer == null) return this; const previousSibling = initializer.getPreviousSiblingIfKindOrThrow(common.SyntaxKind.EqualsToken); removeChildren({ children: [previousSibling, initializer], removePrecedingSpaces: true, }); return this; } setInitializer(textOrWriterFunction) { const text = getTextFromStringOrWriter(this._getWriterWithQueuedChildIndentation(), textOrWriterFunction); common.errors.throwIfWhitespaceOrNotString(text, "textOrWriterFunction"); if (this.hasInitializer()) this.removeInitializer(); const semiColonToken = this.getLastChildIfKind(common.SyntaxKind.SemicolonToken); insertIntoParentTextRange({ insertPos: semiColonToken != null ? semiColonToken.getPos() : this.getEnd(), parent: this, newText: ` = ${text}`, }); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.initializer != null) this.setInitializer(structure.initializer); else if (structure.hasOwnProperty(common.nameof(structure, "initializer"))) this.removeInitializer(); return this; } getStructure() { const initializer = this.getInitializer(); return callBaseGetStructure(Base.prototype, this, { initializer: initializer ? initializer.getText() : undefined, }); } }; } function JSDocableNode(Base) { return class extends Base { getJsDocs() { const nodes = this.compilerNode.jsDoc; return nodes?.map(n => this._getNodeFromCompilerNode(n)) ?? []; } addJsDoc(structure) { return this.addJsDocs([structure])[0]; } addJsDocs(structures) { return this.insertJsDocs(getEndIndexFromArray(this.compilerNode.jsDoc), structures); } insertJsDoc(index, structure) { return this.insertJsDocs(index, [structure])[0]; } insertJsDocs(index, structures) { if (common.ArrayUtils.isNullOrEmpty(structures)) return []; const writer = this._getWriterWithQueuedIndentation(); const structurePrinter = this._context.structurePrinterFactory.forJSDoc(); structurePrinter.printDocs(writer, structures); writer.write(""); const code = writer.toString(); const nodes = this.getJsDocs(); index = verifyAndGetIndex(index, nodes.length); const insertPos = index === nodes.length ? this.getStart() : nodes[index].getStart(); insertIntoParentTextRange({ insertPos, parent: this, newText: code, }); return getNodesToReturn(nodes, this.getJsDocs(), index, false); } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.docs != null) { this.getJsDocs().forEach(doc => doc.remove()); this.addJsDocs(structure.docs); } return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { docs: this.getJsDocs().map(jsdoc => jsdoc.getStructure()), }); } }; } function LiteralLikeNode(Base) { return class extends Base { getLiteralText() { return this.compilerNode.text; } isTerminated() { return !(this.compilerNode.isUnterminated || false); } hasExtendedUnicodeEscape() { return this.compilerNode.hasExtendedUnicodeEscape || false; } }; } function ModifierableNode(Base) { return class extends Base { getModifiers() { return this.getCompilerModifiers().map(m => this._getNodeFromCompilerNode(m)); } getFirstModifierByKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getFirstModifierByKind(kind), message ?? (() => `Expected a modifier of syntax kind: ${common.getSyntaxKindName(kind)}`), this); } getFirstModifierByKind(kind) { for (const modifier of this.getCompilerModifiers()) { if (modifier.kind === kind) return this._getNodeFromCompilerNode(modifier); } return undefined; } hasModifier(textOrKind) { if (typeof textOrKind === "string") return this.getModifiers().some(m => m.getText() === textOrKind); else return this.getCompilerModifiers().some(m => m.kind === textOrKind); } toggleModifier(text, value) { if (value == null) value = !this.hasModifier(text); if (value) this.addModifier(text); else this.removeModifier(text); return this; } addModifier(text) { const rawModifiers = this.getModifiers(); const modifiers = this.getModifiers().filter(m => m.getKind() !== common.SyntaxKind.Decorator); const existingModifier = modifiers.find(m => m.getText() === text); if (existingModifier != null) return existingModifier; const insertPos = getInsertPos(this); let startPos; let newText; const isFirstModifier = modifiers.length === 0 || insertPos === modifiers[0].getStart(); if (isFirstModifier) { newText = text + " "; startPos = insertPos; } else { newText = " " + text; startPos = insertPos + 1; } insertIntoParentTextRange({ parent: rawModifiers.length === 0 ? this : rawModifiers[0].getParentSyntaxListOrThrow(), insertPos, newText, }); return this.getModifiers().find(m => m.getStart() === startPos); function getInsertPos(node) { let pos = getInitialInsertPos(); for (const addAfterText of getAddAfterModifierTexts(text)) { for (let i = 0; i < modifiers.length; i++) { const modifier = modifiers[i]; if (modifier.getText() === addAfterText) { if (pos < modifier.getEnd()) pos = modifier.getEnd(); break; } } } return pos; function getInitialInsertPos() { if (modifiers.length > 0) return modifiers[0].getStart(); for (const child of node._getChildrenIterator()) { if (child.getKind() === common.SyntaxKind.SyntaxList || common.ts.isJSDocCommentContainingNode(child.compilerNode)) continue; return child.getStart(); } return node.getStart(); } } } removeModifier(text) { const modifiers = this.getModifiers(); const modifier = modifiers.find(m => m.getText() === text); if (modifier == null) return false; removeChildren({ children: [modifiers.length === 1 ? modifier.getParentSyntaxListOrThrow() : modifier], removeFollowingSpaces: true, }); return true; } getCompilerModifiers() { return this.compilerNode.modifiers ?? []; } }; } function getAddAfterModifierTexts(text) { switch (text) { case "export": return []; case "public": case "protected": case "private": return []; case "default": return ["export"]; case "const": return ["export"]; case "declare": return ["export", "default"]; case "static": return ["public", "protected", "private"]; case "override": return ["public", "private", "protected", "static"]; case "abstract": return ["export", "default", "declare", "public", "private", "protected", "static", "override"]; case "async": return ["export", "default", "declare", "public", "private", "protected", "static", "override", "abstract"]; case "readonly": return ["export", "default", "declare", "public", "private", "protected", "static", "override", "abstract"]; case "out": return ["const", "in"]; case "in": return ["const"]; case "accessor": return ["public", "private", "protected", "declare", "override", "static", "abstract", "readonly"]; default: common.errors.throwNotImplementedForNeverValueError(text); } } function ModuledNode(Base) { return class extends Base { addImportDeclaration(structure) { return this.addImportDeclarations([structure])[0]; } addImportDeclarations(structures) { const compilerChildren = this._getCompilerStatementsWithComments(); return this.insertImportDeclarations(getInsertIndex(), structures); function getInsertIndex() { let insertIndex = 0; let wasLastComment = true; for (let i = 0; i < compilerChildren.length; i++) { const child = compilerChildren[i]; if (wasLastComment && child.kind === common.SyntaxKind.MultiLineCommentTrivia) insertIndex = i + 1; else { wasLastComment = false; if (child.kind === common.SyntaxKind.ImportDeclaration) insertIndex = i + 1; } } return insertIndex; } } insertImportDeclaration(index, structure) { return this.insertImportDeclarations(index, [structure])[0]; } insertImportDeclarations(index, structures) { return this._insertChildren({ expectedKind: common.SyntaxKind.ImportDeclaration, index, structures, write: (writer, info) => { this._standardWrite(writer, info, () => { this._context.structurePrinterFactory.forImportDeclaration().printTexts(writer, structures); }, { previousNewLine: previousMember => Node.isImportDeclaration(previousMember) || isComment(previousMember.compilerNode), nextNewLine: nextMember => Node.isImportDeclaration(nextMember), }); }, }); } getImportDeclaration(conditionOrModuleSpecifier) { return this.getImportDeclarations().find(getCondition()); function getCondition() { if (typeof conditionOrModuleSpecifier === "string") return (dec) => dec.getModuleSpecifierValue() === conditionOrModuleSpecifier; else return conditionOrModuleSpecifier; } } getImportDeclarationOrThrow(conditionOrModuleSpecifier, message) { return common.errors.throwIfNullOrUndefined(this.getImportDeclaration(conditionOrModuleSpecifier), message ?? "Expected to find an import with the provided condition.", this); } getImportDeclarations() { return this.getStatements().filter(Node.isImportDeclaration); } addExportDeclaration(structure) { return this.addExportDeclarations([structure])[0]; } addExportDeclarations(structures) { return this.insertExportDeclarations(this.getChildSyntaxListOrThrow().getChildCount(), structures); } insertExportDeclaration(index, structure) { return this.insertExportDeclarations(index, [structure])[0]; } insertExportDeclarations(index, structures) { return this._insertChildren({ expectedKind: common.SyntaxKind.ExportDeclaration, index, structures, write: (writer, info) => { this._standardWrite(writer, info, () => { this._context.structurePrinterFactory.forExportDeclaration().printTexts(writer, structures); }, { previousNewLine: previousMember => Node.isExportDeclaration(previousMember) || isComment(previousMember.compilerNode), nextNewLine: nextMember => Node.isExportDeclaration(nextMember), }); }, }); } getExportDeclaration(conditionOrModuleSpecifier) { return this.getExportDeclarations().find(getCondition()); function getCondition() { if (typeof conditionOrModuleSpecifier === "string") return (dec) => dec.getModuleSpecifierValue() === conditionOrModuleSpecifier; else return conditionOrModuleSpecifier; } } getExportDeclarationOrThrow(conditionOrModuleSpecifier, message) { return common.errors.throwIfNullOrUndefined(this.getExportDeclaration(conditionOrModuleSpecifier), message ?? "Expected to find an export declaration with the provided condition.", this); } getExportDeclarations() { return this.getStatements().filter(Node.isExportDeclaration); } addExportAssignment(structure) { return this.addExportAssignments([structure])[0]; } addExportAssignments(structures) { return this.insertExportAssignments(this.getChildSyntaxListOrThrow().getChildCount(), structures); } insertExportAssignment(index, structure) { return this.insertExportAssignments(index, [structure])[0]; } insertExportAssignments(index, structures) { return this._insertChildren({ expectedKind: common.SyntaxKind.ExportAssignment, index, structures, write: (writer, info) => { this._standardWrite(writer, info, () => { this._context.structurePrinterFactory.forExportAssignment().printTexts(writer, structures); }, { previousNewLine: previousMember => Node.isExportAssignment(previousMember) || isComment(previousMember.compilerNode), nextNewLine: nextMember => Node.isExportAssignment(nextMember), }); }, }); } getExportAssignment(condition) { return this.getExportAssignments().find(condition); } getExportAssignmentOrThrow(condition, message) { return common.errors.throwIfNullOrUndefined(this.getExportAssignment(condition), message ?? "Expected to find an export assignment with the provided condition.", this); } getExportAssignments() { return this.getStatements().filter(Node.isExportAssignment); } getDefaultExportSymbol() { const sourceFileSymbol = this.getSymbol(); if (sourceFileSymbol == null) return undefined; return sourceFileSymbol.getExport("default"); } getDefaultExportSymbolOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getDefaultExportSymbol(), message ?? "Expected to find a default export symbol"); } getExportSymbols() { const symbol = this.getSymbol(); return symbol == null ? [] : this._context.typeChecker.getExportsOfModule(symbol); } getExportedDeclarations() { const result = new Map(); const exportSymbols = this.getExportSymbols(); for (const symbol of exportSymbols) { for (const declaration of symbol.getDeclarations()) { const declarations = Array.from(getDeclarationHandlingImportsAndExports(declaration)); const name = symbol.getName(); const existingArray = result.get(name); if (existingArray != null) existingArray.push(...declarations); else result.set(symbol.getName(), declarations); } } return result; function* getDeclarationHandlingImportsAndExports(declaration) { if (Node.isExportSpecifier(declaration)) { for (const d of declaration.getLocalTargetDeclarations()) yield* getDeclarationHandlingImportsAndExports(d); } else if (Node.isExportAssignment(declaration)) { const expression = declaration.getExpression(); if (expression == null || expression.getKind() !== common.SyntaxKind.Identifier) { yield expression; return; } yield* getDeclarationsForSymbol(expression.getSymbol()); } else if (Node.isImportSpecifier(declaration)) { const identifier = declaration.getNameNode(); const symbol = identifier.getSymbol(); if (symbol == null) return; yield* getDeclarationsForSymbol(symbol.getAliasedSymbol() || symbol); } else if (Node.isImportClause(declaration)) { const identifier = declaration.getDefaultImport(); if (identifier == null) return; const symbol = identifier.getSymbol(); if (symbol == null) return; yield* getDeclarationsForSymbol(symbol.getAliasedSymbol() || symbol); } else if (Node.isNamespaceImport(declaration) || Node.isNamespaceExport(declaration)) { const symbol = declaration.getNameNode().getSymbol(); if (symbol == null) return; yield* getDeclarationsForSymbol(symbol.getAliasedSymbol() || symbol); } else { yield declaration; } function* getDeclarationsForSymbol(symbol) { if (symbol == null) return; for (const d of symbol.getDeclarations()) yield* getDeclarationHandlingImportsAndExports(d); } } } removeDefaultExport(defaultExportSymbol) { defaultExportSymbol = defaultExportSymbol || this.getDefaultExportSymbol(); if (defaultExportSymbol == null) return this; const declaration = defaultExportSymbol.getDeclarations()[0]; if (declaration.compilerNode.kind === common.SyntaxKind.ExportAssignment) removeChildrenWithFormatting({ children: [declaration], getSiblingFormatting: () => FormattingKind.Newline }); else if (Node.isModifierable(declaration)) { declaration.toggleModifier("default", false); declaration.toggleModifier("export", false); } return this; } }; } function NamedNodeBase(Base) { return class extends Base { getNameNode() { return this._getNodeFromCompilerNode(this.compilerNode.name); } getName() { return this.getNameNode().getText(); } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.name != null) this.getNameNode().replaceWithText(structure.name); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { name: this.getName(), }); } }; } function ReferenceFindableNode(Base) { return class extends Base { findReferences() { return this._context.languageService.findReferences(getNodeForReferences(this)); } findReferencesAsNodes() { return this._context.languageService.findReferencesAsNodes(getNodeForReferences(this)); } }; } function getNodeForReferences(node) { if (Node.isIdentifier(node) || Node.isStringLiteral(node)) return node; const nameNode = node.getNodeProperty("name"); if (nameNode != null) return nameNode; if (Node.isExportable(node)) return node.getDefaultKeyword() || node; return node; } function RenameableNode(Base) { return class extends Base { rename(newName, options) { renameNode(getNodeToRename(this), newName, options); return this; function getNodeToRename(thisNode) { if (Node.isIdentifier(thisNode) || Node.isPrivateIdentifier(thisNode) || Node.isStringLiteral(thisNode)) return thisNode; else if (thisNode.getNameNode != null) { const node = thisNode.getNameNode(); common.errors.throwIfNullOrUndefined(node, "Expected to find a name node when renaming."); if (Node.isArrayBindingPattern(node) || Node.isObjectBindingPattern(node)) throw new common.errors.NotImplementedError(`Not implemented renameable scenario for ${node.getKindName()}.`); return node; } else { throw new common.errors.NotImplementedError(`Not implemented renameable scenario for ${thisNode.getKindName()}`); } } } }; } function BindingNamedNode(Base) { const base = ReferenceFindableNode(RenameableNode(Base)); return NamedNodeBase(base); } function ImportAttributeNamedNode(Base) { const base = ReferenceFindableNode(RenameableNode(Base)); return NamedNodeBase(base); } function ModuleNamedNode(Base) { const base = ReferenceFindableNode(RenameableNode(Base)); return NamedNodeBase(base); } function NameableNode(Base) { return NameableNodeInternal(ReferenceFindableNode(RenameableNode(Base))); } function NameableNodeInternal(Base) { return class extends Base { getNameNode() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.name); } getNameNodeOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getNameNode(), message ?? "Expected to have a name node.", this); } getName() { return this.getNameNode()?.getText() ?? undefined; } getNameOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getName(), message ?? "Expected to have a name.", this); } rename(newName) { if (newName === this.getName()) return this; if (common.StringUtils.isNullOrWhitespace(newName)) { this.removeName(); return this; } const nameNode = this.getNameNode(); if (nameNode == null) addNameNode(this, newName); else Base.prototype.rename.call(this, newName); return this; } removeName() { const nameNode = this.getNameNode(); if (nameNode == null) return this; removeChildren({ children: [nameNode], removePrecedingSpaces: true }); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.name != null) { common.errors.throwIfWhitespaceOrNotString(structure.name, "structure.name"); const nameNode = this.getNameNode(); if (nameNode == null) addNameNode(this, structure.name); else nameNode.replaceWithText(structure.name); } else if (structure.hasOwnProperty(common.nameof(structure, "name"))) { this.removeName(); } return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { name: this.getName(), }); } }; } function addNameNode(node, newName) { if (Node.isClassDeclaration(node) || Node.isClassExpression(node)) { const classKeyword = node.getFirstChildByKindOrThrow(common.SyntaxKind.ClassKeyword); insertIntoParentTextRange({ insertPos: classKeyword.getEnd(), newText: " " + newName, parent: node, }); } else { const openParenToken = node.getFirstChildByKindOrThrow(common.SyntaxKind.OpenParenToken); insertIntoParentTextRange({ insertPos: openParenToken.getStart(), newText: " " + newName, parent: node, }); } } function NamedNode(Base) { const base = RenameableNode(ReferenceFindableNode(Base)); return NamedNodeBase(base); } function PropertyNamedNode(Base) { const base = ReferenceFindableNode(RenameableNode(Base)); return NamedNodeBase(base); } function OverrideableNode(Base) { return class extends Base { hasOverrideKeyword() { return this.hasModifier(common.SyntaxKind.OverrideKeyword); } getOverrideKeyword() { return this.getFirstModifierByKind(common.SyntaxKind.OverrideKeyword); } getOverrideKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getOverrideKeyword(), message ?? "Expected to find an override keyword.", this); } setHasOverrideKeyword(value) { this.toggleModifier("override", value); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.hasOverrideKeyword != null) this.setHasOverrideKeyword(structure.hasOverrideKeyword); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { hasOverrideKeyword: this.hasOverrideKeyword(), }); } }; } function ParameteredNode(Base) { return class extends Base { getParameter(nameOrFindFunction) { return getNodeByNameOrFindFunction(this.getParameters(), nameOrFindFunction); } getParameterOrThrow(nameOrFindFunction) { return common.errors.throwIfNullOrUndefined(this.getParameter(nameOrFindFunction), () => getNotFoundErrorMessageForNameOrFindFunction("parameter", nameOrFindFunction)); } getParameters() { return this.compilerNode.parameters.map(p => this._getNodeFromCompilerNode(p)); } addParameter(structure) { return this.addParameters([structure])[0]; } addParameters(structures) { return this.insertParameters(getEndIndexFromArray(this.compilerNode.parameters), structures); } insertParameter(index, structure) { return this.insertParameters(index, [structure])[0]; } insertParameters(index, structures) { if (common.ArrayUtils.isNullOrEmpty(structures)) return []; const parameters = this.getParameters(); const syntaxList = this.getFirstChildByKindOrThrow(common.SyntaxKind.OpenParenToken).getNextSiblingIfKindOrThrow(common.SyntaxKind.SyntaxList); index = verifyAndGetIndex(index, parameters.length); const writer = this._getWriterWithQueuedChildIndentation(); const structurePrinter = this._context.structurePrinterFactory.forParameterDeclaration(); structurePrinter.printTexts(writer, structures); insertIntoCommaSeparatedNodes({ parent: syntaxList, currentNodes: parameters, insertIndex: index, newText: writer.toString(), useTrailingCommas: false, }); return getNodesToReturn(parameters, this.getParameters(), index, false); } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.parameters != null) { this.getParameters().forEach(p => p.remove()); this.addParameters(structure.parameters); } return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { parameters: this.getParameters().map(p => p.getStructure()), }); } }; } function QuestionDotTokenableNode(Base) { return class extends Base { hasQuestionDotToken() { return this.compilerNode.questionDotToken != null; } getQuestionDotTokenNode() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.questionDotToken); } getQuestionDotTokenNodeOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getQuestionDotTokenNode(), message ?? "Expected to find a question dot token.", this); } setHasQuestionDotToken(value) { const questionDotTokenNode = this.getQuestionDotTokenNode(); const hasQuestionDotToken = questionDotTokenNode != null; if (value === hasQuestionDotToken) return this; if (value) { if (Node.isPropertyAccessExpression(this)) this.getFirstChildByKindOrThrow(common.SyntaxKind.DotToken).replaceWithText("?."); else { insertIntoParentTextRange({ insertPos: getInsertPos.call(this), parent: this, newText: "?.", }); } } else { if (Node.isPropertyAccessExpression(this)) questionDotTokenNode.replaceWithText("."); else removeChildren({ children: [questionDotTokenNode] }); } return this; function getInsertPos() { if (Node.isCallExpression(this)) return this.getFirstChildByKindOrThrow(common.SyntaxKind.OpenParenToken).getStart(); if (Node.isElementAccessExpression(this)) return this.getFirstChildByKindOrThrow(common.SyntaxKind.OpenBracketToken).getStart(); common.errors.throwNotImplementedForSyntaxKindError(this.compilerNode.kind); } } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.hasQuestionDotToken != null) this.setHasQuestionDotToken(structure.hasQuestionDotToken); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { hasQuestionDotToken: this.hasQuestionDotToken(), }); } }; } function QuestionTokenableNode(Base) { return class extends Base { hasQuestionToken() { return this.compilerNode.questionToken != null; } getQuestionTokenNode() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.questionToken); } getQuestionTokenNodeOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getQuestionTokenNode(), message ?? "Expected to find a question token.", this); } setHasQuestionToken(value) { const questionTokenNode = this.getQuestionTokenNode(); const hasQuestionToken = questionTokenNode != null; if (value === hasQuestionToken) return this; if (value) { if (Node.isExclamationTokenable(this)) this.setHasExclamationToken(false); insertIntoParentTextRange({ insertPos: getInsertPos.call(this), parent: this, newText: "?", }); } else { removeChildren({ children: [questionTokenNode] }); } return this; function getInsertPos() { if (Node.hasName(this)) return this.getNameNode().getEnd(); const colonNode = this.getFirstChildByKind(common.SyntaxKind.ColonToken); if (colonNode != null) return colonNode.getStart(); const semicolonToken = this.getLastChildByKind(common.SyntaxKind.SemicolonToken); if (semicolonToken != null) return semicolonToken.getStart(); return this.getEnd(); } } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.hasQuestionToken != null) this.setHasQuestionToken(structure.hasQuestionToken); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { hasQuestionToken: this.hasQuestionToken(), }); } }; } function ReadonlyableNode(Base) { return class extends Base { isReadonly() { return this.getReadonlyKeyword() != null; } getReadonlyKeyword() { return this.getFirstModifierByKind(common.SyntaxKind.ReadonlyKeyword); } getReadonlyKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getReadonlyKeyword(), message ?? "Expected to find a readonly keyword.", this); } setIsReadonly(value) { this.toggleModifier("readonly", value); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.isReadonly != null) this.setIsReadonly(structure.isReadonly); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { isReadonly: this.isReadonly(), }); } }; } function ReturnTypedNode(Base) { return class extends Base { getReturnType() { return this.getSignature().getReturnType(); } getReturnTypeNode() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.type); } getReturnTypeNodeOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getReturnTypeNode(), message ?? "Expected to find a return type node.", this); } setReturnType(textOrWriterFunction) { const text = getTextFromStringOrWriter(this._getWriterWithQueuedChildIndentation(), textOrWriterFunction); if (common.StringUtils.isNullOrWhitespace(text)) return this.removeReturnType(); const returnTypeNode = this.getReturnTypeNode(); if (returnTypeNode != null) { if (returnTypeNode.getText() !== text) returnTypeNode.replaceWithText(text); return this; } insertIntoParentTextRange({ parent: this, insertPos: getEndNode(this).getEnd(), newText: `: ${text}`, }); return this; function getEndNode(thisNode) { if (thisNode.getKind() === common.SyntaxKind.IndexSignature) return thisNode.getFirstChildByKindOrThrow(common.SyntaxKind.CloseBracketToken); return thisNode.getFirstChildByKindOrThrow(common.SyntaxKind.CloseParenToken); } } removeReturnType() { const returnTypeNode = this.getReturnTypeNode(); if (returnTypeNode == null) return this; const colonToken = returnTypeNode.getPreviousSiblingIfKindOrThrow(common.SyntaxKind.ColonToken); removeChildren({ children: [colonToken, returnTypeNode], removePrecedingSpaces: true }); return this; } getSignature() { const signature = this._context.typeChecker.getSignatureFromNode(this); if (signature == null) throw new common.errors.NotImplementedError("Expected the node to have a signature."); return signature; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.returnType != null) this.setReturnType(structure.returnType); else if (structure.hasOwnProperty(common.nameof(structure, "returnType"))) this.removeReturnType(); return this; } getStructure() { const returnTypeNode = this.getReturnTypeNode(); return callBaseGetStructure(Base.prototype, this, { returnType: returnTypeNode ? returnTypeNode.getText({ trimLeadingIndentation: true }) : undefined, }); } }; } function ScopeableNode(Base) { return class extends Base { getScope() { const scope = getScopeForNode(this); if (scope != null) return scope; if (Node.isParameterDeclaration(this) && this.isReadonly()) return exports.Scope.Public; return undefined; } setScope(scope) { setScopeForNode(this, scope); return this; } getScopeKeyword() { return this.getModifiers().find(m => { const text = m.getText(); return text === "public" || text === "protected" || text === "private"; }); } hasScopeKeyword() { return this.getScopeKeyword() != null; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.hasOwnProperty(common.nameof(structure, "scope"))) this.setScope(structure.scope); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { scope: this.getScope(), }); } }; } function getScopeForNode(node) { const modifierFlags = node.getCombinedModifierFlags(); if ((modifierFlags & common.ts.ModifierFlags.Private) !== 0) return exports.Scope.Private; else if ((modifierFlags & common.ts.ModifierFlags.Protected) !== 0) return exports.Scope.Protected; else if ((modifierFlags & common.ts.ModifierFlags.Public) !== 0) return exports.Scope.Public; else return undefined; } function setScopeForNode(node, scope) { node.toggleModifier("public", scope === exports.Scope.Public); node.toggleModifier("protected", scope === exports.Scope.Protected); node.toggleModifier("private", scope === exports.Scope.Private); } function ScopedNode(Base) { return class extends Base { getScope() { return getScopeForNode(this) || exports.Scope.Public; } setScope(scope) { setScopeForNode(this, scope); return this; } hasScopeKeyword() { return getScopeForNode(this) != null; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.hasOwnProperty(common.nameof(structure, "scope"))) this.setScope(structure.scope); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { scope: this.hasScopeKeyword() ? this.getScope() : undefined, }); } }; } function SignaturedDeclaration(Base) { return ReturnTypedNode(ParameteredNode(Base)); } function StaticableNode(Base) { return class extends Base { isStatic() { return this.hasModifier(common.SyntaxKind.StaticKeyword); } getStaticKeyword() { return this.getFirstModifierByKind(common.SyntaxKind.StaticKeyword); } getStaticKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getStaticKeyword(), message ?? "Expected to find a static keyword.", this); } setIsStatic(value) { this.toggleModifier("static", value); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.isStatic != null) this.setIsStatic(structure.isStatic); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { isStatic: this.isStatic(), }); } }; } function TextInsertableNode(Base) { return class extends Base { insertText(pos, textOrWriterFunction) { this.replaceText([pos, pos], textOrWriterFunction); return this; } removeText(pos, end) { if (pos == null) this.replaceText(getValidRange(this), ""); else this.replaceText([pos, end], ""); return this; } replaceText(range, textOrWriterFunction) { const childSyntaxList = this.getChildSyntaxListOrThrow(); const validRange = getValidRange(this); const pos = range[0]; const end = range[1]; verifyArguments(); insertIntoParentTextRange({ insertPos: pos, newText: getTextFromStringOrWriter(this._getWriter(), textOrWriterFunction), parent: childSyntaxList.getParentOrThrow(), replacing: { textLength: end - pos, nodes: [childSyntaxList], }, }); return this; function verifyArguments() { verifyInRange(pos); verifyInRange(end); if (pos > end) throw new common.errors.ArgumentError("range", "Cannot specify a start position greater than the end position."); } function verifyInRange(i) { if (i >= validRange[0] && i <= validRange[1]) return; throw new common.errors.InvalidOperationError(`Cannot insert or replace text outside the bounds of the node. ` + `Expected a position between [${validRange[0]}, ${validRange[1]}], but received ${i}.`); } } }; } function getValidRange(thisNode) { const rangeNode = getRangeNode(); const openBrace = Node.isSourceFile(rangeNode) ? undefined : rangeNode.getPreviousSiblingIfKind(common.SyntaxKind.OpenBraceToken); const closeBrace = openBrace == null ? undefined : rangeNode.getNextSiblingIfKind(common.SyntaxKind.CloseBraceToken); if (openBrace != null && closeBrace != null) return [openBrace.getEnd(), closeBrace.getStart()]; else return [rangeNode.getPos(), rangeNode.getEnd()]; function getRangeNode() { if (Node.isSourceFile(thisNode)) return thisNode; return thisNode.getChildSyntaxListOrThrow(); } } function TypeArgumentedNode(Base) { return class extends Base { getTypeArguments() { if (this.compilerNode.typeArguments == null) return []; return this.compilerNode.typeArguments.map(a => this._getNodeFromCompilerNode(a)); } addTypeArgument(argumentText) { return this.addTypeArguments([argumentText])[0]; } addTypeArguments(argumentTexts) { return this.insertTypeArguments(this.getTypeArguments().length, argumentTexts); } insertTypeArgument(index, argumentText) { return this.insertTypeArguments(index, [argumentText])[0]; } insertTypeArguments(index, argumentTexts) { if (common.ArrayUtils.isNullOrEmpty(argumentTexts)) return []; const typeArguments = this.getTypeArguments(); index = verifyAndGetIndex(index, typeArguments.length); if (typeArguments.length === 0) { const identifier = this.getFirstChildByKindOrThrow(common.SyntaxKind.Identifier); insertIntoParentTextRange({ insertPos: identifier.getEnd(), parent: this, newText: `<${argumentTexts.join(", ")}>`, }); } else { insertIntoCommaSeparatedNodes({ parent: this.getFirstChildByKindOrThrow(common.SyntaxKind.LessThanToken).getNextSiblingIfKindOrThrow(common.SyntaxKind.SyntaxList), currentNodes: typeArguments, insertIndex: index, newText: argumentTexts.join(", "), useTrailingCommas: false, }); } return getNodesToReturn(typeArguments, this.getTypeArguments(), index, false); } removeTypeArgument(typeArgOrIndex) { const typeArguments = this.getTypeArguments(); if (typeArguments.length === 0) throw new common.errors.InvalidOperationError("Cannot remove a type argument when none exist."); const typeArgToRemove = typeof typeArgOrIndex === "number" ? getTypeArgFromIndex(typeArgOrIndex) : typeArgOrIndex; if (typeArguments.length === 1) { const childSyntaxList = typeArguments[0].getParentSyntaxListOrThrow(); removeChildren({ children: [ childSyntaxList.getPreviousSiblingIfKindOrThrow(common.SyntaxKind.LessThanToken), childSyntaxList, childSyntaxList.getNextSiblingIfKindOrThrow(common.SyntaxKind.GreaterThanToken), ], }); } else { removeCommaSeparatedChild(typeArgToRemove); } return this; function getTypeArgFromIndex(index) { return typeArguments[verifyAndGetIndex(index, typeArguments.length - 1)]; } } }; } function TypedNode(Base) { return class extends Base { getTypeNode() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.type); } getTypeNodeOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getTypeNode(), message ?? "Expected to find a type node.", this); } setType(textOrWriterFunction) { const text = getTextFromStringOrWriter(this._getWriterWithQueuedChildIndentation(), textOrWriterFunction); if (common.StringUtils.isNullOrWhitespace(text)) return this.removeType(); const typeNode = this.getTypeNode(); if (typeNode != null && typeNode.getText() === text) return this; const separatorSyntaxKind = getSeparatorSyntaxKindForNode(this); const separatorNode = this.getFirstChildByKind(separatorSyntaxKind); let insertPos; let newText; if (separatorNode == null) { insertPos = getInsertPosWhenNoType(this); newText = (separatorSyntaxKind === common.SyntaxKind.EqualsToken ? " = " : ": ") + text; } else { insertPos = typeNode.getStart(); newText = text; } insertIntoParentTextRange({ parent: this, insertPos, newText, replacing: { textLength: typeNode == null ? 0 : typeNode.getWidth(), }, }); return this; function getInsertPosWhenNoType(node) { let identifier = node.getFirstChildByKind(common.SyntaxKind.Identifier) ?? node.getFirstChildByKind(common.SyntaxKind.ArrayBindingPattern) ?? node.getFirstChildIfKindOrThrow(common.SyntaxKind.ObjectBindingPattern, "A first child of the kind Identifier, ArrayBindingPattern, or ObjectBindingPattern was expected."); const nextSibling = identifier.getNextSibling(); const insertAfterNode = isQuestionOrExclamation(nextSibling) ? nextSibling : identifier; return insertAfterNode.getEnd(); } function isQuestionOrExclamation(node) { if (node == null) return false; const kind = node.getKind(); return kind === common.SyntaxKind.QuestionToken || kind === common.SyntaxKind.ExclamationToken; } } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.type != null) this.setType(structure.type); else if (structure.hasOwnProperty(common.nameof(structure, "type"))) this.removeType(); return this; } removeType() { if (this.getKind() === common.SyntaxKind.TypeAliasDeclaration) throw new common.errors.NotSupportedError(`Cannot remove the type of a type alias. Use ${common.nameof("setType")} instead.`); const typeNode = this.getTypeNode(); if (typeNode == null) return this; const separatorToken = typeNode.getPreviousSiblingIfKindOrThrow(getSeparatorSyntaxKindForNode(this)); removeChildren({ children: [separatorToken, typeNode], removePrecedingSpaces: true }); return this; } getStructure() { const typeNode = this.getTypeNode(); return callBaseGetStructure(Base.prototype, this, { type: typeNode ? typeNode.getText({ trimLeadingIndentation: true }) : undefined, }); } }; } function getSeparatorSyntaxKindForNode(node) { switch (node.getKind()) { case common.SyntaxKind.TypeAliasDeclaration: return common.SyntaxKind.EqualsToken; default: return common.SyntaxKind.ColonToken; } } function TypeElementMemberedNode(Base) { return class extends Base { addMember(member) { return this.addMembers([member])[0]; } addMembers(members) { return this.insertMembers(getEndIndexFromArray(this.getMembersWithComments()), members); } insertMember(index, member) { return this.insertMembers(index, [member])[0]; } insertMembers(index, members) { return insertIntoBracesOrSourceFileWithGetChildrenWithComments({ getIndexedChildren: () => this.getMembersWithComments(), index, parent: this, write: writer => { writer.newLineIfLastNot(); const memberWriter = this._getWriter(); const memberPrinter = this._context.structurePrinterFactory.forTypeElementMember(); memberPrinter.printTexts(memberWriter, members); writer.write(memberWriter.toString()); writer.newLineIfLastNot(); }, }); } addConstructSignature(structure) { return this.addConstructSignatures([structure])[0]; } addConstructSignatures(structures) { return this.insertConstructSignatures(getEndIndexFromArray(this.getMembersWithComments()), structures); } insertConstructSignature(index, structure) { return this.insertConstructSignatures(index, [structure])[0]; } insertConstructSignatures(index, structures) { return insertChildren$1({ thisNode: this, index, structures, expectedKind: common.SyntaxKind.ConstructSignature, createStructurePrinter: () => this._context.structurePrinterFactory.forConstructSignatureDeclaration(), }); } getConstructSignature(findFunction) { return this.getConstructSignatures().find(findFunction); } getConstructSignatureOrThrow(findFunction, message) { return common.errors.throwIfNullOrUndefined(this.getConstructSignature(findFunction), message ?? "Expected to find a construct signature with the provided condition.", this); } getConstructSignatures() { return this.compilerNode.members.filter(m => m.kind === common.SyntaxKind.ConstructSignature) .map(m => this._getNodeFromCompilerNode(m)); } addCallSignature(structure) { return this.addCallSignatures([structure])[0]; } addCallSignatures(structures) { return this.insertCallSignatures(getEndIndexFromArray(this.getMembersWithComments()), structures); } insertCallSignature(index, structure) { return this.insertCallSignatures(index, [structure])[0]; } insertCallSignatures(index, structures) { return insertChildren$1({ thisNode: this, index, structures, expectedKind: common.SyntaxKind.CallSignature, createStructurePrinter: () => this._context.structurePrinterFactory.forCallSignatureDeclaration(), }); } getCallSignature(findFunction) { return this.getCallSignatures().find(findFunction); } getCallSignatureOrThrow(findFunction, message) { return common.errors.throwIfNullOrUndefined(this.getCallSignature(findFunction), message ?? "Expected to find a call signature with the provided condition.", this); } getCallSignatures() { return this.compilerNode.members.filter(m => m.kind === common.SyntaxKind.CallSignature) .map(m => this._getNodeFromCompilerNode(m)); } addIndexSignature(structure) { return this.addIndexSignatures([structure])[0]; } addIndexSignatures(structures) { return this.insertIndexSignatures(getEndIndexFromArray(this.getMembersWithComments()), structures); } insertIndexSignature(index, structure) { return this.insertIndexSignatures(index, [structure])[0]; } insertIndexSignatures(index, structures) { return insertChildren$1({ thisNode: this, index, structures, expectedKind: common.SyntaxKind.IndexSignature, createStructurePrinter: () => this._context.structurePrinterFactory.forIndexSignatureDeclaration(), }); } getIndexSignature(findFunction) { return this.getIndexSignatures().find(findFunction); } getIndexSignatureOrThrow(findFunction, message) { return common.errors.throwIfNullOrUndefined(this.getIndexSignature(findFunction), message ?? "Expected to find a index signature with the provided condition.", this); } getIndexSignatures() { return this.compilerNode.members.filter(m => m.kind === common.SyntaxKind.IndexSignature) .map(m => this._getNodeFromCompilerNode(m)); } addMethod(structure) { return this.addMethods([structure])[0]; } addMethods(structures) { return this.insertMethods(getEndIndexFromArray(this.getMembersWithComments()), structures); } insertMethod(index, structure) { return this.insertMethods(index, [structure])[0]; } insertMethods(index, structures) { return insertChildren$1({ thisNode: this, index, structures, expectedKind: common.SyntaxKind.MethodSignature, createStructurePrinter: () => this._context.structurePrinterFactory.forMethodSignature(), }); } getMethod(nameOrFindFunction) { return getNodeByNameOrFindFunction(this.getMethods(), nameOrFindFunction); } getMethodOrThrow(nameOrFindFunction) { return common.errors.throwIfNullOrUndefined(this.getMethod(nameOrFindFunction), () => getNotFoundErrorMessageForNameOrFindFunction("interface method signature", nameOrFindFunction)); } getMethods() { return this.compilerNode.members.filter(m => m.kind === common.SyntaxKind.MethodSignature) .map(m => this._getNodeFromCompilerNode(m)); } addProperty(structure) { return this.addProperties([structure])[0]; } addProperties(structures) { return this.insertProperties(getEndIndexFromArray(this.getMembersWithComments()), structures); } insertProperty(index, structure) { return this.insertProperties(index, [structure])[0]; } insertProperties(index, structures) { return insertChildren$1({ thisNode: this, index, structures, expectedKind: common.SyntaxKind.PropertySignature, createStructurePrinter: () => this._context.structurePrinterFactory.forPropertySignature(), }); } getProperty(nameOrFindFunction) { return getNodeByNameOrFindFunction(this.getProperties(), nameOrFindFunction); } getPropertyOrThrow(nameOrFindFunction) { return common.errors.throwIfNullOrUndefined(this.getProperty(nameOrFindFunction), () => getNotFoundErrorMessageForNameOrFindFunction("interface property signature", nameOrFindFunction)); } getProperties() { return this.compilerNode.members.filter(m => m.kind === common.SyntaxKind.PropertySignature) .map(m => this._getNodeFromCompilerNode(m)); } addGetAccessor(structure) { return this.addGetAccessors([structure])[0]; } addGetAccessors(structures) { const result = []; for (const structure of structures) { const setAccessor = this.getSetAccessor(structure.name); const index = setAccessor == null ? getEndIndexFromArray(this.getMembersWithComments()) : setAccessor.getChildIndex(); result.push(this.insertGetAccessor(index, structure)); } return result; } insertGetAccessor(index, structure) { return this.insertGetAccessors(index, [structure])[0]; } insertGetAccessors(index, structures) { return insertChildren$1({ thisNode: this, index, structures, expectedKind: common.SyntaxKind.GetAccessor, createStructurePrinter: () => this._context.structurePrinterFactory.forGetAccessorDeclaration({ isAmbient: true, }), }); } getGetAccessor(nameOrFindFunction) { return getNodeByNameOrFindFunction(this.getGetAccessors(), nameOrFindFunction); } getGetAccessorOrThrow(nameOrFindFunction) { return common.errors.throwIfNullOrUndefined(this.getGetAccessor(nameOrFindFunction), () => getNotFoundErrorMessageForNameOrFindFunction("interface get accessor", nameOrFindFunction)); } getGetAccessors() { return this.compilerNode.members.filter(m => m.kind === common.SyntaxKind.GetAccessor) .map(m => this._getNodeFromCompilerNode(m)); } addSetAccessor(structure) { return this.addSetAccessors([structure])[0]; } addSetAccessors(structures) { const result = []; for (const structure of structures) { const getAccessor = this.getGetAccessor(structure.name); const index = getAccessor == null ? getEndIndexFromArray(this.getMembersWithComments()) : getAccessor.getChildIndex() + 1; result.push(this.insertSetAccessor(index, structure)); } return result; } insertSetAccessor(index, structure) { return this.insertSetAccessors(index, [structure])[0]; } insertSetAccessors(index, structures) { return insertChildren$1({ thisNode: this, index, structures, expectedKind: common.SyntaxKind.SetAccessor, createStructurePrinter: () => this._context.structurePrinterFactory.forSetAccessorDeclaration({ isAmbient: true, }), }); } getSetAccessor(nameOrFindFunction) { return getNodeByNameOrFindFunction(this.getSetAccessors(), nameOrFindFunction); } getSetAccessorOrThrow(nameOrFindFunction) { return common.errors.throwIfNullOrUndefined(this.getSetAccessor(nameOrFindFunction), () => getNotFoundErrorMessageForNameOrFindFunction("interface set accessor", nameOrFindFunction)); } getSetAccessors() { return this.compilerNode.members.filter(m => m.kind === common.SyntaxKind.SetAccessor) .map(m => this._getNodeFromCompilerNode(m)); } getMembers() { return this.compilerNode.members.map(m => this._getNodeFromCompilerNode(m)); } getMembersWithComments() { const compilerNode = this.compilerNode; return ExtendedParser.getContainerArray(compilerNode, this._sourceFile.compilerNode) .map(m => this._getNodeFromCompilerNode(m)); } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.callSignatures != null) { this.getCallSignatures().forEach(c => c.remove()); this.addCallSignatures(structure.callSignatures); } if (structure.constructSignatures != null) { this.getConstructSignatures().forEach(c => c.remove()); this.addConstructSignatures(structure.constructSignatures); } if (structure.indexSignatures != null) { this.getIndexSignatures().forEach(c => c.remove()); this.addIndexSignatures(structure.indexSignatures); } if (structure.properties != null) { this.getProperties().forEach(c => c.remove()); this.addProperties(structure.properties); } if (structure.getAccessors != null) { this.getGetAccessors().forEach(c => c.remove()); this.addGetAccessors(structure.getAccessors); } if (structure.setAccessors != null) { this.getSetAccessors().forEach(c => c.remove()); this.addSetAccessors(structure.setAccessors); } if (structure.methods != null) { this.getMethods().forEach(c => c.remove()); this.addMethods(structure.methods); } return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { callSignatures: this.getCallSignatures().map(node => node.getStructure()), constructSignatures: this.getConstructSignatures().map(node => node.getStructure()), getAccessors: this.getGetAccessors().map(node => node.getStructure()), indexSignatures: this.getIndexSignatures().map(node => node.getStructure()), methods: this.getMethods().map(node => node.getStructure()), properties: this.getProperties().map(node => node.getStructure()), setAccessors: this.getSetAccessors().map(node => node.getStructure()), }); } }; } function insertChildren$1(opts) { return insertIntoBracesOrSourceFileWithGetChildren({ getIndexedChildren: () => opts.thisNode.getMembersWithComments(), parent: opts.thisNode, index: opts.index, structures: opts.structures, expectedKind: opts.expectedKind, write: (writer, info) => { writer.newLineIfLastNot(); opts.createStructurePrinter().printTexts(writer, opts.structures); writer.newLineIfLastNot(); }, }); } function TypeParameteredNode(Base) { return class extends Base { getTypeParameter(nameOrFindFunction) { return getNodeByNameOrFindFunction(this.getTypeParameters(), nameOrFindFunction); } getTypeParameterOrThrow(nameOrFindFunction) { return common.errors.throwIfNullOrUndefined(this.getTypeParameter(nameOrFindFunction), () => getNotFoundErrorMessageForNameOrFindFunction("type parameter", nameOrFindFunction)); } getTypeParameters() { const typeParameters = this.compilerNode.typeParameters; if (typeParameters == null) return []; return typeParameters.map(t => this._getNodeFromCompilerNode(t)); } addTypeParameter(structure) { return this.addTypeParameters([structure])[0]; } addTypeParameters(structures) { return this.insertTypeParameters(getEndIndexFromArray(this.compilerNode.typeParameters), structures); } insertTypeParameter(index, structure) { return this.insertTypeParameters(index, [structure])[0]; } insertTypeParameters(index, structures) { if (common.ArrayUtils.isNullOrEmpty(structures)) return []; const typeParameters = this.getTypeParameters(); const writer = this._getWriterWithQueuedChildIndentation(); const structurePrinter = this._context.structurePrinterFactory.forTypeParameterDeclaration(); index = verifyAndGetIndex(index, typeParameters.length); structurePrinter.printTexts(writer, structures); if (typeParameters.length === 0) { insertIntoParentTextRange({ insertPos: getInsertPos(this), parent: this, newText: `<${writer.toString()}>`, }); } else { insertIntoCommaSeparatedNodes({ parent: this.getFirstChildByKindOrThrow(common.SyntaxKind.LessThanToken).getNextSiblingIfKindOrThrow(common.SyntaxKind.SyntaxList), currentNodes: typeParameters, insertIndex: index, newText: writer.toString(), useTrailingCommas: false, }); } return getNodesToReturn(typeParameters, this.getTypeParameters(), index, false); } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.typeParameters != null) { this.getTypeParameters().forEach(t => t.remove()); this.addTypeParameters(structure.typeParameters); } return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { typeParameters: this.getTypeParameters().map(p => p.getStructure()), }); } }; } function getInsertPos(node) { const namedNode = node; if (namedNode.getNameNode != null) return namedNode.getNameNode().getEnd(); else if (Node.isCallSignatureDeclaration(node) || Node.isFunctionTypeNode(node)) return node.getFirstChildByKindOrThrow(common.SyntaxKind.OpenParenToken).getStart(); else throw new common.errors.NotImplementedError(`Not implemented scenario inserting type parameters for node with kind ${node.getKindName()}.`); } function UnwrappableNode(Base) { return class extends Base { unwrap() { unwrapNode(this); } }; } class ArrayBindingPattern extends Node { getElements() { return this.compilerNode.elements.map(e => this._getNodeFromCompilerNode(e)); } } const createBase$F = (ctor) => DotDotDotTokenableNode(InitializerExpressionableNode(BindingNamedNode(ctor))); const BindingElementBase = createBase$F(Node); class BindingElement extends BindingElementBase { getPropertyNameNodeOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getPropertyNameNode(), message ?? "Expected to find a property name node.", this); } getPropertyNameNode() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.propertyName); } } class ObjectBindingPattern extends Node { getElements() { return this.compilerNode.elements.map(e => this._getNodeFromCompilerNode(e)); } } function AbstractableNode(Base) { return class extends Base { isAbstract() { return this.getAbstractKeyword() != null; } getAbstractKeyword() { return this.getFirstModifierByKind(common.SyntaxKind.AbstractKeyword); } getAbstractKeywordOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getAbstractKeyword(), message ?? "Expected to find an abstract keyword.", this); } setIsAbstract(isAbstract) { this.toggleModifier("abstract", isAbstract); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.isAbstract != null) this.setIsAbstract(structure.isAbstract); return this; } getStructure() { return callBaseGetStructure(Base.prototype, this, { isAbstract: this.isAbstract(), }); } }; } class Expression extends Node { getContextualType() { return this._context.typeChecker.getContextualType(this); } } const BinaryExpressionBase = Expression; class BinaryExpression extends BinaryExpressionBase { getLeft() { return this._getNodeFromCompilerNode(this.compilerNode.left); } getOperatorToken() { return this._getNodeFromCompilerNode(this.compilerNode.operatorToken); } getRight() { return this._getNodeFromCompilerNode(this.compilerNode.right); } } const AssignmentExpressionBase = BinaryExpression; class AssignmentExpression extends AssignmentExpressionBase { getOperatorToken() { return this._getNodeFromCompilerNode(this.compilerNode.operatorToken); } } const ArrayDestructuringAssignmentBase = AssignmentExpression; class ArrayDestructuringAssignment extends ArrayDestructuringAssignmentBase { getLeft() { return this._getNodeFromCompilerNode(this.compilerNode.left); } } class UnaryExpression extends Expression { } class UpdateExpression extends UnaryExpression { } class LeftHandSideExpression extends UpdateExpression { } class MemberExpression extends LeftHandSideExpression { } class PrimaryExpression extends MemberExpression { } class ArrayLiteralExpression extends PrimaryExpression { getElements() { return this.compilerNode.elements.map(e => this._getNodeFromCompilerNode(e)); } addElement(textOrWriterFunction, options) { return this.addElements([textOrWriterFunction], options)[0]; } addElements(textsOrWriterFunction, options) { return this.insertElements(this.compilerNode.elements.length, textsOrWriterFunction, options); } insertElement(index, textOrWriterFunction, options) { return this.insertElements(index, [textOrWriterFunction], options)[0]; } insertElements(index, textsOrWriterFunction, options = {}) { const elements = this.getElements(); index = verifyAndGetIndex(index, elements.length); const useNewLines = getUseNewLines(this); const writer = useNewLines ? this._getWriterWithChildIndentation() : this._getWriterWithQueuedChildIndentation(); const stringStructurePrinter = new StringStructurePrinter(); const structurePrinter = useNewLines ? new CommaNewLineSeparatedStructuresPrinter(stringStructurePrinter) : new CommaSeparatedStructuresPrinter(stringStructurePrinter); structurePrinter.printText(writer, textsOrWriterFunction); return insertTexts(this); function insertTexts(node) { insertIntoCommaSeparatedNodes({ parent: node.getFirstChildByKindOrThrow(common.SyntaxKind.SyntaxList), currentNodes: elements, insertIndex: index, newText: writer.toString(), useNewLines, useTrailingCommas: useNewLines && node._context.manipulationSettings.getUseTrailingCommas(), }); const newElements = node.getElements(); return getNodesToReturn(elements, newElements, index, false); } function getUseNewLines(node) { if (options.useNewLines != null) return options.useNewLines; if (elements.length > 1) return allElementsOnDifferentLines(); return node.getStartLineNumber() !== node.getEndLineNumber(); function allElementsOnDifferentLines() { let previousLine = elements[0].getStartLineNumber(); for (let i = 1; i < elements.length; i++) { const currentLine = elements[i].getStartLineNumber(); if (previousLine === currentLine) return false; previousLine = currentLine; } return true; } } } removeElement(elementOrIndex) { const elements = this.getElements(); if (elements.length === 0) throw new common.errors.InvalidOperationError("Cannot remove an element when none exist."); const elementToRemove = typeof elementOrIndex === "number" ? getElementFromIndex(elementOrIndex) : elementOrIndex; removeCommaSeparatedChild(elementToRemove); function getElementFromIndex(index) { return elements[verifyAndGetIndex(index, elements.length - 1)]; } } } function ExpressionableNode(Base) { return class extends Base { getExpression() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.expression); } getExpressionOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getExpression(), message ?? "Expected to find an expression.", this); } getExpressionIfKind(kind) { const expression = this.getExpression(); return expression?.getKind() === kind ? expression : undefined; } getExpressionIfKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getExpressionIfKind(kind), message ?? `An expression with the kind kind ${common.getSyntaxKindName(kind)} was expected.`, this); } }; } function BaseExpressionedNode(Base) { return class extends Base { getExpression() { return this._getNodeFromCompilerNode(this.compilerNode.expression); } getExpressionIfKind(kind) { const { expression } = this.compilerNode; return expression.kind === kind ? this._getNodeFromCompilerNode(expression) : undefined; } getExpressionIfKindOrThrow(kind, message) { return common.errors.throwIfNullOrUndefined(this.getExpressionIfKind(kind), message ?? `An expression of the kind ${common.getSyntaxKindName(kind)} was expected.`, this); } setExpression(textOrWriterFunction) { this.getExpression().replaceWithText(textOrWriterFunction, this._getWriterWithQueuedChildIndentation()); return this; } set(structure) { callBaseSet(Base.prototype, this, structure); if (structure.expression != null) this.setExpression(structure.expression); return this; } }; } function ExpressionedNode(Base) { return BaseExpressionedNode(Base); } function ImportExpressionedNode(Base) { return BaseExpressionedNode(Base); } function LeftHandSideExpressionedNode(Base) { return BaseExpressionedNode(Base); } function SuperExpressionedNode(Base) { return BaseExpressionedNode(Base); } function UnaryExpressionedNode(Base) { return BaseExpressionedNode(Base); } const createBase$E = (ctor) => TypedNode(ExpressionedNode(ctor)); const AsExpressionBase = createBase$E(Expression); class AsExpression extends AsExpressionBase { } const AwaitExpressionBase = UnaryExpressionedNode(UnaryExpression); class AwaitExpression extends AwaitExpressionBase { } const createBase$D = (ctor) => TypeArgumentedNode(ArgumentedNode(QuestionDotTokenableNode(LeftHandSideExpressionedNode(ctor)))); const CallExpressionBase = createBase$D(LeftHandSideExpression); class CallExpression extends CallExpressionBase { getReturnType() { return this._context.typeChecker.getTypeAtLocation(this); } } const CommaListExpressionBase = Expression; class CommaListExpression extends CommaListExpressionBase { getElements() { return this.compilerNode.elements.map(e => this._getNodeFromCompilerNode(e)); } } const ConditionalExpressionBase = Expression; class ConditionalExpression extends ConditionalExpressionBase { getCondition() { return this._getNodeFromCompilerNode(this.compilerNode.condition); } getQuestionToken() { return this._getNodeFromCompilerNode(this.compilerNode.questionToken); } getWhenTrue() { return this._getNodeFromCompilerNode(this.compilerNode.whenTrue); } getColonToken() { return this._getNodeFromCompilerNode(this.compilerNode.colonToken); } getWhenFalse() { return this._getNodeFromCompilerNode(this.compilerNode.whenFalse); } } const DeleteExpressionBase = UnaryExpressionedNode(UnaryExpression); class DeleteExpression extends DeleteExpressionBase { } const createBase$C = (ctor) => QuestionDotTokenableNode(LeftHandSideExpressionedNode(ctor)); const ElementAccessExpressionBase = createBase$C(MemberExpression); class ElementAccessExpression extends ElementAccessExpressionBase { getArgumentExpression() { return this._getNodeFromCompilerNodeIfExists(this.compilerNode.argumentExpression); } getArgumentExpressionOrThrow(message) { return common.errors.throwIfNullOrUndefined(this.getArgumentExpression(), message ?? "Expected to find an argument expression.", this); } } const ImportExpressionBase = PrimaryExpression; class ImportExpression extends ImportExpressionBase { } const LiteralExpressionBase = LiteralLikeNode(PrimaryExpression); class LiteralExpression extends LiteralExpressionBase { } const MetaPropertyBase = NamedNode(PrimaryExpression); class MetaProperty extends MetaPropertyBase { getKeywordToken() { return this.compilerNode.keywordToken; } } const createBase$B = (ctor) => TypeArgumentedNode(ArgumentedNode(LeftHandSideExpressionedNode(ctor))); const NewExpressionBase = createBase$B(PrimaryExpression); class NewExpression extends NewExpressionBase { } const NonNullExpressionBase = ExpressionedNode(LeftHandSideExpression); class NonNullExpression extends NonNullExpressionBase { } class ObjectLiteralElement extends Node { remove() { removeCommaSeparatedChild(this); } } class CommentObjectLiteralElement extends ObjectLiteralElement { } const ObjectDestructuringAssignmentBase = AssignmentExpression; class ObjectDestructuringAssignment extends ObjectDestructuringAssignmentBase { getLeft() { return this._getNodeFromCompilerNode(this.compilerNode.left); } } const ObjectLiteralExpressionBase = PrimaryExpression; class ObjectLiteralExpression extends ObjectLiteralExpressionBase { getPropertyOrThrow(nameOrFindFunction) { return common.errors.throwIfNullOrUndefined(this.getProperty(nameOrFindFunction), () => getNotFoundErrorMessageForNameOrFindFunction("property", nameOrFindFunction)); } getProperty(nameOrFindFunction) { let findFunc; if (typeof nameOrFindFunction === "string") { findFunc = prop => { if (prop[common.nameof("getName")] == null) return false; return prop.getName() === nameOrFindFunction; }; } else { findFunc = nameOrFindFunction; } return this.getProperties().find(findFunc); } getProperties() { return this.compilerNode.properties.map(p => this._getNodeFromCompilerNode(p)); } getPropertiesWithComments() { const members = ExtendedParser.getContainerArray(this.compilerNode, this.getSourceFile().compilerNode); return members.map(p => this._getNodeFromCompilerNode(p)); } #getAddIndex() { const members = ExtendedParser.getContainerArray(this.compilerNode, this.getSourceFile().compilerNode); return members.length; } addProperty(structure) { return this.insertProperties(this.#getAddIndex(), [structure])[0]; } addProperties(structures) { return this.insertProperties(this.#getAddIndex(), structures); } insertProperty(index, structure) { return this.insertProperties(index, [structure])[0]; } insertProperties(index, structures) { const properties = this.getPropertiesWithComments(); index = verifyAndGetIndex(index, properties.length); const writer = this._getWriterWithChildIndentation(); const structurePrinter = this._context.structurePrinterFactory.forObjectLiteralExpressionProperty(); structurePrinter.printTexts(writer, structures); insertIntoCommaSeparatedNodes({ parent: this.getChildSyntaxListOrThrow(), currentNodes: properties, insertIndex: index, newText: writer.toString(), useNewLines: true, useTrailingCommas: this._context.manipulationSettings.getUseTrailingCommas(), }); return getNodesToReturn(properties, this.getPropertiesWithComments(), index, true); } addPropertyAssignment(structure) { return this.addPropertyAssignments([structure])[0]; } addPropertyAssignments(structures) { return this.insertPropertyAssignments(this.#getAddIndex(), structures); } insertPropertyAssignment(index, structure) { return this.insertPropertyAssignments(index, [structure])[0]; } insertPropertyAssignments(index, structures) { return this.#insertProperty(index, structures, () => this._context.structurePrinterFactory.forPropertyAssignment()); } addShorthandPropertyAssignment(structure) { return this.addShorthandPropertyAssignments([structure])[0]; } addShorthandPropertyAssignments(structures) { return this.insertShorthandPropertyAssignments(this.#getAddIndex(), structures); } insertShorthandPropertyAssignment(index, structure) { return this.insertShorthandPropertyAssignments(index, [structure])[0]; } insertShorthandPropertyAssignments(index, structures) { return this.#insertProperty(index, structures, () => this._context.structurePrinterFactory.forShorthandPropertyAssignment()); } addSpreadAssignment(structure) { return this.addSpreadAssignments([structure])[0]; } addSpreadAssignments(structures) { return this.insertSpreadAssignments(this.#getAddIndex(), structures); } insertSpreadAssignment(index, structure) { return this.insertSpreadAssignments(index, [structure])[0]; } insertSpreadAssignments(index, structures) { return this.#insertProperty(index, structures, () => this._context.structurePrinterFactory.forSpreadAssignment()); } addMethod(structure) { return this.addMethods([structure])[0]; } addMethods(structures) { return this.insertMethods(this.#getAddIndex(), structures); } insertMethod(index, structure) { return this.insertMethods(index, [structure])[0]; } insertMethods(index, structures) { return this.#insertProperty(index, structures, () => this._context.structurePrinterFactory.forMethodDeclaration({ isAmbient: false })); } addGetAccessor(structure) { return this.addGetAccessors([structure])[0]; } addGetAccessors(structures) { return this.insertGetAccessors(this.#getAddIndex(), structures); } insertGetAccessor(index, structure) { return this.insertGetAccessors(index, [structure])[0]; } insertGetAccessors(index, structures) { return this.#insertProperty(index, structures, () => this._context.structurePrinterFactory.forGetAccessorDeclaration({ isAmbient: false })); } addSetAccessor(structure) { return this.addSetAccessors([structure])[0]; } addSetAccessors(structures) { return this.insertSetAccessors(this.#getAddIndex