Skip to content

Don't rewrite at-rules mentioned inside CSS comments - #1625

Open
SahinurDEV wants to merge 4 commits into
tailwindlabs:mainfrom
SahinurDEV:fix/css-rewrite-ignore-comments
Open

SahinurDEV wants to merge 4 commits into
tailwindlabs:mainfrom
SahinurDEV:fix/css-rewrite-ignore-comments

Conversation

@SahinurDEV

Copy link
Copy Markdown

Fixes #1615

The CSS language server rewrites Tailwind's at-rules with a series of regexes (rewriteCss in packages/tailwindcss-language-server/src/language/rewriting.ts) before it hands the document to vscode-css-languageservice. Those regexes don't know about comments, so an at-rule name mentioned in a comment gets rewritten too. For the {-terminated ones the prelude is [^{]+, which runs across newlines up to the next {. In the repro from the issue, @variant on line 2 eats everything up to the { of @theme on line 4, */ included. The comment never gets closed, the parser treats the file as a comment until the next */, and you get { expected on a perfectly valid .a {.

There's a second problem that makes this much harder to trace: replaceWithStyleRule (used for @utility, @theme, @custom-variant … { and @variant) and the @custom-variant …; replacement pad the prelude with spaces, newlines included. So every rewrite that spans lines moves everything below it up, and diagnostics land on the wrong line. replaceWithAtRule already keeps the line breaks; the other two didn't.

Changes

  • Added replaceOutsideComments(), which works like a global String#replace but leaves alone any match that starts or ends inside a /* … */ comment. Comment ranges come from a small scanner that skips quoted strings, so content: "/*" doesn't open a comment. When it skips a match it picks up again at the next character, not at the end of the skipped match. Otherwise a match that starts in a comment could hide a real at-rule right after it (/* @variant */\n@variant foo { still gets rewritten). A comment that sits entirely inside a real prelude (@utility bar /* note */ {) gets blanked out the same way it did before.
  • All of the rewrites in rewriteCss now go through it.
  • replaceWithStyleRule and the @custom-variant …; replacement now keep the line breaks they consume, the same way replaceWithAtRule does, so positions after a multi-line prelude stay correct.

Tests

  • src/language/rewriting.test.ts: at-rules (and --foo-*) mentioned in comments are left untouched, real at-rules after/around such comments (and after a string containing /*) are still rewritten, and multi-line preludes keep their line count.
  • tests/css/css-server.test.ts: the exact repro from the issue now has no diagnostics, and an error after multi-line @utility / @custom-variant preludes is reported on the right line (it was off by two before).

All five new tests fail on main and pass with this change. vitest run src/language tests/css passes (35 tests). I also ran the full language-server suite: everything passes except src/project-locator.test.ts and the #-path test in tests/env/v4.test.js, which fail the same way on main on my machine (fixture/environment issue, nothing to do with this change). tsc --noEmit reports no new errors.

The CSS language server rewrites Tailwind at-rules with regexes before
handing documents to vscode-css-languageservice. Those regexes also matched
at-rule names written inside comments, and since `[^{]+` spans newlines a
mention like `@variant` in a comment would swallow everything up to the
next `{`, including the `*/`. The rest of the file was then parsed as a
comment and bogus diagnostics showed up far away from the cause.

Skip matches that start or end inside a comment, and make the style rule
and `@custom-variant …;` replacements keep the line breaks they consume so
positions after a multi-line prelude stay correct.

Fixes tailwindlabs#1615
@greptile-apps

greptile-apps Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; the previous finding is fixed and no new issues were found.

Reviews (3) · Last reviewed commit: "Don't treat #url( and @url( as unquoted ..." · Reviewed by Greptile

Also keeps columns intact for a multiline @custom-variant whose semicolon starts a line, and resumes matching at the end of a comment instead of rescanning it.
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.

At-rules mentioned inside CSS comments corrupt pre-processing, producing false diagnostics at wrong line numbers

1 participant