Keep a hoisted class's next piece when the initializer ends with it

In minified output the class closes right where the initializer body
does (`…Counter=class{…}}})`), so the empty insertion that opens the next
run-once piece shared its position with the body's closing edit and was
dropped: the initializer then called a piece that did not exist. The
opener now rides on the class's own closing brace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Malte Ubl
2026-10-20 01:21:28 -07:00
co-authored by Claude Opus 5.5
parent 4d29f27186
commit 14f1fe97f0
2 changed files with 23 additions and 5 deletions
@@ -256,3 +256,10 @@ console.log(typeof make().on);
`);
expect(lowered).toContain('new (require("events")).EventEmitter()');
});
test("a minified initializer that ends with its class still hoists it", () => {
const lowered = expectSameBehavior(
`${helpers}var Counter;var init_counter=__esm({"src/counter.ts"(){console.log("counter init"),Counter=class{n=0;next(){return++this.n}}}});function run(){init_counter();const c=new Counter;c.next();console.log(c.next())}run();`,
);
expect(lowered).toContain("class Counter{");
});
@@ -984,11 +984,22 @@ function hoistInitClasses(
hoistedEls.add(el);
edits.push({ start: from, end: cls.getStart(sf), text: `${sep} ${rest}(); ${close} ` });
const next = els[i + 1];
edits.push({
start: cls.getEnd(),
end: next === undefined ? cls.getEnd() : next.getStart(sf),
text: ` function ${rest}() { ${strict}`,
});
// The class's own closing brace carries the next piece's opener: an
// empty insertion at its end would share its position with the
// initializer body's closing edit in minified text (`…}}})`).
edits.push(
next === undefined
? {
start: cls.getEnd() - 1,
end: cls.getEnd(),
text: `} function ${rest}() { ${strict}`,
}
: {
start: cls.getEnd(),
end: next.getStart(sf),
text: ` function ${rest}() { ${strict}`,
},
);
if (cls.name === undefined) {
const keyword = cls.getStart(sf);
edits.push({ start: keyword, end: keyword + "class".length, text: `class ${name}` });