{"version":3,"names":["_buffer","require","n","_t","_tokenMap","generatorFunctions","isExpression","isFunction","isStatement","isClassBody","isTSInterfaceBody","isTSEnumDeclaration","SCIENTIFIC_NOTATION","ZERO_DECIMAL_INTEGER","HAS_NEWLINE","HAS_NEWLINE_OR_BlOCK_COMMENT_END","commentIsNewline","c","type","test","value","needsParens","Printer","constructor","format","map","tokens","originalCode","inForStatementInit","tokenContext","_tokens","_originalCode","_currentNode","_indent","_indentRepeat","_insideAux","_noLineTerminator","_noLineTerminatorAfterNode","_printAuxAfterOnNextUserNode","_printedComments","Set","_endsWithInteger","_endsWithWord","_endsWithDiv","_lastCommentLine","_endsWithInnerRaw","_indentInnerComments","tokenMap","_boundGetRawIdentifier","_getRawIdentifier","bind","indent","style","length","_inputMap","_buf","Buffer","enterForStatementInit","enterDelimited","oldInForStatementInit","oldNoLineTerminatorAfterNode","generate","ast","preserveFormat","TokenMap","print","_maybeAddAuxComment","get","compact","concise","dedent","semicolon","force","_appendChar","node","start","end","endMatches","indexes","getIndexes","_catchUpTo","loc","_queue","rightBrace","minified","removeLastSemicolon","sourceWithOffset","token","rightParens","space","_space","hasContent","lastCp","getLastChar","word","str","noLineTerminatorAfter","_maybePrintInnerComments","charCodeAt","_append","number","isNonDecimalLiteral","secondChar","Number","isInteger","maybeNewline","occurrenceCount","lastChar","strFirst","tokenChar","char","String","fromCharCode","newline","i","retainLines","getNewlineCount","j","_newline","endsWith","endsWithCharAndNewline","removeTrailingNewline","exactSource","cb","_catchUp","source","prop","columnOffset","sourceIdentifierName","identifierName","pos","_canMarkIdName","sourcePosition","_sourcePosition","identifierNamePos","findMatching","_maybeIndent","append","appendChar","queue","firstChar","queueIndentation","_getIndent","_shouldIndent","catchUp","line","count","getCurrentLine","column","index","spacesCount","getCurrentColumn","spaces","slice","replace","repeat","printTerminatorless","trailingCommentsLineOffset","_node$extra","_node$leadingComments","_node$leadingComments2","nodeType","oldConcise","_compact","printMethod","undefined","ReferenceError","JSON","stringify","name","parent","oldInAux","parenthesized","extra","shouldPrintParens","retainFunctionParens","leadingComments","parentType","callee","indentParenthesized","some","oldInForStatementInitWasTrue","isLastChild","_node$trailingComment","trailingComments","_printLeadingComments","_printTrailingComments","enteredPositionlessNode","_printAuxBeforeComment","_printAuxAfterComment","comment","auxiliaryCommentBefore","_printComment","auxiliaryCommentAfter","getPossibleRaw","raw","rawValue","printJoin","nodes","opts","_nodes$0$loc","startLine","newlineOpts","addNewlines","nextNodeStartLine","separator","len","statement","_printNewline","iterator","printTrailingSeparator","_node$trailingComment2","_nextNode$loc","nextNode","printAndIndentOnComments","printBlock","body","lineOffset","innerComments","_printComments","comments","nextTokenStr","nextTokenOccurrenceCount","_this$tokenMap","printInnerComments","nextToken","hasSpace","printedCommentsCount","size","noIndentInnerCommentsHere","printSequence","_opts$indent","printList","items","commaSeparator","shouldPrintTrailingComma","listEnd","listEndIndex","findLastIndex","matchesOriginal","newLine","lastCommentLine","offset","_shouldPrintComment","ignore","has","commentTok","find","add","shouldPrintComment","skipNewLines","noLineTerminator","isBlockComment","printNewLines","lastCharCode","val","adjustMultilineComment","_comment$loc","newlineRegex","RegExp","indentSize","nodeLoc","hasLoc","nodeStartLine","nodeEndLine","lastLine","leadingCommentNewline","shouldPrint","commentStartLine","commentEndLine","Math","max","min","singleLine","shouldSkipNewline","properties","Object","assign","prototype","Noop","_default","exports","default","last"],"sources":["../src/printer.ts"],"sourcesContent":["import Buffer, { type Pos } from \"./buffer.ts\";\nimport type { Loc } from \"./buffer.ts\";\nimport * as n from \"./node/index.ts\";\nimport type * as t from \"@babel/types\";\nimport {\n isExpression,\n isFunction,\n isStatement,\n isClassBody,\n isTSInterfaceBody,\n isTSEnumDeclaration,\n} from \"@babel/types\";\nimport type { Opts as jsescOptions } from \"jsesc\";\n\nimport { TokenMap } from \"./token-map.ts\";\nimport type { GeneratorOptions } from \"./index.ts\";\nimport * as generatorFunctions from \"./generators/index.ts\";\nimport type SourceMap from \"./source-map.ts\";\nimport type { TraceMap } from \"@jridgewell/trace-mapping\";\nimport type { Token } from \"@babel/parser\";\n\n// We inline this package\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport * as charCodes from \"charcodes\";\n\nconst SCIENTIFIC_NOTATION = /e/i;\nconst ZERO_DECIMAL_INTEGER = /\\.0+$/;\nconst HAS_NEWLINE = /[\\n\\r\\u2028\\u2029]/;\nconst HAS_NEWLINE_OR_BlOCK_COMMENT_END = /[\\n\\r\\u2028\\u2029]|\\*\\//;\n\nfunction commentIsNewline(c: t.Comment) {\n return c.type === \"CommentLine\" || HAS_NEWLINE.test(c.value);\n}\n\nconst { needsParens } = n;\n\nconst enum COMMENT_TYPE {\n LEADING,\n INNER,\n TRAILING,\n}\n\nconst enum COMMENT_SKIP_NEWLINE {\n DEFAULT,\n ALL,\n LEADING,\n TRAILING,\n}\n\nconst enum PRINT_COMMENT_HINT {\n SKIP,\n ALLOW,\n DEFER,\n}\n\nexport type Format = {\n shouldPrintComment: (comment: string) => boolean;\n preserveFormat: boolean;\n retainLines: boolean;\n retainFunctionParens: boolean;\n comments: boolean;\n auxiliaryCommentBefore: string;\n auxiliaryCommentAfter: string;\n compact: boolean | \"auto\";\n minified: boolean;\n concise: boolean;\n indent: {\n adjustMultilineComment: boolean;\n style: string;\n };\n /**\n * @deprecated Removed in Babel 8, syntax type is always 'hash'\n */\n recordAndTupleSyntaxType?: GeneratorOptions[\"recordAndTupleSyntaxType\"];\n jsescOption: jsescOptions;\n /**\n * @deprecated Removed in Babel 8, use `jsescOption` instead\n */\n jsonCompatibleStrings?: boolean;\n /**\n * For use with the Hack-style pipe operator.\n * Changes what token is used for pipe bodies’ topic references.\n */\n topicToken?: GeneratorOptions[\"topicToken\"];\n /**\n * @deprecated Removed in Babel 8\n */\n decoratorsBeforeExport?: boolean;\n /**\n * The import attributes syntax style:\n * - \"with\" : `import { a } from \"b\" with { type: \"json\" };`\n * - \"assert\" : `import { a } from \"b\" assert { type: \"json\" };`\n * - \"with-legacy\" : `import { a } from \"b\" with type: \"json\";`\n */\n importAttributesKeyword?: \"with\" | \"assert\" | \"with-legacy\";\n};\n\ninterface AddNewlinesOptions {\n addNewlines(leading: boolean, node: t.Node): number;\n nextNodeStartLine: number;\n}\n\ninterface PrintSequenceOptions extends Partial {\n statement?: boolean;\n indent?: boolean;\n trailingCommentsLineOffset?: number;\n}\n\ninterface PrintListOptions {\n separator?: (this: Printer, occurrenceCount: number, last: boolean) => void;\n iterator?: (node: t.Node, index: number) => void;\n statement?: boolean;\n indent?: boolean;\n printTrailingSeparator?: boolean;\n}\n\nexport type PrintJoinOptions = PrintListOptions & PrintSequenceOptions;\nclass Printer {\n constructor(\n format: Format,\n map: SourceMap,\n tokens?: Token[],\n originalCode?: string,\n ) {\n this.format = format;\n\n this._tokens = tokens;\n this._originalCode = originalCode;\n\n this._indentRepeat = format.indent.style.length;\n\n this._inputMap = map?._inputMap;\n\n this._buf = new Buffer(map, format.indent.style[0]);\n }\n declare _inputMap: TraceMap;\n\n declare format: Format;\n\n inForStatementInit: boolean = false;\n enterForStatementInit() {\n if (this.inForStatementInit) return () => {};\n this.inForStatementInit = true;\n return () => {\n this.inForStatementInit = false;\n };\n }\n\n enterDelimited() {\n const oldInForStatementInit = this.inForStatementInit;\n const oldNoLineTerminatorAfterNode = this._noLineTerminatorAfterNode;\n if (\n oldInForStatementInit === false &&\n oldNoLineTerminatorAfterNode === null\n ) {\n return () => {};\n }\n this.inForStatementInit = false;\n this._noLineTerminatorAfterNode = null;\n return () => {\n this.inForStatementInit = oldInForStatementInit;\n this._noLineTerminatorAfterNode = oldNoLineTerminatorAfterNode;\n };\n }\n\n tokenContext: number = 0;\n\n _tokens: Token[] = null;\n _originalCode: string | null = null;\n\n declare _buf: Buffer;\n _currentNode: t.Node = null;\n _indent: number = 0;\n _indentRepeat: number = 0;\n _insideAux: boolean = false;\n _noLineTerminator: boolean = false;\n _noLineTerminatorAfterNode: t.Node | null = null;\n _printAuxAfterOnNextUserNode: boolean = false;\n _printedComments = new Set();\n _endsWithInteger = false;\n _endsWithWord = false;\n _endsWithDiv = false;\n _lastCommentLine = 0;\n _endsWithInnerRaw: boolean = false;\n _indentInnerComments: boolean = true;\n tokenMap: TokenMap = null;\n\n _boundGetRawIdentifier = this._getRawIdentifier.bind(this);\n\n generate(ast: t.Node) {\n if (this.format.preserveFormat) {\n this.tokenMap = new TokenMap(ast, this._tokens, this._originalCode);\n }\n this.print(ast);\n this._maybeAddAuxComment();\n\n return this._buf.get();\n }\n\n /**\n * Increment indent size.\n */\n\n indent(): void {\n const { format } = this;\n if (format.preserveFormat || format.compact || format.concise) {\n return;\n }\n\n this._indent++;\n }\n\n /**\n * Decrement indent size.\n */\n\n dedent(): void {\n const { format } = this;\n if (format.preserveFormat || format.compact || format.concise) {\n return;\n }\n\n this._indent--;\n }\n\n /**\n * Add a semicolon to the buffer.\n */\n\n semicolon(force: boolean = false): void {\n this._maybeAddAuxComment();\n if (force) {\n this._appendChar(charCodes.semicolon);\n this._noLineTerminator = false;\n return;\n }\n if (this.tokenMap) {\n const node = this._currentNode;\n if (node.start != null && node.end != null) {\n if (!this.tokenMap.endMatches(node, \";\")) {\n // no semicolon\n return;\n }\n const indexes = this.tokenMap.getIndexes(this._currentNode);\n this._catchUpTo(this._tokens[indexes[indexes.length - 1]].loc.start);\n }\n }\n this._queue(charCodes.semicolon);\n this._noLineTerminator = false;\n }\n\n /**\n * Add a right brace to the buffer.\n */\n\n rightBrace(node: t.Node): void {\n if (this.format.minified) {\n this._buf.removeLastSemicolon();\n }\n this.sourceWithOffset(\"end\", node.loc, -1);\n this.token(\"}\");\n }\n\n rightParens(node: t.Node): void {\n this.sourceWithOffset(\"end\", node.loc, -1);\n this.token(\")\");\n }\n\n /**\n * Add a space to the buffer unless it is compact.\n */\n\n space(force: boolean = false): void {\n const { format } = this;\n if (format.compact || format.preserveFormat) return;\n\n if (force) {\n this._space();\n } else if (this._buf.hasContent()) {\n const lastCp = this.getLastChar();\n if (lastCp !== charCodes.space && lastCp !== charCodes.lineFeed) {\n this._space();\n }\n }\n }\n\n /**\n * Writes a token that can't be safely parsed without taking whitespace into account.\n */\n\n word(str: string, noLineTerminatorAfter: boolean = false): void {\n this.tokenContext = 0;\n\n this._maybePrintInnerComments(str);\n\n // prevent concatenating words and creating // comment out of division and regex\n if (\n this._endsWithWord ||\n (this._endsWithDiv && str.charCodeAt(0) === charCodes.slash)\n ) {\n this._space();\n }\n\n this._maybeAddAuxComment();\n this._append(str, false);\n\n this._endsWithWord = true;\n this._noLineTerminator = noLineTerminatorAfter;\n }\n\n /**\n * Writes a number token so that we can validate if it is an integer.\n */\n\n number(str: string, number?: number): void {\n // const NON_DECIMAL_LITERAL = /^0[box]/;\n function isNonDecimalLiteral(str: string) {\n if (str.length > 2 && str.charCodeAt(0) === charCodes.digit0) {\n const secondChar = str.charCodeAt(1);\n return (\n secondChar === charCodes.lowercaseB ||\n secondChar === charCodes.lowercaseO ||\n secondChar === charCodes.lowercaseX\n );\n }\n return false;\n }\n this.word(str);\n\n // Integer tokens need special handling because they cannot have '.'s inserted\n // immediately after them.\n this._endsWithInteger =\n Number.isInteger(number) &&\n !isNonDecimalLiteral(str) &&\n !SCIENTIFIC_NOTATION.test(str) &&\n !ZERO_DECIMAL_INTEGER.test(str) &&\n str.charCodeAt(str.length - 1) !== charCodes.dot;\n }\n\n /**\n * Writes a simple token.\n *\n * @param {string} str The string to append.\n * @param {boolean} [maybeNewline=false] Wether `str` might potentially\n * contain a line terminator or not.\n * @param {number} [occurrenceCount=0] The occurrence count of this token in\n * the current node. This is used when printing in `preserveFormat` mode,\n * to know which token we should map to (for example, to disambiguate the\n * commas in an array literal).\n */\n token(str: string, maybeNewline = false, occurrenceCount = 0): void {\n this.tokenContext = 0;\n\n this._maybePrintInnerComments(str, occurrenceCount);\n\n const lastChar = this.getLastChar();\n const strFirst = str.charCodeAt(0);\n if (\n (lastChar === charCodes.exclamationMark &&\n // space is mandatory to avoid outputting