Skip to content

Conversation

@ematipico
Copy link
Member

Summary

Closes #8019

I had to simplify how the keywords of the svelte syntax are consumed, so I had to add a bit more logic to the parser.

I started removing the TextExpression::new_single because it started to be complicated, so I decided to just create a simple function called parse_single_text_expression_content.

Test Plan

Added various tests

Docs

@changeset-bot
Copy link

changeset-bot bot commented Nov 7, 2025

🦋 Changeset detected

Latest commit: 4763ba4

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

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

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

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

@ematipico ematipico requested review from a team and dyc3 November 7, 2025 10:53
@github-actions github-actions bot added A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-HTML Language: HTML and super languages labels Nov 7, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 7, 2025

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 50977 50977 0
Passed 49764 49764 0
Failed 1171 1171 0
Panics 42 42 0
Coverage 97.62% 97.62% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 40 40 0
Passed 37 37 0
Failed 3 3 0
Panics 0 0 0
Coverage 92.50% 92.50% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 6320 6320 0
Passed 2106 2106 0
Failed 4214 4214 0
Panics 0 0 0
Coverage 33.32% 33.32% 0.00%

ts/babel

Test result main count This PR count Difference
Total 835 835 0
Passed 742 742 0
Failed 93 93 0
Panics 0 0 0
Coverage 88.86% 88.86% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 18813 18813 0
Passed 14065 14065 0
Failed 4747 4747 0
Panics 1 1 0
Coverage 74.76% 74.76% 0.00%

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 7, 2025

Walkthrough

Adds full Svelte {#if}/{:else if}/{:else}/{/if} support across lexer, parser, syntax codegen and formatter. Introduces new grammar nodes (opening, else-if list, else clause, closing), new HtmlReLexContext paths and Svelte keywords (if, else), parser handlers for opening/else-if/else/closing blocks and element lists, formatter implementations and grouping for Svelte if/else clauses, generated formatter wiring, and test fixtures exercising if, if–else and if–else-if–else scenarios.

Possibly related PRs

Suggested reviewers

  • dyc3

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.94% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title 'feat(html/svelte): if/else syntax' clearly describes the main feature—Svelte conditional block support.
Description check ✅ Passed Description relates to the changeset by referencing issue #8019, explaining parser simplifications, and documenting test coverage.
Linked Issues check ✅ Passed PR implements all requirements from #8019: parser and formatter support for {#if}, {:else if}, {:else}, {/if} syntax with comprehensive test coverage [#8019].
Out of Scope Changes check ✅ Passed All changes directly support Svelte conditional block implementation; no unrelated modifications detected.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/html-svelte-if

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
crates/biome_html_formatter/src/html/lists/element_list.rs (1)

85-97: Group id silently dropped in fmt

At the moment the BestFitting arm throws away group_id, so FormatHtmlElementList::default().with_group_id(...).fmt(...) still falls back to the anonymous best_fitting! group. Anything depending on the shared group (like your new Svelte blocks) will break as soon as it goes through fmt. Let’s forward the variant to your new FormatChildrenResult formatter instead so the stored group_id is honoured.

         match result {
             FormatChildrenResult::ForceMultiline(format_multiline) => {
                 write!(f, [format_multiline])?;
             }
-            FormatChildrenResult::BestFitting {
-                flat_children,
-                expanded_children,
-                group_id: _,
-            } => {
-                write!(f, [best_fitting![flat_children, expanded_children]])?;
-            }
+            best @ FormatChildrenResult::BestFitting { .. } => {
+                write!(f, [best])?;
+            }
         }
🧹 Nitpick comments (2)
.changeset/spicy-actors-leave.md (1)

5-5: Minor style suggestion.

Consider simplifying "is now able to parse and format" to "can now parse and format" for more concise phrasing.

Apply this diff:

-Added support for the Svelte syntax `{#if}{/if}`. The Biome HTML parser is now able to parse and format the [`{#if}{/if} blocks`](https://svelte.dev/docs/svelte/if):
+Added support for the Svelte syntax `{#if}{/if}`. The Biome HTML parser can now parse and format the [`{#if}{/if} blocks`](https://svelte.dev/docs/svelte/if):
crates/biome_html_parser/src/syntax/svelte.rs (1)

367-370: Pedantic: Redundant boolean comparison.

Line 370 uses self.stop_at_curly_colon == true which can be simplified to self.stop_at_curly_colon.

Apply this diff:

-            || (self.stop_at_curly_colon == true && p.at(T!["{:"]))
+            || (self.stop_at_curly_colon && p.at(T!["{:"]))
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2cef76a and 55342a0.

⛔ Files ignored due to path filters (19)
  • crates/biome_html_factory/src/generated/node_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_factory/src/generated/syntax_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else_if_else.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_formatter/tests/specs/prettier/html/front-matter/empty2.html.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/error/svelte/debug-trailing-comma.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/error/svelte/debug.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_close.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else_if_else.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/key.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_syntax/src/generated/kind.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/macros.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/nodes.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/nodes_mut.rs is excluded by !**/generated/**, !**/generated/** and included by **
📒 Files selected for processing (34)
  • .changeset/spicy-actors-leave.md (1 hunks)
  • crates/biome_html_formatter/src/generated.rs (3 hunks)
  • crates/biome_html_formatter/src/html/auxiliary/element.rs (1 hunks)
  • crates/biome_html_formatter/src/html/lists/element_list.rs (5 hunks)
  • crates/biome_html_formatter/src/lib.rs (0 hunks)
  • crates/biome_html_formatter/src/svelte/any/block.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (2 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs (0 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/mod.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/lists/mod.rs (1 hunks)
  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte (1 hunks)
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else.svelte (1 hunks)
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else_if_else.svelte (1 hunks)
  • crates/biome_html_parser/src/lexer/mod.rs (4 hunks)
  • crates/biome_html_parser/src/lexer/tests.rs (1 hunks)
  • crates/biome_html_parser/src/parser.rs (2 hunks)
  • crates/biome_html_parser/src/syntax/mod.rs (3 hunks)
  • crates/biome_html_parser/src/syntax/parse_error.rs (1 hunks)
  • crates/biome_html_parser/src/syntax/svelte.rs (9 hunks)
  • crates/biome_html_parser/src/token_source.rs (2 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte (1 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if.svelte (1 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else.svelte (1 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else_if_else.svelte (1 hunks)
  • crates/biome_html_parser/tests/spec_test.rs (1 hunks)
  • crates/biome_syntax_codegen/src/generate_syntax_kinds.rs (0 hunks)
  • xtask/codegen/html.ungram (2 hunks)
  • xtask/codegen/src/html_kinds_src.rs (2 hunks)
💤 Files with no reviewable changes (3)
  • crates/biome_html_formatter/src/lib.rs
  • crates/biome_syntax_codegen/src/generate_syntax_kinds.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs
🧰 Additional context used
🧠 Learnings (40)
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_parser/src/syntax/svelte.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/crates/**/src/lexer/mod.rs : Create a lexer module at crates/<parser_crate>/src/lexer/mod.rs

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/mod.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/Cargo.toml : Declare the dependency `biome_js_formatter = { version = "0.0.1", path = "../biome_js_formatter" }` for internal installation

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/crates/biome_*_{syntax,factory}/src/generated/** : Each new biome_<lang>_{syntax,factory} crate must have a src/generated/ directory for codegen output

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/xtask/codegen/src/*_kinds_src.rs : Add src/<lang>_kinds_src.rs under xtask/codegen that returns a static KindSrc

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
  • xtask/codegen/src/html_kinds_src.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/**/*.rs : Do not copy or clone data between module graph entries (including behind Arc). Each module must avoid holding duplicated data from another module to enable simple invalidation.

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/crates/biome_*_{syntax,factory}/** : Create per-language crates biome_<lang>_syntax and biome_<lang>_factory under crates/

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code; if a mandatory token/node is missing, return `None` instead

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/syntax/svelte.rs
  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Add the provided AsFormat, IntoFormat, and iterator plumbing code to lib.rs

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/type_info.rs : Add new TypeScript type support by extending the TypeData enum rather than introducing parallel structures.

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/mod.rs
  • crates/biome_html_parser/src/lexer/tests.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Implement FormatLanguage for HtmlFormatLanguage with associated types: SyntaxLanguage=HtmlLanguage, Context=HtmlFormatContext, FormatRule=FormatHtmlSyntaxNode

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/syntax/parse_error.rs
  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/cst.rs : Create FormatHtmlSyntaxNode in cst.rs implementing FormatRule<HtmlSyntaxNode> and AsFormat/IntoFormat for HtmlSyntaxNode using the provided plumbing

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import and use the `FormatNode` trait for AST nodes

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Implement the `Format` trait for your node type and use `JsFormatter` with `write!`/`format_args!` to define formatting

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/context.rs : Create HtmlFormatContext in context.rs with comments and source_map fields and implement FormatContext and CstFormatContext

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/language.rs : Create tests/language.rs defining `HtmlTestFormatLanguage` and implement the TestFormatLanguage trait

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Define the HtmlFormatter type alias: `type HtmlFormatter<'buf> = Formatter<'buf, HtmlFormatContext>;`

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/comments.rs : Define HtmlCommentStyle implementing CommentStyle in comments.rs

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Expose a documented public function `format_node(options: HtmlFormatOptions, root: &HtmlSyntaxNode) -> FormatResult<Formatted<HtmlFormatContext>>` delegating to `biome_formatter::format_node`

Applied to files:

  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When a token is mandatory and present in the AST, use the AST-provided token (e.g., `node.l_paren_token().format()`) instead of emitting a static token

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: The formatter relies on two pillars: implementing `Format`/`FormatNode` for nodes and creating an intermediate IR via helpers

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Add a new LanguageKind variant (e.g., Html) in language_kind.rs and implement/cover all methods

Applied to files:

  • crates/biome_html_parser/src/token_source.rs
  • xtask/codegen/src/html_kinds_src.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/comments.rs : Expose a public HtmlComments type alias: `pub type HtmlComments = Comments<HtmlLanguage>;`

Applied to files:

  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For non-mandatory tokens, use the provided helper constructors (e.g., `token`, `space_token`, `dynamic_token`)

Applied to files:

  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: If lookahead is needed, wrap the lexer with BufferedLexer and implement TokenSourceWithBufferedLexer and LexerWithCheckpoint

Applied to files:

  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/specs/html/**/*.html : Place HTML test cases under tests/specs/html as .html files discovered by the test macro

Applied to files:

  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else_if_else.svelte
  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else_if_else.svelte
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else.svelte
  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else.svelte
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/spec_tests.rs : In tests/spec_tests.rs, generate tests with `tests_macros::gen_tests! {"tests/specs/html/**/*.html", crate::spec_test::run, ""}`

Applied to files:

  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else_if_else.svelte
  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else.svelte
  • crates/biome_html_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/** : Create a tests directory containing a specs subfolder and the files spec_test.rs, spec_tests.rs, and language.rs

Applied to files:

  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte
  • crates/biome_html_parser/tests/spec_test.rs
📚 Learning: 2025-10-15T09:25:05.698Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:25:05.698Z
Learning: Applies to crates/biome_service/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in ../biome_lsp/src/server.tests.rs

Applied to files:

  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/tests/spec_test.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/spec_test.rs : Implement a `run` function in tests/spec_test.rs that wires SpecSnapshot and includes!("language.rs") as shown

Applied to files:

  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte
  • crates/biome_html_parser/tests/spec_test.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use `dbg_write!` to debug and inspect the emitted IR during formatting

Applied to files:

  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Lexer must implement the biome_parser::Lexer trait

Applied to files:

  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/parser.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Parse rules should return ParsedSyntax; return Absent without consuming tokens when the node cannot be predicted

Applied to files:

  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference}.rs : When inference is missing or cannot determine a type, use TypeData::Unknown; use TypeData::UnknownKeyword only when the user explicitly wrote unknown.

Applied to files:

  • crates/biome_html_parser/src/lexer/tests.rs
📚 Learning: 2025-10-25T07:22:18.540Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7852
File: crates/biome_css_parser/src/syntax/property/mod.rs:161-168
Timestamp: 2025-10-25T07:22:18.540Z
Learning: In the Biome CSS parser, lexer token emission should not be gated behind parser options like `is_tailwind_directives_enabled()`. The lexer must emit correct tokens regardless of parser options to enable accurate diagnostics and error messages when the syntax is used incorrectly.

Applied to files:

  • crates/biome_html_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/xtask/codegen/*.ungram : Nodes for enclosing syntax errors must include the Bogus word (e.g., HtmlBogusAttribute)

Applied to files:

  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/syntax/parse_error.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Use p.eat for optional tokens, p.expect for required tokens; use .ok() for optional nodes and .or_add_diagnostic(...) for required nodes

Applied to files:

  • crates/biome_html_parser/src/syntax/parse_error.rs
  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: When parsing lists, implement error recovery (e.g., via ParseSeparatedList/ParseNodeList) to avoid infinite loops

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/xtask/codegen/*.ungram : List node types must end with the postfix List (e.g., HtmlAttributeList)

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-03T12:28:56.788Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7670
File: crates/biome_service/src/file_handlers/html.rs:744-748
Timestamp: 2025-10-03T12:28:56.788Z
Learning: In Biome's codebase, when creating tokens with new text content, use the factory pattern with functions like `ident(text)` from the respective `*_factory` crates (e.g., `biome_html_factory::make::ident`). There is no `.with_text()` method on tokens. The `ident()` function creates a new detached token with the IDENT kind, which is the standard approach for token construction.

Applied to files:

  • crates/biome_html_parser/src/parser.rs
🧬 Code graph analysis (14)
crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (4)
crates/biome_html_syntax/src/generated/nodes.rs (34)
  • html (624-626)
  • sv_curly_colon_token (1024-1026)
  • sv_curly_colon_token (1076-1078)
  • else_token (1027-1029)
  • else_token (1079-1081)
  • if_token (1082-1084)
  • if_token (1236-1238)
  • if_token (1283-1285)
  • expression (441-443)
  • expression (726-728)
  • expression (880-882)
  • expression (930-932)
  • expression (1085-1087)
  • expression (1140-1142)
  • expression (1286-1288)
  • expression (1430-1432)
  • expression (1515-1517)
  • r_curly_token (729-731)
  • r_curly_token (883-885)
  • r_curly_token (933-935)
  • r_curly_token (983-985)
  • r_curly_token (1030-1032)
  • r_curly_token (1088-1090)
  • r_curly_token (1143-1145)
  • r_curly_token (1239-1241)
  • r_curly_token (1289-1291)
  • r_curly_token (1384-1386)
  • r_curly_token (1433-1435)
  • r_curly_token (1518-1520)
  • children (486-488)
  • children (1033-1035)
  • children (1091-1093)
  • children (1292-1294)
  • children (1336-1338)
crates/biome_html_formatter/src/html/lists/element_list.rs (2)
  • write (761-797)
  • write (907-921)
crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1)
  • fmt_fields (9-32)
crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1)
  • fmt_fields (9-35)
crates/biome_html_parser/src/token_source.rs (2)
crates/biome_html_parser/src/lexer/mod.rs (1)
  • re_lex (962-982)
crates/biome_html_parser/src/parser.rs (1)
  • re_lex (73-75)
crates/biome_html_formatter/src/svelte/auxiliary/mod.rs (1)
crates/biome_html_syntax/src/generated/nodes.rs (1)
  • else_clause (1190-1192)
crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs (5)
crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1)
  • fmt_fields (9-32)
crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1)
  • fmt_fields (9-38)
crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs (1)
  • fmt_fields (7-24)
crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1)
  • fmt_fields (9-35)
crates/biome_html_syntax/src/generated/nodes.rs (17)
  • sv_curly_slash_token (1233-1235)
  • sv_curly_slash_token (1378-1380)
  • if_token (1082-1084)
  • if_token (1236-1238)
  • if_token (1283-1285)
  • r_curly_token (729-731)
  • r_curly_token (883-885)
  • r_curly_token (933-935)
  • r_curly_token (983-985)
  • r_curly_token (1030-1032)
  • r_curly_token (1088-1090)
  • r_curly_token (1143-1145)
  • r_curly_token (1239-1241)
  • r_curly_token (1289-1291)
  • r_curly_token (1384-1386)
  • r_curly_token (1433-1435)
  • r_curly_token (1518-1520)
crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (7)
crates/biome_html_syntax/src/generated/nodes.rs (32)
  • html (624-626)
  • sv_curly_hash_token (1280-1282)
  • sv_curly_hash_token (1424-1426)
  • if_token (1082-1084)
  • if_token (1236-1238)
  • if_token (1283-1285)
  • expression (441-443)
  • expression (726-728)
  • expression (880-882)
  • expression (930-932)
  • expression (1085-1087)
  • expression (1140-1142)
  • expression (1286-1288)
  • expression (1430-1432)
  • expression (1515-1517)
  • r_curly_token (729-731)
  • r_curly_token (883-885)
  • r_curly_token (933-935)
  • r_curly_token (983-985)
  • r_curly_token (1030-1032)
  • r_curly_token (1088-1090)
  • r_curly_token (1143-1145)
  • r_curly_token (1239-1241)
  • r_curly_token (1289-1291)
  • r_curly_token (1384-1386)
  • r_curly_token (1433-1435)
  • r_curly_token (1518-1520)
  • children (486-488)
  • children (1033-1035)
  • children (1091-1093)
  • children (1292-1294)
  • children (1336-1338)
crates/biome_html_formatter/src/html/lists/element_list.rs (2)
  • write (761-797)
  • write (907-921)
crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1)
  • fmt_fields (9-32)
crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1)
  • fmt_fields (9-38)
crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (1)
  • fmt_fields (9-24)
crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs (1)
  • fmt_fields (8-25)
crates/biome_formatter/src/builders.rs (1)
  • hard_line_break (99-101)
crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (2)
crates/biome_html_syntax/src/generated/nodes.rs (8)
  • html (624-626)
  • children (486-488)
  • children (1033-1035)
  • children (1091-1093)
  • children (1292-1294)
  • children (1336-1338)
  • closing_block (1193-1195)
  • closing_block (1339-1341)
crates/biome_html_formatter/src/html/lists/element_list.rs (2)
  • write (761-797)
  • write (907-921)
crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (6)
crates/biome_html_syntax/src/generated/nodes.rs (22)
  • html (624-626)
  • sv_curly_colon_token (1024-1026)
  • sv_curly_colon_token (1076-1078)
  • else_token (1027-1029)
  • else_token (1079-1081)
  • r_curly_token (729-731)
  • r_curly_token (883-885)
  • r_curly_token (933-935)
  • r_curly_token (983-985)
  • r_curly_token (1030-1032)
  • r_curly_token (1088-1090)
  • r_curly_token (1143-1145)
  • r_curly_token (1239-1241)
  • r_curly_token (1289-1291)
  • r_curly_token (1384-1386)
  • r_curly_token (1433-1435)
  • r_curly_token (1518-1520)
  • children (486-488)
  • children (1033-1035)
  • children (1091-1093)
  • children (1292-1294)
  • children (1336-1338)
crates/biome_html_formatter/src/html/lists/element_list.rs (2)
  • write (761-797)
  • write (907-921)
crates/biome_html_formatter/src/html/auxiliary/element.rs (1)
  • fmt_fields (26-174)
crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1)
  • fmt_fields (9-38)
crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1)
  • fmt_fields (9-35)
crates/biome_formatter/src/builders.rs (1)
  • hard_line_break (99-101)
crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs (5)
crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1)
  • fmt_fields (9-32)
crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1)
  • fmt_fields (9-38)
crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs (1)
  • fmt_fields (8-23)
crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1)
  • fmt_fields (9-35)
crates/biome_html_syntax/src/generated/nodes.rs (6)
  • opening_block (1184-1186)
  • opening_block (1333-1335)
  • else_if_clauses (1187-1189)
  • else_clause (1190-1192)
  • closing_block (1193-1195)
  • closing_block (1339-1341)
crates/biome_html_formatter/src/html/lists/element_list.rs (3)
crates/biome_formatter/src/format_element/tag.rs (1)
  • with_group_id (229-232)
crates/biome_formatter/src/lib.rs (1)
  • group_id (2136-2138)
crates/biome_formatter/src/builders.rs (2)
  • if_group_breaks (1943-1952)
  • if_group_fits_on_line (2024-2033)
crates/biome_html_parser/src/lexer/mod.rs (2)
crates/biome_html_parser/src/token_source.rs (3)
  • lexer (227-229)
  • re_lex (168-170)
  • current (176-178)
crates/biome_html_parser/src/parser.rs (2)
  • context (90-92)
  • re_lex (73-75)
crates/biome_html_parser/src/syntax/parse_error.rs (1)
crates/biome_parser/src/diagnostic.rs (1)
  • expect_one_of (491-494)
crates/biome_html_parser/src/syntax/svelte.rs (3)
crates/biome_html_parser/src/syntax/parse_error.rs (2)
  • expected_child_or_block (43-45)
  • expected_text_expression (35-37)
crates/biome_html_parser/src/syntax/mod.rs (6)
  • parse_html_element (218-249)
  • parse_single_text_expression_content (573-586)
  • parse_element (119-192)
  • parse_element (259-261)
  • parse_element (291-293)
  • parse_element (589-622)
crates/biome_html_parser/src/token_source.rs (1)
  • single_expression (59-61)
crates/biome_html_parser/src/parser.rs (2)
crates/biome_html_parser/src/lexer/mod.rs (1)
  • re_lex (962-982)
crates/biome_html_parser/src/token_source.rs (1)
  • re_lex (168-170)
crates/biome_html_formatter/src/generated.rs (2)
crates/biome_html_syntax/src/generated/nodes.rs (1)
  • else_clause (1190-1192)
crates/biome_html_formatter/src/lib.rs (10)
  • format (51-51)
  • format (64-66)
  • format (81-86)
  • format (101-103)
  • format (297-299)
  • new (146-148)
  • into_format (112-112)
  • into_format (121-123)
  • into_format (135-137)
  • into_format (305-307)
🪛 LanguageTool
.changeset/spicy-actors-leave.md

[style] ~5-~5: As a shorter alternative for ‘able to’, consider using “can now”.
Context: ...tax {#if}{/if}. The Biome HTML parser is now able to parse and format the [`{#if}{/if} block...

(BE_ABLE_TO)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Test Node.js API
  • GitHub Check: Parser conformance
  • GitHub Check: End-to-end tests
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Documentation
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: autofix
🔇 Additional comments (42)
crates/biome_html_formatter/src/svelte/lists/mod.rs (1)

1-4: LGTM!

The module declaration aligns with the new SvelteElseIfClauseList formatting support introduced in this PR.

xtask/codegen/src/html_kinds_src.rs (2)

24-27: LGTM!

The if and else keywords are properly added to support Svelte conditional block tokenisation.


73-78: LGTM!

The new Svelte AST node kinds comprehensively cover all components of the conditional block syntax: opening, closing, else clauses, and else-if clause lists.

crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte (1)

1-4: LGTM!

Adding {@debug debug} tests the edge case where a keyword is used as an identifier argument, ensuring the parser handles potential keyword conflicts correctly.

crates/biome_html_parser/tests/spec_test.rs (1)

145-146: LGTM!

The test input change to {@debug something,} aligns with the updated parser tokenisation where Svelte identifiers map to specific keyword tokens.

crates/biome_html_parser/src/lexer/tests.rs (1)

382-407: LGTM!

The lexer tests correctly validate that debug is now tokenised as DEBUG_KW rather than a generic SVELTE_IDENT, consistent with the more specific keyword handling introduced for Svelte syntax.

crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (2)

1-3: LGTM!

Import cleanup reflects the simplified formatting approach that no longer requires branching on FormatChildrenResult.


19-24: LGTM!

The refactor to group-based formatting with a dedicated "svelte-key-group" simplifies the logic and provides more consistent formatting behaviour across Svelte blocks.

crates/biome_html_formatter/src/svelte/any/block.rs (1)

15-15: LGTM!

The SvelteIfBlock variant is properly integrated into the AnySvelteBlock formatter match, completing the conditional block formatting path.

crates/biome_html_parser/tests/html_specs/ok/svelte/if_else.svelte (1)

1-6: LGTM!

Clean test fixture for basic Svelte if/else blocks. The temperature check demonstrates the conditional rendering nicely.

crates/biome_html_formatter/src/html/auxiliary/element.rs (1)

146-146: LGTM!

The structural change properly accommodates the new group_id field from FormatChildrenResult::BestFitting.

crates/biome_html_formatter/tests/specs/html/svelte/if_else.svelte (1)

1-6: LGTM!

Appropriate test fixture for the formatter test suite, mirroring the parser test coverage.

crates/biome_html_formatter/tests/specs/html/svelte/if.svelte (1)

1-4: LGTM!

Clean test for the simplest conditional case—just an if block without else branches.

crates/biome_html_parser/tests/html_specs/ok/svelte/if_else_if_else.svelte (1)

1-8: LGTM!

Good test coverage for the if/else-if/else chain, verifying that the parser handles multiple branches correctly.

crates/biome_html_parser/tests/html_specs/ok/svelte/if.svelte (1)

1-4: LGTM!

Straightforward test fixture for basic if blocks in the parser test suite.

crates/biome_html_parser/src/parser.rs (2)

1-3: LGTM!

Import additions correctly support the new re-lexing functionality.


71-75: LGTM!

The re_lex method is well-documented and correctly delegates to the underlying token source. This provides a clean public API for re-tokenization based on context.

crates/biome_html_formatter/tests/specs/html/svelte/if_else_if_else.svelte (1)

1-10: LGTM!

Excellent test coverage for multiple else-if branches. The formatter needs to handle this more complex scenario, and this fixture does the job nicely.

crates/biome_html_parser/src/syntax/parse_error.rs (1)

39-45: LGTM!

The new expected_child_or_block helper follows the established pattern and appropriately extends error messaging for Svelte block contexts.

crates/biome_html_parser/src/token_source.rs (1)

100-170: LGTM!

The HtmlReLexContext enum and re_lex method are cleanly integrated and properly delegate to the underlying lexer.

crates/biome_html_formatter/src/svelte/auxiliary/mod.rs (1)

6-11: LGTM!

Module declarations correctly registered for the new Svelte if/else formatters.

crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs (1)

1-10: LGTM!

Standard list formatter implementation following established patterns.

crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs (1)

1-24: LGTM!

Token ordering correctly produces {/if} closing block syntax.

crates/biome_html_parser/src/syntax/mod.rs (2)

603-603: Verify context removal is intentional.

Changed from bump_remap_with_context(HTML_LITERAL, HtmlLexContext::InsideTag) to bump_remap(HTML_LITERAL), removing the explicit context. Confirm this doesn't affect lexing behaviour for single text expressions.


573-586: Function is actively used—not dead code.

The function is called 7 times in crates/biome_html_parser/src/syntax/svelte.rs (lines 86, 122, 166, 236, 249, 264, 277). The original concern was based on incomplete visibility of the codebase.

Likely an incorrect or invalid review comment.

crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs (1)

1-25: LGTM!

Block ordering correctly represents the Svelte if/else-if/else structure.

crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1)

1-33: LGTM!

Correctly formats {:else} clause with proper child delegation and line breaks, consistent with other Svelte block formatters.

crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1)

18-35: Header flow looks spot on

Mirrors the key-block formatter nicely; the delegated list with its own group keeps the branch tidy.

crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1)

19-38: Else-if formatter reads well

Token sequencing and delegated children match the surrounding clauses cleanly.

xtask/codegen/html.ungram (1)

198-312: Grammar wiring looks good

Nice to see the conditional family slotted into AnySvelteBlock with the expected children layout.

crates/biome_html_parser/src/lexer/mod.rs (1)

3-983: Re-lex hook is welcome

Hooking HtmlReLexContext through the lexer and mapping if/else keeps the conditional blocks lexically sound.

crates/biome_html_parser/src/syntax/svelte.rs (10)

22-38: LGTM!

The refactoring to create the marker once and pass it to specific block parsers is clean. Proper marker abandonment when neither key nor if matches.


40-55: LGTM!

The refactoring to accept parent_marker is consistent with the new pattern. Good use of diagnostic details to point users back to where the unclosed block started.


57-76: LGTM!

The structure mirrors parse_key_block nicely. Proper handling of optional else clause and mandatory closing block with helpful diagnostics.


102-136: LGTM! Clever checkpoint usage.

The checkpoint/rewind logic at lines 114-119 neatly distinguishes {:else if} from {:else} without consuming tokens. Good pattern for lookahead disambiguation.


138-149: LGTM!

Straightforward parsing of the final {:else} clause. Correctly omits stop_at_curly_colon since else is terminal.


154-176: LGTM!

The refactoring to accept a pre-created Marker aligns with the pattern established for if/key blocks.


236-236: LGTM! Consistent refactoring.

Good consolidation of expression parsing logic into parse_single_text_expression_content across multiple block parsers.

Also applies to: 249-249, 264-264, 277-277


20-20: The import is correct and actively used.

The std::ops::Sub trait is properly implemented for TextRange in the biome_text_size crate, and the .sub(m.start()) calls at lines 51 and 72 invoke this trait method. The API is the intended one for this operation.

Likely an incorrect or invalid review comment.


398-419: Pattern is sound—no issues identified.

The checkpoint/rewind with re-lexing approach is correct. It properly leverages the BufferedLexer infrastructure that's already in place, matches the recommended pattern from the codebase learnings, and safely reverts state after peeking. The comments explaining the context-dependent lexing are clear. Code looks good as-is.


86-91: Original review comment is incorrect.

The code intentionally uses different methods for different error contexts. sub() subtracts from the entire range (used for closing block errors), whilst sub_start() subtracts only from the start (used for expression parsing errors). These are semantically distinct operations, not an inconsistency.

Likely an incorrect or invalid review comment.

crates/biome_html_formatter/src/generated.rs (1)

833-1346: Generated boilerplate looks correct.

This file is code-generated (per line 1), and the new formatting implementations for Svelte if/else constructs follow the established pattern consistently. Module paths reference the expected crate::svelte::auxiliary::* and crate::svelte::lists::* locations.

If the generator is functioning correctly, these additions are appropriate. Based on learnings, ensure the actual FormatSvelte* implementations in the auxiliary modules don't use format_verbatim_node and implement real formatting logic instead.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55342a0 and 81d25b4.

📒 Files selected for processing (1)
  • crates/biome_html_parser/src/syntax/svelte.rs (9 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Parse rules should return ParsedSyntax; return Absent without consuming tokens when the node cannot be predicted

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Use p.eat for optional tokens, p.expect for required tokens; use .ok() for optional nodes and .or_add_diagnostic(...) for required nodes

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: When parsing lists, implement error recovery (e.g., via ParseSeparatedList/ParseNodeList) to avoid infinite loops

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/xtask/codegen/*.ungram : List node types must end with the postfix List (e.g., HtmlAttributeList)

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
🧬 Code graph analysis (1)
crates/biome_html_parser/src/syntax/svelte.rs (4)
crates/biome_html_parser/src/syntax/parse_error.rs (2)
  • expected_child_or_block (43-45)
  • expected_text_expression (35-37)
crates/biome_html_parser/src/syntax/mod.rs (8)
  • parse_html_element (218-249)
  • parse_single_text_expression_content (573-586)
  • parse_element (119-192)
  • parse_element (259-261)
  • parse_element (291-293)
  • parse_element (589-622)
  • is_at_list_end (263-268)
  • is_at_list_end (295-297)
crates/biome_html_parser/src/parser.rs (2)
  • checkpoint (51-59)
  • source (98-100)
crates/biome_html_parser/src/token_source.rs (2)
  • single_expression (59-61)
  • checkpoint (154-159)
⏰ 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). (8)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Test Node.js API
  • GitHub Check: Parser conformance
  • GitHub Check: autofix

Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

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

🥳

@ematipico ematipico force-pushed the feat/html-svelte-if branch from ceba33c to 4763ba4 Compare November 9, 2025 12:43
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
crates/biome_html_parser/tests/spec_test.rs (1)

145-145: Is this test change meant to be committed?

The test input was changed from {@html ...} to {@debug something,}, which doesn't align with the PR's objective of implementing Svelte {#if}/{:else}/{/if} syntax. Since this is an ignored quick test (development utility), consider whether this change should be included in the PR or reverted to avoid committing development artifacts.

Also, is the trailing comma in something, intentional for testing edge cases, or accidental?

.changeset/spicy-actors-leave.md (1)

5-5: Optional style refinement.

"can now parse and format" reads more concisely than "is now able to parse and format".

Apply this diff:

-Added support for the Svelte syntax `{#if}{/if}`. The Biome HTML parser is now able to parse and format the [`{#if}{/if} blocks`](https://svelte.dev/docs/svelte/if):
+Added support for the Svelte syntax `{#if}{/if}`. The Biome HTML parser can now parse and format the [`{#if}{/if} blocks`](https://svelte.dev/docs/svelte/if):
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81d25b4 and 4763ba4.

⛔ Files ignored due to path filters (19)
  • crates/biome_html_factory/src/generated/node_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_factory/src/generated/syntax_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else_if_else.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/error/svelte/debug-trailing-comma.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/error/svelte/debug.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_close.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else_if_else.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_parser/tests/html_specs/ok/svelte/key.svelte.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_syntax/src/generated/kind.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/macros.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/nodes.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_html_syntax/src/generated/nodes_mut.rs is excluded by !**/generated/**, !**/generated/** and included by **
📒 Files selected for processing (35)
  • .changeset/spicy-actors-leave.md (1 hunks)
  • crates/biome_html_formatter/src/generated.rs (3 hunks)
  • crates/biome_html_formatter/src/html/auxiliary/element.rs (1 hunks)
  • crates/biome_html_formatter/src/html/lists/element_list.rs (5 hunks)
  • crates/biome_html_formatter/src/lib.rs (0 hunks)
  • crates/biome_html_formatter/src/svelte/any/block.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (2 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs (0 hunks)
  • crates/biome_html_formatter/src/svelte/auxiliary/mod.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs (1 hunks)
  • crates/biome_html_formatter/src/svelte/lists/mod.rs (1 hunks)
  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte (1 hunks)
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else.svelte (1 hunks)
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else_if_else.svelte (1 hunks)
  • crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte (1 hunks)
  • crates/biome_html_parser/src/lexer/mod.rs (4 hunks)
  • crates/biome_html_parser/src/lexer/tests.rs (1 hunks)
  • crates/biome_html_parser/src/parser.rs (2 hunks)
  • crates/biome_html_parser/src/syntax/mod.rs (3 hunks)
  • crates/biome_html_parser/src/syntax/parse_error.rs (1 hunks)
  • crates/biome_html_parser/src/syntax/svelte.rs (9 hunks)
  • crates/biome_html_parser/src/token_source.rs (2 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte (1 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if.svelte (1 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else.svelte (1 hunks)
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else_if_else.svelte (1 hunks)
  • crates/biome_html_parser/tests/spec_test.rs (1 hunks)
  • crates/biome_syntax_codegen/src/generate_syntax_kinds.rs (0 hunks)
  • xtask/codegen/html.ungram (2 hunks)
  • xtask/codegen/src/html_kinds_src.rs (2 hunks)
💤 Files with no reviewable changes (3)
  • crates/biome_html_formatter/src/lib.rs
  • crates/biome_syntax_codegen/src/generate_syntax_kinds.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs
🚧 Files skipped from review as they are similar to previous changes (14)
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_formatter/src/svelte/lists/else_if_clause_list.rs
  • crates/biome_html_parser/src/syntax/mod.rs
  • crates/biome_html_parser/src/syntax/parse_error.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/mod.rs
  • crates/biome_html_parser/src/token_source.rs
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else.svelte
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else_if_else.svelte
  • crates/biome_html_formatter/src/svelte/lists/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if.svelte
  • crates/biome_html_formatter/tests/specs/html/svelte/if_else.svelte
🧰 Additional context used
🧠 Learnings (39)
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/crates/**/src/lexer/mod.rs : Create a lexer module at crates/<parser_crate>/src/lexer/mod.rs

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Lexer must implement the biome_parser::Lexer trait

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Implement FormatLanguage for HtmlFormatLanguage with associated types: SyntaxLanguage=HtmlLanguage, Context=HtmlFormatContext, FormatRule=FormatHtmlSyntaxNode

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Add a new LanguageKind variant (e.g., Html) in language_kind.rs and implement/cover all methods

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • xtask/codegen/src/html_kinds_src.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/comments.rs : Expose a public HtmlComments type alias: `pub type HtmlComments = Comments<HtmlLanguage>;`

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_parser/src/lexer/mod.rs
📚 Learning: 2025-11-09T12:47:46.273Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8031
File: crates/biome_html_parser/src/syntax/svelte.rs:140-147
Timestamp: 2025-11-09T12:47:46.273Z
Learning: In the Biome HTML parser, `expect` and `expect_with_context` consume the current token and then lex the next token. The context parameter in `expect_with_context` controls how the next token (after the consumed one) is lexed, not the current token being consumed. For example, in Svelte parsing, after `bump_with_context(T!["{:"], HtmlLexContext::Svelte)`, the next token is already lexed in the Svelte context, so `expect(T![else])` is sufficient unless the token after `else` also needs to be lexed in a specific context.

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_parser/src/syntax/svelte.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/lexer/tests.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/context.rs : Create HtmlFormatContext in context.rs with comments and source_map fields and implement FormatContext and CstFormatContext

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/xtask/codegen/src/*_kinds_src.rs : Add src/<lang>_kinds_src.rs under xtask/codegen that returns a static KindSrc

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • xtask/codegen/src/html_kinds_src.rs
  • crates/biome_html_parser/src/lexer/tests.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/language.rs : Create tests/language.rs defining `HtmlTestFormatLanguage` and implement the TestFormatLanguage trait

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/cst.rs : Create FormatHtmlSyntaxNode in cst.rs implementing FormatRule<HtmlSyntaxNode> and AsFormat/IntoFormat for HtmlSyntaxNode using the provided plumbing

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Define the HtmlFormatter type alias: `type HtmlFormatter<'buf> = Formatter<'buf, HtmlFormatContext>;`

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For non-mandatory tokens, use the provided helper constructors (e.g., `token`, `space_token`, `dynamic_token`)

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/lexer/tests.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When a token is mandatory and present in the AST, use the AST-provided token (e.g., `node.l_paren_token().format()`) instead of emitting a static token

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_parser/src/syntax/svelte.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-03T12:28:56.788Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7670
File: crates/biome_service/src/file_handlers/html.rs:744-748
Timestamp: 2025-10-03T12:28:56.788Z
Learning: In Biome's codebase, when creating tokens with new text content, use the factory pattern with functions like `ident(text)` from the respective `*_factory` crates (e.g., `biome_html_factory::make::ident`). There is no `.with_text()` method on tokens. The `ident()` function creates a new detached token with the IDENT kind, which is the standard approach for token construction.

Applied to files:

  • crates/biome_html_parser/src/parser.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: If lookahead is needed, wrap the lexer with BufferedLexer and implement TokenSourceWithBufferedLexer and LexerWithCheckpoint

Applied to files:

  • crates/biome_html_parser/src/parser.rs
  • crates/biome_html_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import and use the `FormatNode` trait for AST nodes

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_parser/src/syntax/svelte.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Implement the `Format` trait for your node type and use `JsFormatter` with `write!`/`format_args!` to define formatting

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code; if a mandatory token/node is missing, return `None` instead

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_parser/src/syntax/svelte.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Expose a documented public function `format_node(options: HtmlFormatOptions, root: &HtmlSyntaxNode) -> FormatResult<Formatted<HtmlFormatContext>>` delegating to `biome_formatter::format_node`

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/generated.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: The formatter relies on two pillars: implementing `Format`/`FormatNode` for nodes and creating an intermediate IR via helpers

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs
📚 Learning: 2025-10-25T07:22:18.540Z
Learnt from: ematipico
Repo: biomejs/biome PR: 7852
File: crates/biome_css_parser/src/syntax/property/mod.rs:161-168
Timestamp: 2025-10-25T07:22:18.540Z
Learning: In the Biome CSS parser, lexer token emission should not be gated behind parser options like `is_tailwind_directives_enabled()`. The lexer must emit correct tokens regardless of parser options to enable accurate diagnostics and error messages when the syntax is used incorrectly.

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
  • crates/biome_html_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Parse rules should return ParsedSyntax; return Absent without consuming tokens when the node cannot be predicted

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Use p.eat for optional tokens, p.expect for required tokens; use .ok() for optional nodes and .or_add_diagnostic(...) for required nodes

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: When parsing lists, implement error recovery (e.g., via ParseSeparatedList/ParseNodeList) to avoid infinite loops

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/xtask/codegen/*.ungram : List node types must end with the postfix List (e.g., HtmlAttributeList)

Applied to files:

  • crates/biome_html_parser/src/syntax/svelte.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Add the provided AsFormat, IntoFormat, and iterator plumbing code to lib.rs

Applied to files:

  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/svelte/any/block.rs
  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/comments.rs : Define HtmlCommentStyle implementing CommentStyle in comments.rs

Applied to files:

  • crates/biome_html_formatter/src/html/lists/element_list.rs
  • crates/biome_html_formatter/src/generated.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/spec_tests.rs : In tests/spec_tests.rs, generate tests with `tests_macros::gen_tests! {"tests/specs/html/**/*.html", crate::spec_test::run, ""}`

Applied to files:

  • crates/biome_html_parser/src/lexer/mod.rs
  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/xtask/codegen/*.ungram : Nodes for enclosing syntax errors must include the Bogus word (e.g., HtmlBogusAttribute)

Applied to files:

  • crates/biome_html_parser/src/lexer/mod.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use `dbg_write!` to debug and inspect the emitted IR during formatting

Applied to files:

  • crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs
  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Add a new language prefix (e.g., html_) to LANGUAGE_PREFIXES in language_kind.rs

Applied to files:

  • xtask/codegen/src/html_kinds_src.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/specs/html/**/*.html : Place HTML test cases under tests/specs/html as .html files discovered by the test macro

Applied to files:

  • crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte
  • crates/biome_html_parser/tests/html_specs/ok/svelte/if_else_if_else.svelte
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte
📚 Learning: 2025-10-15T09:25:05.698Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:25:05.698Z
Learning: Applies to crates/biome_service/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in ../biome_lsp/src/server.tests.rs

Applied to files:

  • crates/biome_html_parser/src/lexer/tests.rs
  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference}.rs : When inference is missing or cannot determine a type, use TypeData::Unknown; use TypeData::UnknownKeyword only when the user explicitly wrote unknown.

Applied to files:

  • crates/biome_html_parser/src/lexer/tests.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/type_info.rs : Add new TypeScript type support by extending the TypeData enum rather than introducing parallel structures.

Applied to files:

  • crates/biome_html_parser/src/lexer/tests.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/spec_test.rs : Implement a `run` function in tests/spec_test.rs that wires SpecSnapshot and includes!("language.rs") as shown

Applied to files:

  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/** : Create a tests directory containing a specs subfolder and the files spec_test.rs, spec_tests.rs, and language.rs

Applied to files:

  • crates/biome_html_parser/tests/spec_test.rs
  • crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/xtask/codegen/*.ungram : Bogus nodes must be part of a variant/union (e.g., AnyHtmlAttribute includes HtmlBogusAttribute)

Applied to files:

  • crates/biome_html_parser/tests/spec_test.rs
🧬 Code graph analysis (8)
crates/biome_html_parser/src/parser.rs (2)
crates/biome_html_parser/src/lexer/mod.rs (1)
  • re_lex (962-982)
crates/biome_html_parser/src/token_source.rs (1)
  • re_lex (168-170)
crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (5)
crates/biome_html_syntax/src/generated/nodes.rs (34)
  • html (624-626)
  • sv_curly_colon_token (1024-1026)
  • sv_curly_colon_token (1076-1078)
  • else_token (1027-1029)
  • else_token (1079-1081)
  • if_token (1082-1084)
  • if_token (1236-1238)
  • if_token (1283-1285)
  • expression (441-443)
  • expression (726-728)
  • expression (880-882)
  • expression (930-932)
  • expression (1085-1087)
  • expression (1140-1142)
  • expression (1286-1288)
  • expression (1430-1432)
  • expression (1515-1517)
  • r_curly_token (729-731)
  • r_curly_token (883-885)
  • r_curly_token (933-935)
  • r_curly_token (983-985)
  • r_curly_token (1030-1032)
  • r_curly_token (1088-1090)
  • r_curly_token (1143-1145)
  • r_curly_token (1239-1241)
  • r_curly_token (1289-1291)
  • r_curly_token (1384-1386)
  • r_curly_token (1433-1435)
  • r_curly_token (1518-1520)
  • children (486-488)
  • children (1033-1035)
  • children (1091-1093)
  • children (1292-1294)
  • children (1336-1338)
crates/biome_html_formatter/src/html/lists/element_list.rs (2)
  • write (761-797)
  • write (907-921)
crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1)
  • fmt_fields (9-32)
crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1)
  • fmt_fields (9-35)
crates/biome_formatter/src/builders.rs (2)
  • space (606-608)
  • hard_line_break (99-101)
crates/biome_html_parser/src/syntax/svelte.rs (4)
crates/biome_html_parser/src/syntax/parse_error.rs (2)
  • expected_child_or_block (43-45)
  • expected_text_expression (35-37)
crates/biome_html_parser/src/syntax/mod.rs (1)
  • parse_single_text_expression_content (573-586)
crates/biome_html_parser/src/parser.rs (2)
  • checkpoint (51-59)
  • source (98-100)
crates/biome_html_parser/src/token_source.rs (2)
  • single_expression (59-61)
  • checkpoint (154-159)
crates/biome_html_formatter/src/html/lists/element_list.rs (3)
crates/biome_formatter/src/format_element/tag.rs (1)
  • with_group_id (229-232)
crates/biome_formatter/src/lib.rs (1)
  • group_id (2136-2138)
crates/biome_formatter/src/builders.rs (2)
  • if_group_breaks (1943-1952)
  • if_group_fits_on_line (2024-2033)
crates/biome_html_parser/src/lexer/mod.rs (2)
crates/biome_html_parser/src/token_source.rs (3)
  • lexer (227-229)
  • re_lex (168-170)
  • current (176-178)
crates/biome_html_parser/src/parser.rs (2)
  • context (90-92)
  • re_lex (73-75)
crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs (5)
crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1)
  • fmt_fields (9-32)
crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1)
  • fmt_fields (9-38)
crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs (1)
  • fmt_fields (8-23)
crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1)
  • fmt_fields (9-35)
crates/biome_html_syntax/src/generated/nodes.rs (6)
  • opening_block (1184-1186)
  • opening_block (1333-1335)
  • else_if_clauses (1187-1189)
  • else_clause (1190-1192)
  • closing_block (1193-1195)
  • closing_block (1339-1341)
crates/biome_html_formatter/src/generated.rs (3)
crates/biome_js_syntax/src/file_source.rs (1)
  • svelte (222-224)
crates/biome_html_syntax/src/file_source.rs (1)
  • svelte (96-100)
crates/biome_html_syntax/src/generated/nodes.rs (1)
  • else_clause (1190-1192)
crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (9)
crates/biome_html_syntax/src/generated/nodes.rs (32)
  • html (624-626)
  • sv_curly_hash_token (1280-1282)
  • sv_curly_hash_token (1424-1426)
  • if_token (1082-1084)
  • if_token (1236-1238)
  • if_token (1283-1285)
  • expression (441-443)
  • expression (726-728)
  • expression (880-882)
  • expression (930-932)
  • expression (1085-1087)
  • expression (1140-1142)
  • expression (1286-1288)
  • expression (1430-1432)
  • expression (1515-1517)
  • r_curly_token (729-731)
  • r_curly_token (883-885)
  • r_curly_token (933-935)
  • r_curly_token (983-985)
  • r_curly_token (1030-1032)
  • r_curly_token (1088-1090)
  • r_curly_token (1143-1145)
  • r_curly_token (1239-1241)
  • r_curly_token (1289-1291)
  • r_curly_token (1384-1386)
  • r_curly_token (1433-1435)
  • r_curly_token (1518-1520)
  • children (486-488)
  • children (1033-1035)
  • children (1091-1093)
  • children (1292-1294)
  • children (1336-1338)
crates/biome_html_formatter/src/html/lists/element_list.rs (2)
  • write (761-797)
  • write (907-921)
crates/biome_html_formatter/src/svelte/auxiliary/else_clause.rs (1)
  • fmt_fields (9-32)
crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1)
  • fmt_fields (9-38)
crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs (1)
  • fmt_fields (7-24)
crates/biome_html_formatter/src/svelte/auxiliary/if_closing_block.rs (1)
  • fmt_fields (8-23)
crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (1)
  • fmt_fields (9-24)
crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs (1)
  • fmt_fields (8-25)
crates/biome_formatter/src/builders.rs (1)
  • hard_line_break (99-101)
🪛 LanguageTool
.changeset/spicy-actors-leave.md

[style] ~5-~5: As a shorter alternative for ‘able to’, consider using “can now”.
Context: ...tax {#if}{/if}. The Biome HTML parser is now able to parse and format the [`{#if}{/if} block...

(BE_ABLE_TO)

⏰ 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). (8)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test Node.js API
  • GitHub Check: Parser conformance
  • GitHub Check: autofix
🔇 Additional comments (24)
crates/biome_html_parser/tests/html_specs/ok/svelte/if.svelte (1)

7-12: Verify mixed indentation is intentional.

Lines 8 and 10 use spaces for indentation whilst surrounding lines use tabs. If this tests the formatter's handling of inconsistent input, brilliant. Otherwise, it's worth standardising.

xtask/codegen/src/html_kinds_src.rs (2)

26-26: LGTM!

Keywords "else" and "if" correctly added for Svelte conditional syntax.


73-78: LGTM!

The six new node kinds properly represent the Svelte if/else structure: block, opening, closing, else-if list, else-if clause, and else clause. Well structured.

crates/biome_html_parser/src/syntax/svelte.rs (6)

22-38: LGTM!

Clean dispatch pattern for hash blocks using the parent marker. Routing to key and if handlers is straightforward.


57-100: LGTM!

The if block parsing is well structured. The opening block handler correctly uses single_expression() context for the condition and stop_at_curly_colon to halt element parsing at else-if/else boundaries.


103-136: LGTM!

Clever use of checkpoint and rewind to differentiate {:else if} from {:else}. The lookahead at line 114 correctly identifies standalone else blocks and backtracks.


138-149: LGTM!

The else clause parsing is correct. Per the learning from @ematipico, after bump_with_context(T!["{:"], HtmlLexContext::Svelte) on line 144, the next token (else) is already lexed in Svelte context, so expect(T![else]) on line 145 is sufficient.

Based on learnings


338-384: LGTM!

The configurable stop_at_curly_colon flag elegantly solves the boundary detection problem for if/else-if/else element lists.


398-419: Creative re-lexing lookahead for detecting {:else} vs {:else if}.

The checkpoint-bump-relex-rewind dance works around lexing constraints to peek ahead and distinguish between else-if continuation and else termination. Whilst effective, it's worth confirming there's no simpler approach as this adds some complexity.

If this is the idiomatic pattern for Svelte keyword disambiguation in the parser, consider adding a brief comment explaining why re-lexing is necessary here.

crates/biome_html_formatter/src/svelte/any/block.rs (1)

15-15: LGTM!

Match arm for SvelteIfBlock correctly added to the formatter dispatch.

crates/biome_html_parser/tests/html_specs/ok/svelte/debug.svelte (1)

3-3: LGTM!

Good edge case: using the debug keyword as a variable name. Tests parser's ability to handle keyword context correctly.

crates/biome_html_parser/tests/html_specs/ok/svelte/if_else_if_else.svelte (1)

1-8: LGTM!

Clean test fixture covering the if/else-if/else pattern with consistent formatting. Perfect for validating the parser and formatter.

crates/biome_html_formatter/tests/specs/html/svelte/if_nested.svelte (1)

3-8: Verify mixed indentation is intentional.

Lines 4 and 6 use spaces for indentation whilst others use tabs. If this is testing the formatter's normalisation of inconsistent input, spot on. Otherwise, worth aligning with the rest.

crates/biome_html_parser/src/lexer/tests.rs (1)

397-397: LGTM! Test expectations correctly updated.

The change from SVELTE_IDENT to DEBUG_KW aligns with the lexer's new specific token kinds for Svelte keywords. Both test cases now correctly expect DEBUG_KW for the "debug" identifier in Svelte context.

Also applies to: 404-404

crates/biome_html_parser/src/parser.rs (1)

71-75: LGTM! Clean re-lexing entry point.

The new re_lex method provides a clear public interface for context-aware re-tokenization, properly delegating to the underlying token source. The documentation comment accurately describes the method's behavior.

crates/biome_html_formatter/src/svelte/auxiliary/if_block.rs (1)

1-25: LGTM! Well-structured formatter implementation.

The FormatSvelteIfBlock formatter follows the established pattern for Svelte block formatting. The field ordering (opening, else-if clauses, else clause, closing) correctly reflects the grammar structure and matches the conventions used in similar formatters like FormatSvelteKeyBlock.

crates/biome_html_formatter/src/svelte/auxiliary/if_opening_block.rs (1)

1-36: LGTM! Consistent opening block formatter.

The implementation correctly formats the Svelte if opening block with proper token ordering and delegates child formatting to FormatHtmlElementList with an appropriate group ID. The pattern matches other opening block formatters (e.g., FormatSvelteKeyOpeningBlock), ensuring consistency across the codebase.

crates/biome_html_formatter/src/svelte/auxiliary/else_if_clause.rs (1)

1-39: LGTM! Proper else-if clause formatting.

The formatter correctly handles the {:else if ...} syntax with appropriate spacing between tokens (line 24's space()). The implementation follows the established pattern with proper child delegation and grouping.

crates/biome_html_formatter/src/html/lists/element_list.rs (2)

31-38: LGTM! Clean group support addition.

The new with_group_id method provides a fluent interface for attaching group IDs to element lists, enabling coordinated formatting decisions across Svelte blocks and other grouped content.


137-167: LGTM! Proper group-aware formatting implementation.

The new Format implementation for FormatChildrenResult correctly threads the group ID through the formatting logic. The fallback to a generated group ID (line 148) ensures consistent behavior when no explicit group is provided, and the use of if_group_breaks and if_group_fits_on_line with the group ID enables proper coordination of line breaking decisions.

crates/biome_html_parser/src/lexer/mod.rs (2)

417-427: LGTM! Proper Svelte keyword tokenization.

The updated identifier matching correctly emits specific token kinds (IF_KW, ELSE_KW, DEBUG_KW, etc.) for Svelte keywords, replacing the previous generic SVELTE_IDENT. This provides better type safety and enables more precise parser logic downstream.


961-983: LGTM! Solid re-lexing implementation.

The ReLexer implementation correctly handles context-aware re-tokenization. The position preservation logic (lines 974-976) when no re-lexing occurs is important for avoiding unnecessary work, and the delegation to appropriate consume methods based on HtmlReLexContext is clean and maintainable.

xtask/codegen/html.ungram (1)

268-312: LGTM! Comprehensive Svelte conditional grammar.

The grammar correctly models Svelte's {#if} / {:else if} / {:else} / {/if} syntax with appropriate nesting and optional branches. The structure with separate SvelteIfOpeningBlock, SvelteElseIfClauseList, optional SvelteElseClause, and mandatory SvelteIfClosingBlock accurately reflects the language's conditional block semantics and enables proper parsing of all valid Svelte conditional patterns.

crates/biome_html_formatter/src/generated.rs (1)

833-1346: LGTM! Generated code follows established patterns.

This is auto-generated formatter wiring for the new Svelte if/else syntax nodes. All implementations follow the exact boilerplate pattern used throughout the file, correctly delegating to the corresponding format modules.

@ematipico ematipico merged commit fa6798a into main Nov 9, 2025
14 checks passed
@ematipico ematipico deleted the feat/html-svelte-if branch November 9, 2025 12:58
@github-actions github-actions bot mentioned this pull request Nov 9, 2025
ematipico added a commit to hamirmahal/biome that referenced this pull request Nov 19, 2025
l0ngvh pushed a commit to l0ngvh/biome that referenced this pull request Dec 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Formatter Area: formatter A-Parser Area: parser A-Tooling Area: internal tools L-HTML Language: HTML and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement svelte {#if} {:else if} {:else} {/if}

3 participants