mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
beb46d31fa
## Summary
In unambiguous (`.js`) sources, `@foo export default class C { x = await + 1 }` reported a spurious `A module cannot have multiple default exports`.
A leading decorator makes the statement start with `@`, not `export`, so the eager Module-goal switch from #22684 didn't fire. The `await` identifier in the field initializer then triggered the unambiguous-mode top-level-await reparse, which re-ran `parse_statement_list_item` and recorded the `export default` a second time.
## Fix
- Commit to the Module goal in `parse_export_declaration` — the single place both leading and decorated exports flow through — so the export body parses under `Await` on the first pass, matching a non-decorated leading `export` (`ExportDeclaration` is unambiguously a `ModuleItem`, ECMA-262 §16.2.3).
- Skip the reparse for module declarations (`!stmt.is_module_declaration()`): an `export` / `import` is recorded on the first pass and is goal-independent, so reparsing only double-records it.
This also simplifies `parse_directives_and_statements`: the mutable `track_await_reparse` flag and the inline eager-commit block are removed; committing is now driven by `!ctx.has_await()`.
`await` stays correctly reserved in the module, so the input is still a syntax error (`The keyword 'await' is reserved`) — just no longer a *spurious* duplicate-export one. `tasks/coverage/misc/fail/oxc-22684.js` covers this.
Conformance: zero snapshot drift outside the new `misc` fixture.
Follow-up to #22684.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
11 lines
447 B
JavaScript
11 lines
447 B
JavaScript
// https://github.com/oxc-project/oxc/pull/22684
|
|
// `await` is reserved in a module, so this is a (correct) error. The point of
|
|
// this test is that the decorated `export default` must be recorded only once:
|
|
// it must NOT also report a spurious "A module cannot have multiple default
|
|
// exports". The `await` identifier is what previously triggered the reparse
|
|
// that double-recorded the export.
|
|
@foo
|
|
export default class C {
|
|
x = await + 1;
|
|
}
|