Skip to content

repl: recognize regex literals and comments in continuation detection - #37327

Open
robobun wants to merge 32 commits into
mainfrom
farm/10b8d6c1/repl-regex-literals
Open

robobun wants to merge 32 commits into
mainfrom
farm/10b8d6c1/repl-regex-literals

Conversation

@robobun

@robobun robobun commented Aug 10, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #37326

Problem

  • bun repl shows ... for a complete line when a regex or a comment holds a quote or a bracket (x = /hello "world/;, // don't). Fed by a pipe, it swallows every later line and exits 0.
  • The cause is is_incomplete_code (src/runtime/cli/repl.rs:3010). It counts quotes and brackets by bytes and does not know regex literals or comments.

Fix

  • The scan skips comments and regex bodies. The token before a / decides between a regex and a division.
  • A regex that reaches the end of its line counts as closed: /hello (world/ reports its SyntaxError at once.
  • Verified: test/js/bun/repl/repl.test.ts. Main fails 23 of 167 tests, this branch passes all. The measured table matches Node 26.3 in every row.

Background

  • On Enter, the REPL calls is_incomplete_code. On true, it shows ... and waits for more lines.
  • Not built: ask the real parser, which transform_for_repl already runs on every input. "Wait when the first parse error is at the end of the input" is right for 27 of 29 buffers. A maintainer decides.

Downsides

  • Two shapes work on main and break here: // in JSX text ((<a>https://x</a>)) waits for more input, and function () {} / ( runs before its next line.
  • Three shapes stay wrong: a quoted backtick in a template substitution, a string with no closing quote, and foo(]. All five are todo tests.
  • An Enter with a ( or a { costs 1 or 2 heap allocations (main: 0). The function grows from 691 to 8228 bytes.
Notes

What decides regex or division. The scan keeps the last significant byte and the identifier that ends at it, plus small context trackers:

  • conditional heads (if/for/while/with, and for await), so a / after their ) starts a regex
  • block braces and object-literal braces, so a / after a block } starts a regex and a / after an object } divides
  • postfix ++, -- and !
  • member accesses named like keywords (obj.in, this.#in)
  • JSX closing tags and tag ends (</a.b>, </my-el>, </a >)
  • nested generic closers (A<B<T>>) and as/satisfies type positions

An unclosed block comment continues to the next line.

Tests. The continuation block of test/js/bun/repl/repl.test.ts has 38 tests and 5 todo tests. Two more tests run on a terminal. On main (release build 367d939, whose repl.rs is identical to c1df64b), 22 of the 38 fail, and so does the terminal test for the prompt. The .load and .editor tests are guards: they pass on main and here.

The five todo shapes, and what each prints now.

  • var t = `${'`'}`; t: no output. The backtick in the string ends the template for the scan. Wrong on main too.
  • var u = "abc: no output. Node reports the SyntaxError at once. Wrong on main too.
  • foo(]: no output. Node reports the SyntaxError at once. Wrong on main too.
  • (<a>https://x</a>): no output. //x</a>) reads as a line comment. Main evaluates the line.
  • q = function () {} / ( then 2): two SyntaxErrors. The / after the function body reads as a regex start. Main prints NaN.

A quote or a bracket in JSX text, for example (<a>don't</a>), is wrong on main and here.

Parser probe. new Bun.Transpiler({ loader: "tsx" }).transformSync(code) on 29 buffers. The rule: wait for more input when the parse fails and the offset of the first error is the end of the input. For 26 plain JS buffers, the rule makes the same choice as Node 26.3 in 24. The 3 JSX and TypeScript buffers also come out right. The two misses are an unterminated template and a string that ends with a backslash. Both report Unterminated string literal at the start of the token.

How the costs were measured.

  • Size: each version of the function compiled alone with rustc -C opt-level=3 -C codegen-units=1 -C panic=abort --emit=obj, then size. Main: 691 bytes. This branch: 8228 bytes (text 7820, data 408).
  • Allocations: a counting global allocator over 8 sample lines. Main: 0 for each line. This branch: 0 for a line with no ( and no {, 1 for a line with one of them, 2 for a line with both. More than 8 open levels of one kind add a reallocation.
  • Instructions: not measured. perf and valgrind are not installed in the build container.

no test proof · iteration 5 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/js/bun/repl/repl.test.ts

The REPL's incomplete-input scanner tracked quotes and bracket depth but
had no notion of regex literals or comments, so a quote, backtick, or
bracket inside a regex body (x = /hello "world/;) was counted as code
and forced a bogus continuation prompt. Skip regex bodies (using the
previous significant token to tell a regex start from division, with
character-class and escape handling) and // and /* */ comments. An
unterminated /* */ comment now continues instead of erroring.

Fixes #37326
@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

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

The REPL continuation scanner now recognizes regex literals and ignores comments when checking for incomplete input. Regression tests cover regex syntax, division, JSX, invalid patterns, and comment handling.

Changes

REPL continuation detection

Layer / File(s) Summary
Syntax-aware continuation scanner
src/runtime/cli/repl.rs
is_incomplete_code now distinguishes regex literals from division, skips comments and regex bodies, tracks syntax delimiters, and detects unterminated block comments.
Continuation detection regression tests
test/js/bun/repl/repl.test.ts
Tests cover regex literals, character classes, escaped slashes, division expressions, JSX, keyword-like properties, invalid regex syntax, and comment continuation.

Suggested reviewers: jarred-sumner, dylan-conway

Pre-merge checks: Passed 4
Check name Status Explanation
Linked Issues check Passed The changes address issue #37326 by recognizing regex literals and contained delimiters during REPL continuation detection.
Out of Scope Changes check Passed The implementation and regression tests remain within the linked issue scope of improving regex, division, and comment continuation detection.
Title check Passed The title clearly identifies the main change: recognizing regex literals and comments during REPL continuation detection.
Description check Passed The description explains the problem, implementation, verification, known limitations, and test results. It does not use the exact template headings, but it provides the required information in equiva…
Full details: Description check

Explanation

The description explains the problem, implementation, verification, known limitations, and test results. It does not use the exact template headings, but it provides the required information in equivalent sections.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/runtime/cli/repl.rs`:
- Around line 2612-2623: Update the regex scan loop around the escape handling
in the REPL parser so a backslash immediately before a newline cannot advance
past the newline and continue scanning. Guard the b'\\' case against the
end-of-line boundary, while preserving escaped-character handling for
non-newline bytes and the existing in_class delimiter logic.

In `@test/js/bun/repl/repl.test.ts`:
- Around line 720-724: Add two REPL tests alongside the existing regex
character-class case: one covering an escaped slash inside the regex body and
another covering an unbalanced “{” or “(” inside the regex body. Assert each
evaluates successfully with the expected result and exits cleanly, exercising
the scanner’s escaped-character and delimiter-counter branches.
🪄 Autofix

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: 6ca3794d-e5c1-4eff-b025-ff801798ec43

📥 Commits

Reviewing files that changed from the base of the PR and between 827475e and 8bd0c41.

📒 Files selected for processing (2)
  • src/runtime/cli/repl.rs
  • test/js/bun/repl/repl.test.ts

Comment thread src/runtime/cli/repl.rs
Comment thread test/js/bun/repl/repl.test.ts
Also cover escaped slashes and unbalanced braces/parens inside regex
bodies in the tests.
Comment thread src/runtime/cli/repl.rs Outdated
Comment thread src/runtime/cli/repl.rs Outdated
Comment thread src/runtime/cli/repl.rs Outdated
Comment thread src/runtime/cli/repl.rs Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Caution

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

⚠️ Outside diff range comments (1)
src/runtime/cli/repl.rs (1)

2579-2606: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Track token context instead of only the previous byte.

is_incomplete_code misclassifies valid JavaScript. It treats regex delimiters as ordinary code in const value = 10 / /[(]/.test("("); and if (true) /[(]/.test("(");, counts the ( inside [(], and requests continuation. In obj.in / {, it treats property in as a keyword, skips {, and evaluates incomplete input.

Track token kinds and syntactic context. Distinguish division from regex, property names from keywords, and control-statement closers from expression closers. Add regression cases in test/js/bun/repl/repl.test.ts, then run bun bd test test/js/bun/repl/repl.test.ts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/runtime/cli/repl.rs` around lines 2579 - 2606, Update is_incomplete_code
to track token kinds and syntactic context rather than only the previous byte,
distinguishing regex literals from division, property names from REGEX_KEYWORDS,
and control-statement closers from expression closers. Ensure regex contents
such as [(] are skipped without affecting delimiter balance, and obj.in / { is
treated as valid input rather than incomplete. Add regression cases to
repl.test.ts and run the specified test command.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/runtime/cli/repl.rs`:
- Around line 2579-2606: Update is_incomplete_code to track token kinds and
syntactic context rather than only the previous byte, distinguishing regex
literals from division, property names from REGEX_KEYWORDS, and
control-statement closers from expression closers. Ensure regex contents such as
[(] are skipped without affecting delimiter balance, and obj.in / { is treated
as valid input rather than incomplete. Add regression cases to repl.test.ts and
run the specified test command.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 893f513c-2cc8-413d-acb0-7e9814ebb0e2

📥 Commits

Reviewing files that changed from the base of the PR and between 8bd0c41 and 7c6ebe5.

📒 Files selected for processing (2)
  • src/runtime/cli/repl.rs
  • test/js/bun/repl/repl.test.ts

…, and division operands

A / right after an if/for/while/with condition's closing paren now reads
as a regex, a property access like obj.in no longer counts as the in
keyword, and a regex can follow a division operator.
@robobun

robobun commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the review's misclassification cases in 9a67d3a: a / right after an if/for/while/with condition's closing paren now starts a regex (tracked with a small paren stack), a property access like obj.in no longer matches the keyword list, and a regex can follow a division operator (10 / /[(]/.test("(")). Tests added for all three.

I stopped short of a full token tracker: this function is a continuation hint, not a parser, and the remaining ambiguities (for example postfix ++ before /) degrade to the pre-existing behavior rather than breaking evaluation.

Comment thread src/runtime/cli/repl.rs Outdated
Comment thread src/runtime/cli/repl.rs Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Caution

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

⚠️ Outside diff range comments (2)
src/runtime/cli/repl.rs (2)

2581-2606: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Track postfix operators in regex detection.

x++ / "unterminated is reported as complete because b'+' starts regex scanning. Track token kind and expression-start context instead of only the previous byte. Add regression tests for postfix ++ and -- followed by division and an unterminated string.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/runtime/cli/repl.rs` around lines 2581 - 2606, Update the regex-detection
logic around starts_regex to track token kind and whether the current expression
context permits a regex, so postfix ++ and -- are treated as operators on the
preceding expression rather than regex-starting bytes. Ensure division after
postfix operators is parsed correctly and add regression coverage for ++/--
followed by division containing an unterminated string.

2559-2570: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Handle ECMAScript whitespace and line terminators in is_incomplete_code.

LineEditor preserves raw UTF-8 input. The scanner recognizes only ASCII whitespace and LF. Therefore // comment\u2028{ hides {, and return\u00A0/hello "world/ is not recognized as a complete regex literal. Decode UTF-8 before classification and recognize the complete ECMAScript whitespace and line-terminator sets. Add regression tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/runtime/cli/repl.rs` around lines 2559 - 2570, Update is_incomplete_code
to decode the raw UTF-8 input before scanning, and classify the full ECMAScript
whitespace and line-terminator sets rather than only ASCII whitespace and LF;
ensure line comments terminate on all recognized ECMAScript line terminators so
hidden syntax such as U+2028 is scanned correctly, and add regression tests
covering these cases.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/runtime/cli/repl.rs`:
- Around line 2581-2606: Update the regex-detection logic around starts_regex to
track token kind and whether the current expression context permits a regex, so
postfix ++ and -- are treated as operators on the preceding expression rather
than regex-starting bytes. Ensure division after postfix operators is parsed
correctly and add regression coverage for ++/-- followed by division containing
an unterminated string.
- Around line 2559-2570: Update is_incomplete_code to decode the raw UTF-8 input
before scanning, and classify the full ECMAScript whitespace and line-terminator
sets rather than only ASCII whitespace and LF; ensure line comments terminate on
all recognized ECMAScript line terminators so hidden syntax such as U+2028 is
scanned correctly, and add regression tests covering these cases.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: bf39b0ab-4d20-4b38-b06f-36b66221a641

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6ebe5 and 6e4c4a6.

📒 Files selected for processing (1)
  • src/runtime/cli/repl.rs

Comment thread src/runtime/cli/repl.rs Outdated
Comment thread src/runtime/cli/repl.rs Outdated

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/js/bun/repl/repl.test.ts`:
- Around line 767-770: Update the test “regex after a conditional's closing
paren” so the first REPL input contains the observable expression itself, then
submit “.exit” as the next input instead of “x”. Assert that the stripped output
does not contain “SyntaxError”, ensuring the test distinguishes correct one-line
evaluation from unintended multiline continuation.
🪄 Autofix

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: 999fca0c-623d-4cd6-8c9b-a8be45eb3059

📥 Commits

Reviewing files that changed from the base of the PR and between 6e4c4a6 and 0064fa8.

📒 Files selected for processing (2)
  • src/runtime/cli/repl.rs
  • test/js/bun/repl/repl.test.ts

Comment thread test/js/bun/repl/repl.test.ts
… context

A / after doubled +/- (postfix operator) or after a } inside parens or
brackets (object literal) is division, not a regex start.
@robobun

robobun commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator Author

Latest round addressed in ef1f3ae: a / after postfix ++/-- or after a } inside parens/brackets (object literal) now reads as division, with tests for both.

On the full ECMAScript whitespace and line-terminator sets (U+2028, U+00A0, etc.): declining for this heuristic. The scanner is a byte-level continuation hint over terminal input, the pre-existing code was ASCII-only in the same way, and a miss degrades to an extra continuation prompt or an immediate syntax error from the real parser, both recoverable. Decoding UTF-8 here would add complexity out of proportion to inputs a terminal user can realistically type.

Comment thread src/runtime/cli/repl.rs Outdated
…literals as division context

An adjacent </ is a JSX closing tag (the REPL parses TSX), x! ends an
expression, } inside a brace body is an object literal, and a method
named if/for/while/with does not make its call parens a regex context.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/runtime/cli/repl.rs`:
- Around line 2597-2603: Update the scanner’s brace handling around starts_regex
to maintain a stack recording whether each `{` begins a statement block or
object literal, and classify `}` using its matching entry. Set after_block only
for closing statement blocks, so division after an assigned object literal is
not treated as a regex; add a continuation regression covering `q = {} / ({`.

In `@test/js/bun/repl/repl.test.ts`:
- Around line 767-775: Ensure each affected REPL test proves one-line evaluation
by including its observable expression in the initial input and submitting only
.exit afterward: in test/js/bun/repl/repl.test.ts lines 767-775, include q for
both increment/decrement cases; lines 777-781, include q for the object-literal
division; lines 783-787, include g(); lines 789-793, include q; and lines
803-807, include q for the method-call case. Preserve the existing assertions
while preventing multiline continuation from producing the expected value.
🪄 Autofix

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: 543149cb-90ef-4f86-97c7-278d8e220cfd

📥 Commits

Reviewing files that changed from the base of the PR and between 0064fa8 and 072a487.

📒 Files selected for processing (2)
  • src/runtime/cli/repl.rs
  • test/js/bun/repl/repl.test.ts

Comment thread src/runtime/cli/repl.rs Outdated
Comment thread test/js/bun/repl/repl.test.ts
Track whether each { opens in statement or expression position, so a /
after an object literal's } is division while a / after a block's } can
still start a regex.
Comment thread src/runtime/cli/repl.rs Outdated
Comment thread src/runtime/cli/repl.rs Outdated
Comment thread src/runtime/cli/repl.rs Outdated
(84 as void / 2) is division; void /re/ keeps its regex operand.
Comment thread src/runtime/cli/repl.rs Outdated
Map<Array<T>, string> and Record<K, V[]> walk their argument run,
including inner closers and brackets, back to a word-adjacent <.
Comment thread src/runtime/cli/repl.rs Outdated
(x as string | void / 2) and (x as void! / 2) are division; | void /re/
and void /re/ keep their regex operands.
@robobun

robobun commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator Author

CI status: 189 of 190 jobs pass. The one red lane (debian 13 x64-asan) fails only on test/js/node/worker_threads/worker-transfer-list.test.ts, an unchecked-exception assert in the module loader that this PR's REPL-only diff does not touch; it has been reported separately as a main-side break. Everything else that flaked passed on retry. The diff is ready for review.

Comment thread src/runtime/cli/repl.rs
Comment thread src/runtime/cli/repl.rs
@robobun

robobun commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

#39622 proposed a second fix for #37326 in the same function. It is now closed in favor of this PR. Both branches merge cleanly into current main.

One difference for the record: #39622 also made ends_inside_string, the gate for tab completion and ghost suggestions, skip regex bodies. This PR does not change that path. A quote inside a regex still suppresses completion for the rest of that input. That is a separate and smaller problem than #37326, and it can follow on its own after this lands.

…inal

Each new case feeds complete lines and stops at the end of the input. A
line that the continuation scan takes for an open string or bracket
swallows every line after it, so each case asserts the output of every
line.

- An apostrophe in a line comment, a brace in a block comment, and a
  paren in a regex character class do not hold back the lines after them.
- On a terminal, the prompt stays "> " after a comment with an apostrophe.
- .load and .editor evaluate their text whole. Two guards pin that.
- Five shapes that the scan still misjudges are todo tests. Each has a
  comment with the output it gives now.

The division tests with several cases now feed all of their cases to one
REPL session. The debug build ran up to seven sessions in sequence for
one test and exceeded the 5 s timeout.
@robobun

robobun commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

I measured this branch against main and Node 26.3, and added the measured rows as tests in fb553e4.

Setup

  • "This PR" is this branch merged with main c1df64b, debug build.
  • "Main" is the release build at 367d939. Its src/runtime/cli/repl.rs is identical to c1df64b.
  • Each line named a, b, c prints a mark. A cell lists the marks that ran.

Fed by a pipe, then end of input

Input Main This PR Node 26.3
// don't, then 3 lines nothing a, b, c a, b, c
// don't, a, // isn't, c a, c as one input a, c a, c
// don't, a, var q = 'x', c nothing a, c a, c
// don't, a, var q = "it's", c nothing a, c a, c
/* { */, then 3 lines nothing a, b, c a, b, c
/* { */, a, a lone }, c c, 1 error a, c, 1 error a, c, 1 error
var r = /[(]/, a, b nothing a, b a, b
// don't, then 200 lines nothing all 200 all 200
.load of a file with the three shapes a, b, after a, b, after a, b, after
Exit code and stderr, every row 0, empty 0, empty 0, empty

On a terminal

Input Main This PR Node 26.3
// don't Enter, a Enter, Ctrl-C, b Enter: the prompts ... ... > > > > > > > > > >
The same input: what ran b a, b a, b
.editor, the three shapes, Ctrl-D a, b a, b a, b

Every row above is right on this branch.

Shapes that are still wrong

Input Main This PR Node 26.3
var t = `${'`'}` , a, b nothing nothing a, b
var u = "abc, a, b nothing nothing 1 error, a, b
foo(], a, b nothing nothing 1 error, a, b
(<a>https://x</a>), a, b 1 runtime error, a, b nothing no JSX
q = function () {} / (, 2), a NaN, a 2 errors, a NaN, a

The first three never worked. The last two are the limits that the description names: they work on main, and this change breaks them. A quote or a bracket in JSX text, for example (<a>don't</a>), is also wrong on main and here.

Tests in fb553e4 (test/js/bun/repl/repl.test.ts)

  • Pipe rows 1 to 7: one test each. Each asserts the output of every line, stderr, and the exit code. Main fails all 7.
  • The 200-line row has no test of its own. It takes the same path as the first row.
  • The terminal row: one test on the screen rows after // don't and one more line. It leaves out the Ctrl-C step, which is only the way out of the stuck prompt. Main fails it with ... as the last row.
  • .load and .editor: one guard each. They pass on main and here.
  • The five shapes that are still wrong: test.todo cases, each with a comment that says what it prints now. With --todo, main passes the last two.
  • The division tests with several cases now feed all cases to one REPL session. Under the debug build, 3 of them ran up to 7 sessions in sequence and exceeded the 5 s timeout.

What the real parser says

transform_for_repl already parses every input with Bun's parser and drops the log. I probed 29 buffers with new Bun.Transpiler({ loader: "tsx" }) and this rule: wait for more input when the parse fails and the first error is at the end of the input.

  • For 26 plain JS buffers, the rule makes the same choice as Node 26.3 (wait, or evaluate now) in 24.
  • The 3 JSX and TypeScript buffers, which Node cannot parse, also come out right.
  • All five shapes above are among the 27 right answers.
  • The two misses are an unterminated template and a string that ends with a backslash. Both report Unterminated string literal at the start of the token, so they need one more rule.

If that direction is preferred to the byte scan, I can rework this PR to it. The tests here carry over.

@claude claude Bot left a comment

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.

Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.

Comment thread src/runtime/cli/repl.rs Outdated
@robobun

robobun commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

Relation to #46105 (JSX in bun repl, stacked on #45915).

The test division after a JSX element here expects /^ReferenceError: / for its five JSX inputs, with the comment "no JSX runtime is configured". The test.todo row for (<a>https://x</a>) expects the same. With #46105 the REPL imports the JSX runtime, so those inputs evaluate. The test passes no cwd, so they use the repository's own react. The two PRs merge without a textual conflict, and the one that lands second leaves repl.test.ts failing.

A form that holds on both sides: run those rows in a temp directory with a stand-in runtime (as jsxPackage("react") does in #46105), or assert only the number of outputs and the final 42.

Two JSX shapes of the continuation check that show once JSX evaluates. Both are the same on 1.4.3:

  • <p>it's</p>: the quote opens a string for is_incomplete_code. The prompt waits for more input, and on a pipe the rest of the script is dropped.
  • <ul> then Enter: the line is evaluated alone and prints SyntaxError: Unexpected token '<'. An element continues over lines only inside an open bracket.

…ers are words

The nested is_word_char duplicated is_word_byte without its >= 0x80 arm,
so (café! / 2) read the bang as a prefix and swallowed the closing paren.

@claude claude Bot left a comment

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.

Code review completed

Nothing new to post: everything this review found is already covered by existing comments on this pull request or didn't merit a separate one.

This branch has not been deployed

No deployments
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.

REPL doesn't know how to handle regex literals

2 participants