+
Skip to content

Conversation

hamirmahal
Copy link
Contributor

Summary

This sorts interface members.

Test Plan

There are new test files and expected output.

crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/mixed.ts
crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/mixed.ts.snap
crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts
crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts.snap
crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts
crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts.snap

Docs

Included above pub UseSortedInterfaceMembers

Copy link

changeset-bot bot commented Sep 21, 2025

⚠️ No Changeset found

Latest commit: 347ebc6

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 github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis A-Project Area: project labels Sep 21, 2025
Copy link

codspeed-hq bot commented Sep 21, 2025

CodSpeed Performance Report

Merging #7553 will not alter performance

Comparing hamirmahal:feat/sort-interface-members (347ebc6) with main (d6da4d5)

Summary

✅ 53 untouched
⏩ 85 skipped1

Footnotes

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

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution. The groundwork of the rule is solid, however there are important things to address:

  • the documentation: it doesn't explain why some items aren't sortable, it doesn't explain the option sortOrder, it doesn't explain how multiple non-sortable items are sorted among themselves
  • Tests for the option are absent
  • The option is missing and it's not documented with docstrings
  • The action must be placed inside the nursery group

@hamirmahal
Copy link
Contributor Author

Thanks for the feedback. I usually don't have much availability during the week, so I'll try to do as much of the implementation as I can on weekends.

@hamirmahal hamirmahal force-pushed the feat/sort-interface-members branch from b009251 to 654b64b Compare September 27, 2025 01:44
Copy link
Contributor

coderabbitai bot commented Sep 27, 2025

Walkthrough

Adds a new nursery lint rule UseSortedInterfaceMembers for TypeScript interfaces with implementation and automatic fix in crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs. Introduces rule options via a new UseSortedInterfaceMembersOptions struct and pub mod use_sorted_interface_members in crates/biome_rule_options. Exposes a public type alias in crates/biome_js_analyze/src/options.rs and enables the rule in biome.json. Adds multiple test fixtures covering sorted, unsorted, comments, and mixed non‑sortable-member scenarios. Also contains unrelated TypeScript API/interface ordering and scripts/version-check typings changes.

Suggested reviewers

  • ematipico
  • dyc3

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title uses a clear conventional commit style and succinctly describes the introduction of interface member sorting, matching the primary change in the pull request.
Description Check ✅ Passed The description outlines the purpose of sorting interface members, includes a test plan with new test files and a documentation note, and is directly relevant to the implemented changes in the pull request.
✨ 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: 3

🧹 Nitpick comments (5)
crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/mixed.ts (1)

1-11: Broaden the test to cover sort_order and multiple non‑sortables

Please add variants asserting both natural and lexicographic orders and a case with multiple call/construct/index signatures to verify stability among non‑sortable members.

Would you like me to draft the extra test cases?

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

1-6: Add tests that exercise the option

Please add tests asserting both SortOrder::Natural and SortOrder::Lexicographic behaviours.

I can add snapshots for both orders if you confirm the desired defaults.

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

46-52: Use the helper and simplify control flow

Removes Result plumbing.

Apply this diff:

-    for member in list.iter() {
-        if let Ok(Some(name)) = member.name()
-            && let Some(token_text) = name.name()
-        {
-            sortable_keys.push(ComparableToken::new(token_text));
-        }
-    }
+    for member in list.iter() {
+        if let Some(name) = type_member_name(&member)
+            && let Some(token_text) = name.name()
+        {
+            sortable_keys.push(ComparableToken::new(token_text));
+        }
+    }

99-107: Clarify docs: explicitly list sortable vs non‑sortable, no parentheses

Small wording tweak helps users understand what moves and what doesn’t.

Apply this diff:

-    /// This rule sorts all sortable members (properties, methods, getters, setters)
-    /// and groups them at the beginning of the interface. Non-sortable members
-    /// (call signatures, construct signatures, and index signatures) are grouped
-    /// at the end of the interface.
+    /// This rule sorts only:
+    /// - properties
+    /// - methods
+    /// - getters
+    /// - setters
+    ///
+    /// It does not sort:
+    /// - call signatures
+    /// - construct signatures
+    /// - index signatures
+    ///
+    /// Non‑sortable members are not re‑ordered and keep their original positions.

If you keep trailing non‑sortables, adjust the last sentence accordingly.


154-157: DRY the comparator mapping (optional)

The SortOrder→comparator mapping is duplicated; consider a small helper to return the comparator.

Example:

fn cmp_for(order: SortOrder) -> fn(&ComparableToken, &ComparableToken) -> std::cmp::Ordering {
    match order {
        SortOrder::Natural => ComparableToken::ascii_nat_cmp,
        SortOrder::Lexicographic => ComparableToken::lexicographic_cmp,
    }
}

Then use cmp_for(options.sort_order) in both places.

Also applies to: 186-189

📜 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 c294644 and 654b64b.

⛔ Files ignored due to path filters (6)
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/mixed.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts.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 (9)
  • crates/biome_configuration/src/analyzer/assist/actions.rs (9 hunks)
  • crates/biome_js_analyze/src/assist/source.rs (1 hunks)
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs (1 hunks)
  • crates/biome_js_analyze/src/options.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/mixed.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts (1 hunks)
  • crates/biome_rule_options/src/lib.rs (1 hunks)
  • crates/biome_rule_options/src/use_sorted_interface_members.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
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/tests/specs/source/useSortedInterfaceMembers/unsorted.ts
  • crates/biome_js_analyze/src/options.rs
  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/mixed.ts
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts
  • crates/biome_js_analyze/src/options.rs
  • crates/biome_rule_options/src/use_sorted_interface_members.rs
  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/mixed.ts
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/mixed.ts
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/options.rs
  • crates/biome_rule_options/src/use_sorted_interface_members.rs
  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
crates/biome_configuration/src/**

📄 CodeRabbit inference engine (CLAUDE.md)

Keep configuration sources under biome_configuration/src/

Files:

  • crates/biome_configuration/src/analyzer/assist/actions.rs
🧠 Learnings (14)
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)

Applied to files:

  • crates/biome_js_analyze/src/options.rs
  • crates/biome_rule_options/src/use_sorted_interface_members.rs
  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Options types must implement serialization/deserialization and schema support using derives: `Serialize`, `Deserialize`, `Deserializable`, and `#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]`

Applied to files:

  • crates/biome_js_analyze/src/options.rs
  • crates/biome_rule_options/src/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • crates/biome_js_analyze/src/options.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Applied to files:

  • crates/biome_js_analyze/src/options.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper advice types from biome_diagnostics::v2 (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) when suitable

Applied to files:

  • crates/biome_js_analyze/src/options.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)

Applied to files:

  • crates/biome_js_analyze/src/options.rs
  • crates/biome_js_analyze/src/assist/source.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously

Applied to files:

  • crates/biome_js_analyze/src/options.rs
  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules

Applied to files:

  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-07T17:35:00.517Z
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-09-07T17:35:00.517Z
Learning: Update documentation when features change; for rules/assists/options, use inline Rust rustdoc

Applied to files:

  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Avoid deep indentation and panics; prefer `?`, `ok()?`, and combinators (`map`, `and_then`, `filter`) over nested `if let`/`unwrap`/`expect`

Applied to files:

  • crates/biome_js_analyze/src/assist/source.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`

Applied to files:

  • crates/biome_js_analyze/src/assist/source.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate

Applied to files:

  • crates/biome_js_analyze/src/assist/source.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)

Applied to files:

  • crates/biome_js_analyze/src/assist/source.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action

Applied to files:

  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/assist/source.rs (1)
crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs (2)
  • name (21-21)
  • name (24-37)
⏰ 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). (25)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Check JS Files
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Test Node.js API
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
🔇 Additional comments (6)
crates/biome_js_analyze/src/options.rs (1)

453-454: Alias slots in nicely.
Thanks for threading the new assist into the generated aliases without rocking the alphabetical boat.

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

20-38: Replace single‑use trait with a simple helper that returns Option<_>

A trait implemented for a single type adds indirection. A small function with .ok() is clearer.

Apply this diff:

-trait TsTypeMemberName {
-    fn name(&self) -> SyntaxResult<Option<AnyJsObjectMemberName>>;
-}
-impl TsTypeMemberName for AnyTsTypeMember {
-    fn name(&self) -> SyntaxResult<Option<AnyJsObjectMemberName>> {
-        match self {
-            // Property signatures have names
-            Self::TsPropertySignatureTypeMember(prop) => prop.name().map(Some),
-            // Method signatures have names
-            Self::TsMethodSignatureTypeMember(method) => method.name().map(Some),
-            // Getter signatures have names
-            Self::TsGetterSignatureTypeMember(getter) => getter.name().map(Some),
-            // Setter signatures have names
-            Self::TsSetterSignatureTypeMember(setter) => setter.name().map(Some),
-            // Call signatures, construct signatures, and index signatures don't have sortable names
-            _ => Ok(None),
-        }
-    }
-}
+fn type_member_name(member: &AnyTsTypeMember) -> Option<AnyJsObjectMemberName> {
+    match member {
+        AnyTsTypeMember::TsPropertySignatureTypeMember(prop) => prop.name().ok(),
+        AnyTsTypeMember::TsMethodSignatureTypeMember(method) => method.name().ok(),
+        AnyTsTypeMember::TsGetterSignatureTypeMember(getter) => getter.name().ok(),
+        AnyTsTypeMember::TsSetterSignatureTypeMember(setter) => setter.name().ok(),
+        // Call, construct, and index signatures have no sortable name
+        _ => None,
+    }
+}

70-97: Don’t move non‑sortable members; perform an in‑place stable reorder

Current fix moves non‑sortable members to the end, contradicting the intent that they’re “non‑sortable”, and mismatches detection (which ignores their positions). Keep them in place and only reorder sortable slots.

Apply this diff:

-    let mut sortable_members = Vec::new();
-    let mut non_sortable_members = Vec::new();
-
-    // Separate sortable from non-sortable members
-    for member in list.iter() {
-        if let Ok(Some(name)) = member.name() {
-            if let Some(token_text) = name.name() {
-                sortable_members.push((member, ComparableToken::new(token_text)));
-            } else {
-                // Name exists but is not sortable (computed/dynamic)
-                non_sortable_members.push(member);
-            }
-        } else {
-            // No name (call signatures, construct signatures, index signatures)
-            non_sortable_members.push(member);
-        }
-    }
-
-    // Sort the sortable members
-    sortable_members.sort_by(|(_, a), (_, b)| comparator(a, b));
-
-    // Combine: all sortable members first, then all non-sortable members
-    let mut new_members: Vec<AnyTsTypeMember> = sortable_members
-        .into_iter()
-        .map(|(member, _)| member)
-        .collect();
-
-    new_members.extend(non_sortable_members);
-
-    make::ts_type_member_list(new_members)
+    // Collect sortable members and mark which positions are sortable
+    let mut sortable: Vec<(AnyTsTypeMember, ComparableToken)> = Vec::new();
+    let mut is_sortable: Vec<bool> = Vec::new();
+    for member in list.iter() {
+        if let Some(name) = type_member_name(&member)
+            && let Some(token) = name.name()
+        {
+            is_sortable.push(true);
+            sortable.push((member, ComparableToken::new(token)));
+        } else {
+            is_sortable.push(false);
+        }
+    }
+
+    // Sort only the sortable members by the chosen comparator
+    sortable.sort_by(|(_, a), (_, b)| comparator(a, b));
+    let mut sorted_iter = sortable.into_iter().map(|(m, _)| m);
+
+    // Rebuild the list: keep non-sortables in place, fill sortable slots with the next sorted member
+    let new_members: Vec<AnyTsTypeMember> = list
+        .iter()
+        .enumerate()
+        .map(|(idx, member)| if is_sortable[idx] {
+            sorted_iter.next().expect("sorted members length should match")
+        } else {
+            member
+        })
+        .collect();
+
+    make::ts_type_member_list(new_members)

If you prefer grouping non‑sortables at the end, then update the detection to also assert “non‑sortables are trailing”, so run() and the fix stay consistent.


135-135: Set version: "next" for new rules

New or updated rules should use version: "next".

Apply this diff:

-        version: "2.0.0",
+        version: "next",

As per coding guidelines

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

1-6: Add the missing sort_order option (and wire it into the rule)

The options struct is empty but the rule reads options.sort_order via UseSortedKeysOptions. Either alias to that type or add the field here and update the rule to use this options type. Below adds the field and keeps derives consistent.

Apply this diff:

 use biome_deserialize_macros::Deserializable;
 use serde::{Deserialize, Serialize};
+use crate::use_sorted_keys::SortOrder;
 #[derive(Default, Clone, Debug, Deserialize, Deserializable, Eq, PartialEq, Serialize)]
 #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields, default)]
-pub struct UseSortedInterfaceMembersOptions {}
+pub struct UseSortedInterfaceMembersOptions {
+    pub sort_order: SortOrder,
+}

As per coding guidelines

crates/biome_configuration/src/analyzer/assist/actions.rs (1)

200-206: Looks consistent with the other assists.

Nice to see the new rule documented and threaded through the config in one sweep.

};

use biome_console::markup;
use biome_deserialize::TextRange;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix incorrect TextRange import (compile error)

TextRange comes from biome_rowan, not biome_deserialize.

Apply this diff:

-use biome_deserialize::TextRange;
+use biome_rowan::TextRange;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
use biome_deserialize::TextRange;
use biome_rowan::TextRange;
🤖 Prompt for AI Agents
In crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
around line 7, the code imports TextRange from the wrong crate
(biome_deserialize) causing a compile error; replace that import with TextRange
from biome_rowan by changing the use statement to import TextRange from
biome_rowan (i.e., remove or replace the existing biome_deserialize::TextRange
import so the file uses biome_rowan::TextRange).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All checks have passed without this suggestion.

@hamirmahal hamirmahal force-pushed the feat/sort-interface-members branch from 654b64b to befa13a Compare September 27, 2025 05:18
@github-actions github-actions bot removed the A-Project Area: project label Sep 27, 2025
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

📜 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 654b64b and befa13a.

⛔ Files ignored due to path filters (4)
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/multiple_non_sortable.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (6)
  • crates/biome_js_analyze/src/assist/source.rs (1 hunks)
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs (1 hunks)
  • crates/biome_js_analyze/src/options.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/multiple_non_sortable.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/biome_js_analyze/src/assist/source.rs
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/src/options.rs
🧰 Additional context used
📓 Path-based instructions (4)
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/tests/specs/source/useSortedInterfaceMembers/unsorted.ts
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/multiple_non_sortable.ts
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts
  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/multiple_non_sortable.ts
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts
  • crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/multiple_non_sortable.ts
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
🧠 Learnings (12)
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper advice types from biome_diagnostics::v2 (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) when suitable

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Avoid avoidable string allocations: prefer comparing `&str` or using `TokenText` over calling `to_string()`

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs : When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Options types must implement serialization/deserialization and schema support using derives: `Serialize`, `Deserialize`, `Deserializable`, and `#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]`

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously

Applied to files:

  • crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
⏰ 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). (24)
  • GitHub Check: Documentation
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: autofix
🔇 Additional comments (4)
crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs (2)

7-8: Fix the TextRange import

TextRange lives in biome_rowan; the current import won’t compile. Let’s pull it from the existing biome_rowan import bundle so the build stays happy.

-use biome_deserialize::TextRange;
-use biome_rowan::{AstNode, AstNodeList, BatchMutationExt};
+use biome_rowan::{AstNode, AstNodeList, BatchMutationExt, TextRange};

Also applies to: 15-15


116-121: Respect ctx.metadata().applicability()

Assists are expected to honour the analyser metadata, otherwise global applicability tweaks are ignored. Swapping out the hard-coded Applicability::Always keeps us in line with the other rules. Based on learnings

-            rule_action_category!(),
-            Applicability::Always,
+            rule_action_category!(),
+            ctx.metadata().applicability(),
crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/unsorted.ts (1)

1-5: LGTM: Unsorted fixture gives the rule something to chew on.

Leaving zebra ahead of apple nails the detection path—nicely done.

crates/biome_js_analyze/tests/specs/source/useSortedInterfaceMembers/multiple_non_sortable.ts (1)

1-11: LGTM: Mixed members thoroughly exercise the tricky cases.

This line-up keeps sortable bits and the call/construct/index signatures distinct, which is exactly what the fixer needs.

Comment on lines 84 to 114
type Options = UseSortedKeysOptions;
fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let interface = ctx.query();
let body = interface.members();
let comparator = ComparableToken::ascii_nat_cmp;

if is_interface_members_sorted(&body, comparator) {
None
} else {
Some(())
}
}
fn diagnostic(ctx: &RuleContext<Self>, _state: &Self::State) -> Option<RuleDiagnostic> {
let interface = ctx.query();
let body = interface.members();

Some(RuleDiagnostic::new(
category!("assist/source/useSortedInterfaceMembers"),
body.range(),
markup! {
"The interface members are not sorted by key."
},
))
}
fn action(ctx: &RuleContext<Self>, (): &Self::State) -> Option<JsRuleAction> {
let interface = ctx.query();
let list = interface.members();
let mut mutation = ctx.root().begin();
let comparator = ComparableToken::ascii_nat_cmp;
let new_list = sort_interface_members(&list, comparator);
mutation.replace_node_discard_trivia(list, new_list);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Hook comparator selection up to the rule options

We surface UseSortedKeysOptions here but never read them, so any configured sort order is silently ignored. Please pull the comparator from ctx.options() (mirroring use_sorted_keys) rather than hard-coding ascii_nat_cmp, so custom settings actually take effect. Based on learnings

🤖 Prompt for AI Agents
In crates/biome_js_analyze/src/assist/source/use_sorted_interface_members.rs
around lines 84 to 114, the rule currently hard-codes
ComparableToken::ascii_nat_cmp in two places and ignores UseSortedKeysOptions;
update the code to read the comparator from ctx.options() (the Options =
UseSortedKeysOptions) instead of hard-coding ascii_nat_cmp so configured sort
order is respected. Concretely, fetch the options once (e.g. let opts =
ctx.options();), derive the comparator using the same logic as use_sorted_keys
(mapping the option to the appropriate ComparableToken comparator), then replace
both occurrences of ComparableToken::ascii_nat_cmp with that computed comparator
before calling is_interface_members_sorted and sort_interface_members. Ensure
the options type is used and that behavior matches the existing use_sorted_keys
implementation.

@github-actions github-actions bot added the A-Project Area: project label Sep 27, 2025
@hamirmahal hamirmahal force-pushed the feat/sort-interface-members branch from a837aed to 192a896 Compare September 27, 2025 23:00
@github-actions github-actions bot added the A-CLI Area: CLI label Sep 27, 2025
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: 2

🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1)

185-194: Sanity-check trivia/comment preservation in the fix

Rebuilding the list via make::ts_type_member_list and replace_node_discard_trivia may drop list-level trivia. Likely fine since member nodes are reused, but please verify comments between members survive the reordering; switch to replace_node if needed.

You can add a test with comments between members to ensure they’re preserved after applying the fix.

Also applies to: 109-113

📜 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 a837aed and 192a896.

⛔ Files ignored due to path filters (9)
  • crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs is excluded by !**/migrate/eslint_any_rule_to_biome.rs and included by **
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts.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 (8)
  • biome.json (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1 hunks)
  • crates/biome_js_analyze/src/options.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts (1 hunks)
  • crates/biome_rule_options/src/lib.rs (1 hunks)
  • crates/biome_rule_options/src/use_sorted_interface_members.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_sorted_interface_members.rs
🧰 Additional context used
📓 Path-based instructions (4)
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/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts
  • crates/biome_js_analyze/src/options.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts
  • crates/biome_js_analyze/src/options.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_analyze/src/options.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Options types must implement serialization/deserialization and schema support using derives: `Serialize`, `Deserialize`, `Deserializable`, and `#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]`
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)

Applied to files:

  • biome.json
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)

Applied to files:

  • crates/biome_js_analyze/src/options.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Options types must implement serialization/deserialization and schema support using derives: `Serialize`, `Deserialize`, `Deserializable`, and `#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]`

Applied to files:

  • crates/biome_js_analyze/src/options.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules

Applied to files:

  • crates/biome_js_analyze/src/options.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • crates/biome_js_analyze/src/options.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Avoid avoidable string allocations: prefer comparing `&str` or using `TokenText` over calling `to_string()`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper advice types from biome_diagnostics::v2 (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) when suitable

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs : When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1)
crates/biome_analyze/src/rule.rs (3)
  • recommended (554-557)
  • sources (569-572)
  • inspired (249-254)
⏰ 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). (25)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Documentation
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test Node.js API
  • GitHub Check: Check JS Files
🔇 Additional comments (3)
crates/biome_js_analyze/src/options.rs (1)

453-454: LGTM: options alias wiring looks correct

Alias points to the rule’s Options and follows the established pattern.

crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1)

7-7: Fix incorrect TextRange import (compile error)

Import TextRange from biome_rowan, not biome_deserialize.

Apply this diff:

- use biome_deserialize::TextRange;
+ use biome_rowan::TextRange;
biome.json (1)

79-82: Approve rule registration: useSortedInterfaceMembers correctly referenced
Config in biome.json contains a single reference matching the declare_lint_rule! name in use_sorted_interface_members.rs.

@hamirmahal hamirmahal force-pushed the feat/sort-interface-members branch 2 times, most recently from b554dd0 to 33c7e4d Compare September 27, 2025 23:51
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/lint/nursery/use_sorted_interface_members.rs (1)

78-82: Let the rule use its options struct

We just added UseSortedInterfaceMembersOptions, yet the rule still advertises () as its options. Wiring the rule to the struct keeps the schema tooling honest and avoids leaving that new type as a wallflower. Based on learnings

+use biome_rule_options::use_sorted_interface_members::UseSortedInterfaceMembersOptions;
@@
-    type Options = ();
+    type Options = UseSortedInterfaceMembersOptions;
📜 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 b554dd0 and 33c7e4d.

⛔ Files ignored due to path filters (11)
  • crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs is excluded by !**/migrate/eslint_any_rule_to_biome.rs and included by **
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/with_comments.ts.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 (10)
  • biome.json (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1 hunks)
  • crates/biome_js_analyze/src/options.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/with_comments.ts (1 hunks)
  • crates/biome_rule_options/src/lib.rs (1 hunks)
  • crates/biome_rule_options/src/use_sorted_interface_members.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/biome_js_analyze/src/options.rs
  • biome.json
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts
🧰 Additional context used
📓 Path-based instructions (4)
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_rule_options/src/use_sorted_interface_members.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/with_comments.ts
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_rule_options/src/use_sorted_interface_members.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.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_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/with_comments.ts
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/with_comments.ts
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Options types must implement serialization/deserialization and schema support using derives: `Serialize`, `Deserialize`, `Deserializable`, and `#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]`
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Options types must implement serialization/deserialization and schema support using derives: `Serialize`, `Deserialize`, `Deserializable`, and `#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]`

Applied to files:

  • crates/biome_rule_options/src/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)

Applied to files:

  • crates/biome_rule_options/src/use_sorted_interface_members.rs
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : If a rule returns a code action (implements `action`), add `fix_kind` in `declare_lint_rule!` and use `ctx.metadata().applicability()` when building the action

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : In declare_lint_rule! macros, set `version: "next"` for new or updated rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Avoid avoidable string allocations: prefer comparing `&str` or using `TokenText` over calling `to_string()`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper advice types from biome_diagnostics::v2 (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) when suitable

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs : When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Code blocks in rule docs must specify language; invalid snippets require `expect_diagnostic`; use `options`/`full_options`/`use_options` markers as appropriate

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Recommended rules with domains are enabled only when users enable the matching domains; use `domains` metadata judiciously

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : Follow rule naming conventions: use `no<Concept>` to forbid and `use<Concept>` to mandate; prefer consistent prefixes (e.g., `noDuplicate<Concept>`, `useConsistent<Concept>`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement rule files under a `.../src/*/nursery/` directory)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/**/src/{lint,assist}/**/*.rs : When deprecating a rule, add `deprecated: "<reason>"` to `declare_lint_rule!`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1)
crates/biome_analyze/src/rule.rs (3)
  • recommended (554-557)
  • sources (569-572)
  • inspired (249-254)
⏰ 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). (26)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Documentation
  • GitHub Check: Check JS Files
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)
🔇 Additional comments (1)
crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1)

8-15: Import TextRange from biome_rowan

Line 8 grabs TextRange from biome_deserialize, but that crate doesn’t export it—cargo will sulk at compile time. Bring it in from biome_rowan alongside the other rowan imports so the build stays happy.

-use biome_deserialize::TextRange;
-use biome_rowan::{AstNode, AstNodeList, BatchMutationExt};
+use biome_rowan::{AstNode, AstNodeList, BatchMutationExt, TextRange};

@hamirmahal hamirmahal force-pushed the feat/sort-interface-members branch from 3cbb585 to 4a2ab26 Compare October 11, 2025 16:58
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: 2

♻️ Duplicate comments (1)
crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1)

7-7: Critical: Wrong crate for TextRange import.

TextRange should be imported from biome_rowan, not biome_deserialize. This will cause a compile error.

Apply this diff:

-use biome_deserialize::TextRange;
+use biome_rowan::TextRange;

Note: This was previously flagged and may have been addressed in a later commit not shown here.

📜 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 3cbb585 and 4a2ab26.

⛔ Files ignored due to path filters (11)
  • crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs is excluded by !**/migrate/eslint_any_rule_to_biome.rs and included by **
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/with_comments.ts.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 (13)
  • biome.json (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (1 hunks)
  • crates/biome_js_analyze/src/options.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/with_comments.ts (1 hunks)
  • crates/biome_rule_options/src/lib.rs (1 hunks)
  • crates/biome_rule_options/src/use_sorted_interface_members.rs (1 hunks)
  • packages/@biomejs/backend-jsonrpc/src/transport.ts (3 hunks)
  • packages/@biomejs/js-api/src/wasm.ts (1 hunks)
  • scripts/version-check.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/biome_rule_options/src/use_sorted_interface_members.rs
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/unsorted.ts
  • biome.json
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/with_comments.ts
  • crates/biome_js_analyze/src/options.rs
🧰 Additional context used
📓 Path-based instructions (5)
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/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts
  • crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Before committing, format Rust and TOML files (e.g., via just f/just format)

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
  • crates/biome_rule_options/src/lib.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Document rules, assists, and options via inline rustdoc in Rust source

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
  • crates/biome_rule_options/src/lib.rs
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.228Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : Place all new JavaScript lint rules in the nursery group under biome_js_analyze/lib/src/lint/nursery/<rule_name>.rs
📚 Learning: 2025-10-02T12:57:33.228Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.228Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : Place all new JavaScript lint rules in the nursery group under biome_js_analyze/lib/src/lint/nursery/<rule_name>.rs

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
📚 Learning: 2025-10-02T12:57:33.228Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-02T12:57:33.228Z
Learning: Applies to crates/biome_analyze/crates/**/src/**/lint/**/*.rs : If a rule returns a code action, add fix_kind in declare_lint_rule! and ensure action uses ctx.action_category(ctx.category(), ctx.group()) and ctx.metadata().applicability()

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs
🧬 Code graph analysis (2)
packages/@biomejs/js-api/src/wasm.ts (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (15)
  • Diagnostic (8818-8828)
  • Workspace (9828-9861)
  • Configuration (30-95)
  • CloseFileParams (9519-9522)
  • FixFileParams (9742-9755)
  • FixFileResult (9763-9780)
  • FormatFileParams (9709-9712)
  • FormatRangeParams (9732-9736)
  • GetFormatterIRParams (9575-9578)
  • OpenFileParams (9420-9431)
  • OpenProjectParams (9351-9360)
  • OpenProjectResult (9361-9366)
  • PullDiagnosticsParams (9621-9635)
  • PullDiagnosticsResult (9639-9643)
  • UpdateSettingsParams (22-26)
crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (2)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (2)
  • FixKind (7941-7941)
  • TextRange (9288-9288)
crates/biome_js_factory/src/generated/node_factory.rs (1)
  • ts_type_member_list (7360-7371)
⏰ 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). (13)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Check JS Files
  • GitHub Check: Lint project (depot-windows-2022)
🔇 Additional comments (18)
packages/@biomejs/js-api/src/wasm.ts (1)

87-117: LGTM! Alphabetical ordering applied correctly.

All three interfaces (DiagnosticPrinter, Workspace, and Module) now follow alphabetical member ordering, consistent with the new useSortedInterfaceMembers rule being introduced in this PR.

crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sortable_after_non_sortable.ts (1)

1-7: LGTM!

The test fixture correctly exercises the sortable-after-non-sortable constraint. The interface design is spot-on for validating the rule's behaviour.

packages/@biomejs/backend-jsonrpc/src/transport.ts (4)

2-2: Verify this change belongs in this PR.

The addition of destroy(): void to the Socket interface appears unrelated to sorting interface members. Is this intended to be part of this PR?


15-15: Kind discriminants added for tagged unions.

Adding readonly kind fields establishes proper discriminated unions for ReaderState, which is good practice. However, this appears orthogonal to the UseSortedInterfaceMembers rule.

Are these changes intended for this PR or should they be in a separate PR?

Also applies to: 21-21


28-28: Verify jsonrpc version field belongs in this PR.

Explicit jsonrpc: "2.0" field added. This change appears unrelated to sorting interface members.


95-96: Method reordering demonstrates the lint rule in action.

The PendingRequest interface now has reject before resolve, which is alphabetically correct. If intentional, this nicely demonstrates the rule's behaviour. However, verify this reordering is intentional and won't break existing code that depends on member order (though TypeScript interfaces shouldn't be order-dependent at runtime).

crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/sorted.ts (1)

1-6: LGTM!

Clean test fixture for the already-sorted case. All members are sortable and correctly ordered alphabetically.

crates/biome_js_analyze/tests/specs/nursery/useSortedInterfaceMembers/multiple_non_sortable.ts (1)

1-11: LGTM!

Excellent test fixture exercising multiple non-sortable member types interleaved with sortable ones. This covers the complex scenario comprehensively.

crates/biome_js_analyze/src/lint/nursery/use_sorted_interface_members.rs (7)

16-76: Rule declaration and documentation are clear.

The declare_lint_rule! macro is properly structured with comprehensive documentation explaining sortable vs non-sortable members and expected behaviour.


77-92: Detection logic delegates to helper.

The run method correctly uses is_interface_members_sorted with the ASCII natural comparator.


93-103: Diagnostic message is clear.

Simple, direct message about unsorted members.


105-119: Fix generation uses correct applicability.

The action method now correctly uses ctx.metadata().applicability() rather than hard-coded Applicability::Always. Well done addressing the previous review comment.


124-134: Member name extraction handles all sortable types.

The get_type_member_name function correctly identifies sortable members (property, method, getter, setter) and returns None for non-sortable members (call, construct, index signatures).


135-169: Detection correctly enforces sortable-first constraint.

The is_interface_members_sorted function now properly tracks whether a non-sortable member has been seen and returns false if any sortable member appears after a non-sortable one. This addresses the previous detection gap. The logic is sound:

  1. Maintains previous key for order checking
  2. Flags sortable-after-non-sortable as unsorted
  3. Checks alphabetical order among sortable members
  4. Marks non-sortable members seen

170-204: Sorting implementation separates and orders correctly.

The sort_interface_members function:

  1. Separates sortable from non-sortable members
  2. Sorts sortable members alphabetically
  3. Concatenates sorted sortable members first, then non-sortable in original order

This matches the documented behaviour perfectly.

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

347-347: Manual codegen verification required. The sandbox couldn’t run xtask codegen. Please run locally in crates/biome_rule_options:

cargo run --bin xtask codegen
git diff --exit-code src/lib.rs

and confirm src/use_sorted_interface_members.rs exists.

scripts/version-check.ts (2)

239-241: Field reordering looks fine.

The alphabetical ordering of interface members is consistent with the PR's goal to sort interface members.


336-337: Field reordering is appropriate.

The repositioning of these fields aligns with the interface member sorting objective.

Also applies to: 342-342, 348-348

Comment on lines +263 to 267
function isPackageObj(value: unknown): value is PackageObj {
return (
!!value && typeof value === "object" && value !== null && "version" in value
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Type guard is incomplete.

Whilst the explicit null check is a good addition, the guard doesn't verify that version is actually a string. Consider strengthening the check.

Apply this diff to verify the version type:

 function isPackageObj(value: unknown): value is PackageObj {
 	return (
-		!!value && typeof value === "object" && value !== null && "version" in value
+		!!value && 
+		typeof value === "object" && 
+		value !== null && 
+		"version" in value &&
+		typeof value.version === "string"
 	);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function isPackageObj(value: unknown): value is PackageObj {
return (
!!value && typeof value === "object" && value !== null && "version" in value
);
}
function isPackageObj(value: unknown): value is PackageObj {
return (
!!value &&
typeof value === "object" &&
value !== null &&
"version" in value &&
typeof (value as any).version === "string"
);
}
🤖 Prompt for AI Agents
In scripts/version-check.ts around lines 263 to 267, the type guard isPackageObj
currently only checks for presence of a version property but not its type;
update the guard to also verify that value.version is a string (e.g., ensure
"version" in value && typeof (value as Record<string, unknown>).version ===
"string") so the function narrows to PackageObj only when version exists and is
a string.

Comment on lines +270 to +289
author: {
login: string;
id: number;
node_id: string;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
organizations_url: string;
repos_url: string;
events_url: string;
receive_events_url: string;
type: string;
site_admin: boolean;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify alignment with GitHub API response structure.

The new author object significantly expands the interface's public surface. Please confirm this matches the current GitHub commits API response structure.


🌐 Web query:

What is the structure of the author field in the GitHub REST API commits endpoint response?

💡 Result:

There are two different "author" fields in the commits endpoint response:

  1. commit.author — an object from the Git commit metadata with:

    • name (string)
    • email (string)
    • date (ISO 8601 string).
      Example: { "name":"Monalisa Octocat", "email":"support@github.com", "date":"2011-04-14T16:00:49Z" }. [1]
  2. author — the top-level GitHub user object (the account associated with that commit), or null if GitHub can't map the commit email to a user. Typical fields include:

    • login, id, node_id, avatar_url, gravatar_id, url, html_url,
    • followers_url, following_url, gists_url, starred_url, subscriptions_url, organizations_url, repos_url, events_url, received_events_url,
    • type, site_admin, etc.
      Example: { "login":"octocat", "id":1, "avatar_url":"...", "url":"https://api.github.com/users/octocat", "type":"User", "site_admin":false }. [1]

(There is an analogous pair for committer: commit.committer and top-level committer.) [1]

Source: GitHub REST API commits documentation and example response. [1]


Correct author interface

  • Rename receive_events_url to received_events_url to match GitHub’s API.
  • Update author type to Author | null, as the API may return null when unmapped.
🤖 Prompt for AI Agents
In scripts/version-check.ts around lines 270 to 289, the author interface
wrongly names receive_events_url and uses a non-nullable author type; rename the
property to received_events_url to match GitHub’s API and change the author type
to Author | null (or the inline object to allow null) so the code handles cases
where the API returns null; update any usages to check for null before accessing
author fields and replace receive_events_url references with
received_events_url.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This uses pre-existing code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the existing author field, just moved.

@hamirmahal
Copy link
Contributor Author

@ematipico I fixed merge conflicts. Are there other changes you'd like me to make here?

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

Labels

A-CLI Area: CLI A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载