mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Address code review: remove boolean field, use sentinel value instead
Changes based on code review feedback:
1. Removed `is_at_module_scope` boolean field from lexer
- Instead, use `fn_or_arrow_start_loc` as a sentinel
- When at module scope, set it to `await_keyword_loc`
- Compare locations to detect module scope: `fn_or_arrow_start_loc.start == await_keyword_loc.start`
- This avoids adding persistent state to the lexer
2. Fixed test for async function in CJS format
- Changed from `main().catch(console.error)` to IIFE: `(async function main() { ... })().catch(console.error)`
- This ensures the promise is created and executed immediately
- Prevents the CJS process from exiting before async work completes
The sentinel approach is cleaner as it reuses existing fields rather than
adding new state. The lexer already tracks both `await_keyword_loc` and
`fn_or_arrow_start_loc`, so we can encode the module scope information by
setting them to the same value when appropriate.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -136,9 +136,14 @@ pub fn ParsePrefix(
|
||||
.allow_ident => {
|
||||
p.lexer.prev_token_was_await_keyword = true;
|
||||
p.lexer.await_keyword_loc = name_range.loc;
|
||||
p.lexer.fn_or_arrow_start_loc = p.fn_or_arrow_data_parse.needs_async_loc;
|
||||
// Check if we're at module scope by comparing current scope to module scope
|
||||
p.lexer.is_at_module_scope = p.current_scope == p.module_scope;
|
||||
// Use fn_or_arrow_start_loc as a signal:
|
||||
// - If at module scope, set it to await_keyword_loc (sentinel)
|
||||
// - Otherwise, set it to needs_async_loc (may be empty for arrow functions)
|
||||
if (p.current_scope == p.module_scope) {
|
||||
p.lexer.fn_or_arrow_start_loc = name_range.loc;
|
||||
} else {
|
||||
p.lexer.fn_or_arrow_start_loc = p.fn_or_arrow_data_parse.needs_async_loc;
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -138,7 +138,6 @@ fn NewLexer_(
|
||||
prev_token_was_await_keyword: bool = false,
|
||||
await_keyword_loc: logger.Loc = logger.Loc.Empty,
|
||||
fn_or_arrow_start_loc: logger.Loc = logger.Loc.Empty,
|
||||
is_at_module_scope: bool = true,
|
||||
regex_flags_start: ?u16 = null,
|
||||
allocator: std.mem.Allocator,
|
||||
string_literal_raw_content: string = "",
|
||||
@@ -1821,7 +1820,13 @@ fn NewLexer_(
|
||||
|
||||
pub fn expectedString(self: *LexerType, text: string) !void {
|
||||
if (self.prev_token_was_await_keyword) {
|
||||
if (self.is_at_module_scope) {
|
||||
// Use fn_or_arrow_start_loc as a signal:
|
||||
// - If it equals await_keyword_loc, we're at module scope (sentinel value)
|
||||
// - If it's not empty and different, we're in a function with a location for "async"
|
||||
// - If it's empty, we're in a function without a clear location (e.g., arrow function)
|
||||
const is_at_module_scope = self.fn_or_arrow_start_loc.start == self.await_keyword_loc.start;
|
||||
|
||||
if (is_at_module_scope) {
|
||||
// Top-level await - provide better error message
|
||||
try self.addRangeErrorWithNotes(
|
||||
self.range(),
|
||||
|
||||
@@ -54,16 +54,14 @@ describe("bundler", () => {
|
||||
itBundled("top_level_await_error/AwaitInAsyncFunctionShouldStillWork", {
|
||||
files: {
|
||||
"/entry.ts": /* ts */ `
|
||||
async function main() {
|
||||
(async function main() {
|
||||
async function sum(a: number, b: number) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
const result = await sum(5, 5);
|
||||
console.log(result);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
})().catch(console.error);
|
||||
`,
|
||||
},
|
||||
format: "cjs",
|
||||
|
||||
Reference in New Issue
Block a user