Skip to content

Commit

Permalink
fix #3205: panic with const enum inside parens
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jul 12, 2023
1 parent bf165fc commit aad8818
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

## Unreleased

* Fix a panic with `const enum` inside parentheses ([#3205](https://github.com/evanw/esbuild/issues/3205))

This release fixes an edge case where esbuild could potentially panic if a TypeScript `const enum` statement was used inside of a parenthesized expression and was followed by certain other scope-related statements. Here's a minimal example that triggers this edge case:

```ts
(() => {
const enum E { a };
() => E.a
})
```

* Allow a newline in the middle of TypeScript `export type` statement ([#3225](https://github.com/evanw/esbuild/issues/3225))

Previously esbuild incorrectly rejected the following valid TypeScript code:
Expand Down
5 changes: 4 additions & 1 deletion internal/js_parser/ts_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1427,7 +1427,10 @@ func (p *parser) parseTypeScriptEnumStmt(loc logger.Loc, opts parseStmtOpts) js_
if p.scopesInOrderForEnum == nil {
p.scopesInOrderForEnum = make(map[logger.Loc][]scopeOrder)
}
p.scopesInOrderForEnum[loc] = p.scopesInOrder[scopeIndex:]

// Make a copy of "scopesInOrder" instead of a slice since the original
// array may be flattened in the future by "popAndFlattenScope"
p.scopesInOrderForEnum[loc] = append([]scopeOrder{}, p.scopesInOrder[scopeIndex:]...)

return js_ast.Stmt{Loc: loc, Data: &js_ast.SEnum{
Name: name,
Expand Down
10 changes: 10 additions & 0 deletions internal/js_parser/ts_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,16 @@ var Foo = /* @__PURE__ */ ((Foo) => {
return Foo;
})(Foo || {});
bar = 0 /* FOO */;
`)

// https://github.com/evanw/esbuild/issues/3205
expectPrintedTS(t, "(() => { const enum Foo { A } () => Foo.A })", `() => {
let Foo;
((Foo) => {
Foo[Foo["A"] = 0] = "A";
})(Foo || (Foo = {}));
() => 0 /* A */;
};
`)
}

Expand Down
12 changes: 12 additions & 0 deletions scripts/end-to-end-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,18 @@ tests.push(
if (foo !== 1 || bar !== 3) throw 'fail'
`,
}),

// https://github.com/evanw/esbuild/issues/3205
test(['entry.ts', '--outfile=node.js'], {
'entry.ts': `
// Note: The parentheses are important here
let x = (() => {
const enum E { a = 123 }
return () => E.a
})
if (x()() !== 123) throw 'fail'
`,
}),
)

// Check "tsconfig.json" behavior
Expand Down

0 comments on commit aad8818

Please sign in to comment.