Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@denbezrukov
Copy link
Contributor

Summary

Port astral-sh/ruff#7411

Test Plan

Green CI

Docs

@changeset-bot
Copy link

changeset-bot bot commented Nov 17, 2025

🦋 Changeset detected

Latest commit: 573c6cb

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

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

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-Formatter Area: formatter L-JavaScript Language: JavaScript and super languages L-HTML Language: HTML and super languages labels Nov 17, 2025
@codspeed-hq
Copy link

codspeed-hq bot commented Nov 17, 2025

CodSpeed Performance Report

Merging #8137 will not alter performance

Comparing dbezrukov/best-fitt (573c6cb) with main (3710702)

Summary

✅ 58 untouched
⏩ 95 skipped1

Footnotes

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 17, 2025

Walkthrough

The PR replaces the BestFittingElement representation with a new BestFittingVariants type across the formatter. It introduces StartBestFittingEntry / EndBestFittingEntry tags, changes builders to emit variants directly into a VecBuffer and call BestFittingVariants::from_vec_unchecked, increases an initial buffer capacity heuristic, and updates iteration helpers, printing logic, document transforms and tests to operate on the new container. Tag classification and printer flows were extended to recognise the new BestFitting entry tags; several modules and tests were adjusted accordingly.

Suggested reviewers

  • ematipico
  • dyc3
  • chansuke

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarises the main refactoring objective: reducing memory allocations in the best-fitting formatter logic.
Description check ✅ Passed The description relates to the changeset by referencing a ported upstream refactor and provides context about the test plan and expectations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dbezrukov/best-fitt

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/biome_js_formatter/src/js/expressions/call_arguments.rs (1)

472-542: Potentially swallowed errors when building the “most flat” variant

Here:

let result = write!(buffer, [ /* ... */ ]);

if matches!(result, Err(FormatError::PoorLayout)) {
    // fallback
    return f.write_elements(most_expanded_iter);
}

// then continue, ignoring `result` for any other error
buffer.write_element(FormatElement::Tag(Tag::EndBestFittingEntry))?;

Only FormatError::PoorLayout is handled specially; any other error (e.g. SyntaxError) is ignored rather than propagated. If write! can ever return a non‑PoorLayout error in this block, it will silently succeed here and continue with an invalid IR.

It would be safer to explicitly propagate non‑PoorLayout errors, e.g.:

match result {
    Ok(()) => { /* close entry and proceed */ }
    Err(FormatError::PoorLayout) => { /* current fallback logic */ }
    Err(e) => return Err(e),
}

Might be pre‑existing, but this spot is worth tightening while you’re touching the logic.

crates/biome_formatter/src/builders.rs (1)

1-8: BestFittingVariants is used without being imported

In BestFitting::fmt you call:

FormatElement::BestFitting(BestFittingVariants::from_vec_unchecked(buffer.into_vec()))

but this file doesn’t import BestFittingVariants, and it’s namespaced under crate::format_element. Given call_arguments.rs explicitly imports it via format_element::BestFittingVariants, this will fail to compile unless the type happens to be pulled in transitively via some other glob.

I’d suggest making the dependency explicit:

-use crate::{Argument, Arguments, GroupId, TextRange, TextSize, write};
+use crate::{Argument, Arguments, GroupId, TextRange, TextSize, write};
+use crate::format_element::BestFittingVariants;

or fully qualifying the call:

-FormatElement::BestFitting(BestFittingVariants::from_vec_unchecked(buffer.into_vec()))
+FormatElement::BestFitting(
+    crate::format_element::BestFittingVariants::from_vec_unchecked(buffer.into_vec()),
+)

Also applies to: 2671-2688

🧹 Nitpick comments (1)
crates/biome_html_formatter/tests/quick_test.rs (1)

16-21: Consider removing the commented-out test input.

Since the old test input has been replaced, the commented code could be removed to keep the test file tidy.

Apply this diff to remove the commented-out code:

-    //     let src = r#"
-    // <span>foo</span>
-    // <!-- biome-ignore format: reason -->
-    // foo bar baz boof
-    // quick brown fox
-    // "#;
     let src = r#"
📜 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 803a44a and 78491d5.

📒 Files selected for processing (8)
  • crates/biome_formatter/src/builders.rs (2 hunks)
  • crates/biome_formatter/src/format_element.rs (4 hunks)
  • crates/biome_formatter/src/format_element/document.rs (6 hunks)
  • crates/biome_formatter/src/format_element/tag.rs (4 hunks)
  • crates/biome_formatter/src/macros.rs (1 hunks)
  • crates/biome_formatter/src/printer/mod.rs (11 hunks)
  • crates/biome_html_formatter/tests/quick_test.rs (1 hunks)
  • crates/biome_js_formatter/src/js/expressions/call_arguments.rs (6 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: The biome_formatter printer deduplicates consecutive LineMode::Hard elements by checking if the current line is already empty (line_width > 0) before printing a newline. This prevents multiple consecutive hard line breaks from creating extra blank lines in the output.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/printer/mod.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: In biome_formatter, consecutive LineMode::Hard elements are automatically collapsed to a single newline by the printer. The printer has a test "it_prints_consecutive_hard_lines_as_one" that demonstrates this behavior - multiple consecutive hard line breaks result in only one newline in the output, not extra blank lines.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: In biome_formatter, the printer correctly handles consecutive LineMode::Hard elements without creating extra blank lines. Multiple consecutive FormatElement::Line(LineMode::Hard) elements in the formatting code do not result in duplicate blank lines in the output because the printer has logic to track line states and handle indentation properly.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/printer/mod.rs
🧬 Code graph analysis (4)
crates/biome_formatter/src/builders.rs (2)
crates/biome_formatter/src/buffer.rs (1)
  • with_capacity (189-194)
crates/biome_formatter/src/format_element.rs (1)
  • from_vec_unchecked (310-320)
crates/biome_formatter/src/format_element/document.rs (2)
crates/biome_html_formatter/src/html/lists/element_list.rs (2)
  • write (761-797)
  • write (907-921)
crates/biome_formatter/src/format_element.rs (1)
  • from_vec_unchecked (310-320)
crates/biome_formatter/src/printer/mod.rs (3)
crates/biome_formatter/src/format_element.rs (3)
  • next (388-406)
  • end_tag (280-285)
  • end_tag (459-459)
crates/biome_formatter/src/format_element/tag.rs (1)
  • kind (108-126)
crates/biome_formatter/src/format_element/document.rs (1)
  • end_tag (780-782)
crates/biome_js_formatter/src/js/expressions/call_arguments.rs (2)
crates/biome_formatter/src/builders.rs (5)
  • new (198-200)
  • new (2429-2436)
  • new (2498-2505)
  • new (2585-2593)
  • expand_parent (1856-1858)
crates/biome_formatter/src/format_element.rs (4)
  • new (129-131)
  • most_expanded (323-336)
  • most_flat (351-361)
  • from_vec_unchecked (310-320)
⏰ 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). (19)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-windows-2022-16)
  • 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: Test Node.js API
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_parser)
🔇 Additional comments (10)
crates/biome_html_formatter/tests/quick_test.rs (1)

22-30: LGTM! Test input aligned with best-fitting refactor.

The new test input cleverly exercises nested templates with varying line lengths—perfect for validating the best-fitting allocation changes.

crates/biome_formatter/src/macros.rs (1)

314-329: Doc link update matches new BestFittingVariants API

The MostExpanded reference now correctly points at BestFittingVariants::most_expanded; looks consistent with the refactor.

crates/biome_formatter/src/format_element/tag.rs (1)

77-80: Best‑fitting entry tags are wired correctly

StartBestFittingEntry/EndBestFittingEntry are correctly:

  • added to Tag,
  • treated as start tags in is_start, and
  • mapped to TagKind::BestFittingEntry in kind.

This keeps the tagging model coherent with the existing Fill/Entry tags.

Also applies to: 85-100, 111-125, 135-148

crates/biome_js_formatter/src/js/expressions/call_arguments.rs (3)

12-19: Best‑fitting variants import looks correct

Bringing format_element::BestFittingVariants in here is consistent with how you construct the BestFitting IR later; no issues.


396-487: Best‑fitting variants construction is structurally sound

  • Each of most_expanded and most_flat is wrapped with StartBestFittingEntry/EndBestFittingEntry, and you always build at least the expanded + one other variant, satisfying from_vec_unchecked’s invariant.
  • The PoorLayout fallback correctly restores the formatter state and re‑emits the expanded layout after stripping the best‑fitting entry tags.

All of that looks consistent with the new BestFittingVariants representation.


489-542: Unsafe BestFittingVariants::from_vec_unchecked usage is justified here

Given that:

  • variants is the concatenation of 2–3 vectors, each starting/ending with StartBestFittingEntry / EndBestFittingEntry, and
  • you always construct at least two variants (middle_variant + most_expanded, optionally most_flat),

the from_vec_unchecked call respects its documented preconditions.

crates/biome_formatter/src/builders.rs (1)

2671-2688: Best‑fitting builder now aligns with BestFittingVariants invariants

The revised BestFitting::fmt:

  • preallocates the buffer (with_capacity(variants.len() * 8)), which should reduce reallocations compared to the old pattern; and
  • wraps each variant in StartBestFittingEntry / EndBestFittingEntry before feeding the concatenated vector into BestFittingVariants::from_vec_unchecked.

Assuming the constructor’s variants.len() >= 2 assertion holds, the unsafe call is justified and the IR shape matches the new iterator logic.

crates/biome_formatter/src/format_element.rs (3)

7-13: New tag_kind convenience method is a nice small win

FormatElement::tag_kind() is a straightforward helper over Tag::kind(), and should simplify callers that only care about tag classification. No behavioural changes beyond that.

Also applies to: 197-241


322-362: most_expanded / most_flat implementations look correct

  • Both methods debug‑assert the “at least two StartBestFittingEntry tags” condition again, which nicely mirrors the constructor invariant.
  • They delegate to the forward/backward iterator to obtain first/last variants, which keeps the slicing logic centralised in BestFittingVariantsIter.

Given the builder always emits ≥2 variants, the .last().expect(...) / .next().unwrap() calls are safe under their stated preconditions.


338-344: Best‑fitting variants iterator behaves sensibly in both directions

BestFittingVariantsIter:

  • walks forward by taking slices from the first StartBestFittingEntry up to and including the matching EndBestFittingEntry, then advancing the remainder; and
  • walks backward by slicing from the last StartBestFittingEntry to the end.

That matches how the builder concatenates [Start, body, End] chunks, and the FusedIterator impl is appropriate once elements is empty. Looks good.

Also applies to: 364-383

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 17, 2025

Walkthrough

This change refactors the best-fitting element representation across the formatter codebase. The BestFittingElement type is replaced with BestFittingVariants, which now stores a boxed slice of FormatElement directly. Associated tags are updated from StartEntry/EndEntry to StartBestFittingEntry/EndBestFittingEntry. The buffering strategy in the builder is optimised to use capacity-based allocation. Iterator support and accessor methods (as_slice, most_expanded, most_flat) are added to the new type. Updates propagate across the printer, document handling, and JavaScript formatter modules.

Suggested reviewers

  • ematipico
  • dyc3
  • arendjr

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarises the main change: refactoring to reduce allocations in best-fitting formatter logic through structural optimisations.
Description check ✅ Passed The description references a specific upstream PR being ported and mentions the test plan, directly relating to the changeset's performance optimisation objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dbezrukov/best-fitt

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/biome_formatter/src/printer/mod.rs (1)

1176-1191: Fix matches! pattern for BestFitting in fits_element

slice.first() returns an Option<&FormatElement>, but the matches! currently uses a pattern without the reference:

if !matches!(
    slice.first(),
    Some(FormatElement::Tag(StartBestFittingEntry))
) {
    return invalid_start_tag(TagKind::BestFittingEntry, slice.first());
}

This should mirror the earlier pattern you use in print_best_fitting and explicitly match the reference, for both correctness and consistency.

Consider:

-                if !matches!(
-                    slice.first(),
-                    Some(FormatElement::Tag(StartBestFittingEntry))
-                ) {
+                if !matches!(
+                    slice.first(),
+                    Some(&FormatElement::Tag(Tag::StartBestFittingEntry))
+                ) {
                     return invalid_start_tag(TagKind::BestFittingEntry, slice.first());
                 }

Without this, you risk a type mismatch (or at best a very surprising pattern) when compiling.

♻️ Duplicate comments (1)
crates/biome_formatter/src/builders.rs (1)

4-5: BestFitting builder refactor looks sound; please de-mystify the * 8

The new BestFitting::fmt writes all variants into a single VecBuffer and wraps each one with StartBestFittingEntry/EndBestFittingEntry before feeding them to BestFittingVariants::from_vec_unchecked. That matches the invariants enforced in format_element.rs and should avoid the previous per-variant allocations.

One small nit: VecBuffer::with_capacity(variants.len() * 8, ..) introduces a magic 8. A brief comment explaining the heuristic (or a named constant) would make this easier to maintain and addresses the earlier review asking why 8 was chosen.

Also applies to: 2670-2688

🧹 Nitpick comments (2)
crates/biome_js_formatter/src/js/expressions/call_arguments.rs (1)

12-12: Best-fitting variants construction is consistent with the new Tag/BestFittingVariants model

The call-argument path now:

  • Wraps each variant (most_expanded, most_flat, middle_variant) in StartBestFittingEntry/EndBestFittingEntry tags.
  • Ensures the fallback on FormatError::PoorLayout correctly strips those tags and writes the expanded layout directly.
  • Builds the final variants Vec with at least two entries in all cases before calling BestFittingVariants::from_vec_unchecked, which matches the safety contract in crates/biome_formatter/src/format_element.rs.

Behaviourally this keeps the existing grouped-argument layout while aligning with the new IR representation. If you ever want to chase allocations further, you could consider building all three variants directly into a single VecBuffer rather than via three intermediate Vec<FormatElement>, but that’s firmly in the “later, maybe” bucket.

Also applies to: 396-547

crates/biome_formatter/src/format_element.rs (1)

288-361: BestFittingVariants invariants and docs

The BestFittingVariants wrapper plus the debug_assert! in from_vec_unchecked, most_expanded, and most_flat give a reasonable level of safety for an unsafe constructor.

One small nit: the safety comment still talks about “StartEntry/EndEntry” delimiters, but the code now checks StartBestFittingEntry. Might be worth aligning the docs with reality:

-    /// The slice must contain at least two variants (each delimited by StartEntry/EndEntry tags).
+    /// The slice must contain at least two variants (each delimited by
+    /// `StartBestFittingEntry`/`EndBestFittingEntry` tags).

The description of “least/most space horizontally” is also a bit contradictory; if you’re back in this file later, tightening that wording would save future readers a head‑scratch.

📜 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 803a44a and b3ac681.

📒 Files selected for processing (8)
  • crates/biome_formatter/src/builders.rs (2 hunks)
  • crates/biome_formatter/src/format_element.rs (4 hunks)
  • crates/biome_formatter/src/format_element/document.rs (6 hunks)
  • crates/biome_formatter/src/format_element/tag.rs (4 hunks)
  • crates/biome_formatter/src/macros.rs (1 hunks)
  • crates/biome_formatter/src/printer/mod.rs (11 hunks)
  • crates/biome_html_formatter/tests/quick_test.rs (1 hunks)
  • crates/biome_js_formatter/src/js/expressions/call_arguments.rs (6 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: The biome_formatter printer deduplicates consecutive LineMode::Hard elements by checking if the current line is already empty (line_width > 0) before printing a newline. This prevents multiple consecutive hard line breaks from creating extra blank lines in the output.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/printer/mod.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: In biome_formatter, consecutive LineMode::Hard elements are automatically collapsed to a single newline by the printer. The printer has a test "it_prints_consecutive_hard_lines_as_one" that demonstrates this behavior - multiple consecutive hard line breaks result in only one newline in the output, not extra blank lines.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: In biome_formatter, the printer correctly handles consecutive LineMode::Hard elements without creating extra blank lines. Multiple consecutive FormatElement::Line(LineMode::Hard) elements in the formatting code do not result in duplicate blank lines in the output because the printer has logic to track line states and handle indentation properly.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/printer/mod.rs
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_js_formatter/src/js/expressions/call_arguments.rs
  • crates/biome_formatter/src/format_element.rs
🧬 Code graph analysis (5)
crates/biome_formatter/src/format_element/document.rs (2)
crates/biome_html_formatter/src/html/lists/element_list.rs (2)
  • write (761-797)
  • write (907-921)
crates/biome_formatter/src/format_element.rs (1)
  • from_vec_unchecked (310-320)
crates/biome_formatter/src/printer/mod.rs (2)
crates/biome_formatter/src/format_element.rs (1)
  • next (388-406)
crates/biome_formatter/src/format_element/tag.rs (1)
  • kind (108-126)
crates/biome_js_formatter/src/js/expressions/call_arguments.rs (1)
crates/biome_formatter/src/format_element.rs (3)
  • most_expanded (323-336)
  • most_flat (351-361)
  • from_vec_unchecked (310-320)
crates/biome_formatter/src/builders.rs (2)
crates/biome_formatter/src/buffer.rs (1)
  • with_capacity (189-194)
crates/biome_formatter/src/format_element.rs (1)
  • from_vec_unchecked (310-320)
crates/biome_formatter/src/format_element.rs (2)
crates/biome_rowan/src/green/node.rs (6)
  • element (430-432)
  • count (357-362)
  • deref (232-238)
  • last (365-370)
  • next_back (392-394)
  • next_back (479-487)
crates/biome_formatter/src/format_element/tag.rs (1)
  • count (250-252)
⏰ 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). (6)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)
🔇 Additional comments (17)
crates/biome_formatter/src/macros.rs (1)

315-329: Doc link now matches the new BestFittingVariants API

The reference to MostExpanded now points at BestFittingVariants::most_expanded, which keeps the docs in sync with the refactor. No further changes needed here.

crates/biome_formatter/src/format_element/tag.rs (1)

77-80: Best-fitting entry tags and kind wiring look consistent

StartBestFittingEntry/EndBestFittingEntry are added symmetrically, Tag::is_start recognises the start tag, and Tag::kind maps both to TagKind::BestFittingEntry. That keeps the tag classification consistent for the printer and document machinery.

Also applies to: 84-101, 111-125, 133-148

crates/biome_html_formatter/tests/quick_test.rs (1)

22-31: Updated quick-test snippet is fine

Switching the sample to nested <template> elements is a sensible way to exercise the formatter; the raw string is well-formed and integrates cleanly with the existing test harness.

crates/biome_formatter/src/format_element/document.rs (5)

74-115: BestFitting expand propagation boundary looks sound

The new FormatElement::BestFitting arm correctly treats best‑fitting as a boundary while still recursing into its contents for side‑effects, without resetting expands. This matches the long comment scenario and should keep interned expansion propagation behaving as intended.


180-182: Nice in‑place transform for best‑fitting variants

Using best_fitting.as_slice_mut() here avoids extra allocations and keeps the structure intact while still letting the visitor rewrite nested elements.


366-375: IR display of BestFitting aligns with new variants iterator

Iterating best_fitting to emit each variant as a slice plus hard_line_break() is a clean fit with the new iterator API; with the printer’s de‑duping of consecutive hard lines, this shouldn’t introduce spurious blank lines.


582-586: Tag handling for BestFittingEntry integrated cleanly

Treating StartBestFittingEntry/EndBestFittingEntry the same as normal entries in the IR printer keeps the structure consistent and ensures best‑fitting variants round‑trip nicely in diagnostics.


871-921: Good regression test for interned + best‑fitting expand propagation

The new interned_best_fitting_allows_sibling_expand_propagation test exercises exactly the subtle interned/best‑fitting interaction described in the comment above and should guard against future regressions in propagate_expand().

crates/biome_formatter/src/printer/mod.rs (6)

153-155: Delegating BestFitting printing via print_best_fitting

Routing FormatElement::BestFitting through print_best_fitting keeps the main dispatch lean and centralises the variant‑selection logic in one place.


267-280: Stack handling extended for BestFittingEntry tags

Adding StartBestFittingEntry/EndBestFittingEntry into the general tag stack handling aligns them with other container‑like tags, which should keep stack invariants intact during both printing and measuring.


441-509: print_best_fitting logic matches the variant ordering

The new print_best_fitting:

  • Uses most_flat() when the group is already known to fit, favouring the flattest variant in flat mode.
  • Otherwise walks variants from flat to expanded, re‑measuring each in PrintMode::Flat and falling back to the last (most expanded) variant when none fit.
  • Wraps each chosen variant in a BestFittingEntry frame via print_entry, so tag stack state is consistent.

This mirrors the intended “try flattest first, then expand” behaviour and looks correct.


668-688: print_fill_item / print_fill_separator refactor looks good

Passing TagKind::Entry explicitly into print_entry is a neat generalisation and keeps the fill‑specific helpers as thin aliases.


695-744: Generalised print_entry correctly supports Entry and BestFittingEntry

Allowing both StartEntry and StartBestFittingEntry at the front, and matching against corresponding end tags while tracking depth, preserves the original semantics and lets you reuse the same machinery for best‑fitting entries. The separation between kind (for error reporting) and end_tag.kind() (for stack popping) also keeps diagnostics accurate.


2033-2133: Excellent targeted tests for interned entries and best‑fitting variants

The three new tests nicely exercise:

  • Interned content containing StartEntry tags inside a Fill.
  • Long interned entries forcing line breaks.
  • A best‑fitting variant wrapping a Fill that in turn uses interned entries.

That’s exactly the sort of evil input that tends to break printers, so it’s good to have these locked in.

crates/biome_formatter/src/format_element.rs (3)

60-63: Switch to BestFittingVariants looks tidy

Wiring FormatElement::BestFitting to the new BestFittingVariants container and delegating Debug to it keeps the enum lean and avoids an extra layer of boxing.

Also applies to: 80-82


234-240: Handy tag_kind helper

FormatElement::tag_kind() is a small but useful helper that avoids repeated if let Tag(..) patterns at call sites; good call adding this.


372-429: Iterator over best‑fitting variants is well‑structured

BestFittingVariantsIter correctly:

  • Yields each variant as a &[FormatElement] bounded by a single start/end pair.
  • Supports DoubleEndedIterator by scanning from the back for the last start tag.
  • Implements FusedIterator as expected.

That plays nicely with the uses in Document and the printer.

@ematipico
Copy link
Member

Feel free to merge it once the CI is fixed

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_analyze/src/diagnostics.rs (1)

35-41: Public visibility of DiagnosticKind – confirm intended API surface

Making DiagnosticKind pub exposes it as part of the crate’s public API, which seems fine if external callers need to distinguish rule vs raw diagnostics. If this is only for internal wiring between modules, you might prefer pub(crate) instead to keep the surface smaller; and if you expect to add variants later, consider marking it #[non_exhaustive] to avoid future breaking changes.

For example:

-#[derive(Debug)]
-pub enum DiagnosticKind {
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum DiagnosticKind {

Purely an API-shape consideration, nothing blocking 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 43cb143 and 4f2ad6c.

⛔ Files ignored due to path filters (1)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
📒 Files selected for processing (7)
  • .changeset/blue-teeth-obey.md (1 hunks)
  • crates/biome_analyze/src/diagnostics.rs (2 hunks)
  • crates/biome_configuration/src/analyzer/assist/actions.rs (1 hunks)
  • crates/biome_formatter/src/format_element.rs (4 hunks)
  • crates/biome_formatter/src/format_element/tag.rs (4 hunks)
  • crates/biome_html_syntax/src/script_type.rs (1 hunks)
  • xtask/codegen/src/generate_configuration.rs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • crates/biome_html_syntax/src/script_type.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/biome_formatter/src/format_element/tag.rs
  • crates/biome_formatter/src/format_element.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • xtask/codegen/src/generate_configuration.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_analyze/src/diagnostics.rs
.changeset/**/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/**/*.md: Create changesets for user-facing changes using just new-changeset; use headers with #### or ##### only; keep descriptions concise (1-3 sentences) and focus on user-facing changes
Use past tense when describing what was done ('Added new feature'), present tense when describing Biome behavior ('Biome now supports'); end sentences with a full stop
For new lint rules, show an example of an invalid case in an inline code snippet or code block; for rule changes, demonstrate what is now invalid or valid; for formatter changes, use a diff code block

Files:

  • .changeset/blue-teeth-obey.md
🧠 Learnings (25)
📓 Common learnings
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.
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: The formatter foundation relies on using the generic `Format` trait and `FormatNode` for nodes, with creation of an intermediate IR via a series of helpers
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Document rules with a one-line brief description in the first paragraph of the doc comment, followed by detailed paragraphs, `## Examples` section with `### Invalid` and `### Valid` subsections, and optional `## Options` section

Applied to files:

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

Applied to files:

  • xtask/codegen/src/generate_configuration.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-11-28T09:08:10.091Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.091Z
Learning: Applies to .changeset/**/*.md : For new lint rules, show an example of an invalid case in an inline code snippet or code block; for rule changes, demonstrate what is now invalid or valid; for formatter changes, use a `diff` code block

Applied to files:

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

Applied to files:

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

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.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/context.rs : Define `<Language>FormatContext` struct in a `context.rs` file containing `comments` and `source_map` fields, implementing `FormatContext` and `CstFormatContext` traits

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Use `Box<[T]>` instead of `Vec<T>` for rule options array fields to save memory (boxed slices and boxed str use 2 words instead of three words)

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.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_configuration/src/analyzer/assist/actions.rs
  • crates/biome_analyze/src/diagnostics.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Code actions must specify a `fix_kind` field in the `declare_lint_rule!` macro as either `FixKind::Safe` or `FixKind::Unsafe` to indicate whether fixes always preserve program behavior

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_analyze/src/diagnostics.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUndeclared` prefix for rules that report undefined entities (e.g., `noUndeclaredVariables`)

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Avoid unnecessary string allocations by comparing against `&str` or `TokenText` instead of calling `to_string()` which allocates heap memory

Applied to files:

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

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-11-28T09:08:10.091Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.091Z
Learning: Applies to .changeset/**/*.md : Create changesets for user-facing changes using `just new-changeset`; use headers with `####` or `#####` only; keep descriptions concise (1-3 sentences) and focus on user-facing changes

Applied to files:

  • .changeset/blue-teeth-obey.md
📚 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/blue-teeth-obey.md
📚 Learning: 2025-11-28T09:08:10.091Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.091Z
Learning: Applies to .changeset/**/*.md : Use past tense when describing what was done ('Added new feature'), present tense when describing Biome behavior ('Biome now supports'); end sentences with a full stop

Applied to files:

  • .changeset/blue-teeth-obey.md
📚 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: Use the `just gen-formatter` command to generate initial formatter implementations from the grammar, which will use `format_verbatim_node` that must be replaced with proper `biome_formatter` utilities

Applied to files:

  • .changeset/blue-teeth-obey.md
📚 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_analyze/src/diagnostics.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_analyze/src/diagnostics.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_analyze/src/diagnostics.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : The `diagnostic` function must return a `RuleDiagnostic` that defines the message reported to the user using the `markup!` macro

Applied to files:

  • crates/biome_analyze/src/diagnostics.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use `rule_category!()` macro instead of dynamic string parsing to refer to rule diagnostic categories for compile-time validation

Applied to files:

  • crates/biome_analyze/src/diagnostics.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_analyze/src/diagnostics.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_analyze/src/diagnostics.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : In rule documentation code blocks, mark invalid examples with the `expect_diagnostic` property and valid examples without it; each invalid example must emit exactly one diagnostic

Applied to files:

  • crates/biome_analyze/src/diagnostics.rs
🧬 Code graph analysis (1)
xtask/codegen/src/generate_configuration.rs (6)
crates/biome_service/src/file_handlers/html.rs (1)
  • format (649-664)
crates/biome_service/src/file_handlers/grit.rs (1)
  • format (336-351)
crates/biome_service/src/file_handlers/css.rs (1)
  • format (472-487)
crates/biome_service/src/file_handlers/graphql.rs (1)
  • format (363-378)
crates/biome_service/src/file_handlers/json.rs (1)
  • format (424-439)
crates/biome_service/src/file_handlers/javascript.rs (1)
  • format (937-954)
🔇 Additional comments (4)
.changeset/blue-teeth-obey.md (1)

1-5: Changeset looks good.

The entry is properly formatted, uses the correct tense (past), includes the full stop, and clearly communicates the user-facing benefit. Nice and straightforward.

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

184-206: LGTM! Documentation formatting improved.

The angle brackets around URLs ensure proper link rendering in rustdoc. Since this is a generated file, the improvements were correctly applied via the code generator.

xtask/codegen/src/generate_configuration.rs (1)

854-907: URL angle‑bracket wrapping in summaries looks good

Wrapping the rule docs URL in <…> in the generated summary ("{}.\nSee <{}>" / "See <{}>") is correct here and plays nicely with Markdown autolinks and the existing trim_end_matches('.') logic. No functional concerns from this change on the codegen side.

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

137-139: Doc comment matches the actual behaviour

The updated doc comment correctly describes that the offset is only applied when the kind is DiagnosticKind::Rule; it’s consistent with the implementation and improves clarity. Nothing to change here.

@ematipico ematipico force-pushed the dbezrukov/best-fitt branch from 4f2ad6c to 5ea4de4 Compare December 5, 2025 14:47
@github-actions
Copy link
Contributor

github-actions bot commented Dec 5, 2025

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 52552 52552 0
Passed 51339 51339 0
Failed 1171 1171 0
Panics 42 42 0
Coverage 97.69% 97.69% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 38 38 0
Passed 37 37 0
Failed 1 1 0
Panics 0 0 0
Coverage 97.37% 97.37% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 6327 6327 0
Passed 2108 2108 0
Failed 4219 4219 0
Panics 0 0 0
Coverage 33.32% 33.32% 0.00%

ts/babel

Test result main count This PR count Difference
Total 626 626 0
Passed 561 561 0
Failed 65 65 0
Panics 0 0 0
Coverage 89.62% 89.62% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 18827 18827 0
Passed 14073 14073 0
Failed 4753 4753 0
Panics 1 1 0
Coverage 74.75% 74.75% 0.00%

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 (1)
crates/biome_formatter/src/format_element.rs (1)

300-321: Safety docs still reference the old entry tag names

The from_vec_unchecked safety comment still talks about variants “delimited by StartEntry/EndEntry tags”, but the code and debug assertion now rely on StartBestFittingEntry/EndBestFittingEntry. It’d be good to update that sentence to name the current tags (or TagKind::BestFittingEntry) so the documented invariant matches the actual one.

🧹 Nitpick comments (2)
crates/biome_formatter/src/printer/mod.rs (2)

668-744: Generalised print_entry plus tests cover tricky interned/entry cases

Parameterising print_entry with a TagKind and allowing both StartEntry and StartBestFittingEntry gives you a single, well‑tested implementation for fills and best‑fitting variants. The new tests around interned vectors containing entry tags and best‑fitting variants that wrap fills are exactly the sort of edge cases that tend to break this kind of stack/queue machinery, so it’s good to see them exercised.

Also applies to: 2033-2134


1176-1191: Minor consistency nit in BestFitting fits invariant check

For the invariant check in fits_element’s BestFitting arm, you might want to mirror the pattern style you used in print_best_fitting (matching on Some(&FormatElement::Tag(Tag::StartBestFittingEntry))). That keeps the guard symmetrical between the print and fits paths and makes it clearer they’re enforcing the same structural constraint.

📜 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 4f2ad6c and 5ea4de4.

⛔ Files ignored due to path filters (1)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
📒 Files selected for processing (10)
  • .changeset/blue-teeth-obey.md (1 hunks)
  • crates/biome_analyze/src/diagnostics.rs (2 hunks)
  • crates/biome_configuration/src/analyzer/assist/actions.rs (1 hunks)
  • crates/biome_formatter/src/builders.rs (2 hunks)
  • crates/biome_formatter/src/format_element.rs (4 hunks)
  • crates/biome_formatter/src/format_element/document.rs (6 hunks)
  • crates/biome_formatter/src/format_element/tag.rs (4 hunks)
  • crates/biome_formatter/src/macros.rs (1 hunks)
  • crates/biome_formatter/src/printer/mod.rs (11 hunks)
  • crates/biome_html_formatter/tests/quick_test.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/biome_formatter/src/format_element/tag.rs
  • crates/biome_analyze/src/diagnostics.rs
  • .changeset/blue-teeth-obey.md
  • crates/biome_html_formatter/tests/quick_test.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/biome_formatter/src/macros.rs
  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/builders.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_formatter/src/format_element.rs
  • crates/biome_formatter/src/printer/mod.rs
🧠 Learnings (41)
📓 Common learnings
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.
Learnt from: arendjr
Repo: biomejs/biome PR: 7593
File: crates/biome_service/src/workspace/server.rs:1306-1306
Timestamp: 2025-09-25T12:32:59.003Z
Learning: In the biomejs/biome project, do not flag compilation errors during code review as they are handled by the existing test infrastructure and CI. Focus on other code quality aspects instead.
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: The formatter foundation relies on using the generic `Format` trait and `FormatNode` for nodes, with creation of an intermediate IR via a series of helpers
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Document rules with a one-line brief description in the first paragraph of the doc comment, followed by detailed paragraphs, `## Examples` section with `### Invalid` and `### Valid` subsections, and optional `## Options` section

Applied to files:

  • crates/biome_formatter/src/macros.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_formatter/src/format_element.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/Cargo.toml : Include development dependencies in `Cargo.toml` for formatter tests: `biome_formatter_test`, `biome_<language>_factory`, `biome_<language>_parser`, `biome_parser`, `biome_service`, `countme`, `iai`, `quickcheck`, `quickcheck_macros`, and `tests_macros`

Applied to files:

  • crates/biome_formatter/src/macros.rs
  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/builders.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/context.rs : Define `<Language>FormatContext` struct in a `context.rs` file containing `comments` and `source_map` fields, implementing `FormatContext` and `CstFormatContext` traits

Applied to files:

  • crates/biome_formatter/src/macros.rs
  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/builders.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_formatter/src/format_element.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 : Expose a public `format_node` function that accepts formatting options and a root syntax node, returning a `FormatResult<Formatted<Context>>` with appropriate documentation

Applied to files:

  • crates/biome_formatter/src/macros.rs
  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
  • crates/biome_formatter/src/printer/mod.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 : Use `TypeReference` instead of `Arc` for types that reference other types to avoid stale cache issues when modules are replaced

Applied to files:

  • crates/biome_formatter/src/macros.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_formatter/src/format_element.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/tests/spec_tests.rs : Use the `tests_macros::gen_tests!` macro in `spec_tests.rs` to generate test functions for each specification file matching the pattern `tests/specs/<language>/**/*.<ext>`

Applied to files:

  • crates/biome_formatter/src/macros.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 : Import the `FormatNode` trait and implement it for your Node when creating formatters in biome_js_formatter

Applied to files:

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

Applied to files:

  • crates/biome_formatter/src/macros.rs
  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.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 : Do not attempt to 'fix' the code; if a token/node is known to be mandatory but is missing, return `None` instead

Applied to files:

  • crates/biome_formatter/src/macros.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/tests/language.rs : Implement `TestFormatLanguage` trait in `tests/language.rs` for the formatter's test language

Applied to files:

  • crates/biome_formatter/src/macros.rs
  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/printer/mod.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: The biome_formatter printer deduplicates consecutive LineMode::Hard elements by checking if the current line is already empty (line_width > 0) before printing a newline. This prevents multiple consecutive hard line breaks from creating extra blank lines in the output.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/printer/mod.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: In biome_formatter, consecutive LineMode::Hard elements are automatically collapsed to a single newline by the printer. The printer has a test "it_prints_consecutive_hard_lines_as_one" that demonstrates this behavior - multiple consecutive hard line breaks result in only one newline in the output, not extra blank lines.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: In biome_formatter, the printer correctly handles consecutive LineMode::Hard elements without creating extra blank lines. Multiple consecutive FormatElement::Line(LineMode::Hard) elements in the formatting code do not result in duplicate blank lines in the output because the printer has logic to track line states and handle indentation properly.

Applied to files:

  • crates/biome_formatter/src/format_element/document.rs
  • crates/biome_formatter/src/printer/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 : 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_formatter/src/format_element/document.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_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.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_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.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: Define `FormatHtmlSyntaxNode` struct in a `cst.rs` file implementing `FormatRule<HtmlSyntaxNode>`, `AsFormat<HtmlFormatContext>`, and `IntoFormat<HtmlFormatContext>` traits using the provided boilerplate code

Applied to files:

  • crates/biome_formatter/src/builders.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 `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported

Applied to files:

  • crates/biome_formatter/src/builders.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_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For tokens that are not mandatory, use helper functions instead of hardcoding

Applied to files:

  • crates/biome_formatter/src/builders.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: The formatter foundation relies on using the generic `Format` trait and `FormatNode` for nodes, with creation of an intermediate IR via a series of helpers

Applied to files:

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

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • crates/biome_formatter/src/format_element.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 `AsFormat<Context>` trait in `lib.rs` with generic implementations for references, `SyntaxResult`, and `Option` types as provided in the formatter boilerplate code

Applied to files:

  • crates/biome_formatter/src/builders.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 `IntoFormat<Context>` trait in `lib.rs` with implementations for `SyntaxResult` and `Option` types as part of the formatter infrastructure

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/printer/mod.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_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
  • crates/biome_formatter/src/printer/mod.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 `FormatLanguage` trait with `SyntaxLanguage`, `Context`, and `FormatRule` associated types for the language's formatter

Applied to files:

  • crates/biome_formatter/src/builders.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 `FormatNodeRule<N>` trait with `fmt_fields` as the only required method; default implementations of `fmt`, `is_suppressed`, `fmt_leading_comments`, `fmt_dangling_comments`, and `fmt_trailing_comments` are provided

Applied to files:

  • crates/biome_formatter/src/builders.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : For rules ported from other ecosystems like ESLint or Clippy, add a `sources` field with `RuleSource` metadata using `.same()` for identical behavior or `.inspired()` for different behavior

Applied to files:

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

Applied to files:

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

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.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 : Implement a token source struct that wraps the lexer and implements `TokenSourceWithBufferedLexer` and `LexerWithCheckpoint` for lookahead and re-lexing capabilities

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Avoid using `unwrap()` or `expect()` on `Result` and `Option` types; instead use helper functions like `map`, `filter`, `and_then` to maintain code clarity and avoid panics

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Code actions must specify a `fix_kind` field in the `declare_lint_rule!` macro as either `FixKind::Safe` or `FixKind::Unsafe` to indicate whether fixes always preserve program behavior

Applied to files:

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

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/actions.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Use `Box<[T]>` instead of `Vec<T>` for rule options array fields to save memory (boxed slices and boxed str use 2 words instead of three words)

Applied to files:

  • crates/biome_formatter/src/format_element.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/**/language_kind.rs : Add a new variant to `LanguageKind` enum in `language_kind.rs` file and implement all methods for the new language variant

Applied to files:

  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-11-28T09:08:10.091Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.091Z
Learning: Applies to **/*.rs : Use the `dbg!()` macro for debugging output during testing, and pass the `--show-output` flag to `cargo` to view debug output

Applied to files:

  • crates/biome_formatter/src/format_element.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_formatter/src/format_element.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 : Store type data in linear vectors instead of using recursive data structures with `Arc` for improved data locality and performance

Applied to files:

  • crates/biome_formatter/src/format_element.rs
🧬 Code graph analysis (3)
crates/biome_formatter/src/builders.rs (2)
crates/biome_formatter/src/buffer.rs (1)
  • with_capacity (189-194)
crates/biome_formatter/src/format_element.rs (1)
  • from_vec_unchecked (310-320)
crates/biome_formatter/src/format_element.rs (2)
crates/biome_formatter/src/format_element/tag.rs (1)
  • count (250-252)
crates/biome_html_formatter/src/context.rs (1)
  • deref (386-388)
crates/biome_formatter/src/printer/mod.rs (2)
crates/biome_formatter/src/format_element.rs (3)
  • next (388-406)
  • end_tag (280-285)
  • end_tag (459-459)
crates/biome_formatter/src/format_element/tag.rs (1)
  • kind (108-126)
⏰ 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). (23)
  • GitHub Check: Documentation
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: End-to-end tests
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Validate rules documentation
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: autofix
  • GitHub Check: Parser conformance
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_json_analyze)
🔇 Additional comments (6)
crates/biome_configuration/src/analyzer/assist/actions.rs (1)

184-206: Generated file with doc formatting improvements—looks good.

The URL formatting in angle brackets follows Rust documentation conventions. Since this is a generated file (line 1), ensure the changes originate from the codegen tool (xtask/codegen) rather than manual edits to avoid them being overwritten.

crates/biome_formatter/src/macros.rs (1)

314-329: Doc link now matches the refactored API

The reference to MostExpanded correctly points to BestFittingVariants::most_expanded, in line with the new representation. Nothing else to change here.

crates/biome_formatter/src/builders.rs (1)

4-6: Best‑fitting builder wiring looks sound

The new BestFitting::fmt path cleanly wraps each variant between StartBestFittingEntry/EndBestFittingEntry and feeds a single VecBuffer into BestFittingVariants::from_vec_unchecked. Together with the from_arguments_unchecked length check, this preserves the “≥ 2 variants” invariant, and the * 3 capacity plus comment is a reasonable heuristic.

Also applies to: 2670-2689

crates/biome_formatter/src/format_element/document.rs (1)

49-78: Best‑fitting integration in Document preserves semantics

The switch to walking BestFittingVariants as a flat slice in propagate_expand/transform_elements, plus the IR display that iterates variants and treats StartBestFittingEntry/EndBestFittingEntry like normal entries, all line up nicely with the new representation. The interned_best_fitting_allows_sibling_expand_propagation test is a good guard that the expand boundary + interned caching behaviour hasn’t regressed.

Also applies to: 170-190, 366-383, 870-921

crates/biome_formatter/src/printer/mod.rs (1)

153-156: Best‑fitting printing path looks consistent with the new representation

The BestFittingVariants‑based logic in print_element, print_best_fitting, and fits_element keeps the previous behaviour: flat mode prefers the most‑flat variant, expanded mode falls back to the most‑expanded, and the BestFittingEntry stack frames ensure tag‑pair validation stays precise. The invariant checks on the leading StartBestFittingEntry tags are a useful sanity net for malformed IR.

Also applies to: 441-509, 1076-1191

crates/biome_formatter/src/format_element.rs (1)

12-13: Best‑fitting variants container and iterator are well‑structured

Moving to BestFittingVariants(Box<[FormatElement]>) with the iterator that slices out each StartBestFittingEntryEndBestFittingEntry segment gives you a compact, cache‑friendly representation and a clean API (most_flat, most_expanded, IntoIterator, as_slice[_mut]). The extra tag_kind helper on FormatElement rounds out the tagging story without affecting the enum’s layout constraints.

Also applies to: 60-66, 234-241, 288-361, 364-429

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 (1)
crates/biome_formatter/src/format_element.rs (1)

288-321: BestFittingVariants design looks good, but the safety docs are slightly stale

The flattened BestFittingVariants + iterator combo is neat: debug‑asserting on at least two StartBestFittingEntry tags and then exposing most_flat/most_expanded through the iterator keeps the invariants local and the API ergonomic. Two tiny nits while you’re here:

  • The safety comment on from_vec_unchecked still says “delimited by StartEntry/EndEntry tags”; that should now reference StartBestFittingEntry/EndBestFittingEntry (or TagKind::BestFittingEntry) to match the debug_assert and builder logic.
  • The panic message in most_expanded says “Most contain at least two elements”; that wants to be “Must contain…”.

Behaviour‑wise this all lines up with the new builder and printer paths.

Also applies to: 323-361, 364-429

🧹 Nitpick comments (2)
crates/biome_formatter/src/builders.rs (1)

4-4: BestFitting buffer construction and tagging look solid

Writing variants directly into a VecBuffer with variants.len() * 3 capacity and wrapping each in StartBestFittingEntry/EndBestFittingEntry lines up nicely with the new BestFittingVariants invariants; the unsafe call is justified by from_arguments_unchecked’s length check. If you ever touch this again, a tiny note like “2 tags + 1 content element” would de‑mystify the * 3 for future readers, but it’s perfectly fine as is.

Also applies to: 2671-2689

crates/biome_formatter/src/printer/mod.rs (1)

668-688: Generalised print_entry cleanly supports both Fill entries and BestFitting entries

Passing a TagKind into print_entry and teaching it to recognise both StartEntry/EndEntry and StartBestFittingEntry/EndBestFittingEntry gives you a single, well‑tested path for “print this entry and all its descendants”. The depth counter plus only pushing the provided kind at depth 0 keeps nested entries behaving correctly, and the symmetric fits logic now uses the same tag kinds, which should avoid the sort of subtle mismatches that are painful to debug later.

Also applies to: 694-744, 1274-1295

📜 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 4f2ad6c and 573c6cb.

⛔ Files ignored due to path filters (1)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
📒 Files selected for processing (10)
  • .changeset/blue-teeth-obey.md (1 hunks)
  • crates/biome_analyze/src/diagnostics.rs (2 hunks)
  • crates/biome_configuration/src/analyzer/assist/actions.rs (1 hunks)
  • crates/biome_formatter/src/builders.rs (2 hunks)
  • crates/biome_formatter/src/format_element.rs (4 hunks)
  • crates/biome_formatter/src/format_element/document.rs (6 hunks)
  • crates/biome_formatter/src/format_element/tag.rs (4 hunks)
  • crates/biome_formatter/src/macros.rs (1 hunks)
  • crates/biome_formatter/src/printer/mod.rs (11 hunks)
  • crates/biome_html_formatter/tests/quick_test.rs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • crates/biome_formatter/src/macros.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/biome_analyze/src/diagnostics.rs
  • crates/biome_configuration/src/analyzer/assist/actions.rs
  • .changeset/blue-teeth-obey.md
  • crates/biome_formatter/src/format_element/tag.rs
  • crates/biome_html_formatter/tests/quick_test.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
  • crates/biome_formatter/src/printer/mod.rs
  • crates/biome_formatter/src/format_element/document.rs
🧠 Learnings (33)
📓 Common learnings
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.
📚 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 : Import the `FormatNode` trait and implement it for your Node when creating formatters in biome_js_formatter

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
  • crates/biome_formatter/src/printer/mod.rs
  • crates/biome_formatter/src/format_element/document.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/context.rs : Define `<Language>FormatContext` struct in a `context.rs` file containing `comments` and `source_map` fields, implementing `FormatContext` and `CstFormatContext` traits

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
  • crates/biome_formatter/src/format_element/document.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_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When formatting AST nodes, use mandatory tokens from the AST instead of hardcoding token strings (e.g., use `node.l_paren_token().format()` instead of `token("(")`)

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
  • crates/biome_formatter/src/format_element/document.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 : Expose a public `format_node` function that accepts formatting options and a root syntax node, returning a `FormatResult<Formatted<Context>>` with appropriate documentation

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
  • crates/biome_formatter/src/printer/mod.rs
  • crates/biome_formatter/src/format_element/document.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Use `Box<[T]>` instead of `Vec<T>` for rule options array fields to save memory (boxed slices and boxed str use 2 words instead of three words)

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.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/Cargo.toml : Include development dependencies in `Cargo.toml` for formatter tests: `biome_formatter_test`, `biome_<language>_factory`, `biome_<language>_parser`, `biome_parser`, `biome_service`, `countme`, `iai`, `quickcheck`, `quickcheck_macros`, and `tests_macros`

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element/document.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_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.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/tests/language.rs : Implement `TestFormatLanguage` trait in `tests/language.rs` for the formatter's test language

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/printer/mod.rs
  • crates/biome_formatter/src/format_element/document.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 : Store type data in linear vectors instead of using recursive data structures with `Arc` for improved data locality and performance

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.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: Define `FormatHtmlSyntaxNode` struct in a `cst.rs` file implementing `FormatRule<HtmlSyntaxNode>`, `AsFormat<HtmlFormatContext>`, and `IntoFormat<HtmlFormatContext>` traits using the provided boilerplate code

Applied to files:

  • crates/biome_formatter/src/builders.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 `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported

Applied to files:

  • crates/biome_formatter/src/builders.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_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For tokens that are not mandatory, use helper functions instead of hardcoding

Applied to files:

  • crates/biome_formatter/src/builders.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: The formatter foundation relies on using the generic `Format` trait and `FormatNode` for nodes, with creation of an intermediate IR via a series of helpers

Applied to files:

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

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/format_element.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 `AsFormat<Context>` trait in `lib.rs` with generic implementations for references, `SyntaxResult`, and `Option` types as provided in the formatter boilerplate code

Applied to files:

  • crates/biome_formatter/src/builders.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 `IntoFormat<Context>` trait in `lib.rs` with implementations for `SyntaxResult` and `Option` types as part of the formatter infrastructure

Applied to files:

  • crates/biome_formatter/src/builders.rs
  • crates/biome_formatter/src/printer/mod.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_formatter/src/builders.rs
  • crates/biome_formatter/src/printer/mod.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 `FormatLanguage` trait with `SyntaxLanguage`, `Context`, and `FormatRule` associated types for the language's formatter

Applied to files:

  • crates/biome_formatter/src/builders.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 `FormatNodeRule<N>` trait with `fmt_fields` as the only required method; default implementations of `fmt`, `is_suppressed`, `fmt_leading_comments`, `fmt_dangling_comments`, and `fmt_trailing_comments` are provided

Applied to files:

  • crates/biome_formatter/src/builders.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/**/language_kind.rs : Add a new variant to `LanguageKind` enum in `language_kind.rs` file and implement all methods for the new language variant

Applied to files:

  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_formatter/src/format_element.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/**/flattening.rs : Implement type flattening to simplify `TypeofExpression` variants once all component types are resolved

Applied to files:

  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-11-28T09:08:10.091Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.091Z
Learning: Applies to **/*.rs : Use the `dbg!()` macro for debugging output during testing, and pass the `--show-output` flag to `cargo` to view debug output

Applied to files:

  • crates/biome_formatter/src/format_element.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_formatter/src/format_element.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Document rules with a one-line brief description in the first paragraph of the doc comment, followed by detailed paragraphs, `## Examples` section with `### Invalid` and `### Valid` subsections, and optional `## Options` section

Applied to files:

  • crates/biome_formatter/src/format_element.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 : Use `TypeReference` instead of `Arc` for types that reference other types to avoid stale cache issues when modules are replaced

Applied to files:

  • crates/biome_formatter/src/format_element.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: In biome_formatter, the printer correctly handles consecutive LineMode::Hard elements without creating extra blank lines. Multiple consecutive FormatElement::Line(LineMode::Hard) elements in the formatting code do not result in duplicate blank lines in the output because the printer has logic to track line states and handle indentation properly.

Applied to files:

  • crates/biome_formatter/src/printer/mod.rs
  • crates/biome_formatter/src/format_element/document.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: The biome_formatter printer deduplicates consecutive LineMode::Hard elements by checking if the current line is already empty (line_width > 0) before printing a newline. This prevents multiple consecutive hard line breaks from creating extra blank lines in the output.

Applied to files:

  • crates/biome_formatter/src/printer/mod.rs
  • crates/biome_formatter/src/format_element/document.rs
📚 Learning: 2025-09-13T16:16:06.459Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7467
File: crates/biome_service/src/file_handlers/html.rs:456-466
Timestamp: 2025-09-13T16:16:06.459Z
Learning: In biome_formatter, consecutive LineMode::Hard elements are automatically collapsed to a single newline by the printer. The printer has a test "it_prints_consecutive_hard_lines_as_one" that demonstrates this behavior - multiple consecutive hard line breaks result in only one newline in the output, not extra blank lines.

Applied to files:

  • crates/biome_formatter/src/format_element/document.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_formatter/src/format_element/document.rs
🧬 Code graph analysis (4)
crates/biome_formatter/src/builders.rs (3)
crates/biome_formatter/src/buffer.rs (1)
  • with_capacity (189-194)
crates/biome_formatter/src/format_element/document.rs (1)
  • from (193-195)
crates/biome_formatter/src/format_element.rs (1)
  • from_vec_unchecked (310-320)
crates/biome_formatter/src/format_element.rs (1)
crates/biome_formatter/src/format_element/tag.rs (1)
  • count (250-252)
crates/biome_formatter/src/printer/mod.rs (2)
crates/biome_formatter/src/format_element.rs (3)
  • next (388-406)
  • end_tag (280-285)
  • end_tag (459-459)
crates/biome_formatter/src/format_element/tag.rs (1)
  • kind (108-126)
crates/biome_formatter/src/format_element/document.rs (3)
crates/biome_formatter/src/lib.rs (1)
  • write (1428-1435)
crates/biome_formatter/src/builders.rs (2)
  • hard_line_break (99-101)
  • text (279-283)
crates/biome_formatter/src/format_element.rs (1)
  • from_vec_unchecked (310-320)
⏰ 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). (11)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test Node.js API
  • GitHub Check: Check JS Files
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_json_formatter)
🔇 Additional comments (6)
crates/biome_formatter/src/format_element/document.rs (3)

49-53: Best‑fitting expand boundary behaviour is preserved

Switching the BestFitting arm to recurse over the BestFittingVariants slice (via Deref) while still pushing an Enclosing::BestFitting and returning false keeps the “expand doesn’t leak past best‑fitting” semantics, and the long comment still matches what the code does. The new test with interned content nicely proves the subtle case where an interned element followed by a best‑fitting still propagates expansion to sibling groups.

Also applies to: 74-115


170-190: Using as_slice_mut for BestFitting transforms is a clean integration

Transforming best‑fitting content via best_fitting.as_slice_mut() keeps the visitor logic consistent with interned elements and lets the new iterator/representation worry about variant boundaries. This is a tidy way to hook the new container into the existing transform pipeline.


366-383: BestFitting IR display matches the new variant container

Iterating for variant in best_fitting and printing each slice with an indent + hard line works well with BestFittingVariantsIter, and the updated expectation in interned_best_fitting_allows_sibling_expand_propagation (best_fitting([[["a"]] [["b"]]])) confirms the debug IR for individual variants is still comprehensible under the new layout.

Also applies to: 871-921

crates/biome_formatter/src/format_element.rs (1)

197-241: Helper tag_kind nicely centralises tag inspection

The new tag_kind accessor is a straightforward, idiomatic way to surface a TagKind from a FormatElement without open‑coding matches everywhere; good reuse for the printer and other helpers.

crates/biome_formatter/src/printer/mod.rs (2)

9-9: Best‑fitting printing/measure logic is consistent with the new variants container

The printer’s BestFitting path now hangs together nicely:

  • print_element delegates to print_best_fitting, so all logic funnels through one place.
  • print_best_fitting uses a cheap fast‑path (flat mode + known‑fitting group → most_flat()), and otherwise walks the variants in order, measuring each candidate in flat mode and falling back to the last (most expanded) variant if nothing fits—which is exactly what you want for best‑fitting.
  • Both the print and fits paths explicitly validate that slices start with StartBestFittingEntry and surface InvalidDocumentError via invalid_start_tag if the IR is malformed, keeping the invariants honest.

This all lines up with BestFittingVariants and the new entry tags without introducing extra stack weirdness.

Also applies to: 153-155, 441-510, 1176-1191


2033-2134: New tests nicely cover interned entries and best‑fitting + fill interactions

The three added tests exercise exactly the gnarlier corners: interned vectors containing StartEntry tags under a fill, very long interned entries that trigger line‑breaking, and a BestFitting where each variant contains a fill with interned entries. Together they give good confidence that the new print_entry/BestFitting plumbing behaves correctly under stress.

@ematipico ematipico merged commit d407efb into main Dec 5, 2025
29 checks passed
@ematipico ematipico deleted the dbezrukov/best-fitt branch December 5, 2025 15:22
@github-actions github-actions bot mentioned this pull request Dec 5, 2025
ematipico added a commit that referenced this pull request Dec 8, 2025
Co-authored-by: Emanuele Stoppa <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This was referenced Dec 15, 2025
l0ngvh pushed a commit to l0ngvh/biome that referenced this pull request Dec 21, 2025
Co-authored-by: Emanuele Stoppa <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Formatter Area: formatter A-Linter Area: linter A-Parser Area: parser A-Project Area: project A-Tooling Area: internal tools L-HTML Language: HTML and super languages L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants