-
-
Notifications
You must be signed in to change notification settings - Fork 792
feat(html/analyze): add useVueValidVIf, useVueValidVElseIf, useVueValidVElse, useVueValidVOn and useVueValidVHtml
#8077
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: 9febe70 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
CodSpeed Performance ReportMerging #8077 will not alter performanceComparing Summary
Footnotes
|
WalkthroughAdds five new Vue-focused lints to the HTML analyzer: UseVueValidVIf, UseVueValidVElse, UseVueValidVElseIf, UseVueValidVHtml and UseVueValidVOn. Each rule inspects Vue directives for invalid arguments, modifiers, missing or unexpected values, and incorrect conditional chaining; emits specific diagnostics and notes. Corresponding option types were added to biome_rule_options, each rule declared via the lint macro, and comprehensive valid/invalid test fixtures were included. Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (4)
.changeset/use-vue-valid-v-else.md (1)
5-5: Incomplete changeset description.The description only mentions one validation case (missing preceding v-if/v-else-if), but the rule also flags directives with arguments, modifiers, values, or conflicts with v-if/v-else-if on the same element.
Consider expanding to: "This rule reports
v-elsedirectives that have arguments, modifiers, values, are not preceded by av-iforv-else-ifdirective, or conflict withv-if/v-else-ifon the same element."crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (1)
67-69: Code duplication: AnyHtmlElement is defined in multiple rules.The
AnyHtmlElementunion is also declared inuse_vue_valid_v_else.rs. Consider extracting this and the shared helper functions (has_v_if_or_else_if_directives,has_previous_sibling_with_v_if_or_else_if) to a common module to reduce duplication.crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (1)
74-76: Duplicate AnyHtmlElement declaration.This union is also declared in
use_vue_valid_v_else_if.rs. Extract to a shared module along with the common helper functions.crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs (1)
133-137: Consider reflecting custom modifiers in the warning textBecause the options struct lets users whitelist extra modifiers, this hard-coded list risks gaslighting them when the rule is configured. Folding the configured modifiers into the note (or recalculating the list on the fly) would keep the diagnostic honest.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (17)
crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_html_analyze/src/lint/nursery.rsis excluded by!**/nursery.rsand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.html.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.html.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/valid.vue.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (26)
.changeset/no-vue-invalid-v-on.md(1 hunks).changeset/use-vue-valid-v-else-if.md(1 hunks).changeset/use-vue-valid-v-else.md(1 hunks).changeset/use-vue-valid-v-html.md(1 hunks).changeset/use-vue-valid-v-if.md(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/valid.vue(1 hunks)crates/biome_rule_options/src/lib.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_else.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_else_if.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_html.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_if.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_on.rs(1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📚 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_analyze/tests/specs/nursery/useVueValidVHtml/valid.vuecrates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue
📚 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_analyze/src/lint/nursery/use_vue_valid_v_html.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_analyze/src/lint/nursery/use_vue_valid_v_html.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_rule_options/src/use_vue_valid_v_else.rscrates/biome_rule_options/src/use_vue_valid_v_if.rscrates/biome_rule_options/src/use_vue_valid_v_else_if.rscrates/biome_rule_options/src/use_vue_valid_v_html.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_rule_options/src/use_vue_valid_v_if.rscrates/biome_rule_options/src/lib.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_rule_options/src/lib.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_rule_options/src/lib.rs
🧬 Code graph analysis (5)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (3)
crates/biome_analyze/src/rule.rs (1)
same(246-251)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
run(84-126)diagnostic(128-183)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (2)
run(82-120)diagnostic(122-168)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs (1)
crates/biome_analyze/src/rule.rs (4)
recommended(602-605)domains(632-635)sources(617-620)same(246-251)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (3)
crates/biome_analyze/src/rule.rs (1)
same(246-251)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (3)
run(77-119)has_v_if_or_else_if_directives(242-265)has_previous_sibling_with_v_if_or_else_if(231-240)crates/biome_rowan/src/ast/mod.rs (2)
cast_ref(143-152)try_cast(182-188)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (3)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (4)
run(84-126)has_previous_sibling_with_v_if_or_else_if(214-224)diagnostic(128-183)has_v_if_or_else_if_directives(186-212)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (2)
run(82-120)diagnostic(122-168)crates/biome_rowan/src/ast/mod.rs (2)
cast_ref(143-152)try_cast(182-188)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (3)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
run(84-126)diagnostic(128-183)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (2)
run(77-119)diagnostic(121-195)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (2)
run(61-105)diagnostic(107-144)
⏰ 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 (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: End-to-end tests
- GitHub Check: Check Dependencies
- GitHub Check: Documentation
- GitHub Check: Check JS Files
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_configuration)
- GitHub Check: autofix
🔇 Additional comments (15)
crates/biome_rule_options/src/use_vue_valid_v_on.rs (1)
1-15: LGTM!The options struct follows the standard pattern with appropriate derives and serde configuration.
crates/biome_rule_options/src/use_vue_valid_v_else_if.rs (1)
1-6: LGTM!Standard empty options struct with appropriate derives for a rule without configuration options.
crates/biome_rule_options/src/use_vue_valid_v_else.rs (1)
1-6: LGTM!Consistent with the other empty options structs in this PR.
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (2)
77-119: LGTM!The validation logic correctly checks for arguments, modifiers, missing values, conflicting directives, and proper chaining with predecessors.
242-286: Good validation of predecessor validity.The rule properly validates that the previous sibling's v-if or v-else-if is itself valid before accepting it as a valid chain predecessor. This prevents false negatives where an invalid predecessor would be considered acceptable.
crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue (1)
1-7: LGTM!The test cases cover the essential valid scenarios for v-if directives.
.changeset/use-vue-valid-v-else-if.md (1)
1-5: LGTM!Changeset accurately documents the new rule.
crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue (1)
1-36: Excellent test coverage!The test cases comprehensively cover invalid v-on scenarios including missing event names, missing handlers, invalid modifiers, and various syntax combinations.
crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue (1)
1-33: LGTM!Valid test cases appropriately cover various v-else usage patterns including chains, whitespace handling, and nested templates.
crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue (1)
1-25: LGTM!Valid test cases appropriately demonstrate proper v-html usage with expressions, combinations with other directives, and various element types.
crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue (1)
1-6: LGTM!Test cases appropriately cover invalid v-if scenarios including unsupported arguments, modifiers, missing conditions, and conflicting directive combinations.
crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/invalid.vue (1)
1-30: Thorough test coverage!Test cases comprehensively cover invalid v-else scenarios including unsupported arguments/modifiers/values, missing preceding conditionals, and conflicting directive combinations.
crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.vue (1)
1-51: Excellent test coverage!Valid test cases thoroughly demonstrate proper v-else-if usage including proper chaining, complex expressions, whitespace handling, template elements, and multiple sequential conditions.
crates/biome_rule_options/src/use_vue_valid_v_html.rs (1)
1-6: Consistent options surface.Matches the existing Vue rule options pattern perfectly, so no worries here.
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (1)
61-141: Solid parity with ESLint’s rule.Nice tidy port: we bail early on non
v-html, surface the first bad modifier, and treat empty literals as missing values while letting real expressions through. Cheers for keeping the diagnostics helpful too.
5fcbb6b to
01beada
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (1)
199-207: v-else still trusts dodgy neighboursWe’re only checking the predecessor’s name here, so
<div v-if></div><div v-else></div>happily slips through even though thev-ifis malformed. ESLint’svalid-v-elserejects that case. Please mirror the guard we use inuseVueValidVElseIfand insist the predecessor has no argument/modifiers and does have an initialiser before we bless it.- let name = name_token.text(); - if name == "v-if" || name == "v-else-if" { - return true; - } + let name = name_token.text(); + if (name == "v-if" || name == "v-else-if") + && vue_dir.arg().is_none() + && vue_dir.modifiers().into_iter().next().is_none() + && vue_dir.initializer().is_some() + { + return true; + }
🧹 Nitpick comments (1)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (1)
97-101: Prefer!is_empty()over.len() > 0.Apply this diff:
- if vue_directive.modifiers().len() > 0 { + if !vue_directive.modifiers().is_empty() { return Some(ViolationKind::HasModifier( vue_directive.modifiers().range(), )); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (17)
crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_html_analyze/src/lint/nursery.rsis excluded by!**/nursery.rsand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.html.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.html.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/valid.vue.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (26)
.changeset/use-vue-valid-v-else-if.md(1 hunks).changeset/use-vue-valid-v-else.md(1 hunks).changeset/use-vue-valid-v-html.md(1 hunks).changeset/use-vue-valid-v-if.md(1 hunks).changeset/use-vue-valid-v-on.md(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/valid.vue(1 hunks)crates/biome_rule_options/src/lib.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_else.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_else_if.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_html.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_if.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_on.rs(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- .changeset/use-vue-valid-v-else-if.md
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue
🚧 Files skipped from review as they are similar to previous changes (10)
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/valid.vue
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/invalid.vue
- crates/biome_rule_options/src/use_vue_valid_v_else_if.rs
- crates/biome_rule_options/src/use_vue_valid_v_html.rs
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue
- crates/biome_rule_options/src/use_vue_valid_v_on.rs
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.vue
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.vue
🧰 Additional context used
🧠 Learnings (6)
📚 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_rule_options/src/lib.rscrates/biome_rule_options/src/use_vue_valid_v_if.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_rule_options/src/lib.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_rule_options/src/use_vue_valid_v_if.rscrates/biome_rule_options/src/use_vue_valid_v_else.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_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue
📚 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_analyze/src/lint/nursery/use_vue_valid_v_html.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_analyze/src/lint/nursery/use_vue_valid_v_html.rs
🧬 Code graph analysis (5)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs (2)
crates/biome_analyze/src/rule.rs (1)
same(246-251)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (2)
run(61-105)diagnostic(107-144)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (3)
run(77-119)has_v_if_or_else_if_directives(242-265)has_previous_sibling_with_v_if_or_else_if(231-240)crates/biome_rowan/src/ast/mod.rs (2)
cast_ref(143-152)try_cast(182-188)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (3)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (4)
run(84-126)has_previous_sibling_with_v_if_or_else_if(214-224)diagnostic(128-183)has_v_if_or_else_if_directives(186-212)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (2)
run(82-120)diagnostic(122-168)crates/biome_rowan/src/ast/mod.rs (2)
cast_ref(143-152)try_cast(182-188)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (3)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
run(84-126)diagnostic(128-183)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (2)
run(77-119)diagnostic(121-195)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (2)
run(61-105)diagnostic(107-144)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (3)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
run(84-126)diagnostic(128-183)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (2)
run(82-120)diagnostic(122-168)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs (2)
run(62-110)diagnostic(112-150)
⏰ 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). (4)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Test Node.js API
- GitHub Check: autofix
🔇 Additional comments (10)
.changeset/use-vue-valid-v-if.md (1)
1-5: LGTM!The changeset description accurately reflects the rule's behaviour.
.changeset/use-vue-valid-v-html.md (1)
1-5: LGTM!The changeset now comprehensively describes all violation types the rule detects.
crates/biome_rule_options/src/use_vue_valid_v_if.rs (1)
1-6: LGTM!Standard options struct pattern with appropriate derives for future extensibility.
crates/biome_rule_options/src/lib.rs (1)
376-380: LGTM!Module exports are properly structured and follow the existing pattern.
crates/biome_rule_options/src/use_vue_valid_v_else.rs (1)
1-6: LGTM!Consistent options struct pattern across Vue rules.
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (2)
109-114: Let-chains syntax used.The
if let ... && let ...syntax requires Rust 1.64+. This is likely fine for the project, but worth noting if minimum supported Rust version is a concern.
82-120: Implementation looks correct.The validation logic properly checks for arguments, modifiers, missing values, and conflicts with v-else/v-else-if directives.
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs (2)
62-110: Rule implementation handles both v-on forms correctly.The logic properly handles both the full
v-on:eventsyntax and the@eventshorthand, with appropriate validation for each.
42-48: Good use ofLazyLockfor static set.Efficient pattern for compile-time constant set initialisation.
.changeset/use-vue-valid-v-on.md (1)
1-5: LGTM!Comprehensive description covering both v-on syntaxes and all validation checks.
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs
Outdated
Show resolved
Hide resolved
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs
Outdated
Show resolved
Hide resolved
01beada to
eb7e199
Compare
…ueValidVElse`, `useVueValidVOn` and `useVueValidVHtml`
eb7e199 to
9febe70
Compare
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_analyze/src/lint/nursery/use_vue_valid_v_on.rs (1)
50-54: MissingDebugderive onViolationKind.Based on learnings, this enum should derive
Debugfor consistency with other rules.Apply this diff:
+#[derive(Debug)] pub enum ViolationKind { MissingEventName, InvalidModifier(TextRange), MissingHandler, }
🧹 Nitpick comments (2)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (2)
49-53: AddDebugderive for consistency.The
ViolationKindenum is missing a#[derive(Debug)]attribute. Whilst not strictly necessary, the equivalent enum inuse_vue_valid_v_if.rs(line 68) includes it, and it's good practice for error types.Apply this diff:
+#[derive(Debug)] pub enum ViolationKind { UnexpectedArgument(TextRange), UnexpectedModifier(TextRange), MissingValue, }
78-99: Consider simplifying the nested empty-value logic.The current implementation is correct but quite deeply nested. Whilst functional, it could be more readable with early returns or helper functions.
Example refactor (optional):
if let Some(initializer) = vue_directive.initializer() { let is_empty_value = match initializer.value() { Ok(AnyHtmlAttributeInitializer::HtmlString(html_string)) => { html_string.value_token() .map_or(true, |token| token.text().is_empty()) } Ok(_) => false, // Non-string values are valid Err(_) => true, }; if is_empty_value { return Some(ViolationKind::MissingValue); } } else { return Some(ViolationKind::MissingValue); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (17)
crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_html_analyze/src/lint/nursery.rsis excluded by!**/nursery.rsand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.html.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.html.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue.snapis excluded by!**/*.snapand included by**crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/valid.vue.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (26)
.changeset/use-vue-valid-v-else-if.md(1 hunks).changeset/use-vue-valid-v-else.md(1 hunks).changeset/use-vue-valid-v-html.md(1 hunks).changeset/use-vue-valid-v-if.md(1 hunks).changeset/use-vue-valid-v-on.md(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs(1 hunks)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue(1 hunks)crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/valid.vue(1 hunks)crates/biome_rule_options/src/lib.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_else.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_else_if.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_html.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_if.rs(1 hunks)crates/biome_rule_options/src/use_vue_valid_v_on.rs(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- .changeset/use-vue-valid-v-else-if.md
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVHtml/valid.vue
🚧 Files skipped from review as they are similar to previous changes (13)
- .changeset/use-vue-valid-v-on.md
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/valid.vue
- crates/biome_rule_options/src/use_vue_valid_v_else.rs
- crates/biome_rule_options/src/use_vue_valid_v_html.rs
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVElseIf/invalid.vue
- .changeset/use-vue-valid-v-if.md
- .changeset/use-vue-valid-v-else.md
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/invalid.vue
- crates/biome_rule_options/src/use_vue_valid_v_on.rs
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVOn/valid.vue
- crates/biome_rule_options/src/use_vue_valid_v_if.rs
- .changeset/use-vue-valid-v-html.md
- crates/biome_html_analyze/tests/specs/nursery/useVueValidVIf/invalid.vue
🧰 Additional context used
🧠 Learnings (9)
📚 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_analyze/src/lint/nursery/use_vue_valid_v_html.rs
📚 Learning: 2025-10-15T09:21:24.116Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:21:24.116Z
Learning: Prefer implementing the Diagnostic trait via `#[derive(Diagnostic)]`
Applied to files:
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs
📚 Learning: 2025-10-15T09:21:24.116Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:21:24.116Z
Learning: Types deriving `Diagnostic` must also implement `Debug`
Applied to files:
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs
📚 Learning: 2025-10-15T09:21:24.116Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:21:24.116Z
Learning: `#[derive(Diagnostic)]` is supported on enums; each variant must contain a type that is itself a diagnostic
Applied to files:
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.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_analyze/src/lint/nursery/use_vue_valid_v_on.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_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vuecrates/biome_html_analyze/tests/specs/nursery/useVueValidVElse/valid.vue
📚 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_analyze/tests/specs/nursery/useVueValidVHtml/invalid.vue
📚 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_rule_options/src/lib.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_rule_options/src/lib.rs
🧬 Code graph analysis (5)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (3)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
run(84-126)diagnostic(128-183)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (2)
run(82-120)diagnostic(122-168)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs (2)
run(62-110)diagnostic(112-158)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_on.rs (4)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
run(84-126)diagnostic(128-183)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (2)
run(77-119)diagnostic(121-195)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_html.rs (2)
run(61-105)diagnostic(107-144)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (2)
run(82-120)diagnostic(122-168)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (3)
crates/biome_analyze/src/rule.rs (3)
domains(632-635)sources(617-620)same(246-251)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
run(84-126)diagnostic(128-183)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (2)
run(77-119)diagnostic(121-195)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (3)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (4)
run(84-126)has_previous_sibling_with_v_if_or_else_if(214-224)diagnostic(128-183)has_v_if_or_else_if_directives(186-212)crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_if.rs (2)
run(82-120)diagnostic(122-168)crates/biome_rowan/src/ast/mod.rs (2)
cast_ref(143-152)try_cast(182-188)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (2)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (2)
has_v_if_or_else_if_directives(242-265)has_previous_sibling_with_v_if_or_else_if(231-240)crates/biome_rowan/src/ast/mod.rs (2)
cast_ref(143-152)try_cast(182-188)
⏰ 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: Check Dependencies
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Documentation
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Check JS Files
- GitHub Check: autofix
🔇 Additional comments (2)
crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else.rs (1)
186-212: Inconsistent predecessor validation compared touse_vue_valid_v_else_if.The
has_v_if_or_else_if_directivesfunction only checks for the presence of v-if or v-else-if by name but doesn't validate that those directives are well-formed. Compare withuse_vue_valid_v_else_if.rs(lines 242-265) which callsis_valid_chain_directiveto ensure predecessors have no argument, no modifiers, and have a value.This inconsistency means v-else could accept an invalid v-if/v-else-if as a valid predecessor, e.g.,
<div v-if></div><div v-else></div>(where v-if is missing a value).Should this rule validate predecessor validity like
use_vue_valid_v_else_ifdoes, or is the current behaviour intentional? If validation is needed, consider adding a helper similar tois_valid_chain_directive:fn has_v_if_or_else_if_directives(element: &AnyHtmlElement) -> bool { let attribute_list = match element { AnyHtmlElement::HtmlElement(html_element) => { let Ok(opening_element) = html_element.opening_element() else { return false; }; opening_element.attributes() } AnyHtmlElement::HtmlSelfClosingElement(self_closing) => self_closing.attributes(), }; for attribute in attribute_list { if let Ok(AnyVueDirective::VueDirective(vue_dir)) = AnyVueDirective::try_cast(attribute.syntax().clone()) && let Ok(name_token) = vue_dir.name_token() { let name = name_token.text(); if (name == "v-if" || name == "v-else-if") && is_valid_predecessor(&vue_dir) { return true; } } } false } fn is_valid_predecessor(dir: &VueDirective) -> bool { dir.arg().is_none() && dir.modifiers().into_iter().next().is_none() && dir.initializer().is_some() }crates/biome_html_analyze/src/lint/nursery/use_vue_valid_v_else_if.rs (1)
59-65: MissingDebugderive onViolationKind.Based on learnings and consistency with other rules in the codebase, this enum should derive
Debug.Apply this diff:
+#[derive(Debug)] pub enum ViolationKind { HasArgument, HasModifier(TextRange), MissingValue, MissingPreviousConditional, ConflictsWithOtherDirective(TextRange), }⛔ Skipped due to learnings
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 : Unions of nodes must start with Any* (e.g., AnyHtmlAttribute)
…ueValidVElse`, `useVueValidVOn` and `useVueValidVHtml` (biomejs#8077)
…ueValidVElse`, `useVueValidVOn` and `useVueValidVHtml` (biomejs#8077)
Summary
This adds 5 lint rules that all have to do with validating Vue directives, much like #8060. They are direct ports of the eslint plugin's rules.
I chose to group them all into one PR because they are all pretty trivial, and to reduce the amount of rebasing I would have to do if I put them in 5 PRs.
The initial passes at these rules were written by AI, but I heavily reviewed their behavior and simplified them.
Test Plan
Snapshot tests.
Docs