Fix class extraction for Rails' strict locals by RobinMalfait · Pull Request #19525 · tailwindlabs/tailwindcss · GitHub
Skip to content

Fix class extraction for Rails' strict locals - #19525

Merged
RobinMalfait merged 5 commits into
mainfrom
fix/issue-19481
Jan 6, 2026
Merged

RobinMalfait merged 5 commits into
mainfrom
fix/issue-19481

Conversation

@RobinMalfait

@RobinMalfait RobinMalfait commented Jan 5, 2026 •

Copy link
Copy Markdown
Contributor

Fixes: #19481

This PR improves the Ruby extractor to better handle strict locals. We recently introduced skipping comments in the Ruby extractor (PR #19243 for #19239) by ignoring comments that start with # until the end of the line.

Strict locals are implemented like this:

<%# locals: (css: "text-amber-600") %>

Notice the # after the <%, we considered this a comment and ignored it.

This PR changes that behavior slightly where we skip comments that are preceded by %. This means that <%# anything here _will_ be scanned %>. This should solve the strict locals case, and normal comments will still be skipped.

We can be more strict in the future if needed, but I think that this should be a good solution for both scenarios.

Test plan

  1. Added a test to ensure we extract candidates in strict locals
  2. Added a regression test for issue Tailwind v4 parsing warnings when scanning Rails gem source files on Heroku #19239 where we introduced skipping comments in the Ruby extractor
  3. Other existing tests are still passing

We can also verify the extracted candidates:
(it's subtle, but you can see that the class is being extracted now)

image

This allows for strict-locals support.
This allows us to verify what the expected extracted candidates are.
We already have `test_extract_contains`, which just ensures that the
provided list is extracted (while ignoring some potential noise).
We introduced skipping comments in the Ruby extractor for issue #19239
This adds a regression test to make sure that the behavior is unchanged
@RobinMalfait RobinMalfait changed the title Fix class extraction Rails strict locals Fix class extraction for Rails' strict locals Jan 5, 2026
@RobinMalfait
RobinMalfait marked this pull request as ready for review January 5, 2026 19:03
@RobinMalfait
RobinMalfait requested a review from a team as a code owner January 5, 2026 19:03
@coderabbitai

coderabbitai Bot commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

@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: 0

🧹 Nitpick comments (3)
crates/oxide/src/extractor/pre_processors/pre_processor.rs (2)

28-51: Exact extraction helper is correct; consider robustness to ordering

The helper correctly reuses Extractor and gathers both candidates and CSS variables, and the comparison logic is sound. If extraction order is not semantically important, you might want to normalize (e.g., sort) both candidates and expected before comparing to avoid brittle tests tied to traversal order.


54-75: Containment helper rename and loop update look good

Renaming items → expected and iterating for item in &expected keeps semantics intact and improves readability; the containment check against candidates remains correct.

You could consider sharing the candidate-collection logic between test_extract_exact and test_extract_contains to avoid duplication, but this is purely a test ergonomics tweak.

crates/oxide/src/extractor/pre_processors/ruby.rs (1)

403-429: test_strict_locals accurately captures the Rails strict‑locals scenario

The test input mirrors the <%# locals: (css: "…") %> pattern plus additional locals and static classes, and test_extract_contains asserts that all relevant class names (text-amber-600, text-sky-500, text-green-500) are discoverable. This directly validates the new guard around # comment stripping and provides solid coverage for the original bug report.

If you later want stronger guarantees here, you could switch to test_extract_exact with a full expected list to ensure no unexpected candidates are introduced from the strict‑locals line.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c07d4a7 and 5ef8cee.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • crates/oxide/src/extractor/pre_processors/pre_processor.rs
  • crates/oxide/src/extractor/pre_processors/ruby.rs
🧰 Additional context used
🧬 Code graph analysis (2)
crates/oxide/src/extractor/pre_processors/ruby.rs (1)
crates/oxide/src/extractor/pre_processors/pre_processor.rs (3)
  • test (5-25)
  • test_extract_exact (28-51)
  • test_extract_contains (54-85)
crates/oxide/src/extractor/pre_processors/pre_processor.rs (3)
crates/oxide/src/extractor/mod.rs (1)
  • new (65-72)
crates/oxide/src/cursor.rs (1)
  • new (30-42)
crates/oxide/src/extractor/machine.rs (1)
  • new (13-15)
🔇 Additional comments (3)
CHANGELOG.md (1)

16-16: Changelog entry is consistent and clear

The new “Rails' strict locals” fix entry matches surrounding formatting and scope; no changes needed.

crates/oxide/src/extractor/pre_processors/ruby.rs (2)

122-126: Guarding comment stripping by previous byte matches strict‑locals requirement

Conditioning the # comment handling on cursor.prev not being % ensures <%# locals: … %> blocks are no longer treated as comments while ordinary Ruby # comments (including the RDoc cross‑reference examples and trailing comments after code) are still stripped. This aligns with the strict‑locals use case without impacting %w#…# handling or string literals.


390-401: test_skip_comments gives a precise regression check for comment handling

This test nicely locks in the expectation that pure comment blocks (including RDoc cross‑refs) yield no extracted candidates by using test_extract_exact with an empty vector. That’s a good targeted regression for the earlier “skip comments” behavior.

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.

Class extraction with Rails' strict locals

1 participant