import type Position from "./position"; import repeat from "lodash/repeat"; import trimEnd from "lodash/trimEnd"; /** * Buffer for collecting generated output. */ export default class Buffer { constructor(position: Position, format: Object) { this.printedCommentStarts = {}; this.parenPushNewlineState = null; this.position = position; this._indent = format.indent.base; this.format = format; this.buf = ""; // Maintaining a reference to the last char in the buffer is an optimization // to make sure that v8 doesn't "flatten" the string more often than needed // see https://github.com/babel/babel/pull/3283 for details. this.last = ""; this.map = null; this._sourcePosition = { line: null, column: null, filename: null, }; this._endsWithWord = false; } printedCommentStarts: Object; parenPushNewlineState: ?Object; position: Position; _indent: number; format: Object; buf: string; last: string; /** * Description */ catchUp(node: Object) { // catch up to this nodes newline if we're behind if (node.loc && this.format.retainLines && this.buf) { while (this.position.line < node.loc.start.line) { this.push("\n"); } } } /** * Get the current trimmed buffer. */ get(): string { return trimEnd(this.buf); } /** * Get the current indent. */ getIndent(): string { if (this.format.compact || this.format.concise) { return ""; } else { return repeat(this.format.indent.style, this._indent); } } /** * Get the current indent size. */ indentSize(): number { return this.getIndent().length; } /** * Increment indent size. */ indent() { this._indent++; } /** * Decrement indent size. */ dedent() { this._indent--; } /** * Add a semicolon to the buffer. */ semicolon() { this.token(";"); } /** * Add a right brace to the buffer. */ rightBrace() { this.newline(true); if (this.format.minified && !this._lastPrintedIsEmptyStatement) { this._removeLast(";"); } this.token("}"); } /** * Add a keyword to the buffer. */ keyword(name: string) { this.word(name); this.space(); } /** * Add a space to the buffer unless it is compact. */ space() { if (this.format.compact) return; if (this.buf && !this.endsWith(" ") && !this.endsWith("\n")) { this.push(" "); } } /** * Writes a token that can't be safely parsed without taking whitespace into account. */ word(str: string) { if (this._endsWithWord) this.push(" "); this.push(str); this._endsWithWord = true; } /** * Writes a simple token. */ token(str: string) { // space is mandatory to avoid outputting