perf(packages/codegen): printNonNegativeFloat write mapping directly (#25968)

Small perf optimization and code simplification.

`printNonNegativeFloat` previously passed the `node` parameter through a long chain of helper functions, so that they could call `writeWithMap` with `node` on their first write.

Instead create the sourcemapping at the start of the chain, so there's no need to pass `node` down and helpers can just use `write` / `writeLast`.
This commit is contained in:
overlookmotel committed 2026-08-22 09:30:31 +00:00
1 parent 7f70606ea1
commit 7e2b4b36a1
1 file changed
+23 -37
+23 -37
View File
@@ -9,14 +9,7 @@
// Each form is written to the output in pieces, so no candidate string is ever built.
import { debugAssert } from "../asserts.ts";
import {
CAT_IDENT,
CAT_INT_DIGIT,
write,
writeNoLast,
writeWithMap,
writeWithMapNoLast,
} from "./write.ts";
import { CAT_IDENT, CAT_INT_DIGIT, markWithMapNoName, write, writeNoLast } from "./write.ts";
import type { State } from "../state.ts";
import type * as ESTree from "../../../../npm/oxc-types/types.d.ts";
@@ -32,14 +25,16 @@ import type * as ESTree from "../../../../npm/oxc-types/types.d.ts";
* from a following `.` already.
*/
export function printNonNegativeFloat(state: State, value: number, node: ESTree.Node): void {
markWithMapNoName(state, node);
if (Number.isInteger(value)) {
if (value < 1000) {
writeWithMap(state, String(value), CAT_INT_DIGIT, node);
write(state, String(value), CAT_INT_DIGIT);
} else {
printShortestInteger(state, value, node);
printShortestInteger(state, value);
}
} else {
printShortestFraction(state, value, node);
printShortestFraction(state, value);
}
}
@@ -49,19 +44,19 @@ export function printNonNegativeFloat(state: State, value: number, node: ESTree.
* `String` gives plain digits below 1e21 and exponent notation from there up, which have different forms
* available to them, so they are separate cases. Both can go hexadecimal.
*/
function printShortestInteger(state: State, value: number, node: ESTree.Node): void {
function printShortestInteger(state: State, value: number): void {
const formatted = String(value);
if (value >= 1e21) {
debugAssert(formatted.includes("e+"), "`String` gives `e+` notation from 1e21 up");
// The `+` always goes, so the text is one shorter than `formatted`
if (printHexIfShorter(state, value, formatted.length - 1, node)) return;
printExponent(state, formatted, formatted.indexOf("e"), node);
if (printHexIfShorter(state, value, formatted.length - 1)) return;
printExponent(state, formatted, formatted.indexOf("e"));
return;
}
const { length } = formatted;
if (printHexIfShorter(state, value, length, node)) return;
if (printHexIfShorter(state, value, length)) return;
// A run of trailing zeros as an exponent: `1000` -> `1e3`
if (formatted.charCodeAt(length - 1) === 48 /* 0 */) {
@@ -72,14 +67,14 @@ function printShortestInteger(state: State, value: number, node: ESTree.Node): v
// Worth it when the `e` and the exponent cost less than the zeros they replace
const exponent = String(zeros);
if (exponent.length + 1 < zeros) {
writeWithMapNoLast(state, formatted.slice(0, length - zeros), node);
writeNoLast(state, formatted.slice(0, length - zeros));
writeNoLast(state, "e");
write(state, exponent, CAT_IDENT);
return;
}
}
writeWithMap(state, formatted, CAT_INT_DIGIT, node);
write(state, formatted, CAT_INT_DIGIT);
}
/**
@@ -89,7 +84,7 @@ function printShortestInteger(state: State, value: number, node: ESTree.Node): v
* below 1e-7. The first always loses its leading zero, and may trade a run of zeros after the point
* for a negative exponent. The second is already as short as it gets.
*/
function printShortestFraction(state: State, value: number, node: ESTree.Node): void {
function printShortestFraction(state: State, value: number): void {
const formatted = String(value);
// The trailing-zero form `printShortestInteger` uses can never win here, so it is not tried.
@@ -117,24 +112,24 @@ function printShortestFraction(state: State, value: number, node: ESTree.Node):
// Both forms keep the digits, so it comes down to the `e-` and the exponent against the `.`
// and the zeros they replace
if (exponent.length + 2 < start - 1) {
writeWithMapNoLast(state, formatted.slice(start), node);
writeNoLast(state, formatted.slice(start));
writeNoLast(state, "e-");
write(state, exponent, CAT_IDENT);
return;
}
}
writeWithMap(state, formatted.slice(1), CAT_IDENT, node);
write(state, formatted.slice(1), CAT_IDENT);
return;
}
const exponentIndex = formatted.indexOf("e");
if (exponentIndex === -1) {
writeWithMap(state, formatted, CAT_IDENT, node);
write(state, formatted, CAT_IDENT);
return;
}
printExponent(state, formatted, exponentIndex, node);
printExponent(state, formatted, exponentIndex);
}
/**
@@ -144,15 +139,11 @@ function printShortestFraction(state: State, value: number, node: ESTree.Node):
* `1.5e+21` -> `15e20`. That drops the `.`, so it wins whenever the exponent it leaves is no longer to write
* than the one it replaces. The `+` of a positive exponent always goes.
*
* @param state - Printer state
* @param formatted - `String(value)`, which is in exponent notation
* @param exponentIndex - Index of the `e` in `formatted`
*/
function printExponent(
state: State,
formatted: string,
exponentIndex: number,
node: ESTree.Node,
): void {
function printExponent(state: State, formatted: string, exponentIndex: number): void {
const exponent =
formatted.charCodeAt(exponentIndex + 1) === "+".charCodeAt(0)
? formatted.slice(exponentIndex + 2)
@@ -166,7 +157,7 @@ function printExponent(
const folded = String(Number(exponent) - (exponentIndex - 2));
if (folded.length <= exponent.length) {
writeWithMapNoLast(state, formatted[0], node);
writeNoLast(state, formatted[0]);
writeNoLast(state, formatted.slice(2, exponentIndex));
writeNoLast(state, "e");
write(state, folded, CAT_IDENT);
@@ -174,7 +165,7 @@ function printExponent(
}
}
writeWithMapNoLast(state, formatted.slice(0, exponentIndex + 1), node);
writeNoLast(state, formatted.slice(0, exponentIndex + 1));
write(state, exponent, CAT_IDENT);
}
@@ -193,18 +184,13 @@ function printExponent(
*
* @param length - Length of the shortest text found for `value` so far
*/
function printHexIfShorter(
state: State,
value: number,
length: number,
node: ESTree.Node,
): boolean {
function printHexIfShorter(state: State, value: number, length: number): boolean {
if (length < 13) return false;
const hex = BigInt(value).toString(16);
if (hex.length + 2 >= length) return false;
writeWithMapNoLast(state, "0x", node);
writeNoLast(state, "0x");
write(state, hex, CAT_IDENT);
return true;