-
-
Notifications
You must be signed in to change notification settings - Fork 791
feat(html/svelte): key blocks #8001
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 5eaa2eb The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
3295620 to
6e6d57e
Compare
WalkthroughAdds parser, lexer, grammar and formatter support for Svelte Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
Parser conformance results onjs/262
jsx/babel
symbols/microsoft
ts/babel
ts/microsoft
|
6e6d57e to
81ca589
Compare
81ca589 to
26baa70
Compare
|
Would be nice to have some error snapshots, but I don't want to block on that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.changeset/light-toys-check.md (1)
5-11: Tweak the changelog wording.A tiny preposition goes a long way—let’s add “for” so the sentence reads naturally.
-Added support Svelte syntax `{#key}`. Biome now is able to parse and format the Svelte syntax [`{#key}`](https://svelte.dev/docs/svelte/key): +Added support for the Svelte syntax `{#key}`. Biome now is able to parse and format the Svelte syntax [`{#key}`](https://svelte.dev/docs/svelte/key):
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (12)
crates/biome_html_factory/src/generated/node_factory.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_html_factory/src/generated/syntax_factory.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_html_formatter/tests/specs/html/component-frameworks/svelte-component-casing.svelte.snapis excluded by!**/*.snapand included by**crates/biome_html_formatter/tests/specs/html/svelte/debug.svelte.snapis excluded by!**/*.snapand included by**crates/biome_html_formatter/tests/specs/html/svelte/key.svelte.snapis excluded by!**/*.snapand included by**crates/biome_html_formatter/tests/specs/html/text_expressions/expressions.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_formatter/tests/specs/prettier/html/front-matter/empty2.html.snapis excluded by!**/*.snapand included by**crates/biome_html_parser/tests/html_specs/ok/svelte/key.svelte.snapis excluded by!**/*.snapand included by**crates/biome_html_syntax/src/generated/kind.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_html_syntax/src/generated/macros.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_html_syntax/src/generated/nodes.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_html_syntax/src/generated/nodes_mut.rsis excluded by!**/generated/**,!**/generated/**and included by**
📒 Files selected for processing (18)
.changeset/light-toys-check.md(1 hunks)crates/biome_html_formatter/src/generated.rs(1 hunks)crates/biome_html_formatter/src/html/lists/element_list.rs(1 hunks)crates/biome_html_formatter/src/svelte/any/block.rs(1 hunks)crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs(1 hunks)crates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rs(1 hunks)crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs(1 hunks)crates/biome_html_formatter/src/svelte/auxiliary/mod.rs(1 hunks)crates/biome_html_formatter/tests/specs/html/svelte/key.svelte(1 hunks)crates/biome_html_parser/src/lexer/mod.rs(4 hunks)crates/biome_html_parser/src/syntax/mod.rs(6 hunks)crates/biome_html_parser/src/syntax/parse_error.rs(1 hunks)crates/biome_html_parser/src/syntax/svelte.rs(2 hunks)crates/biome_html_parser/src/token_source.rs(1 hunks)crates/biome_html_parser/tests/html_specs/ok/svelte/key.svelte(1 hunks)crates/biome_html_parser/tests/spec_test.rs(1 hunks)xtask/codegen/html.ungram(1 hunks)xtask/codegen/src/html_kinds_src.rs(2 hunks)
🧰 Additional context used
🧠 Learnings (37)
📚 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/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_parser/src/token_source.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.rscrates/biome_html_parser/src/lexer/mod.rscrates/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/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/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_formatter/src/svelte/any/block.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.rscrates/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/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities
Applied to files:
crates/biome_html_parser/src/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_formatter/src/svelte/any/block.rscrates/biome_html_parser/tests/spec_test.rscrates/biome_html_formatter/src/svelte/auxiliary/mod.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.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_parser/src/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_formatter/src/svelte/any/block.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.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,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.
Applied to files:
crates/biome_html_parser/src/syntax/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/comments.rs : Expose a public HtmlComments type alias: `pub type HtmlComments = Comments<HtmlLanguage>;`
Applied to files:
crates/biome_html_parser/src/syntax/mod.rscrates/biome_html_formatter/src/html/lists/element_list.rscrates/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 : 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/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/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/crates/biome_*_{syntax,factory}/** : Create per-language crates biome_<lang>_syntax and biome_<lang>_factory under crates/
Applied to files:
crates/biome_html_parser/src/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/mod.rscrates/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/xtask/codegen/*.ungram : Nodes for enclosing syntax errors must include the Bogus word (e.g., HtmlBogusAttribute)
Applied to files:
crates/biome_html_parser/src/syntax/mod.rscrates/biome_html_parser/src/syntax/parse_error.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_parser/src/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_formatter/src/svelte/any/block.rscrates/biome_html_parser/tests/spec_test.rscrates/biome_html_formatter/src/svelte/auxiliary/mod.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/html/lists/element_list.rscrates/biome_html_parser/src/syntax/parse_error.rscrates/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/syntax/mod.rscrates/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 : Define the HtmlFormatter type alias: `type HtmlFormatter<'buf> = Formatter<'buf, HtmlFormatContext>;`
Applied to files:
crates/biome_html_parser/src/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.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/syntax/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_parser/tests/spec_test.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.rscrates/biome_html_parser/tests/html_specs/ok/svelte/key.sveltecrates/biome_html_parser/src/lexer/mod.rscrates/biome_html_formatter/tests/specs/html/svelte/key.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: When parsing lists, implement error recovery (e.g., via ParseSeparatedList/ParseNodeList) to avoid infinite loops
Applied to files:
crates/biome_html_parser/src/syntax/mod.rscrates/biome_html_parser/src/syntax/svelte.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/key_closing_block.rscrates/biome_html_formatter/src/svelte/any/block.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_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/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/auxiliary/key_closing_block.rscrates/biome_html_parser/src/token_source.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.rscrates/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 : For non-mandatory tokens, use the provided helper constructors (e.g., `token`, `space_token`, `dynamic_token`)
Applied to files:
crates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rscrates/biome_html_parser/src/token_source.rscrates/biome_html_formatter/src/svelte/auxiliary/mod.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/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 : 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/key_closing_block.rscrates/biome_html_formatter/src/svelte/any/block.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.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/tests/spec_test.rscrates/biome_html_parser/tests/html_specs/ok/svelte/key.sveltecrates/biome_html_formatter/tests/specs/html/svelte/key.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/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/spec_test.rscrates/biome_html_parser/tests/html_specs/ok/svelte/key.sveltecrates/biome_html_formatter/tests/specs/html/svelte/key.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/tests/spec_test.rscrates/biome_html_parser/tests/html_specs/ok/svelte/key.sveltecrates/biome_html_formatter/tests/specs/html/svelte/key.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_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
📚 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.rscrates/biome_html_parser/tests/html_specs/ok/svelte/key.sveltecrates/biome_html_formatter/tests/specs/html/svelte/key.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.rs : Add new TypeScript type support by extending the TypeData enum rather than introducing parallel structures.
Applied to files:
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/src/workspace/watcher.tests.rs : Place watcher tests related to workspace methods in src/workspace/watcher.tests.rs
Applied to files:
crates/biome_html_parser/tests/spec_test.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.rsxtask/codegen/src/html_kinds_src.rscrates/biome_html_parser/src/lexer/mod.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/token_source.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/auxiliary/mod.rscrates/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/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/auxiliary/mod.rsxtask/codegen/src/html_kinds_src.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/auxiliary/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 : Add the provided AsFormat, IntoFormat, and iterator plumbing code to lib.rs
Applied to files:
crates/biome_html_formatter/src/svelte/auxiliary/mod.rscrates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_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 : Use `dbg_write!` to debug and inspect the emitted IR during formatting
Applied to files:
crates/biome_html_formatter/src/svelte/auxiliary/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: 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/src/comments.rs : Define HtmlCommentStyle implementing CommentStyle in comments.rs
Applied to files:
crates/biome_html_formatter/src/generated.rscrates/biome_html_formatter/src/svelte/auxiliary/key_block.rscrates/biome_html_formatter/src/html/lists/element_list.rscrates/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: 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
📚 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: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
🧬 Code graph analysis (7)
crates/biome_html_parser/src/syntax/mod.rs (2)
crates/biome_html_parser/src/syntax/svelte.rs (4)
parse_svelte_at_block(92-106)parse_svelte_hash_block(17-24)parse_element(138-140)parse_element(185-187)crates/biome_html_parser/src/syntax/parse_error.rs (1)
disabled_interpolation(12-14)
crates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rs (3)
crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (1)
fmt_fields(9-48)crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs (1)
fmt_fields(8-26)crates/biome_html_syntax/src/generated/nodes.rs (7)
sv_curly_slash_token(968-970)key_token(971-973)key_token(1017-1019)r_curly_token(729-731)r_curly_token(883-885)r_curly_token(974-976)r_curly_token(1023-1025)
crates/biome_html_formatter/src/generated.rs (1)
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)
crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs (4)
crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (1)
fmt_fields(9-48)crates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rs (1)
fmt_fields(8-23)crates/biome_html_syntax/src/generated/nodes.rs (10)
sv_curly_hash_token(1014-1016)key_token(971-973)key_token(1017-1019)expression(441-443)expression(726-728)expression(1020-1022)r_curly_token(729-731)r_curly_token(883-885)r_curly_token(974-976)r_curly_token(1023-1025)crates/biome_formatter/src/builders.rs (1)
space(606-608)
crates/biome_html_formatter/src/svelte/auxiliary/key_block.rs (5)
crates/biome_html_syntax/src/generated/nodes.rs (5)
html(624-626)opening_block(923-925)children(486-488)children(926-928)closing_block(929-931)crates/biome_html_formatter/src/html/lists/element_list.rs (2)
write(717-753)write(863-877)crates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rs (1)
fmt_fields(8-23)crates/biome_html_formatter/src/svelte/auxiliary/key_opening_block.rs (1)
fmt_fields(8-26)crates/biome_formatter/src/builders.rs (2)
if_group_breaks(1943-1952)if_group_fits_on_line(2024-2033)
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 (2)
crates/biome_html_parser/src/syntax/parse_error.rs (1)
expected_child(35-37)crates/biome_html_parser/src/syntax/mod.rs (9)
parse_html_element(213-244)parse_element(114-187)parse_element(254-256)parse_element(286-288)parse_element(562-592)is_at_list_end(258-263)is_at_list_end(290-292)recover(265-275)recover(294-304)
🪛 LanguageTool
.changeset/light-toys-check.md
[style] ~5-~5: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...pport Svelte syntax {#key}. Biome now is able to parse and format the Svelte syntax [`{#...
(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). (7)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Documentation
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Check Dependencies
- GitHub Check: Test Node.js API
- GitHub Check: autofix
🔇 Additional comments (12)
crates/biome_html_formatter/src/html/lists/element_list.rs (1)
26-26: Doc comment reformatting looks fine.Minor style change; no functional impact.
crates/biome_html_parser/src/syntax/parse_error.rs (1)
36-36: Good addition for Svelte key block support.Expanding the expected child types to include "closing block" improves diagnostic accuracy for Svelte contexts.
xtask/codegen/src/html_kinds_src.rs (1)
24-24: Codegen additions for Svelte key blocks look correct.The new "key" keyword and three node types follow the established pattern for Svelte block support.
Also applies to: 61-63
crates/biome_html_parser/src/lexer/mod.rs (3)
6-6: KEY_KW additions look correct.Proper integration of the new keyword for Svelte key block lexing.
Also applies to: 427-427
1021-1021: Minor formatting improvement.Adding a newline before the QuotesSeen struct improves readability.
269-269: Based on my research, the change fixes nested curly bracket handling in theconsume_single_text_expressionmethod through a brackets_stack mechanism, resolving issues with parsing text expressions containing nested curly brackets in Astro and Svelte files.The test output you provided shows extensive test coverage for single text expressions across Vue, Svelte, and Astro templates, with proper AST parsing structures visible in the snapshots. The visible test cases—including complex nested expressions like
{{ call(fn({ inner })) }}—all parse correctly.No issues found with the bracket handling change.
The conditional decrement you mentioned is part of a structural improvement, not a breaking change. The lexer modifications fix nested curly bracket handling through a brackets_stack mechanism, which improves upon the previous unconditional logic. Existing Svelte, Vue, and Astro expression parsing continues to work as expected.
crates/biome_html_formatter/src/svelte/any/block.rs (1)
13-13: Perfect pattern match.The new match arm correctly integrates SvelteKeyBlock formatting.
crates/biome_html_formatter/tests/specs/html/svelte/key.svelte (1)
1-3: Basic test coverage in place.The test covers the fundamental key block structure. Consider adding tests for edge cases (nested blocks, empty blocks, multiple children) in follow-up work.
crates/biome_html_parser/tests/spec_test.rs (1)
145-150: Quick test updated for key blocks.The ignored development test now exercises the new key block parsing. Handy for local iteration.
crates/biome_html_parser/tests/html_specs/ok/svelte/key.svelte (1)
1-7: Nicely covers the keyword/identifier ambiguity.Testing "key" as both a keyword (in
{#key}) and as an identifier name (in{#key key}) is clever and thorough.crates/biome_html_formatter/src/svelte/auxiliary/key_closing_block.rs (1)
15-21: Token order looks perfect.The formatter now emits
{/key}in the exact order Svelte expects, so nothing goes sideways when we rebuild the closing block.(svelte.dev)xtask/codegen/html.ungram (1)
192-224: Grammar matches Svelte’s key-block shape.Nice to see
{#key expression}paired with{/key}exactly as the docs describe; the AST additions will line up cleanly with the formatter work above.(svelte.dev)
| pub(crate) fn parse_key_block(p: &mut HtmlParser) -> ParsedSyntax { | ||
| if !p.at(T!["{#"]) { | ||
| return Absent; | ||
| } | ||
|
|
||
| let m = p.start(); | ||
|
|
||
| parse_opening_block(p, T![key], SVELTE_KEY_OPENING_BLOCK).ok(); | ||
|
|
||
| SvelteElementList.parse_list(p); | ||
|
|
||
| parse_closing_block(p, T![key], SVELTE_KEY_CLOSING_BLOCK).ok(); | ||
|
|
||
| Present(m.complete(p, SVELTE_KEY_BLOCK)) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please bail out when this isn’t {#key …}.
Right now parse_svelte_hash_block always falls through to parse_key_block. When we encounter {#if …} (or any other hash block), parse_opening_block rewinds and returns Absent, but parse_key_block still completes a SVELTE_KEY_BLOCK and the cursor never advances, so we recurse straight back into the same code path. That can spin forever and it also hijacks the existing {#if}/{#each} parsing. Please abandon the marker and return Absent as soon as the keyword-matching fails, then reinstate the old or_else chain so the other hash blocks still get their turn.
- parse_opening_block(p, T![key], SVELTE_KEY_OPENING_BLOCK).ok();
+ match parse_opening_block(p, T![key], SVELTE_KEY_OPENING_BLOCK) {
+ Present(_) => {}
+ Absent => {
+ m.abandon(p);
+ return Absent;
+ }
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| pub(crate) fn parse_key_block(p: &mut HtmlParser) -> ParsedSyntax { | |
| if !p.at(T!["{#"]) { | |
| return Absent; | |
| } | |
| let m = p.start(); | |
| parse_opening_block(p, T![key], SVELTE_KEY_OPENING_BLOCK).ok(); | |
| SvelteElementList.parse_list(p); | |
| parse_closing_block(p, T![key], SVELTE_KEY_CLOSING_BLOCK).ok(); | |
| Present(m.complete(p, SVELTE_KEY_BLOCK)) | |
| } | |
| pub(crate) fn parse_key_block(p: &mut HtmlParser) -> ParsedSyntax { | |
| if !p.at(T!["{#"]) { | |
| return Absent; | |
| } | |
| let m = p.start(); | |
| match parse_opening_block(p, T![key], SVELTE_KEY_OPENING_BLOCK) { | |
| Present(_) => {} | |
| Absent => { | |
| m.abandon(p); | |
| return Absent; | |
| } | |
| } | |
| SvelteElementList.parse_list(p); | |
| parse_closing_block(p, T![key], SVELTE_KEY_CLOSING_BLOCK).ok(); | |
| Present(m.complete(p, SVELTE_KEY_BLOCK)) | |
| } |
🤖 Prompt for AI Agents
In crates/biome_html_parser/src/syntax/svelte.rs around lines 26–40,
parse_key_block currently always completes a SVELTE_KEY_BLOCK even when
parse_opening_block fails to match the "key" keyword; change the control flow so
that immediately after calling parse_opening_block you check its result and if
it indicates no match you call m.abandon(p) (to discard the marker) and return
Absent; only proceed to parse the element list and closing block when the
opening-block call succeeded. After this change, restore the previous or_else
chaining in parse_svelte_hash_block so other hash-block parsers ({#if}, {#each},
etc.) get a chance when parse_key_block returns Absent.
Done! Good call. Check the snapshots |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
crates/biome_html_parser/src/syntax/svelte.rs (1)
33-46: Bail out when the opening isn’t{#key …}.If
parse_opening_blockrewinds (e.g. we’re looking at{#if}), we still go on to build aSVELTE_KEY_BLOCK, so we recurse forever and hijack the other hash-block parsers. Cut the marker loose and returnAbsentimmediately—same bug I waved at earlier.- let completed = parse_opening_block(p, T![key], SVELTE_KEY_OPENING_BLOCK).ok(); + let completed = match parse_opening_block(p, T![key], SVELTE_KEY_OPENING_BLOCK) { + Present(marker) => marker, + Absent => { + m.abandon(p); + return Absent; + } + };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
crates/biome_html_parser/tests/html_specs/error/svelte/debug-trailing-comma.svelte.snapis excluded by!**/*.snapand included by**crates/biome_html_parser/tests/html_specs/error/svelte/debug.svelte.snapis excluded by!**/*.snapand included by**crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_close.svelte.snapis excluded by!**/*.snapand included by**crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.svelte.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (6)
crates/biome_html_formatter/src/html/auxiliary/text_expression.rs(1 hunks)crates/biome_html_parser/src/syntax/mod.rs(7 hunks)crates/biome_html_parser/src/syntax/parse_error.rs(2 hunks)crates/biome_html_parser/src/syntax/svelte.rs(2 hunks)crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_close.svelte(1 hunks)crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.svelte(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- crates/biome_html_parser/src/syntax/parse_error.rs
🧰 Additional context used
🧠 Learnings (24)
📚 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/html/auxiliary/text_expression.rscrates/biome_html_parser/src/syntax/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_formatter/src/html/auxiliary/text_expression.rscrates/biome_html_parser/src/syntax/svelte.rscrates/biome_html_parser/src/syntax/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/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/html/auxiliary/text_expression.rscrates/biome_html_parser/src/syntax/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 : 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/html/auxiliary/text_expression.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/html/auxiliary/text_expression.rscrates/biome_html_parser/src/syntax/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 : Define the HtmlFormatter type alias: `type HtmlFormatter<'buf> = Formatter<'buf, HtmlFormatContext>;`
Applied to files:
crates/biome_html_formatter/src/html/auxiliary/text_expression.rscrates/biome_html_parser/src/syntax/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 : 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/html/auxiliary/text_expression.rscrates/biome_html_parser/src/syntax/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/language.rs : Create tests/language.rs defining `HtmlTestFormatLanguage` and implement the TestFormatLanguage trait
Applied to files:
crates/biome_html_formatter/src/html/auxiliary/text_expression.rscrates/biome_html_parser/tests/html_specs/error/svelte/key_missing_close.sveltecrates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.sveltecrates/biome_html_parser/src/syntax/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/comments.rs : Expose a public HtmlComments type alias: `pub type HtmlComments = Comments<HtmlLanguage>;`
Applied to files:
crates/biome_html_formatter/src/html/auxiliary/text_expression.rscrates/biome_html_parser/src/syntax/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 : 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/html/auxiliary/text_expression.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/auxiliary/text_expression.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/html/auxiliary/text_expression.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/error/svelte/key_missing_close.sveltecrates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.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_parser/tests/html_specs/error/svelte/key_missing_close.sveltecrates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.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/html_specs/error/svelte/key_missing_close.sveltecrates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.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/tests/html_specs/error/svelte/key_missing_close.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: 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.rscrates/biome_html_parser/src/syntax/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 : 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: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_parser/src/syntax/svelte.rscrates/biome_html_parser/src/syntax/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: 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_parser/src/syntax/mod.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,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.
Applied to files:
crates/biome_html_parser/src/syntax/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/syntax/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/syntax/mod.rs
🧬 Code graph analysis (3)
crates/biome_html_formatter/src/html/auxiliary/text_expression.rs (1)
crates/biome_html_formatter/src/verbatim.rs (1)
format_verbatim_skipped(40-46)
crates/biome_html_parser/src/syntax/svelte.rs (2)
crates/biome_html_parser/src/syntax/parse_error.rs (2)
expected_child(35-37)expected_svelte_closing_block(96-98)crates/biome_html_parser/src/syntax/mod.rs (9)
parse_html_element(213-244)parse_element(114-187)parse_element(254-256)parse_element(286-288)parse_element(560-593)is_at_list_end(258-263)is_at_list_end(290-292)recover(265-275)recover(294-304)
crates/biome_html_parser/src/syntax/mod.rs (2)
crates/biome_html_parser/src/syntax/svelte.rs (4)
parse_svelte_at_block(105-119)parse_svelte_hash_block(17-24)parse_element(151-153)parse_element(198-200)crates/biome_html_parser/src/token_source.rs (2)
double_expression(63-65)single_expression(59-61)
⏰ 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). (10)
- GitHub Check: Parser conformance
- GitHub Check: Test Node.js API
- GitHub Check: End-to-end tests
- GitHub Check: Check Dependencies
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Documentation
- GitHub Check: autofix
🔇 Additional comments (5)
crates/biome_html_formatter/src/html/auxiliary/text_expression.rs (1)
7-7: Skipping the text expression is spot on.Marking these nodes as skipped while still routing comments keeps the formatter honest. Nice and tidy.
crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_close.svelte (1)
1-2: Cheers for covering the missing closing block.This snapshot nails the regression guard we needed.
crates/biome_html_parser/tests/html_specs/error/svelte/key_missing_expression.svelte (1)
1-3: Extra points for the empty-expression case.Catching the blank
{#key }path keeps the parser honest.crates/biome_html_parser/src/syntax/mod.rs (2)
213-244: Unified element dispatcher looks good.The new matcher keeps the element loop tidy and degrades lone braces to content as expected.
291-292: Nice touch adding}to the attribute break-set.This saves us from chewing through Svelte props by accident.
| pub(crate) fn parse_svelte_hash_block(p: &mut HtmlParser) -> ParsedSyntax { | ||
| if !p.at(T!["{#"]) { | ||
| return Absent; | ||
| } | ||
| // NOTE: use or_else chain here to parse | ||
| // other possible hash blocks | ||
| parse_key_block(p) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please restore the other {#…} handlers.
Handing back only parse_key_block means {#if}, {#each}, {#await}, etc. now fall straight through, so the cursor never advances and the parser gives up. Bring back the old or_else chain so the legacy blocks still get their turn.
- parse_key_block(p)
+ parse_key_block(p)
+ .or_else(|| parse_if_block(p))
+ .or_else(|| parse_each_block(p))
+ .or_else(|| parse_await_block(p))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| pub(crate) fn parse_svelte_hash_block(p: &mut HtmlParser) -> ParsedSyntax { | |
| if !p.at(T!["{#"]) { | |
| return Absent; | |
| } | |
| // NOTE: use or_else chain here to parse | |
| // other possible hash blocks | |
| parse_key_block(p) | |
| } | |
| pub(crate) fn parse_svelte_hash_block(p: &mut HtmlParser) -> ParsedSyntax { | |
| if !p.at(T!["{#"]) { | |
| return Absent; | |
| } | |
| // NOTE: use or_else chain here to parse | |
| // other possible hash blocks | |
| parse_key_block(p) | |
| .or_else(|| parse_if_block(p)) | |
| .or_else(|| parse_each_block(p)) | |
| .or_else(|| parse_await_block(p)) | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderabbitai We don't have those functions @coderabbitai, are you hallucinating?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for any other Svelte block parsing functions that might exist
rg -n "parse_(if|each|await|snippet|html)_block" --type=rust crates/biome_html_parser/
# Also check if there are any other {# block implementations
rg -n "T!\[\"\{#\"\]" --type=rust crates/biome_html_parser/
# Check what Svelte block types are defined in the syntax kinds
rg -n "SVELTE_.*_BLOCK" crates/biome_html_parser/src/syntax/svelte.rs
Length of output: 1306
@ematipico You're absolutely right—I apologize for the confusion! 🙏
I searched the codebase and confirmed that parse_if_block, parse_each_block, and parse_await_block don't exist. The current implementation is correct for this PR's scope. Right now, you only have:
parse_key_block(this PR) for{#key}blocksparse_debug_blockfor{@debug}blocks
The comment "use or_else chain here to parse other possible hash blocks" is a forward-looking note. When/if you add support for other Svelte control-flow blocks like {#if}, {#each}, or {#await} in future PRs, that's when you'd extend the or_else chain. For now, having just parse_key_block(p) is perfectly appropriate.
Sorry for the noise on this one!
🧬 Code Graph Analysis Results
[crates/biome_html_parser/src/syntax/parse_error.rs:35-37]
pub(crate) fn expected_child(p: &HtmlParser, range: TextRange) -> ParseDiagnostic {
expect_one_of(&["element", "text", "closing block"], range).into_diagnostic(p)
}
[crates/biome_html_parser/src/syntax/parse_error.rs:96-98]
pub(crate) fn expected_svelte_closing_block(p: &HtmlParser, range: TextRange) -> ParseDiagnostic {
p.err_builder("Expected a closing block, instead found none.", range)
}
[crates/biome_html_parser/src/syntax/mod.rs:213-244]
pub(crate) fn parse_html_element(p: &mut HtmlParser) -> ParsedSyntax {
match p.cur() {
T!["<![CDATA["] => parse_cdata_section(p),
T![<] => parse_element(p),
T!["{{"] => HtmlSyntaxFeatures::DoubleTextExpressions.parse_exclusive_syntax(
p,
|p| parse_double_text_expression(p, HtmlLexContext::Regular),
|p, m| disabled_interpolation(p, m.range(p)),
),
T!["{@"] => parse_svelte_at_block(p),
T!["{#"] => parse_svelte_hash_block(p),
T!['{'] => parse_single_text_expression(p, HtmlLexContext::Regular).or_else(|| {
let m = p.start();
p.bump_remap(HTML_LITERAL);
Present(m.complete(p, HTML_CONTENT))
}),
T!["}}"] | T!['}'] => {
// The closing text expression should be handled by other functions.
// If we're here, we assume that text expressions are enabled and
// we remap to HTML_LITERAL
let m = p.start();
p.bump_remap(HTML_LITERAL);
Present(m.complete(p, HTML_CONTENT))
}
HTML_LITERAL => {
let m = p.start();
p.bump_with_context(HTML_LITERAL, HtmlLexContext::Regular);
Present(m.complete(p, HTML_CONTENT))
}
_ => Absent,
}
}
🧠 Learnings used
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
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
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
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)
Co-authored-by: dyc3 <[email protected]>
Co-authored-by: dyc3 <[email protected]>
Summary
Closes #7971
Test Plan
Added new tests
Docs