Change space algorithm so trim is no longer needed
MODIFY
packages/@romejs/js-formatter/Printer.ts
packages/@romejs/js-formatter/Printer.ts
@@ -21,14 +21,10 @@ export type PrinterOutput = {
mappings: Array<Mapping>;
};
-type Indent = {
- depth: number;
- value: string;
-};
-
type State = {
- indent: Indent;
flat: boolean;
+ indent: Box<number>;
+ pendingSpaces: Box<number>;
buffer: StringBuffer;
mappings: Array<Mapping>;
lineSuffixes: Array<[Token, State]>;
@@ -42,11 +38,12 @@ class BreakError extends Error {
}
}
-function createIndent(depth: number, options: PrinterOptions): Indent {
- return {
- depth,
- value: ' '.repeat(depth * options.indentWidth),
- };
+class Box<T> {
+ constructor(value: T) {
+ this.value = value;
+ }
+
+ value: T;
}
function forkState(parent: State, callback: (state: State) => void): void {
@@ -54,6 +51,7 @@ function forkState(parent: State, callback: (state: State) => void): void {
const state: State = {
...parent,
buffer: StringBuffer.from(parent.buffer),
+ pendingSpaces: new Box(parent.pendingSpaces.value),
};
try {
@@ -69,6 +67,7 @@ function forkState(parent: State, callback: (state: State) => void): void {
// Merge the states together
parent.buffer.merge(state.buffer);
+ parent.pendingSpaces.value = state.pendingSpaces.value;
}
function print(token: Token, state: State, options: PrinterOptions): void {
@@ -79,6 +78,15 @@ function print(token: Token, state: State, options: PrinterOptions): void {
if (typeof token === 'string') {
if (token !== '') {
+ if (ob1Get0(state.buffer.column) === 0) {
+ state.buffer.push(' '.repeat(state.indent.value));
+ } else {
+ if (state.pendingSpaces.value > 0) {
+ state.buffer.push(' '.repeat(state.pendingSpaces.value));
+ state.pendingSpaces.value = 0;
+ }
+ }
+
state.buffer.push(token);
// If the line is too long, break the group if it is possible
@@ -150,7 +158,10 @@ function print(token: Token, state: State, options: PrinterOptions): void {
case 'Indent': {
stack.push([
token.contents,
- {...state, indent: createIndent(state.indent.depth + 1, options)},
+ {
+ ...state,
+ indent: new Box(state.indent.value + options.indentWidth),
+ },
]);
break;
}
@@ -159,7 +170,7 @@ function print(token: Token, state: State, options: PrinterOptions): void {
if (state.flat) {
switch (token.mode) {
case 'space': {
- state.buffer.push(' ');
+ state.pendingSpaces.value++;
break;
}
@@ -181,9 +192,8 @@ function print(token: Token, state: State, options: PrinterOptions): void {
break;
}
- state.buffer.trim();
state.buffer.push('\n');
- state.buffer.push(state.indent.value);
+ state.pendingSpaces.value = 0;
}
break;
}
@@ -223,7 +233,7 @@ function print(token: Token, state: State, options: PrinterOptions): void {
}
case 'Space': {
- state.buffer.push(' ');
+ state.pendingSpaces.value++;
break;
}
}
@@ -236,8 +246,9 @@ export function printTokenToString(
options: PrinterOptions,
): PrinterOutput {
const state: State = {
- indent: createIndent(options.rootIndent, options),
flat: false,
+ indent: new Box(options.rootIndent * options.indentWidth),
+ pendingSpaces: new Box(0),
buffer: new StringBuffer(),
mappings: [],
lineSuffixes: [],

MODIFY
packages/@romejs/js-formatter/StringBuffer.ts
packages/@romejs/js-formatter/StringBuffer.ts
* LICENSE file in the root directory of this source tree.
*/
-import {
- Number0,
- Number1,
- ob1Inc,
- ob1Number0,
- ob1Number1,
- ob1Sub,
-} from '@romejs/ob1';
+import {Number0, Number1, ob1Inc, ob1Number0, ob1Number1} from '@romejs/ob1';
export default class StringBuffer {
static from(parent: StringBuffer): StringBuffer {
@@ -26,9 +19,7 @@ export default class StringBuffer {
this.column = ob1Number0;
this.line = ob1Number1;
} else {
- // FIXME: This is a aweful for memory usage.
- // It must be replaced by a better algorithm.
- this.buffer = parent.buffer.slice();
+ this.buffer = [];
this.index = parent.index;
this.column = parent.column;
this.line = parent.line;
@@ -54,27 +45,8 @@ export default class StringBuffer {
this.buffer.push(segment);
}
- trim(): void {
- let trimmed = 0;
-
- while (this.buffer.length > 0) {
- const segment = this.buffer[this.buffer.length - 1];
- if (/^ *$/.test(segment)) {
- this.buffer.pop();
- trimmed += segment.length;
- } else {
- break;
- }
- }
-
- if (trimmed > 0) {
- this.index = ob1Sub(this.index, trimmed);
- this.column = ob1Sub(this.column, trimmed);
- }
- }
-
merge(other: StringBuffer): void {
- this.buffer = other.buffer;
+ this.buffer.push(...other.buffer);
this.index = other.index;
this.column = other.column;
this.line = other.line;

Change space algorithm so trim is no longer needed