-
-
Notifications
You must be signed in to change notification settings - Fork 794
refactor(formatter): reduce best fitting allocations #8137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 573c6cb The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
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 |
CodSpeed Performance ReportMerging #8137 will not alter performanceComparing Summary
Footnotes
|
59c0ded to
78491d5
Compare
WalkthroughThe PR replaces the Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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” variantHere:
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::PoorLayoutis handled specially; any other error (e.g.SyntaxError) is ignored rather than propagated. Ifwrite!can ever return a non‑PoorLayouterror in this block, it will silently succeed here and continue with an invalid IR.It would be safer to explicitly propagate non‑
PoorLayouterrors, 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:BestFittingVariantsis used without being importedIn
BestFitting::fmtyou call:FormatElement::BestFitting(BestFittingVariants::from_vec_unchecked(buffer.into_vec()))but this file doesn’t import
BestFittingVariants, and it’s namespaced undercrate::format_element. Givencall_arguments.rsexplicitly imports it viaformat_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
📒 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.rscrates/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.rscrates/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 newBestFittingVariantsAPIThe
MostExpandedreference now correctly points atBestFittingVariants::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/EndBestFittingEntryare correctly:
- added to
Tag,- treated as start tags in
is_start, and- mapped to
TagKind::BestFittingEntryinkind.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 correctBringing
format_element::BestFittingVariantsin here is consistent with how you construct theBestFittingIR later; no issues.
396-487: Best‑fitting variants construction is structurally sound
- Each of
most_expandedandmost_flatis wrapped withStartBestFittingEntry/EndBestFittingEntry, and you always build at least the expanded + one other variant, satisfyingfrom_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
BestFittingVariantsrepresentation.
489-542: UnsafeBestFittingVariants::from_vec_uncheckedusage is justified hereGiven that:
variantsis the concatenation of 2–3 vectors, each starting/ending withStartBestFittingEntry/EndBestFittingEntry, and- you always construct at least two variants (
middle_variant+most_expanded, optionallymost_flat),the
from_vec_uncheckedcall respects its documented preconditions.crates/biome_formatter/src/builders.rs (1)
2671-2688: Best‑fitting builder now aligns withBestFittingVariantsinvariantsThe 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/EndBestFittingEntrybefore feeding the concatenated vector intoBestFittingVariants::from_vec_unchecked.Assuming the constructor’s
variants.len() >= 2assertion 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: Newtag_kindconvenience method is a nice small win
FormatElement::tag_kind()is a straightforward helper overTag::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_flatimplementations look correct
- Both methods debug‑assert the “at least two
StartBestFittingEntrytags” 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
StartBestFittingEntryup to and including the matchingEndBestFittingEntry, then advancing the remainder; and- walks backward by slicing from the last
StartBestFittingEntryto the end.That matches how the builder concatenates
[Start, body, End]chunks, and theFusedIteratorimpl is appropriate onceelementsis empty. Looks good.Also applies to: 364-383
WalkthroughThis change refactors the best-fitting element representation across the formatter codebase. The Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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: Fixmatches!pattern for BestFitting infits_element
slice.first()returns anOption<&FormatElement>, but thematches!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_fittingand 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* 8The new
BestFitting::fmtwrites all variants into a singleVecBufferand wraps each one withStartBestFittingEntry/EndBestFittingEntrybefore feeding them toBestFittingVariants::from_vec_unchecked. That matches the invariants enforced informat_element.rsand should avoid the previous per-variant allocations.One small nit:
VecBuffer::with_capacity(variants.len() * 8, ..)introduces a magic8. 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 modelThe call-argument path now:
- Wraps each variant (
most_expanded,most_flat,middle_variant) inStartBestFittingEntry/EndBestFittingEntrytags.- Ensures the fallback on
FormatError::PoorLayoutcorrectly strips those tags and writes the expanded layout directly.- Builds the final
variantsVec with at least two entries in all cases before callingBestFittingVariants::from_vec_unchecked, which matches the safety contract incrates/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
VecBufferrather than via three intermediateVec<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 docsThe
BestFittingVariantswrapper plus thedebug_assert!infrom_vec_unchecked,most_expanded, andmost_flatgive 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
📒 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.rscrates/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.rscrates/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.rscrates/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 APIThe reference to
MostExpandednow points atBestFittingVariants::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/EndBestFittingEntryare added symmetrically,Tag::is_startrecognises the start tag, andTag::kindmaps both toTagKind::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 fineSwitching 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 soundThe new
FormatElement::BestFittingarm correctly treats best‑fitting as a boundary while still recursing into its contents for side‑effects, without resettingexpands. This matches the long comment scenario and should keep interned expansion propagation behaving as intended.
180-182: Nice in‑place transform for best‑fitting variantsUsing
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 iteratorIterating
best_fittingto emit each variant as a slice plushard_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 cleanlyTreating
StartBestFittingEntry/EndBestFittingEntrythe 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 propagationThe new
interned_best_fitting_allows_sibling_expand_propagationtest exercises exactly the subtle interned/best‑fitting interaction described in the comment above and should guard against future regressions inpropagate_expand().crates/biome_formatter/src/printer/mod.rs (6)
153-155: Delegating BestFitting printing viaprint_best_fittingRouting
FormatElement::BestFittingthroughprint_best_fittingkeeps the main dispatch lean and centralises the variant‑selection logic in one place.
267-280: Stack handling extended for BestFittingEntry tagsAdding
StartBestFittingEntry/EndBestFittingEntryinto 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_fittinglogic matches the variant orderingThe 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::Flatand falling back to the last (most expanded) variant when none fit.- Wraps each chosen variant in a
BestFittingEntryframe viaprint_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_separatorrefactor looks goodPassing
TagKind::Entryexplicitly intoprint_entryis a neat generalisation and keeps the fill‑specific helpers as thin aliases.
695-744: Generalisedprint_entrycorrectly supports Entry and BestFittingEntryAllowing both
StartEntryandStartBestFittingEntryat the front, and matching against corresponding end tags while trackingdepth, preserves the original semantics and lets you reuse the same machinery for best‑fitting entries. The separation betweenkind(for error reporting) andend_tag.kind()(for stack popping) also keeps diagnostics accurate.
2033-2133: Excellent targeted tests for interned entries and best‑fitting variantsThe three new tests nicely exercise:
- Interned content containing
StartEntrytags inside aFill.- Long interned entries forcing line breaks.
- A best‑fitting variant wrapping a
Fillthat 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 toBestFittingVariantslooks tidyWiring
FormatElement::BestFittingto the newBestFittingVariantscontainer and delegatingDebugto it keeps the enum lean and avoids an extra layer of boxing.Also applies to: 80-82
234-240: Handytag_kindhelper
FormatElement::tag_kind()is a small but useful helper that avoids repeatedif let Tag(..)patterns at call sites; good call adding this.
372-429: Iterator over best‑fitting variants is well‑structured
BestFittingVariantsItercorrectly:
- Yields each variant as a
&[FormatElement]bounded by a single start/end pair.- Supports
DoubleEndedIteratorby scanning from the back for the last start tag.- Implements
FusedIteratoras expected.That plays nicely with the uses in
Documentand the printer.
|
Feel free to merge it once the CI is fixed |
There was a problem hiding this 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 ofDiagnosticKind– confirm intended API surfaceMaking
DiagnosticKindpubexposes 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 preferpub(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
⛔ Files ignored due to path filters (1)
crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand 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 thedbg!()macro for debugging output during testing, and pass the--show-outputflag tocargoto view debug output
Usecargo torcargo testto run tests; for a single test, pass the test name after thetestcommand
Use snapshot testing with theinstacrate; runcargo insta accept,cargo insta reject, orcargo insta reviewto manage snapshot changes
Write doctests as doc comments with code blocks; the code inside code blocks will be run during the testing phase
Usejust f(alias forjust format) to format Rust and TOML files before committing
Files:
xtask/codegen/src/generate_configuration.rscrates/biome_configuration/src/analyzer/assist/actions.rscrates/biome_analyze/src/diagnostics.rs
.changeset/**/*.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
.changeset/**/*.md: Create changesets for user-facing changes usingjust 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 adiffcode 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.rscrates/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.rscrates/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.rscrates/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.rscrates/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.rscrates/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 goodWrapping the rule docs URL in
<…>in the generated summary ("{}.\nSee <{}>"/"See <{}>") is correct here and plays nicely with Markdown autolinks and the existingtrim_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 behaviourThe 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.
4f2ad6c to
5ea4de4
Compare
Parser conformance results onjs/262
jsx/babel
symbols/microsoft
ts/babel
ts/microsoft
|
There was a problem hiding this 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 namesThe
from_vec_uncheckedsafety comment still talks about variants “delimited by StartEntry/EndEntry tags”, but the code and debug assertion now rely onStartBestFittingEntry/EndBestFittingEntry. It’d be good to update that sentence to name the current tags (orTagKind::BestFittingEntry) so the documented invariant matches the actual one.
🧹 Nitpick comments (2)
crates/biome_formatter/src/printer/mod.rs (2)
668-744: Generalisedprint_entryplus tests cover tricky interned/entry casesParameterising
print_entrywith aTagKindand allowing bothStartEntryandStartBestFittingEntrygives 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 checkFor the invariant check in
fits_element’sBestFittingarm, you might want to mirror the pattern style you used inprint_best_fitting(matching onSome(&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
⛔ Files ignored due to path filters (1)
crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand 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 thedbg!()macro for debugging output during testing, and pass the--show-outputflag tocargoto view debug output
Usecargo torcargo testto run tests; for a single test, pass the test name after thetestcommand
Use snapshot testing with theinstacrate; runcargo insta accept,cargo insta reject, orcargo insta reviewto manage snapshot changes
Write doctests as doc comments with code blocks; the code inside code blocks will be run during the testing phase
Usejust f(alias forjust format) to format Rust and TOML files before committing
Files:
crates/biome_formatter/src/macros.rscrates/biome_formatter/src/format_element/document.rscrates/biome_formatter/src/builders.rscrates/biome_configuration/src/analyzer/assist/actions.rscrates/biome_formatter/src/format_element.rscrates/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.rscrates/biome_configuration/src/analyzer/assist/actions.rscrates/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.rscrates/biome_formatter/src/format_element/document.rscrates/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.rscrates/biome_formatter/src/format_element/document.rscrates/biome_formatter/src/builders.rscrates/biome_configuration/src/analyzer/assist/actions.rscrates/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.rscrates/biome_formatter/src/format_element/document.rscrates/biome_formatter/src/builders.rscrates/biome_formatter/src/format_element.rscrates/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.rscrates/biome_configuration/src/analyzer/assist/actions.rscrates/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.rscrates/biome_formatter/src/format_element/document.rscrates/biome_formatter/src/builders.rscrates/biome_formatter/src/format_element.rscrates/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.rscrates/biome_formatter/src/format_element/document.rscrates/biome_formatter/src/builders.rscrates/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.rscrates/biome_formatter/src/format_element/document.rscrates/biome_formatter/src/builders.rscrates/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.rscrates/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.rscrates/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.rscrates/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.rscrates/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.rscrates/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.rscrates/biome_formatter/src/format_element.rscrates/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.rscrates/biome_configuration/src/analyzer/assist/actions.rscrates/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.rscrates/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.rscrates/biome_formatter/src/format_element.rscrates/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 APIThe reference to
MostExpandedcorrectly points toBestFittingVariants::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 soundThe new
BestFitting::fmtpath cleanly wraps each variant betweenStartBestFittingEntry/EndBestFittingEntryand feeds a singleVecBufferintoBestFittingVariants::from_vec_unchecked. Together with thefrom_arguments_uncheckedlength check, this preserves the “≥ 2 variants” invariant, and the* 3capacity 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 semanticsThe switch to walking
BestFittingVariantsas a flat slice inpropagate_expand/transform_elements, plus the IR display that iterates variants and treatsStartBestFittingEntry/EndBestFittingEntrylike normal entries, all line up nicely with the new representation. Theinterned_best_fitting_allows_sibling_expand_propagationtest 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 representationThe
BestFittingVariants‑based logic inprint_element,print_best_fitting, andfits_elementkeeps 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 leadingStartBestFittingEntrytags 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‑structuredMoving to
BestFittingVariants(Box<[FormatElement]>)with the iterator that slices out eachStartBestFittingEntry…EndBestFittingEntrysegment gives you a compact, cache‑friendly representation and a clean API (most_flat,most_expanded,IntoIterator,as_slice[_mut]). The extratag_kindhelper onFormatElementrounds out the tagging story without affecting the enum’s layout constraints.Also applies to: 60-66, 234-241, 288-361, 364-429
There was a problem hiding this 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 staleThe flattened
BestFittingVariants+ iterator combo is neat: debug‑asserting on at least twoStartBestFittingEntrytags and then exposingmost_flat/most_expandedthrough the iterator keeps the invariants local and the API ergonomic. Two tiny nits while you’re here:
- The safety comment on
from_vec_uncheckedstill says “delimited by StartEntry/EndEntry tags”; that should now referenceStartBestFittingEntry/EndBestFittingEntry(orTagKind::BestFittingEntry) to match the debug_assert and builder logic.- The panic message in
most_expandedsays “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 solidWriting variants directly into a
VecBufferwithvariants.len() * 3capacity and wrapping each inStartBestFittingEntry/EndBestFittingEntrylines up nicely with the newBestFittingVariantsinvariants; the unsafe call is justified byfrom_arguments_unchecked’s length check. If you ever touch this again, a tiny note like “2 tags + 1 content element” would de‑mystify the* 3for future readers, but it’s perfectly fine as is.Also applies to: 2671-2689
crates/biome_formatter/src/printer/mod.rs (1)
668-688: Generalisedprint_entrycleanly supports both Fill entries and BestFitting entriesPassing a
TagKindintoprint_entryand teaching it to recognise bothStartEntry/EndEntryandStartBestFittingEntry/EndBestFittingEntrygives you a single, well‑tested path for “print this entry and all its descendants”. Thedepthcounter plus only pushing the providedkindat 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
⛔ Files ignored due to path filters (1)
crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand 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 thedbg!()macro for debugging output during testing, and pass the--show-outputflag tocargoto view debug output
Usecargo torcargo testto run tests; for a single test, pass the test name after thetestcommand
Use snapshot testing with theinstacrate; runcargo insta accept,cargo insta reject, orcargo insta reviewto manage snapshot changes
Write doctests as doc comments with code blocks; the code inside code blocks will be run during the testing phase
Usejust f(alias forjust format) to format Rust and TOML files before committing
Files:
crates/biome_formatter/src/builders.rscrates/biome_formatter/src/format_element.rscrates/biome_formatter/src/printer/mod.rscrates/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.rscrates/biome_formatter/src/format_element.rscrates/biome_formatter/src/printer/mod.rscrates/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.rscrates/biome_formatter/src/format_element.rscrates/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.rscrates/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.rscrates/biome_formatter/src/format_element.rscrates/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.rscrates/biome_formatter/src/format_element.rscrates/biome_formatter/src/printer/mod.rscrates/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.rscrates/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.rscrates/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.rscrates/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.rscrates/biome_formatter/src/printer/mod.rscrates/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.rscrates/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.rscrates/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.rscrates/biome_formatter/src/format_element.rscrates/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.rscrates/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.rscrates/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.rscrates/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.rscrates/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.rscrates/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 preservedSwitching the
BestFittingarm to recurse over theBestFittingVariantsslice (via Deref) while still pushing anEnclosing::BestFittingand returningfalsekeeps 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: Usingas_slice_mutfor BestFitting transforms is a clean integrationTransforming 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 containerIterating
for variant in best_fittingand printing each slice with an indent + hard line works well withBestFittingVariantsIter, and the updated expectation ininterned_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: Helpertag_kindnicely centralises tag inspectionThe new
tag_kindaccessor is a straightforward, idiomatic way to surface aTagKindfrom aFormatElementwithout 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 containerThe printer’s BestFitting path now hangs together nicely:
print_elementdelegates toprint_best_fitting, so all logic funnels through one place.print_best_fittinguses 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
StartBestFittingEntryand surfaceInvalidDocumentErrorviainvalid_start_tagif the IR is malformed, keeping the invariants honest.This all lines up with
BestFittingVariantsand 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 interactionsThe three added tests exercise exactly the gnarlier corners: interned vectors containing
StartEntrytags 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 newprint_entry/BestFitting plumbing behaves correctly under stress.
Co-authored-by: Emanuele Stoppa <[email protected]> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Emanuele Stoppa <[email protected]> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Summary
Port astral-sh/ruff#7411
Test Plan
Green CI
Docs