Skip to content

Preserve string-literal names in re-export clauses#29245

Open
robobun wants to merge 5 commits intomainfrom
farm/964629d3/fix-reexport-string-literal
Open

Preserve string-literal names in re-export clauses#29245
robobun wants to merge 5 commits intomainfrom
farm/964629d3/fix-reexport-string-literal

Conversation

@robobun
Copy link
Copy Markdown
Collaborator

@robobun robobun commented Apr 13, 2026

Fixes #29242

Repro

// a.mjs
export { "a b c" } from './b.mjs';
// b.mjs
const a = 1;
export { a as "a b c" };
// main.mjs
import { "a b c" as a } from './a.mjs';
console.log(a);

bun main.mjs fails with:

1 | export { "a b c" } from './b.mjs';
    ^
SyntaxError: Unexpected identifier 'b'. Expected '}' to end an export list.

Cause

Bun's parser already accepts string-literal module export names in export { ... } from 'mod' clauses, but the printer emitted the local name via printIdentifier. For export { "a b c" } from './b.mjs', this stripped the quotes and produced export { a b c } from './b.mjs' which JSC then rejected. Bundled output was fine — only single-file transpile hit this path.

Fix

Added an .export_from variant of printClauseItemAs that prints the local name via printClauseAlias (which quotes the string when it isn't a valid identifier). The regular export { x } path is unchanged — per spec the local name there must be an IdentifierReference, so printIdentifier is still correct.

Verification

test/regression/issue/29242.test.ts covers four variants ({ 'x y z' }, { 'x y z' as a }, { 'x y z' as 'a b c' }, mixed) plus direct printer checks. All seven fail on main and pass with the fix.

@robobun
Copy link
Copy Markdown
Collaborator Author

robobun commented Apr 13, 2026

Updated 9:20 PM PT - Apr 12th, 2026

@autofix-ci[bot], your commit 6f510fb has 2 failures in Build #45435 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 29245

That installs a local version of the PR into your bun-29245 executable, so you can run:

bun-29245 --bun

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Printer extended to emit export { ... } from 'mod' clause items (including string-literal export names and as aliases). A new regression test test/regression/issue/29242.test.ts was added covering runtime and build scenarios for string-literal re-exports and aliases.

Changes

Cohort / File(s) Summary
Export-from Clause Printer Logic
src/js_printer.zig
Added printExportFromClauseItem and a .export_from branch in printClauseItemAs to print export { ... } from ... items. Left-side export names are emitted via printClauseAlias (preferring item.original_name), optional as <alias> is emitted with alias_loc, and s_export_from now calls the new helper.
Regression Tests
test/regression/issue/29242.test.ts
Added five tests exercising runtime and bun build scenarios for export { "<string>" [as ...] } from ... forms, asserting correct quoted names/aliases, absence of SyntaxError, and behavior with --no-bundle and --minify-identifiers.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly captures the main fix: preserving string-literal names in re-export clauses, which is the core issue being addressed.
Description check ✅ Passed The description includes both required sections: 'Repro' (what), 'Cause' and 'Fix' (how verified), with clear examples and technical details about the changes.
Linked Issues check ✅ Passed The PR fully addresses issue #29242 by fixing the printer to preserve quotes in string-literal export names, with comprehensive test coverage for the reported scenarios.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing issue #29242: the printer enhancement in js_printer.zig and corresponding regression tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/js_printer.zig (1)

1933-1974: ⚠️ Potential issue | 🔴 Critical

Use item.original_name in the new export_from printer path.

For re-exports, the left side is the source module’s export name, not the renamed intermediate symbol. ClauseItem.original_name exists for exactly this case. As written, minification/collision renaming can still turn export { foo as out } from "./mod" into export { a as out } from "./mod", which breaks the re-export.

🐛 Suggested fix
 fn printClauseItemAs(p: *Printer, item: js_ast.ClauseItem, comptime as: `@Type`(.enum_literal)) void {
     const name = p.renamer.nameForSymbol(item.name.ref.?);
+    const export_from_name = if (comptime as == .export_from and item.original_name.len > 0)
+        item.original_name
+    else
+        name;
@@
             } else if (comptime as == .export_from) {
                 // In `export { x } from 'mod'`, the "name" on the left of `as` refers
                 // to an export of the other module. ECMAScript allows this to be a
                 // string literal (`export { "a b c" } from 'mod'`), so we must use
                 // `printClauseAlias` rather than `printIdentifier` here. The symbol
                 // does not participate in local renaming.
-                p.printClauseAlias(name);
+                p.printClauseAlias(export_from_name);
 
-                if (!strings.eql(name, item.alias)) {
+                if (!strings.eql(export_from_name, item.alias)) {
                     p.print(" as ");
                     p.addSourceMapping(item.alias_loc);
                     p.printClauseAlias(item.alias);
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/js_printer.zig` around lines 1933 - 1974, The export-from branch in fn
printClauseItemAs currently prints the locally renamed symbol (name) instead of
the source module's export name; change the export_from path to use
item.original_name (e.g., call p.printClauseAlias(item.original_name)) so
re-exports emit the original export identifier/string literal rather than the
renamed local symbol, and keep the existing alias handling (the subsequent if
with item.alias and item.alias_loc) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/29242.test.ts`:
- Around line 107-119: The exit-code assertion is placed too early, which hides
useful stdout failure details; move the expect(exitCode).toBe(0) so it runs
after the stdout content checks. Specifically, in the block using
proc.stdout/stderr/exited and variables stdout, stderr, exitCode and
mustContain, keep expect(stderr).not.toContain("SyntaxError") first, then assert
each mustContain fragment against stdout and the two not.toMatch checks for
unquoted patterns, and only after all stdout assertions call
expect(exitCode).toBe(0); preserve existing comments (e.g., the "No unquoted `a
b c`..." line) and ordering of stderr checks.

---

Outside diff comments:
In `@src/js_printer.zig`:
- Around line 1933-1974: The export-from branch in fn printClauseItemAs
currently prints the locally renamed symbol (name) instead of the source
module's export name; change the export_from path to use item.original_name
(e.g., call p.printClauseAlias(item.original_name)) so re-exports emit the
original export identifier/string literal rather than the renamed local symbol,
and keep the existing alias handling (the subsequent if with item.alias and
item.alias_loc) unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: acc4a9ee-7054-42eb-9fbb-a63dcc092904

📥 Commits

Reviewing files that changed from the base of the PR and between d7526e2 and 0f8671e.

📒 Files selected for processing (2)
  • src/js_printer.zig
  • test/regression/issue/29242.test.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
test/regression/issue/29242.test.ts (1)

95-98: ⚠️ Potential issue | 🟡 Minor

Move the exit-code assertion after stdout content checks (Line 95).

expect(exitCode).toBe(0) currently runs before the stdout fragment assertions, which reduces failure usefulness when content mismatches occur.

Suggested fix
   const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
   expect(stderr).not.toContain("SyntaxError");
-  expect(exitCode).toBe(0);
   for (const frag of mustContain) {
     expect(stdout).toContain(frag);
   }
   // No unquoted `a b c` or `x y z` anywhere.
   expect(stdout).not.toMatch(/(^|[^"])a b c(?!")/);
   expect(stdout).not.toMatch(/(^|[^"])x y z(?!")/);
+  expect(exitCode).toBe(0);

As per coding guidelines, "Expect stdout assertions before exit code assertions - expect(stdout).toBe(...) BEFORE expect(exitCode).toBe(0) for more useful error messages".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/regression/issue/29242.test.ts` around lines 95 - 98, The test currently
asserts expect(exitCode).toBe(0) before verifying stdout fragments; move the
exit-code check to after the stdout checks so failures show the mismatched
output first. Specifically, in the test that uses exitCode, stdout, and
mustContain, iterate over mustContain and assert expect(stdout).toContain(frag)
for each frag first, then call expect(exitCode).toBe(0) afterward.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@test/regression/issue/29242.test.ts`:
- Around line 95-98: The test currently asserts expect(exitCode).toBe(0) before
verifying stdout fragments; move the exit-code check to after the stdout checks
so failures show the mismatched output first. Specifically, in the test that
uses exitCode, stdout, and mustContain, iterate over mustContain and assert
expect(stdout).toContain(frag) for each frag first, then call
expect(exitCode).toBe(0) afterward.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 17ec920a-9f93-43cd-85b7-1171679882c2

📥 Commits

Reviewing files that changed from the base of the PR and between 0f8671e and 8620891.

📒 Files selected for processing (1)
  • test/regression/issue/29242.test.ts

Copy link
Copy Markdown
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — targeted fix with good test coverage.

Extended reasoning...

Overview

This PR modifies src/js_printer.zig to add a new .export_from variant in printClauseItemAs, and introduces a corresponding printExportFromClauseItem helper. The call site at the export { ... } from 'mod' branch is switched from printExportClauseItem to the new printExportFromClauseItem. A regression test file is added.

Security Risks

None. This is a printer output correctness fix — it only affects what JavaScript text gets emitted, and strictly produces more spec-compliant output.

Level of Scrutiny

Low-to-medium. The change is well-contained: one new enum variant in a comptime switch, one new thin wrapper function, and one changed call site. The logic mirrors the existing .import branch (which also uses printClauseAlias for the foreign-module name side). The distinction between local exports (printIdentifier correct per spec) and re-exports (printClauseAlias required per spec) is sound.

Other Factors

The two inline bug reports are style nits (missing test.concurrent and assertion ordering in the test.each block) — neither affects test correctness or the fix itself. The three individual end-to-end tests follow the prescribed ordering correctly. Coverage of four printer variants plus three runtime variants is thorough for the scope of the fix.


Additional findings (outside current diff — PR may have been updated during review):

  • 🟡 test/regression/issue/29242.test.ts:111-118 — In the test.each block (lines ~111-118), expect(exitCode).toBe(0) is checked before the stdout content assertions, violating the CLAUDE.md rule that stdout checks should come before exitCode. The three individual tests in the same file correctly follow the prescribed order (stderr → stdout → exitCode), making this an inconsistency that slightly degrades test failure diagnostics.

    Extended reasoning...

    What the bug is and how it manifests

    The test.each block at the bottom of test/regression/issue/29242.test.ts collects stdout, stderr, and exitCode from the transpiler process, then checks them in this order: expect(stderr).not.toContain("SyntaxError"), then expect(exitCode).toBe(0), and only afterwards iterates mustContain fragments with expect(stdout).toContain(frag) plus the two regex checks. This inverts the recommended ordering for exitCode vs. stdout assertions.

    The specific code path that triggers it

    In the async callback of test.each (approximately lines 111-119 in the new file), after proc.exited resolves, the assertion order is: (1) expect(stderr).not.toContain("SyntaxError"), (2) expect(exitCode).toBe(0) — exitCode checked here, (3) for (const frag of mustContain) { expect(stdout).toContain(frag); } — stdout checked here, and (4) two expect(stdout).not.toMatch(...) regex checks.

    Why existing code does not prevent it

    The three individual tests above ("re-export with string literal local name", "re-export aliasing from string literal to identifier", "re-export aliasing string literal to string literal") all correctly order their assertions as stderr → stdout → exitCode. There is no lint rule or automated check enforcing the CLAUDE.md ordering convention in the test.each block.

    What the impact would be

    If the printer emits incorrect output (e.g., unquoted a b c instead of "a b c"), the transpiler process will likely exit with code 1. With the current ordering, the failing test reports "expected exitCode to be 0 but got 1", which gives no information about why the process failed. If stdout were checked first, the test would instead report something like "expected stdout to contain "a b c"", immediately pointing to the broken printer output.

    How to fix it

    Move expect(exitCode).toBe(0) to after the mustContain loop and the two not.toMatch regex assertions, matching the order used in the three individual tests.

    Step-by-step proof

    1. Suppose the fix in js_printer.zig is accidentally reverted.
    2. The transpiler processes export { "a b c" } from "./mod"; and emits export { a b c } from "./mod"; (unquoted).
    3. Because the output is syntactically invalid, bun build exits with code 1.
    4. With current ordering: expect(exitCode).toBe(0) fires first, failure message: "Expected: 0, Received: 1". Developer must guess why.
    5. With corrected ordering: expect(stdout).toContain("\"a b c\"") fires first, failure message directly shows the malformed stdout. Root cause is immediately obvious.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/js_printer.zig (1)

4213-4263: ⚠️ Potential issue | 🟠 Major

Keep ModuleInfo in sync with the printed re-export name.

When module_info is enabled, Line 4262 still records the indirect source name via p.renamer.nameForSymbol(item.name.ref.?). For export { "x y z" as a } from ..., the emitted code now correctly uses item.original_name, but the metadata still stores the synthesized/local symbol name instead of "x y z". That leaves Bun's internal export graph wrong for the exact case this patch fixes.

🛠️ Suggested fix
                     if (may_have_module_info) {
                         if (p.moduleInfo()) |mi| {
                             const irp_id = bun.handleOom(mi.str(irp));
                             bun.handleOom(mi.requestModule(irp_id, .none));
                             for (s.items) |item| {
-                                const name = p.renamer.nameForSymbol(item.name.ref.?);
-                                bun.handleOom(mi.addExportInfoIndirect(bun.handleOom(mi.str(item.alias)), bun.handleOom(mi.str(name)), irp_id));
+                                const name = p.renamer.nameForSymbol(item.name.ref.?);
+                                const from_name = if (item.original_name.len > 0) item.original_name else name;
+                                bun.handleOom(mi.addExportInfoIndirect(
+                                    bun.handleOom(mi.str(item.alias)),
+                                    bun.handleOom(mi.str(from_name)),
+                                    irp_id,
+                                ));
                             }
                         }
                     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/js_printer.zig` around lines 4213 - 4263, The ModuleInfo export metadata
is using the local/synthesized symbol via
p.renamer.nameForSymbol(item.name.ref.?) instead of the printed re-export token
(item.original_name) for re-exports; update the loop that calls
bun.handleOom(mi.addExportInfoIndirect(...)) inside the .s_export_from arm to
use item.original_name when present (fall back to p.renamer.nameForSymbol(...)
only if item.original_name is null/empty), and ensure you still wrap values with
bun.handleOom(mi.str(...)) and pass the same irp_id as before so the stored
export name matches what p.printExportFromClauseItem emits.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/29242.test.ts`:
- Around line 99-100: The test uses regexes that only treat double quotes as
string delimiters in the expect(stdout).not.toMatch assertions for the tokens "a
b c" and "x y z" (and the similar assertion at line 126); update those regexes
in this test file so the unquoted-token guard is quote-style agnostic by
matching either single or double quotes (use a character class like ["'] or an
alternation) in the lookaround, keeping the same anchors and negative lookahead
logic so the assertions still reject unquoted tokens but accept tokens
surrounded by either single or double quotes.

---

Outside diff comments:
In `@src/js_printer.zig`:
- Around line 4213-4263: The ModuleInfo export metadata is using the
local/synthesized symbol via p.renamer.nameForSymbol(item.name.ref.?) instead of
the printed re-export token (item.original_name) for re-exports; update the loop
that calls bun.handleOom(mi.addExportInfoIndirect(...)) inside the
.s_export_from arm to use item.original_name when present (fall back to
p.renamer.nameForSymbol(...) only if item.original_name is null/empty), and
ensure you still wrap values with bun.handleOom(mi.str(...)) and pass the same
irp_id as before so the stored export name matches what
p.printExportFromClauseItem emits.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9e585682-4784-45af-99ba-ef254876183f

📥 Commits

Reviewing files that changed from the base of the PR and between 8620891 and d6d67f4.

📒 Files selected for processing (2)
  • src/js_printer.zig
  • test/regression/issue/29242.test.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
test/regression/issue/29242.test.ts (1)

99-100: 🧹 Nitpick | 🔵 Trivial

Make the "unquoted token" guard quote-style agnostic.

The regex patterns only treat double quotes as valid delimiters. If the printer formatting ever switches to single-quoted string literals, these assertions will fail even when the output is semantically correct.

♻️ Suggested tweak
-  expect(stdout).not.toMatch(/(^|[^"])a b c(?!")/);
-  expect(stdout).not.toMatch(/(^|[^"])x y z(?!")/);
+  expect(stdout).not.toMatch(/(^|[^"'])a b c(?!["'])/);
+  expect(stdout).not.toMatch(/(^|[^"'])x y z(?!["'])/);

Also applies to: 123-123

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/regression/issue/29242.test.ts` around lines 99 - 100, The two regex
assertions that detect unquoted tokens (the expect(stdout).not.toMatch checks
for "a b c" and "x y z") only treat double quotes as delimiters; update both
patterns so the surrounding-quote guard is agnostic by matching either single or
double quotes (use a character class matching ' or " in place of the literal "
in the left context and the negative lookahead), i.e., change the (^|[^"]) and
(?!") parts to use a ['"] class so both expect(stdout).not.toMatch checks are
resilient to single- or double-quoted output.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@test/regression/issue/29242.test.ts`:
- Around line 99-100: The two regex assertions that detect unquoted tokens (the
expect(stdout).not.toMatch checks for "a b c" and "x y z") only treat double
quotes as delimiters; update both patterns so the surrounding-quote guard is
agnostic by matching either single or double quotes (use a character class
matching ' or " in place of the literal " in the left context and the negative
lookahead), i.e., change the (^|[^"]) and (?!") parts to use a ['"] class so
both expect(stdout).not.toMatch checks are resilient to single- or double-quoted
output.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d0ad0b92-12b8-4b16-b2f9-35c6a001aa7f

📥 Commits

Reviewing files that changed from the base of the PR and between d6d67f4 and 6f510fb.

📒 Files selected for processing (1)
  • test/regression/issue/29242.test.ts

Copy link
Copy Markdown
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — previous feedback addressed, fix is correct and well-tested.

Extended reasoning...

Overview

Touches two files: (printer logic) and (new regression test). The change adds an variant in that routes through for the left-side name in clauses, preserving string-literal quotes. The handler is updated to call the new helper.

Security risks

None. The change only affects how the JS printer serializes export-from clause items; it has no effect on parsing, execution, auth, crypto, or permissions.

Level of scrutiny

Low. This is a narrowly-scoped bug fix in a non-security-critical path (the transpiler printer). The logic is straightforward: string-literal export names need quoting when re-emitted, which already handles correctly. The regular path is intentionally unchanged.

Other factors

All reviewer feedback was addressed in commit d6d67f4: (1) tests switched to per test/CLAUDE.md guidelines, (2) assertion moved after stdout checks, (3) used instead of the renamer name to prevent minifier interference. No outstanding unresolved comments.

Copy link
Copy Markdown
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — the printer fix is correct and all prior review feedback has been addressed; the test title nit is captured in the inline comment.

Extended reasoning...

Overview

The PR modifies src/js_printer.zig to add a dedicated printExportFromClauseItem helper and a new .export_from branch in printClauseItemAs. The fix ensures that in export { ... } from 'mod' clauses, the left-side name is printed via printClauseAlias (which quotes string literals) using item.original_name as the source of truth, rather than the renamer's symbol name which could be mangled or lose quotes. The call site in the s_export_from path is updated accordingly. A new regression test file covers four runtime and five printer-level variants.

Security risks

None. This is a pure code-generation correctness fix in the JS printer with no security surface.

Level of scrutiny

Low-to-medium. The change is narrowly scoped to a single code path (s_export_from in the no-bundle transpile path), does not affect the bundler/linker path, and the logic is straightforward. The fix correctly falls back to name when original_name is empty, preserving existing behavior for normal identifier exports.

Other factors

Both previous review concerns (sequential tests and exitCode assertion ordering) were addressed in commit d6d67f4. The only remaining finding is a cosmetic test title nit (first test.concurrent says 'x y z' but the fixture uses 'a b c'), which is captured as an inline comment and does not affect test correctness or the validity of the fix.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/29242.test.ts`:
- Around line 2-10: Remove the long explanatory prose at the top of the
regression test and replace it with a concise single-line reference to the issue
(e.g., the issue URL or number); specifically edit the header block in
test/regression/issue/29242.test.ts that contains the multi-line
reproduction/output narrative so it only includes the issue link or short
identifier and no extra commentary, leaving the actual test code (the export
string-literal case) unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: acb95d43-7940-4fe9-81db-9ffaf32e840a

📥 Commits

Reviewing files that changed from the base of the PR and between 6f510fb and 3ef5fb3.

📒 Files selected for processing (1)
  • test/regression/issue/29242.test.ts

Comment on lines +2 to +10
//
// The parser handles string-literal names in `export { ... } from 'mod'`
// clauses, but when transpiling without bundling the printer dropped the
// quotes around the local name, producing invalid syntax that JSC then
// rejected:
//
// export { "a b c" } from './b.mjs'; // input
// export { a b c } from './b.mjs'; // old output — SyntaxError
// export { "a b c" } from './b.mjs'; // fixed output
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Trim the top-of-file bug-context prose to keep regression tests concise.

Consider keeping just the issue URL and removing the long reproduction/output narrative block; this context already lives in the PR/issue and makes the test noisier to scan.

Based on learnings: In oven-sh/bun regression test files, do not suggest adding inline comments that explain bug context or issue number being tested; PR descriptions cover that context and test code is kept clean.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/regression/issue/29242.test.ts` around lines 2 - 10, Remove the long
explanatory prose at the top of the regression test and replace it with a
concise single-line reference to the issue (e.g., the issue URL or number);
specifically edit the header block in test/regression/issue/29242.test.ts that
contains the multi-line reproduction/output narrative so it only includes the
issue link or short identifier and no extra commentary, leaving the actual test
code (the export string-literal case) unchanged.

Copy link
Copy Markdown
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — all previously raised nits have been addressed.

Extended reasoning...

Overview

The PR modifies src/js_printer.zig to add a dedicated printExportFromClauseItem path for export { ... } from 'mod' clauses, plus a new regression test test/regression/issue/29242.test.ts. The change is tightly scoped to the printer's export-from rendering.

Security risks

None. This is a pure printer/code-generation fix with no auth, crypto, or permission-sensitive code paths.

Level of scrutiny

Low. The change is small (~30 lines of Zig + a new test file), well-explained, and follows existing patterns in the printer. The distinction between .export (local binding, must be identifier) and .export_from (foreign-module name, may be a string literal) is correctly modeled.

Other factors

All three review threads (concurrent tests, exitCode assertion order, quote-agnostic regex, mismatched test title) were fully resolved before the current HEAD. The bug-hunting system found no new issues. Test coverage spans bare re-export, identifier alias, string-to-string alias, mixed clause, and minify-identifiers variants.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Re-export with spaces don't work

1 participant