Skip to content

feat(useSortedKeys): add groupByNesting option#7799

Merged
ematipico merged 5 commits intobiomejs:nextfrom
PaulRBerg:feat/use-sorted-keys-group-by-nesting
Dec 9, 2025
Merged

feat(useSortedKeys): add groupByNesting option#7799
ematipico merged 5 commits intobiomejs:nextfrom
PaulRBerg:feat/use-sorted-keys-group-by-nesting

Conversation

@PaulRBerg
Copy link
Contributor

@PaulRBerg PaulRBerg commented Oct 20, 2025

Implements a new groupByNesting option for the useSortedKeys assist that groups object keys by their value's nesting depth before applying alphabetical sorting.

Nesting depth classification:

  • Depth 0 (simple): primitives, single-line arrays
  • Depth 1 (nested): objects, multi-line arrays

When enabled, simple values are sorted alphabetically first, followed by nested values sorted alphabetically. This addresses the common use case where developers want scalar properties at the top of objects, with complex nested structures appearing at the bottom.

Implementation details:

  • Added group_by_nesting: bool field to UseSortedKeysOptions
  • Implemented get_nesting_depth_js() for JavaScript AST nodes
  • Implemented get_nesting_depth() for JSON AST nodes
  • Updated sorting comparators to use tuple (depth, name) ordering
  • Works with both natural and lexicographic sort orders

Configuration:

{
  "assist": {
    "actions": {
      "source": {
        "useSortedKeys": {
          "level": "on",
          "options": {
            "groupByNesting": true
          }
        }
      }
    }
  }
}

Summary

Discussed in #7331

Test Plan

  • 4 JS test cases (natural + lexicographic × grouping on/off)
  • 4 JSON test cases (natural + lexicographic × grouping on/off)
  • All snapshot tests generated and validated

@changeset-bot
Copy link

changeset-bot bot commented Oct 20, 2025

🦋 Changeset detected

Latest commit: 40bbf56

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@biomejs/biome Minor
@biomejs/cli-win32-x64 Minor
@biomejs/cli-win32-arm64 Minor
@biomejs/cli-darwin-x64 Minor
@biomejs/cli-darwin-arm64 Minor
@biomejs/cli-linux-x64 Minor
@biomejs/cli-linux-arm64 Minor
@biomejs/cli-linux-x64-musl Minor
@biomejs/cli-linux-arm64-musl Minor
@biomejs/wasm-web Minor
@biomejs/wasm-bundler Minor
@biomejs/wasm-nodejs Minor
@biomejs/backend-jsonrpc Patch
@biomejs/js-api Major

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

Walkthrough

Adds a groupByNesting option to useSortedKeys for both JavaScript and JSON analysers. The option classifies values by nesting/multiline content and, when enabled, sorts object members by (nesting depth, key) instead of by key alone. Implements depth helpers, threads the flag through run/action paths, updates diagnostics and rule declarations where needed, adds the group_by_nesting: bool option to rule options, and includes new tests and fixtures for lexicographic and natural sort orders.

Suggested labels

A-Project, A-Diagnostic

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main change: adding a groupByNesting option to the useSortedKeys assist, which is the core feature across all modified files.
Description check ✅ Passed The description clearly explains the new groupByNesting option, nesting depth classification, implementation details, configuration, and test coverage—all directly related to the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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 (5)
.changeset/group-by-nesting-feature.md (1)

5-7: Polish the changeset text for house style.

  • End sentences with a period; rephrase “Will be sorted as:” to a full sentence.
  • Add a link to the assist page when mentioning useSortedKeys.

Example tweak:

-Added `groupByNesting` option to the `useSortedKeys` assist. When enabled, object keys are grouped by their value's nesting depth before sorting alphabetically.
+Added `groupByNesting` option to the `useSortedKeys` assist. When enabled, object keys are grouped by their value's nesting depth, then sorted using the configured order (natural or lexicographic).
@@
-#### Example
+#### Example.
@@
-Will be sorted as:
+The object will be sorted as follows.

Also applies to: 9-37

crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (3)

134-153: Doc nit: tie wording to configured sort order.

“before sorting alphabetically” isn’t precise given natural vs lexicographic. Prefer: “before sorting by the configured key order (natural or lexicographic).”


164-179: Depth classification misses function/class expressions.

Values like foo: () => {} or foo: function() {} and foo: class {} are currently treated as simple (depth 0). If the intent is “non‑primitives as nested”, mark these as depth 1 (and perhaps only if multi‑line). Happy to draft a follow‑up patch.

Do you want these treated as nested? If yes, I can extend get_nesting_depth_js to handle JsArrowFunctionExpression, JsFunctionExpression, and JsClassExpression.


246-287: Action message could mention grouping when enabled.

Minor: when groupByNesting is on, consider “Sort the object properties by group (nesting) and key.” for clarity.

crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs (1)

108-124: Avoid to_string() allocation; mirror JS detection.

Use array.syntax().text_trimmed().contains_char('\n') for multi‑line detection to reduce allocations and keep parity with the JS path.

-        AnyJsonValue::JsonArrayValue(array) => {
-            // Check if array spans multiple lines by looking for newlines
-            if array.to_string().contains('\n') {
+        AnyJsonValue::JsonArrayValue(array) => {
+            // Multi-line if the text contains a newline.
+            if array.syntax().text_trimmed().contains_char('\n') {
                 1
             } else {
                 0
             }
         }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2063615 and d35c649.

⛔ Files ignored due to path filters (6)
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.json.snap is excluded by !**/*.snap and included by **
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.json.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 (12)
  • .changeset/group-by-nesting-feature.md (1 hunks)
  • crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (5 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json (1 hunks)
  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs (5 hunks)
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.json (1 hunks)
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json (1 hunks)
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.json (1 hunks)
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json (1 hunks)
  • crates/biome_rule_options/src/use_sorted_keys.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_rule_options/src/use_sorted_keys.rs
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.js
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json
  • crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.js
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.json
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.json
  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Format Rust files before committing (e.g., via just f which formats Rust)
Document rules, assists, and options with inline rustdoc in source

Files:

  • crates/biome_rule_options/src/use_sorted_keys.rs
  • crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs
  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.js
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json
  • crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.js
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.json
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.json
  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.js
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json
  • crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.js
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.json
  • crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.json
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/*.md: In changesets, only use #### or ##### headers; other header levels are not allowed
Changesets should cover user-facing changes only; internal changes do not need changesets
Use past tense for what you did and present tense for current Biome behavior in changesets
When fixing a bug in a changeset, start with an issue link (e.g., “Fixed #1234: …”)
When referencing a rule or assist in a changeset, include a link to its page on the website
Include code blocks in changesets when applicable to illustrate changes
End every sentence in a changeset with a period

Files:

  • .changeset/group-by-nesting-feature.md
🧬 Code graph analysis (4)
crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.js (1)
crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.js (1)
  • obj (1-19)
crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (2)
crates/biome_analyze/src/utils.rs (2)
  • is_separated_list_sorted_by (13-43)
  • sorted_separated_list_by (53-107)
crates/biome_string_case/src/comparable_token.rs (1)
  • new (13-15)
crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.js (1)
crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.js (1)
  • obj (1-19)
crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs (1)
crates/biome_analyze/src/utils.rs (2)
  • is_separated_list_sorted_by (13-43)
  • sorted_separated_list_by (53-107)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Validate PR title
  • GitHub Check: Validate PR title
  • GitHub Check: Validate PR title
  • GitHub Check: triage
🔇 Additional comments (12)
crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json (1)

1-16: Configuration looks correct.

The test configuration properly enables the useSortedKeys assist with lexicographic ordering and the new groupByNesting option.

crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.js (1)

1-19: Test fixture correctly structured.

The test data provides a good mix of nesting levels (primitives, single-line arrays, nested objects, and multi-line arrays) to exercise the groupByNesting feature. Keys are intentionally unsorted as this is an input fixture.

crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.json (1)

1-19: JSON test fixture looks good.

The structure correctly mirrors the JavaScript variants, providing consistency across language tests.

crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.js (1)

1-19: Test data structure is sound.

Identical to the lexicographic variant, which allows testing both sort orders with the same data structure.

crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json (1)

1-16: Configuration is correct.

Properly configured for testing natural sort order with grouping by nesting enabled.

crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.json (1)

1-19: JSON fixture correctly structured.

Provides appropriate test data for lexicographic sorting with grouping by nesting.

crates/biome_rule_options/src/use_sorted_keys.rs (1)

10-13: Documentation is clear and implementation looks good.

The documentation concisely explains the grouping behaviour and what constitutes simple vs. nested values. The field is properly integrated into the options struct.

crates/biome_json_analyze/tests/specs/source/useSortedKeys/group-by-nesting-natural.options.json (1)

1-16: Configuration looks proper.

The test configuration correctly enables natural sorting with grouping by nesting for JSON analysis.

crates/biome_js_analyze/tests/specs/source/useSortedKeys/group-by-nesting-lexicographic.options.json (1)

1-16: Looks good.

Config keys match the new option and the test intent. Nothing to change.

crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (1)

1-16: Imports look tidy.

New syntax variants are correctly referenced via AnyJsObjectMember/AnyJsExpression; no extra imports needed for the pattern matches above.

crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs (2)

78-99: Docs are clear and match behaviour.

Nicely explains grouping and examples. Parity with JS docs looks good.


140-174: Comparator wiring and chunking logic look correct.

Composite key (depth, name) with then_with is spot‑on, and you don’t introduce unintended chunk splits. Good job.

Also applies to: 204-236

@PaulRBerg
Copy link
Contributor Author

@coderabbitai generate docstrings

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

✅ Actions performed

Initiated docstring generation; will generate only if new commits exist.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #7800

coderabbitai bot added a commit that referenced this pull request Oct 20, 2025
Docstrings generation was requested by @PaulRBerg.

* #7799 (comment)

The following files were modified:

* `crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs`
* `crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs`
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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 (1)
crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (1)

134-152: Consider enhancing the documentation example.

The example demonstrates an unsorted object but doesn't show the expected output after grouping. Consider adding a comment showing how simple values (id, name) would be grouped before nested values (details), or use expect_diff to show the transformation.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d35c649 and 092b620.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (5 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Format Rust files before committing (e.g., via just f which formats Rust)
Document rules, assists, and options with inline rustdoc in source

Files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (2)
crates/biome_analyze/src/utils.rs (2)
  • is_separated_list_sorted_by (13-43)
  • sorted_separated_list_by (53-107)
crates/biome_string_case/src/comparable_token.rs (1)
  • new (13-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: triage
  • GitHub Check: Validate PR title
🔇 Additional comments (4)
crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (4)

164-182: LGTM! Solid nesting depth logic.

The implementation correctly classifies expressions by depth. The multiline array detection using contains_char('\n') is a pragmatic approach that should work reliably in practice.


184-199: Excellent—addresses the previous review's regression concern.

This implementation correctly treats methods, getters, and setters as sortable with depth 1, preventing them from becoming chunk delimiters. The logic matches the suggested fix from the previous review.

Based on learnings


215-237: LGTM! Clean conditional sorting logic.

The tuple-based comparison d1.cmp(d2).then_with(|| comparator(n1, n2)) correctly prioritizes depth before name. The conditional structure clearly separates grouped vs ungrouped behaviour.


267-287: LGTM! Action correctly mirrors the run logic.

The sorting behaviour in the action path precisely matches the detection logic in run(), ensuring consistency. The separator construction and error handling are appropriate.

@PaulRBerg

This comment was marked as resolved.

@ematipico
Copy link
Member

Please point this PR to next, as per contribution guidelines

@PaulRBerg PaulRBerg changed the base branch from main to next October 20, 2025 15:03
@ematipico ematipico deleted the branch biomejs:next October 23, 2025 10:03
@ematipico ematipico closed this Oct 23, 2025
@PaulRBerg

This comment was marked as resolved.

@ematipico ematipico reopened this Oct 23, 2025
@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages L-JSON Language: JSON and super languages labels Oct 23, 2025
@ematipico

This comment was marked as resolved.

@ematipico ematipico added this to the Biome v2.4 milestone Nov 6, 2025
@PaulRBerg PaulRBerg force-pushed the feat/use-sorted-keys-group-by-nesting branch from 092b620 to 62fb192 Compare November 15, 2025 10:39
@PaulRBerg
Copy link
Contributor Author

Thanks for your feedback @ematipico - the PR is ready for reviewing again.

@codspeed-hq
Copy link

codspeed-hq bot commented Nov 15, 2025

CodSpeed Performance Report

Merging #7799 will not alter performance

Comparing PaulRBerg:feat/use-sorted-keys-group-by-nesting (40bbf56) with next (4460388)

Summary

✅ 58 untouched
⏩ 95 skipped1

Footnotes

  1. 95 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.

Implements a new `groupByNesting` option for the `useSortedKeys` assist
that groups object keys by their value's nesting depth before applying
alphabetical sorting.

Nesting depth classification:
- Depth 0 (simple): primitives, single-line arrays
- Depth 1 (nested): objects, multi-line arrays

When enabled, simple values are sorted alphabetically first, followed
by nested values sorted alphabetically. This addresses the common use
case where developers want scalar properties at the top of objects,
with complex nested structures appearing at the bottom.

Implementation details:
- Added `group_by_nesting: bool` field to `UseSortedKeysOptions`
- Implemented `get_nesting_depth_js()` for JavaScript AST nodes
- Implemented `get_nesting_depth()` for JSON AST nodes
- Updated sorting comparators to use tuple (depth, name) ordering
- Works with both natural and lexicographic sort orders

Test coverage:
- 4 JS test cases (natural + lexicographic × grouping on/off)
- 4 JSON test cases (natural + lexicographic × grouping on/off)
- All snapshot tests generated and validated

Configuration:
```json
{
  "assist": {
    "actions": {
      "source": {
        "useSortedKeys": {
          "level": "on",
          "options": {
            "groupByNesting": true
          }
        }
      }
    }
  }
}
```
- Support single-line objects: Objects that span a single line are now
  treated as simple values (like primitives and single-line arrays) and
  grouped before nested values
- Change group_by_nesting to Option<bool> in UseSortedKeysOptions for
  consistency with other optional fields
- Update changeset with valid biome.json configuration example showing
  the full linter.rules path
- Improve diagnostic message from "not grouped by nesting level and
  sorted by key" to "not sorted by nesting level and key" for clarity
Replace text parsing with has_leading_newline() to properly handle
all line ending variants (\n, \r\n, \r). For non-empty containers,
checks first token; for empty containers, checks closing token.
@PaulRBerg PaulRBerg force-pushed the feat/use-sorted-keys-group-by-nesting branch from 0dde4e6 to c29e56b Compare December 7, 2025 10:31
Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

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

Nice work! Thank you!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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 (2)
crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs (2)

132-152: Consider a more semantically clear type for depth.

Whilst returning Ordering::Equal for simple and Ordering::Greater for nested works in comparisons, Ordering semantically represents comparison results rather than categorical depth. A u8 (0/1) or enum (Simple/Nested) would be clearer, though the current implementation is functional.


168-202: Consider extracting shared key extraction logic.

The key extraction closures in run and action are nearly identical. A helper function returning the appropriate closure and comparator based on options.group_by_nesting would reduce duplication and improve maintainability.

Also applies to: 240-272

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c29e56b and 40bbf56.

⛔ Files ignored due to path filters (2)
  • 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 (1)
  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use the dbg!() macro for debugging output during testing, and pass the --show-output flag to cargo to view debug output
Use cargo t or cargo test to run tests; for a single test, pass the test name after the test command
Use snapshot testing with the insta crate; run cargo insta accept, cargo insta reject, or cargo insta review to manage snapshot changes
Write doctests as doc comments with code blocks; the code inside code blocks will be run during the testing phase
Use just f (alias for just format) to format Rust and TOML files before committing

Files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
🧠 Learnings (13)
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Wrap optional rule option fields in `Option<_>` to properly track set vs unset options during configuration merging

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Rule options struct fields should use `#[serde(rename_all = "camelCase")]`, `#[serde(deny_unknown_fields)]`, and `#[serde(default)]` attributes for proper JSON serialization

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `useConsistent` prefix for rules that ensure consistency across the codebase (e.g., `useConsistentArrayType`)

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Rule options must be defined in the `biome_rule_options` crate and implement traits: `Deserializable`, `Merge`, `Serialize`, `Deserialize`, and `JsonSchema`

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `useShorthand` prefix for rules that report syntax rewritable using equivalent compact syntax (e.g., `useShorthandAssign`)

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Implement the `Merge` trait for rule options to define how options from extended configuration merge with user configuration (usually reset instead of extend)

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noDuplicate` prefix for rules that report duplication overriding previous occurrences (e.g., `noDuplicateObjectKeys`)

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use language tags in documentation code blocks (js, ts, tsx, json, css) and order properties consistently as: language, then `expect_diagnostic`, then options modifiers, then `ignore`, then `file=path`

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : New rules must be placed inside the `nursery` group as an incubation space exempt from semantic versioning, with promotion to appropriate groups done during minor/major releases

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Rules should use the `use` prefix naming convention when the sole intention is to mandate a single concept (e.g., `useValidLang` to enforce valid HTML lang attribute values)

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For tokens that are not mandatory, use helper functions instead of hardcoding

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When formatting AST nodes, use mandatory tokens from the AST instead of hardcoding token strings (e.g., use `node.l_paren_token().format()` instead of `token("(")`)

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `p.eat(token)` for optional tokens, `p.expect(token)` for required tokens, `parse_rule(p).ok(p)` for optional nodes, and `parse_rule(p).or_add_diagnostic(p, error)` for required nodes

Applied to files:

  • crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs
🧬 Code graph analysis (1)
crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs (2)
crates/biome_js_analyze/src/assist/source/use_sorted_keys.rs (2)
  • has_multiline_content (172-184)
  • get_nesting_depth (187-211)
crates/biome_analyze/src/utils.rs (2)
  • is_separated_list_sorted_by (13-43)
  • sorted_separated_list_by (53-107)
🔇 Additional comments (2)
crates/biome_json_analyze/src/assist/source/use_sorted_keys.rs (2)

80-103: Documentation is clear and helpful.

The groupByNesting option is well-documented with practical examples.


115-127: Verify multiline detection approach.

A past review suggested using syntax().text_trimmed().contains_char('\n') instead of checking token newlines. The current approach checks formatting structure; the suggested approach would check text content. Please confirm which behaviour correctly identifies "multiline" arrays/objects for grouping purposes.

@ematipico ematipico merged commit 54682aa into biomejs:next Dec 9, 2025
20 checks passed
@PaulRBerg PaulRBerg deleted the feat/use-sorted-keys-group-by-nesting branch December 9, 2025 07:48
@github-actions github-actions bot mentioned this pull request Feb 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants