Skip to content

feat(cli): rule profiler#8562

Merged
dyc3 merged 1 commit intonextfrom
dyc3/profile-rules
Jan 27, 2026
Merged

feat(cli): rule profiler#8562
dyc3 merged 1 commit intonextfrom
dyc3/profile-rules

Conversation

@dyc3
Copy link
Contributor

@dyc3 dyc3 commented Dec 23, 2025

Summary

Adds --profile-rules cli flag, which prints a report showing execution time for rules. Most of the heavy lifting was done with AI, but I tweaked the actual formatting of the report to make it a bit more useful and pretty.

Not entirely sure if I like the global state.

Here's what it looks like:
image
(this is a debug build, not a release build)

Test Plan

manually tested. it doesn't make a lot of sense to have a snapshot test for it without scrubbing all the numbers from the report

Docs

@changeset-bot
Copy link

changeset-bot bot commented Dec 23, 2025

🦋 Changeset detected

Latest commit: 259f400

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

@github-actions github-actions bot added A-CLI Area: CLI A-Linter Area: linter labels Dec 23, 2025
@dyc3 dyc3 force-pushed the dyc3/profile-rules branch 5 times, most recently from 33e2f3d to 82fec52 Compare December 23, 2025 21:14
Copy link
Contributor Author

dyc3 commented Dec 23, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@dyc3 dyc3 force-pushed the dyc3/profile-rules branch 2 times, most recently from aa337d8 to 2603078 Compare December 24, 2025 14:45
@dyc3 dyc3 marked this pull request as ready for review December 24, 2025 16:31
@dyc3 dyc3 requested review from a team December 24, 2025 16:31
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

Walkthrough

Adds a concurrency-safe, opt-in rule execution profiler to crates/biome_analyze (new profiling module with RuleLabel, RuleProfile, RuleRunTimer, global profiler state and APIs). Instruments analyzer plugins and RegistryRule runs to time built-in and plugin rules using RAII timers and accumulates per-rule metrics. Exposes a --profile-rules CLI switch for Rage/Start/Check/Lint, enables profiling when set, and drains/renders profiles in summary and terminal reporters. Also adds a small public type alias and a changeset for a biomejs/biome patch release.

Possibly related PRs

Suggested labels

A-Tooling

Suggested reviewers

  • ematipico
  • siketyan
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(cli): rule profiler' clearly and concisely describes the main feature addition—a rule profiler in the CLI.
Description check ✅ Passed The description explains the motivation (adds --profile-rules flag for reporting rule execution times), discloses AI assistance, provides visual evidence, and describes testing approach.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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

🧹 Nitpick comments (8)
crates/biome_cli/src/cli_options.rs (1)

25-27: Consider enhancing the documentation.

The doc comment could be more informative. For example:

/// Enable rule profiling output. Displays a report showing execution time for each lint rule.
/// Note: Profiling adds minimal overhead but should primarily be used for diagnostic purposes.

This helps users understand what the output contains and when to use it.

crates/biome_cli/src/reporter/terminal.rs (1)

70-74: Consider extracting common profiling display logic.

This code is duplicated in both summary.rs and terminal.rs. While acceptable for now, consider extracting this into a helper function if the pattern repeats in more reporters:

fn log_profiling_table(console: &mut dyn Console) {
    let profiles = profiling::drain_sorted_by_total(false);
    if !profiles.is_empty() {
        let table = profiling::format_profiles_table(profiles, None);
        console.log(markup!({ table }));
    }
}

Also, the drain_sorted_by_total(false) retains profiling data after draining. Verify this is intentional for multiple reporter invocations.

crates/biome_cli/src/reporter/summary.rs (1)

72-76: Consider adding a comment explaining why profiling data is preserved across report calls.

The false parameter in drain_sorted_by_total(false) is intentional—profiling data persists across the session to aggregate stats. A brief inline comment would clarify this design choice for future maintainers.

crates/biome_analyze/src/profiling.rs (5)

19-20: Minor documentation inconsistency.

The comment states "no output/printing logic", but format_profiles_table (line 343) does provide formatting logic. Consider updating to clarify this distinction (e.g., "no direct I/O; formatting is delegated to consumers").


259-267: Unnecessary Instant::now() call when profiling is disabled.

The new_disabled() constructor still calls Instant::now() (line 265), which can be a syscall on some platforms. This contradicts the "near-zero overhead" claim in the module docs (line 14).

Consider using Option<Instant> or MaybeUninit<Instant> to avoid this cost:

🔎 Proposed fix
 pub struct RuleRunTimer {
     label: Option<RuleLabel>,
     #[cfg(not(target_arch = "wasm32"))]
-    start: Instant,
+    start: Option<Instant>,
 }

 impl RuleRunTimer {
     fn new_enabled(label: RuleLabel) -> Self {
         Self {
             label: Some(label),
             #[cfg(not(target_arch = "wasm32"))]
-            start: Instant::now(),
+            start: Some(Instant::now()),
         }
     }

     fn new_disabled() -> Self {
         Self {
             label: None,
             #[cfg(not(target_arch = "wasm32"))]
-            start: Instant::now(),
+            start: None,
         }
     }
 }

 impl Drop for RuleRunTimer {
     fn drop(&mut self) {
         if let Some(label) = self.label.take() {
             #[cfg(not(target_arch = "wasm32"))]
-            let elapsed = self.start.elapsed();
+            let elapsed = self.start.map(|s| s.elapsed()).unwrap_or(Duration::ZERO);
             #[cfg(target_arch = "wasm32")]
             let elapsed = Duration::ZERO;
             with_profiler(|p| p.record(label, elapsed));
         }
     }
 }

324-335: Function name drain_sorted_by_total is misleading.

This function takes a snapshot and optionally resets—it doesn't truly "drain" (consume and return owned data). Consider renaming to snapshot_sorted_by_total or take_sorted_by_total for clarity.


386-419: Repeated cutoff calculation logic.

The cutoff computation is duplicated five times with near-identical structure. A helper function would reduce repetition and improve maintainability:

🔎 Proposed helper function
fn compute_cutoff<T: Ord + Copy>(values: &mut [T], warn_count: usize) -> Option<T> {
    if warn_count == 0 || values.is_empty() {
        return None;
    }
    values.sort_by(|a, b| b.cmp(a));
    values.get(warn_count - 1).copied()
}

Then replace each block with:

let totals_cutoff = compute_cutoff(&mut totals, warn_count);
let avgs_cutoff = compute_cutoff(&mut avgs, warn_count);
let mins_cutoff = compute_cutoff(&mut mins, warn_count);
let maxs_cutoff = compute_cutoff(&mut maxs, warn_count);
let counts_cutoff = compute_cutoff(&mut counts, warn_count);

343-346: Double-sorting when profiles may already be sorted.

The caller drain_sorted_by_total already sorts the profiles before returning them. If that function is the primary consumer, consider either:

  • Removing the sort here and documenting that input must be pre-sorted, or
  • Keeping this as a defensive measure but noting the redundancy.

Not a correctness issue—just a minor efficiency note.

📜 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 25cdd50 and 2603078.

⛔ Files ignored due to path filters (6)
  • crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_ci/ci_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_migrate/migrate_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_rage/rage_help.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (9)
  • .changeset/rare-queens-doubt.md
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
  • crates/biome_analyze/src/registry.rs
  • crates/biome_cli/src/cli_options.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
  • crates/biome_cli/src/reporter/terminal.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/cli_options.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/registry.rs
  • crates/biome_analyze/src/profiling.rs
  • crates/biome_cli/src/reporter/summary.rs
🧠 Learnings (45)
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Assist rules should detect refactoring opportunities and emit code action signals

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/registry.rs
  • crates/biome_analyze/src/profiling.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Check if a variable is global using the semantic model to avoid false positives

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/execute/traverse.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Prefix line with `#` in documentation code examples sparingly; prefer concise complete snippets

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper types from the biome_diagnostics::v2 module (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) or implement the Advices trait yourself for custom advice handling

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/cli_options.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use helper functions like `map`, `filter`, and `and_then` to avoid deep indentation

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Lines prefixed with `#` in rule documentation code examples will be hidden from output

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/cli_options.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : The first paragraph of rule documentation must be a single line describing what the rule does

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/registry.rs
  • crates/biome_analyze/src/profiling.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Implement `action` function in Rule trait to provide code actions

Applied to files:

  • crates/biome_analyze/src/lib.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/registry.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : No module may copy or clone data from another module in the module graph, not even behind an `Arc`

Applied to files:

  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-12-21T21:15:03.782Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: Applies to **/*.rs : Use the `dbg!()` macro for debugging output in Rust tests and code

Applied to files:

  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `info` for code action rules in analyzer

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Ensure the type implementing Diagnostic derives Debug

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Avoid string allocations by comparing against `&str` or using `TokenText`

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Implement the Diagnostic trait on types, or use the #[derive(Diagnostic)] procedural macro to implement the trait. Configure category, severity, description, message, location, and tags using the #[diagnostic] attribute

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use #[derive(Diagnostic)] on enums when every variant contains a type that is itself a diagnostic

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Fields with #[advice] or #[verbose_advice] attributes must implement the Advices trait to record advices on the diagnostic

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Each invalid code example in rule documentation must emit exactly one diagnostic

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Return `Option<State>` from `run` function for single diagnostic signals

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_analyze/src/registry.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Return `Vec<State>` or `Box<[State]>` from `run` function for multiple diagnostic signals

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/registry.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/crates/biome_diagnostics_categories/src/categories.rs : Register all new diagnostic categories in crates/biome_diagnostics_categories/src/categories.rs

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/execute/traverse.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation code blocks should be ordered as language, expect_diagnostic, options/full_options/use_options, ignore, file

Applied to files:

  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `full_options` code block property for complete biome.json configuration snippets in documentation

Applied to files:

  • crates/biome_cli/src/cli_options.rs
  • crates/biome_cli/src/execute/traverse.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation must include `## Options` section if the rule has options

Applied to files:

  • crates/biome_cli/src/cli_options.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Wrap rule options fields in `Option<>` to properly track set and unset options during merge

Applied to files:

  • crates/biome_cli/src/cli_options.rs
  • crates/biome_analyze/src/registry.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `options` code block property for rule-specific configuration snippets in documentation

Applied to files:

  • crates/biome_cli/src/cli_options.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `use_options` code block property for code examples that follow an options configuration in documentation

Applied to files:

  • crates/biome_cli/src/cli_options.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Use `deny_unknown_fields` in serde derive macro for rule options

Applied to files:

  • crates/biome_cli/src/cli_options.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `file=<path>` property for multi-file rule documentation examples

Applied to files:

  • crates/biome_cli/src/cli_options.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Use `rename_all = "camelCase"` in serde derive macro for rule options

Applied to files:

  • crates/biome_cli/src/cli_options.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `let else` trick when `run` function returns `Vec` to reduce code branching

Applied to files:

  • crates/biome_cli/src/execute/traverse.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use try operator `?` when `run` function returns `Option` to transform `Result` into `Option`

Applied to files:

  • crates/biome_cli/src/execute/traverse.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Applied to files:

  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use generic rule names if the rule could potentially be implemented for multiple languages

Applied to files:

  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/registry.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks

Applied to files:

  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Implement custom Visitor by implementing the Visitor trait for complex rule logic

Applied to files:

  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_cli/src/reporter/summary.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Implement Queryable trait for custom query match types in analyzer rules

Applied to files:

  • crates/biome_analyze/src/analyzer_plugin.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `Semantic<>` query type to access semantic model information like scopes and declarations

Applied to files:

  • crates/biome_analyze/src/analyzer_plugin.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use language-specific rule names if the rule is meant for a specific language only

Applied to files:

  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/registry.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `Ast<>` query type to query AST/CST for nodes of a specific type

Applied to files:

  • crates/biome_analyze/src/analyzer_plugin.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `ctx.model()` to access semantic model information in a rule

Applied to files:

  • crates/biome_analyze/src/registry.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `warn` for rules in performance group

Applied to files:

  • crates/biome_analyze/src/registry.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-21T21:15:03.782Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: Changesets should describe user-facing changes only; internal refactoring without behavior changes does not require a changeset

Applied to files:

  • .changeset/rare-queens-doubt.md
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `warn` or `info` for rules in complexity group

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `error` for rules in correctness, security, and a11y groups

Applied to files:

  • crates/biome_analyze/src/profiling.rs
🧬 Code graph analysis (7)
crates/biome_analyze/src/lib.rs (1)
crates/biome_analyze/src/registry.rs (1)
  • profiling (425-425)
crates/biome_cli/src/reporter/terminal.rs (1)
crates/biome_analyze/src/profiling.rs (2)
  • drain_sorted_by_total (325-335)
  • format_profiles_table (343-473)
crates/biome_cli/src/execute/traverse.rs (3)
crates/biome_analyze/src/registry.rs (1)
  • profiling (425-425)
crates/biome_cli/src/commands/mod.rs (1)
  • cli_options (635-655)
crates/biome_analyze/src/profiling.rs (1)
  • enable (229-231)
crates/biome_analyze/src/analyzer_plugin.rs (2)
crates/biome_analyze/src/registry.rs (3)
  • profiling (425-425)
  • new (298-300)
  • new (382-461)
crates/biome_analyze/src/profiling.rs (2)
  • start_plugin_rule (302-307)
  • default (152-159)
crates/biome_analyze/src/registry.rs (1)
crates/biome_analyze/src/profiling.rs (1)
  • start_rule (291-297)
crates/biome_analyze/src/profiling.rs (1)
crates/biome_analyze/src/registry.rs (3)
  • RuleKey (447-447)
  • new (298-300)
  • new (382-461)
crates/biome_cli/src/reporter/summary.rs (1)
crates/biome_analyze/src/profiling.rs (2)
  • drain_sorted_by_total (325-335)
  • format_profiles_table (343-473)
🔇 Additional comments (10)
crates/biome_analyze/src/lib.rs (1)

16-16: LGTM!

Clean module exposure following standard conventions.

crates/biome_cli/src/execute/traverse.rs (1)

46-48: LGTM!

The profiling is enabled before traversal begins when the flag is set, which is the correct timing.

.changeset/rare-queens-doubt.md (1)

1-5: LGTM!

Clear, concise changeset documenting the user-facing feature.

crates/biome_analyze/src/registry.rs (1)

425-429: LGTM!

The profiling instrumentation correctly wraps only the R::run execution, excluding signal processing from the measurement. The semantic change from direct iteration to collection-then-iteration is necessary and preserves correctness.

crates/biome_analyze/src/analyzer_plugin.rs (2)

17-17: LGTM!

Useful type alias that complements AnalyzerPluginSlice.


111-124: LGTM!

The restructuring correctly isolates timing to the plugin evaluation, excluding signal construction overhead from the measurement.

crates/biome_analyze/src/profiling.rs (4)

84-120: Solid optimisation with pointer-based equality.

The manual PartialEq implementation cleverly short-circuits on pointer equality for static strings before falling back to value comparison. The Hash implementation correctly uses a discriminant prefix to avoid collisions between Builtin and Plugin variants.


142-183: LGTM!

The Metric accumulator is well-designed with appropriate defaults (min: Duration::MAX for proper minimum tracking) and correct handling of the zero-count edge case in into_profile.


209-219: Sensible resilience: silently ignores mutex poisoning.

The with_profiler helper returns None if the mutex is poisoned, which prevents profiling failures from crashing the linter. This is the right trade-off for an optional diagnostic feature.


475-477: LGTM!

Simple and effective duration formatter using Rust's Debug formatting with precision.

Comment on lines 104 to 109
let rule_timer =
profiling::start_plugin_rule(ctx.options.file_path.file_name().unwrap_or("plugin"));
let diagnostics = self
.plugin
.evaluate(node.clone().into(), ctx.options.file_path.clone())
.into_iter()
.map(|diagnostic| {
let name = diagnostic
.subcategory
.clone()
.unwrap_or_else(|| "anonymous".into());

SignalEntry {
text_range: diagnostic.span().unwrap_or_default(),
signal: Box::new(DiagnosticSignal::new(move || diagnostic.clone())),
rule: SignalRuleKey::Plugin(name.into()),
category: RuleCategory::Lint,
instances: Default::default(),
}
});
.evaluate(node.clone().into(), ctx.options.file_path.clone());
rule_timer.stop();
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

Review the profiling label for plugins.

Line 105 uses file_path.file_name() as the profiling label, but this means:

  • All plugins running on the same file share the same label
  • The profile report won't distinguish between different plugin rules
  • Multiple files will show separate entries even for the same plugin

Should the label use the plugin's name instead? For example:

let plugin_name = // derive from self.plugin somehow
let rule_timer = profiling::start_plugin_rule(plugin_name);

If plugin identity isn't readily available, consider passing it through or using a combination like format!("{}/{}", plugin_name, file_name).

🤖 Prompt for AI Agents
In crates/biome_analyze/src/analyzer_plugin.rs around lines 104 to 109, the
profiling label currently uses file_path.file_name() which causes indistinct
profiling across rules; change it to use the plugin's identity (or a combination
of plugin name and file name) as the label. Derive the plugin name from
self.plugin (add or call an accessor like name() on the plugin trait/object if
missing), then call profiling::start_plugin_rule with either plugin_name or
format!("{}/{}", plugin_name, file_name) so each plugin rule is tracked
distinctly; add the accessor or pass the plugin name through if necessary.

@ematipico
Copy link
Member

Btw this should go to next because it's a new feature

@dyc3 dyc3 force-pushed the dyc3/profile-rules branch from 2603078 to e4a390f Compare December 27, 2025 17:46
@dyc3
Copy link
Contributor Author

dyc3 commented Dec 27, 2025

Looks like there's some conflicts with moving this onto next. I'll fix it later.

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

♻️ Duplicate comments (1)
crates/biome_analyze/src/profiling.rs (1)

132-139: Potential truncation when computing average.

The cast self.count as u32 truncates if count exceeds u32::MAX. Unlikely in practice, but for correctness consider saturating.

🔎 Proposed fix
     pub fn avg(&self) -> Duration {
         if self.count == 0 {
             Duration::ZERO
         } else {
-            self.total / (self.count as u32)
+            self.total / self.count.min(u32::MAX as u64) as u32
         }
     }
📜 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 2603078 and e4a390f.

⛔ Files ignored due to path filters (6)
  • crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_ci/ci_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_migrate/migrate_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_rage/rage_help.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (12)
  • .changeset/rare-queens-doubt.md
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_analyze/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
  • crates/biome_analyze/src/registry.rs
  • crates/biome_cli/src/cli_options.rs
  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_cli/src/reporter/summary.rs
  • crates/biome_cli/src/reporter/terminal.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/biome_cli/src/cli_options.rs
  • crates/biome_analyze/src/registry.rs
  • crates/biome_cli/src/reporter/summary.rs
  • crates/biome_analyze/src/analyzer_plugin.rs
  • crates/biome_cli/src/reporter/terminal.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_analyze/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
🧠 Learnings (46)
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Wrap rule options fields in `Option<>` to properly track set and unset options during merge

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Implement `action` function in Rule trait to provide code actions

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : The first paragraph of rule documentation must be a single line describing what the rule does

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_analyze/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rules with `recommended: true` and no domains are enabled by default

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `warn` for rules in performance group

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_analyze/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation must include `## Options` section if the rule has options

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/mod.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rules with `recommended: true` and domains are only enabled when the domain is enabled

Applied to files:

  • crates/biome_cli/src/commands/check.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Assist rules should detect refactoring opportunities and emit code action signals

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_analyze/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-22T09:27:13.161Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:27:13.161Z
Learning: In crates/biome_analyze/**/*analyze/src/**/*.rs, the `fix_kind` field in `declare_lint_rule!` should only be specified when the rule implements the `action` function. Rules that only emit diagnostics without providing code fixes should not include `fix_kind` in their metadata.

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Unsafe` in `declare_lint_rule!` for unsafe code actions

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Safe` in `declare_lint_rule!` for safe code actions

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use try operator `?` when `run` function returns `Option` to transform `Result` into `Option`

Applied to files:

  • crates/biome_cli/src/commands/check.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `let else` trick when `run` function returns `Vec` to reduce code branching

Applied to files:

  • crates/biome_cli/src/commands/check.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use helper functions like `map`, `filter`, and `and_then` to avoid deep indentation

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Applied to files:

  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Implement custom Visitor by implementing the Visitor trait for complex rule logic

Applied to files:

  • crates/biome_cli/src/commands/check.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should perform static analysis of source code to detect invalid or error-prone patterns and emit diagnostics with proposed fixes

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should check syntax according to language specification and emit error diagnostics

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `language` field in `declare_lint_rule!` macro to the language the rule primarily applies to

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Add `deprecated` field to `declare_lint_rule!` macro when deprecating a rule

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation code blocks should be ordered as language, expect_diagnostic, options/full_options/use_options, ignore, file

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `info` for code action rules in analyzer

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Lines prefixed with `#` in rule documentation code examples will be hidden from output

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.

Applied to files:

  • .changeset/rare-queens-doubt.md
📚 Learning: 2025-12-21T21:15:03.796Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.796Z
Learning: Changesets should describe user-facing changes only; internal refactoring without behavior changes does not require a changeset

Applied to files:

  • .changeset/rare-queens-doubt.md
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Commit rule work with message format `feat(biome_<language>_analyze): <ruleName>`

Applied to files:

  • .changeset/rare-queens-doubt.md
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Rule options must be placed inside the `biome_rule_options` crate

Applied to files:

  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Implement `Merge` trait for rule options to support configuration inheritance

Applied to files:

  • crates/biome_cli/src/commands/mod.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Use `rename_all = "camelCase"` in serde derive macro for rule options

Applied to files:

  • crates/biome_cli/src/commands/mod.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `options` code block property for rule-specific configuration snippets in documentation

Applied to files:

  • crates/biome_cli/src/commands/mod.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 : Parse rule functions must be prefixed with `parse_` and use the name defined in the grammar file, e.g., `parse_for_statement` or `parse_expression`

Applied to files:

  • crates/biome_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Place new rules inside the `nursery` group during development

Applied to files:

  • crates/biome_cli/src/lib.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_cli/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Prefix line with `#` in documentation code examples sparingly; prefer concise complete snippets

Applied to files:

  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper types from the biome_diagnostics::v2 module (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) or implement the Advices trait yourself for custom advice handling

Applied to files:

  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Check if a variable is global using the semantic model to avoid false positives

Applied to files:

  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : No module may copy or clone data from another module in the module graph, not even behind an `Arc`

Applied to files:

  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-12-21T21:15:03.796Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.796Z
Learning: Applies to **/*.rs : Use the `dbg!()` macro for debugging output in Rust tests and code

Applied to files:

  • crates/biome_analyze/src/lib.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `warn` or `info` for rules in complexity group

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `error` for rules in correctness, security, and a11y groups

Applied to files:

  • crates/biome_analyze/src/profiling.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 : Use the `dbg_write!` macro to debug formatter output instead of other logging methods

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Implement the `FormattedIterExt` trait and `FormattedIter` struct in `lib.rs` to provide iterator extensions for formatting

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Define a type alias `<Language>Formatter<'buf>` as `Formatter<'buf, <Language>FormatContext>` in the main formatter crate

Applied to files:

  • crates/biome_analyze/src/profiling.rs
🧬 Code graph analysis (3)
crates/biome_cli/src/commands/check.rs (1)
crates/biome_analyze/src/profiling.rs (1)
  • enable (229-231)
crates/biome_cli/src/commands/lint.rs (2)
crates/biome_analyze/src/registry.rs (1)
  • profiling (425-425)
crates/biome_analyze/src/profiling.rs (1)
  • enable (229-231)
crates/biome_analyze/src/profiling.rs (2)
crates/biome_analyze/src/registry.rs (3)
  • RuleKey (447-447)
  • new (298-300)
  • new (382-461)
crates/biome_analyze/src/rule.rs (1)
  • label (1449-1456)
⏰ 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). (9)
  • GitHub Check: autofix
  • GitHub Check: Test Node.js API
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Documentation
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
🔇 Additional comments (7)
crates/biome_analyze/src/lib.rs (1)

16-16: LGTM!

Clean addition of the profiling module export.

.changeset/rare-queens-doubt.md (1)

1-5: LGTM!

Clear changeset documenting the new profiling feature.

crates/biome_analyze/src/profiling.rs (1)

1-479: Well-structured profiling implementation.

The overall design is sound:

  • RAII timer pattern prevents leaks
  • Thread-safe global aggregation via Mutex
  • Proper WASM stubbing
  • Clear separation of concerns

The global state approach is reasonable for a profiling feature, despite your noted uncertainty.

crates/biome_cli/src/commands/check.rs (1)

35-35: LGTM!

Clean integration of profiling flag. The placement before Execution::new() ensures profiling is active during traversal.

Also applies to: 159-161

crates/biome_cli/src/commands/lint.rs (1)

41-41: LGTM!

Consistent with the check command implementation.

Also applies to: 147-149

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

97-97: LGTM!

Correct wiring of profile_rules through the BiomeCommand variants to their respective payloads.

Also applies to: 118-118, 144-144, 170-170

crates/biome_cli/src/commands/mod.rs (1)

174-177: LGTM!

Good documentation clarifying that profiling captures rule execution time only, not preprocessing overhead. Consistent implementation across both commands.

Also applies to: 317-320

@dyc3 dyc3 force-pushed the dyc3/profile-rules branch from 13fb26e to 3f62930 Compare December 27, 2025 18:07
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

♻️ Duplicate comments (2)
crates/biome_analyze/src/profiling.rs (2)

132-139: Cast can truncate large counts.

This issue was previously flagged: casting self.count to u32 truncates if count exceeds u32::MAX. Consider saturating the cast as suggested in the earlier review.


473-473: Remove debug code.

This leftover debug statement will append "test" to every profiling output. Replace with Ok(()).

🔎 Proposed fix
-        write!(f, "test")
+        Ok(())
🧹 Nitpick comments (1)
crates/biome_analyze/src/profiling.rs (1)

346-471: Comprehensive formatting logic, well executed.

The top 10% cutoff calculation for conditional highlighting is correct: for each column, you sort descending and use the value at warn_count - 1 as the threshold. The header and row formatting with markup! properly integrates with the console formatting system.

The clone at line 347 is a minor inefficiency, but acceptable for end-of-run display.

📜 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 e4a390f and 3f62930.

⛔ Files ignored due to path filters (2)
  • crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (7)
  • crates/biome_analyze/src/profiling.rs
  • crates/biome_cli/src/commands/check.rs
  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_cli/src/reporter/summary.rs
  • crates/biome_cli/src/reporter/terminal.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/biome_cli/src/reporter/summary.rs
  • crates/biome_cli/src/lib.rs
  • crates/biome_cli/src/commands/mod.rs
  • crates/biome_cli/src/reporter/terminal.rs
  • crates/biome_cli/src/commands/check.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_analyze/src/profiling.rs
🧠 Learnings (28)
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should perform static analysis of source code to detect invalid or error-prone patterns and emit diagnostics with proposed fixes

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should check syntax according to language specification and emit error diagnostics

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `language` field in `declare_lint_rule!` macro to the language the rule primarily applies to

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-22T09:27:13.161Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:27:13.161Z
Learning: In crates/biome_analyze/**/*analyze/src/**/*.rs, the `fix_kind` field in `declare_lint_rule!` should only be specified when the rule implements the `action` function. Rules that only emit diagnostics without providing code fixes should not include `fix_kind` in their metadata.

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Add `deprecated` field to `declare_lint_rule!` macro when deprecating a rule

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Safe` in `declare_lint_rule!` for safe code actions

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Implement `action` function in Rule trait to provide code actions

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Unsafe` in `declare_lint_rule!` for unsafe code actions

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation code blocks should be ordered as language, expect_diagnostic, options/full_options/use_options, ignore, file

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `info` for code action rules in analyzer

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Lines prefixed with `#` in rule documentation code examples will be hidden from output

Applied to files:

  • crates/biome_cli/src/commands/lint.rs
  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set rule severity to `warn` for rules in performance group

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : The first paragraph of rule documentation must be a single line describing what the rule does

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Wrap rule options fields in `Option<>` to properly track set and unset options during merge

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `options` code block property for rule-specific configuration snippets in documentation

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use generic rule names if the rule could potentially be implemented for multiple languages

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Assist rules should detect refactoring opportunities and emit code action signals

Applied to files:

  • crates/biome_analyze/src/profiling.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 : Use the `dbg_write!` macro to debug formatter output instead of other logging methods

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Implement the `FormattedIterExt` trait and `FormattedIter` struct in `lib.rs` to provide iterator extensions for formatting

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Define a type alias `<Language>Formatter<'buf>` as `Formatter<'buf, <Language>FormatContext>` in the main formatter crate

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-21T21:15:03.796Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.796Z
Learning: Applies to **/*.rs : Use the `dbg!()` macro for debugging output in Rust tests and code

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Prefix line with `#` in documentation code examples sparingly; prefer concise complete snippets

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Each invalid code example in rule documentation must emit exactly one diagnostic

Applied to files:

  • crates/biome_analyze/src/profiling.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `let else` trick when `run` function returns `Vec` to reduce code branching

Applied to files:

  • crates/biome_analyze/src/profiling.rs
🧬 Code graph analysis (2)
crates/biome_cli/src/commands/lint.rs (2)
crates/biome_analyze/src/registry.rs (1)
  • profiling (425-425)
crates/biome_analyze/src/profiling.rs (1)
  • enable (229-231)
crates/biome_analyze/src/profiling.rs (1)
crates/biome_analyze/src/registry.rs (1)
  • RuleKey (447-447)
⏰ 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). (9)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: End-to-end tests
  • GitHub Check: autofix
  • GitHub Check: Test Node.js API
🔇 Additional comments (8)
crates/biome_analyze/src/profiling.rs (6)

1-29: Excellent module documentation.

The design notes and integration guidelines are clear and comprehensive. The explanation of when to start/stop timers and the note about near-zero overhead when disabled are particularly helpful.


45-120: Well-designed label type with efficient equality checks.

The pointer-equality optimisation for static strings followed by value comparison fallback is a nice touch. The manual Hash implementation correctly mirrors the PartialEq logic.


142-207: Solid metric aggregation logic.

The Metric default correctly initialises min to Duration::MAX, and into_profile appropriately handles the zero-count edge case. Using FxHashMap is a good choice for this use case.


209-241: Global state is appropriate for cross-thread profiling.

The Mutex<Option<RuleProfiler>> design with lazy initialisation is sound for aggregating metrics across threads. Using Relaxed ordering for the enable flag is fine since it doesn't guard any data. Silent failure on lock errors is acceptable for non-critical profiling infrastructure.


243-307: Excellent RAII timer design.

The timer correctly records elapsed time on drop, making it impossible to forget. Returning a no-op timer when disabled keeps the API ergonomic whilst maintaining near-zero overhead. The use of RuleKey::rule::<R>() to extract metadata looks correct.


309-340: Clean and straightforward API.

The public functions provide the right level of control: manual recording, snapshots, sorted draining with optional reset. All behave correctly when profiling is disabled.

crates/biome_cli/src/commands/lint.rs (2)

41-41: Field addition looks good.

The profile_rules flag follows the same pattern as other boolean flags in the payload.


147-149: Profiling integration is correct.

Enabling profiling before creating the Execution ensures timers are active during the traversal. Simple and effective.

@dyc3 dyc3 marked this pull request as draft December 28, 2025 02:18
@dyc3 dyc3 added this to the Biome v2.4 milestone Jan 19, 2026
@dyc3 dyc3 self-assigned this Jan 19, 2026
@dyc3 dyc3 force-pushed the dyc3/profile-rules branch from 3f62930 to d8f465e Compare January 21, 2026 19:25
@dyc3 dyc3 changed the base branch from main to next January 21, 2026 19:25
@dyc3 dyc3 marked this pull request as ready for review January 21, 2026 19:27
@dyc3 dyc3 requested review from a team January 21, 2026 19:28
@codspeed-hq
Copy link

codspeed-hq bot commented Jan 21, 2026

CodSpeed Performance Report

Merging this PR will not alter performance

Comparing dyc3/profile-rules (259f400) with next (39e7fd9)

Summary

✅ 58 untouched benchmarks
⏩ 96 skipped benchmarks1

Footnotes

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

The profilers seem good to me, however , the Display implementation is inconsistent (not idiomatic to our internals), and it creates many String that aren't needed. We should address that

@dyc3 dyc3 force-pushed the dyc3/profile-rules branch from d8f465e to 66ef286 Compare January 27, 2026 14:17
@dyc3 dyc3 requested a review from ematipico January 27, 2026 14:17
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.

It would be nice to have at least a snapshot test so we can catch possible regressions in the printing

@dyc3 dyc3 force-pushed the dyc3/profile-rules branch from 66ef286 to c2dd98a Compare January 27, 2026 19:23
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

🤖 Fix all issues with AI agents
In `@crates/biome_analyze/src/profiling.rs`:
- Around line 117-131: The current Hash implementation for RuleLabel (impl Hash
for RuleLabel -> fn hash) concatenates group and rule bytes without separation
causing collisions like ("ab","cd") vs ("abc","d"); fix by adding an unambiguous
separator or length prefix between fields for the Builtin { group, rule } arm
(e.g., write the group length before group bytes and/or write a distinct
delimiter byte between group and rule) while keeping the variant discriminator
and leaving Plugin(name) hashing as-is so all variants remain uniquely encoded.
🧹 Nitpick comments (2)
crates/biome_analyze/src/profiling.rs (2)

270-278: Instant::now() called even when disabled.

The comment explains the trade-off for struct simplicity. If you later find this matters in hot paths, wrapping start in Option<Instant> would avoid the syscall when disabled. Low priority given profiling is opt-in.


386-426: Repetitive cutoff computation.

The five nearly-identical blocks for totals_cutoff, avgs_cutoff, etc., could be extracted into a helper function. Not urgent since this is display code, but would improve maintainability.

♻️ Example helper
fn top_percentile_cutoff<T: Ord + Copy>(values: &mut [T], top_n: usize) -> Option<T> {
    if top_n == 0 || values.is_empty() {
        None
    } else {
        values.sort_by(|a, b| b.cmp(a));
        values.get(top_n - 1).copied()
    }
}

@dyc3 dyc3 force-pushed the dyc3/profile-rules branch from c2dd98a to 259f400 Compare January 27, 2026 19:32
@dyc3 dyc3 merged commit 361350e into next Jan 27, 2026
33 checks passed
@dyc3 dyc3 deleted the dyc3/profile-rules branch January 27, 2026 19:49
@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-CLI Area: CLI A-Linter Area: linter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants