fix(parser): advance by enum scopes length during visiting (#23581)

### What does this PR do?
Matches esbuild behavior.

Fixes #23578
### How did you verify your code works?
Added a test.
This commit is contained in:
Dylan Conway
2025-10-13 05:11:54 -07:00
committed by GitHub
parent db7bcd79ff
commit c820c2b0d3
3 changed files with 33 additions and 2 deletions

View File

@@ -618,7 +618,9 @@ pub const Parser = struct {
.s_enum => {
try parts.appendSlice(preprocessed_enums.items[preprocessed_enum_i]);
preprocessed_enum_i += 1;
p.scope_order_to_visit = p.scope_order_to_visit[1..];
const enum_scope_count = p.scopes_in_order_for_enum.get(stmt.loc).?.len;
p.scope_order_to_visit = p.scope_order_to_visit[enum_scope_count..];
},
else => {
var sliced = try ListManaged(Stmt).initCapacity(p.allocator, 1);

View File

@@ -820,7 +820,9 @@ pub fn Visit(
const enum_stmts = preprocessed_enums.items[preprocessed_enum_i];
preprocessed_enum_i += 1;
try visited.appendSlice(enum_stmts);
p.scope_order_to_visit = p.scope_order_to_visit[1..];
const enum_scope_count = p.scopes_in_order_for_enum.get(stmt.loc).?.len;
p.scope_order_to_visit = p.scope_order_to_visit[enum_scope_count..];
continue;
},
else => {},

View File

@@ -73,6 +73,10 @@ describe("Bun.Transpiler", () => {
expect(ts.parsed(code, !out.endsWith(";\n"), false)).toBe(out);
},
transpiledOutput: code => {
return ts.parsed(code, false, false);
},
expectPrintedMin_: (code, out) => {
expect(ts.parsedMin(code, !out.endsWith(";\n"), false)).toBe(out);
},
@@ -322,6 +326,29 @@ describe("Bun.Transpiler", () => {
err("enum [] { a }", 'Expected identifier but found "["');
});
it("doesn't crash with functions assigned to enum values", () => {
const exp = ts.expectPrinted_;
expect(
ts.transpiledOutput(
`
enum ABC {
A = () => {},
}
function foo() {}
`,
"hi",
),
).toMatchInlineSnapshot(`
"var ABC;
((ABC) => {
ABC[ABC["A"] = () => {}] = "A";
})(ABC ||= {});
function foo() {}
"
`);
});
// TODO: fix all the cases that report generic "Parse error"
it("types", () => {
const exp = ts.expectPrinted_;