Skip to content

fix(useSortedClasses): handle astro files#11088

Open
gameroman wants to merge 6 commits into
biomejs:mainfrom
gameroman:fix-astro-use-sorted-classes
Open

fix(useSortedClasses): handle astro files#11088
gameroman wants to merge 6 commits into
biomejs:mainfrom
gameroman:fix-astro-use-sorted-classes

Conversation

@gameroman

Copy link
Copy Markdown
Contributor

Summary

Closes #9181

Most of this was written by AI with my guidance

Test Plan

I've added crates\biome_html_analyze\tests\specs\nursery\useSortedClasses

Docs

N/A

@changeset-bot

changeset-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ec13c2d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

✅ Organic activity

No automation signals detected in the analyzed events.

View full analysis →

This is an automated analysis by AgentScan

@github-actions github-actions Bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages L-HTML Language: HTML and super languages labels Jul 27, 2026
@codspeed-hq

codspeed-hq Bot commented Jul 27, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 208 untouched benchmarks
⏩ 67 skipped benchmarks1


Comparing gameroman:fix-astro-use-sorted-classes (ec13c2d) with main (762c8c1)

Open in CodSpeed

Footnotes

  1. 67 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@gameroman
gameroman force-pushed the fix-astro-use-sorted-classes branch from a794091 to e1c24f3 Compare July 27, 2026 03:52
@gameroman
gameroman marked this pull request as ready for review July 27, 2026 04:43
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The change moves sorted-class parsing, configuration, and ordering into shared biome_analyze modules. The JavaScript rule now uses the shared sorter and default configuration. A new HTML useSortedClasses rule reports unsorted class attributes and provides unsafe fixes. HTML and Astro valid/invalid fixtures were added, and Tailwind preset generation paths and instructions were updated.

Suggested labels: A-Project, A-Parser, L-JavaScript

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: fixing useSortedClasses for Astro files.
Description check ✅ Passed The description is related and mentions the linked issue plus Astro test coverage.
Linked Issues check ✅ Passed The changes address sorting and unsafe fixes for Astro template expressions, with shared sorter updates and new Astro tests.
Out of Scope Changes check ✅ Passed No clear unrelated changes stand out; the refactors appear to support the shared class-sorting implementation.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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: 1

🧹 Nitpick comments (1)
crates/biome_analyze/src/shared/sorted_classes/mod.rs (1)

1-6: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the shared sorter’s public contract.

These new public submodules expose a cross-analyser API, but the module has no rustdoc explaining its parsing, ordering, or preset contract. Add concise //! documentation at this boundary. As per coding guidelines, new Rust features should use rustdoc documentation.

🤖 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 `@crates/biome_analyze/src/shared/sorted_classes/mod.rs` around lines 1 - 6,
Add concise module-level rustdoc (`//!`) to the shared sorted_classes module,
documenting its public parsing, ordering, and preset contract for cross-analyser
consumers. Place the documentation at the module boundary before the public
submodule declarations, without changing the exposed API.

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.

Inline comments:
In `@crates/biome_html_analyze/src/lint/nursery/use_sorted_classes.rs`:
- Around line 68-73: Extend use_sorted_classes.rs so HtmlAttribute analysis also
handles Astro expression-valued class attributes by extracting the interpolated
expression text and passing an appropriate replacement target through the
rule/action path, while preserving existing HtmlString handling. Add a
regression case to
crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/invalid.astro
covering an unsorted class expression and its expected diagnostic/fix.

---

Nitpick comments:
In `@crates/biome_analyze/src/shared/sorted_classes/mod.rs`:
- Around line 1-6: Add concise module-level rustdoc (`//!`) to the shared
sorted_classes module, documenting its public parsing, ordering, and preset
contract for cross-analyser consumers. Place the documentation at the module
boundary before the public submodule declarations, without changing the exposed
API.
🪄 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: CHILL

Plan: Pro Plus

Run ID: 89a0cd36-7287-4df2-ab36-cae9a9348527

📥 Commits

Reviewing files that changed from the base of the PR and between 762c8c1 and ec13c2d.

⛔ Files ignored due to path filters (7)
  • Cargo.lock is excluded by !**/*.lock and included by **
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/invalid.astro.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/invalid.html.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/valid.astro.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/valid.html.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (18)
  • crates/biome_analyze/Cargo.toml
  • crates/biome_analyze/src/shared/mod.rs
  • crates/biome_analyze/src/shared/sorted_classes/class_info.rs
  • crates/biome_analyze/src/shared/sorted_classes/class_lexer.rs
  • crates/biome_analyze/src/shared/sorted_classes/mod.rs
  • crates/biome_analyze/src/shared/sorted_classes/presets.rs
  • crates/biome_analyze/src/shared/sorted_classes/sort.rs
  • crates/biome_analyze/src/shared/sorted_classes/sort_config.rs
  • crates/biome_analyze/src/shared/sorted_classes/tailwind_preset.rs
  • crates/biome_html_analyze/src/lint/nursery/use_sorted_classes.rs
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/invalid.astro
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/invalid.html
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/valid.astro
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/valid.html
  • crates/biome_js_analyze/benches/use_sorted_classes_parser.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/sort.rs
  • packages/tailwindcss-config-analyzer/src/generate-tailwind-preset.ts
💤 Files with no reviewable changes (1)
  • crates/biome_analyze/src/shared/sorted_classes/presets.rs

Comment on lines +68 to +73
let initializer = attribute.initializer()?;
let value = initializer.value().ok()?;
let html_string = value.as_html_string()?.clone();
let value_token = html_string.value_token().ok()?;
let inner_text = inner_string_text(&value_token);
let value_str = inner_text.text();

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg 'use_sorted_classes|useSortedClasses|ast|html' | sed -n '1,200p'

echo "== rule outline =="
ast-grep outline crates/biome_html_analyze/src/lint/nursery/use_sorted_classes.rs --view expanded || true

echo "== rule relevant lines =="
cat -n crates/biome_html_analyze/src/lint/nursery/use_sorted_classes.rs | sed -n '1,180p'

echo "== tests =="
cat -n crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/invalid.astro | sed -n '1,200p'
fd -a 'useSortedClasses' crates/biome_html_analyze/tests/specs | sed -n '1,200p'

Repository: biomejs/biome

Length of output: 21245


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Astro spec fixtures =="
find crates/biome_html_analyze/tests/specs/nursery/useSortedClasses -type f | sort | while read -r f; do
  echo "--- $f"
  sed -n '1,220p' "$f"
done

echo "== search for useSortedClasses/UseSortedClasses/usages =="
rg -n "useSortedClasses|UseSortedClasses|use_sorted_classes|sorted_classes" crates/biome_html_analyze crates/biome_html_formatter crates/ -g '*.rs' -g '*.astro' -g '*.html' | sed -n '1,240p'

echo "== html string initializer AST refs around HtmlAttribute initializer value_as_html_string =="
rg -n "HtmlAttribute|initializer\(|value\(|as_html_string|HtmlString" crates/biome_html_syntax crates/biome_html_factory -g '*.rs' | sed -n '1,260p'

Repository: biomejs/biome

Length of output: 43386


Handle expression-valued Astro class attributes in both the rule and the fixture.

useSortedClasses currently only descends HtmlAttribute into HtmlString, so Astro interpolations like class={unsortedClasses} are skipped. Add a regression case in the Astro spec and extend the rule/action path to work from the interpolated expression text plus a replacement target rather than only from HtmlString.

📍 Affects 2 files
  • crates/biome_html_analyze/src/lint/nursery/use_sorted_classes.rs#L68-L73 (this comment)
  • crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/invalid.astro#L3-L5
🤖 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 `@crates/biome_html_analyze/src/lint/nursery/use_sorted_classes.rs` around
lines 68 - 73, Extend use_sorted_classes.rs so HtmlAttribute analysis also
handles Astro expression-valued class attributes by extracting the interpolated
expression text and passing an appropriate replacement target through the
rule/action path, while preserving existing HtmlString handling. Add a
regression case to
crates/biome_html_analyze/tests/specs/nursery/useSortedClasses/invalid.astro
covering an unsorted class expression and its expected diagnostic/fix.

Source: Coding guidelines

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, that's out of scope for this PR currently

@ematipico

Copy link
Copy Markdown
Member

This isn't a fix though, we're adding an existing rule to another category of files. It's a new feature, so it's a minor. The PR should be merged into next branch

@gameroman

gameroman commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

This isn't a fix though, we're adding an existing rule to another category of files. It's a new feature, so it's a minor. The PR should be merged into next branch

The next branch currently seems to be a couple of commits behind main so I'll open it once next is rebased on main to avoid merge conflicts

@ematipico

Copy link
Copy Markdown
Member

This isn't a fix though, we're adding an existing rule to another category of files. It's a new feature, so it's a minor. The PR should be merged into next branch

The next branch currently seems to be a couple of commits behind main so I'll open it once next is rebased on main to avoid merge conflicts

It's fine, you can still open it. Is there some specific code you need from main? If not, then you can open the PR without issues

@gameroman

Copy link
Copy Markdown
Contributor Author

This isn't a fix though, we're adding an existing rule to another category of files. It's a new feature, so it's a minor. The PR should be merged into next branch

The next branch currently seems to be a couple of commits behind main so I'll open it once next is rebased on main to avoid merge conflicts

It's fine, you can still open it. Is there some specific code you need from main? If not, then you can open the PR without issues

There were some changes on main (#11041) which will likely cause conflicts

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

Labels

A-Linter Area: linter L-HTML Language: HTML and super languages L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💅 useSortedClasses unsafe fix does not apply to expressions in Astro template

2 participants