Skip to content

jslexer: stop regexp literals from spanning lines - #1392

Open
simpleqt wants to merge 1 commit into
python-babel:masterfrom
simpleqt:fix/jslexer-regex-literal-newline
Open

simpleqt wants to merge 1 commit into
python-babel:masterfrom
simpleqt:fix/jslexer-regex-literal-newline

Conversation

@simpleqt

Copy link
Copy Markdown

Fix jslexer regexp literals spanning lines (issue #640)

The tokenizer matched a JS regexp literal with re.DOTALL, so a match attempt could run past line terminators and swallow everything up to the next / on a later line. That silently dropped every gettext message between such literals — exactly the symptom in #640, where the message between />/g and /'/g disappears.

A JS regexp literal cannot contain a line terminator, so dropping DOTALL and excluding newlines from the character classes bounds a failed match to a single line. With the source from #640:

  • before: extracts ['First message', 'Third message'] (matches the report's POT output)
  • after: extracts ['First message', 'Second message', 'Third message']

The new test_regexp_literal_cannot_span_lines pins the tokenizer behaviour, and test_regexp_literals_do_not_swallow_messages covers both regexp shapes from #640 at the extraction level.

One existing assertion changes meaning: test_jsx_extraction's source also contains regexp literals, and the buggy lexer dropped messages from it in non-JSX mode, which is what the old != assertion was locking in. With extraction fixed, non-JSX now yields the same messages as JSX, so the assertion becomes == (kept as if/else so both parametrised cases stay visible in the report).

Prior art: #791 rewrites this pattern to handle / inside character classes, but it keeps DOTALL (its character classes also match newlines), so it does not address the newline case in #640. The two fixes are independent; mine only changes newline handling.

I used an AI assistant (ZCode) to help locate the swallowing behavior in the tokenizer and to draft the tests; I verified the before/after behavior above myself and wrote the fix.

The tokenizer matched a JS regexp literal with re.DOTALL, so an
unterminated match could run past line terminators and swallow the
rest of the file. A literal like /'/ inside a ternary made
extract_javascript drop every gettext message that followed it
(issue python-babel#640).

A JS regexp literal cannot contain a line terminator, so drop DOTALL
and exclude newlines from the character classes instead. This restores
extraction of the messages after such a literal; test_jsx_extraction
now expects the same messages with and without the jsx option.

Signed-off-by: simpleqt <2015900818@qq.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 14:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants