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

Skip to content

Conversation

@dibashthapa
Copy link
Contributor

@dibashthapa dibashthapa commented Dec 21, 2025

Summary

This PR fixes the issues with false positive errors for safe boolean expressions in variable declarations

Related to #8491

Test Plan

Added new test cases for safe boolean expressions

Docs

@changeset-bot
Copy link

changeset-bot bot commented Dec 21, 2025

🦋 Changeset detected

Latest commit: 4678d89

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

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

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

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

@dibashthapa dibashthapa changed the title fix(lint): Added more test cases for safe literals in noLeakedRender fix(lint): Added more test cases for variable declarations in noLeakedRender Dec 21, 2025
@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Dec 21, 2025
@dibashthapa dibashthapa changed the title fix(lint): Added more test cases for variable declarations in noLeakedRender fix(lint): added more test cases for variable declarations in noLeakedRender Dec 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 21, 2025

Walkthrough

Adds a patch changelog entry and refactors the nursery lint no_leaked_render to use the semantic model to resolve variable initialisers. Replaces ad‑hoc literal checks with a new find_variable helper that returns an initializer AnyJsExpression; treats resolved simple literals (string, number, null) as safe and flags complex/unknown expressions as unsafe. Changes the rule State type from bool to () and updates diagnostics and tests (adds/updates valid.jsx and invalid.jsx) to exercise the new variable-resolution behaviour.

Possibly related PRs

Suggested reviewers

  • dyc3

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding test cases for variable declarations in the noLeakedRender lint rule to address false positives.
Description check ✅ Passed The description is directly related to the changeset, explaining the fix for false positive errors in noLeakedRender and referencing the related issue #8491.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs (1)

286-298: Remove redundant return keyword.

Line 297 has an explicit return that's unnecessary for the last expression in a Rust function.

🔎 Proposed fix
     let expr = declarator.initializer()?.expression().ok()?;
-    return Some(expr);
+    Some(expr)
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f22f1c and 07c7b5c.

⛔ Files ignored due to path filters (2)
  • crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/invalid.jsx.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/valid.jsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (4)
  • .changeset/curvy-worlds-invent.md (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs (6 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/invalid.jsx (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/valid.jsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Write changesets that are concise (1-3 sentences), user-focused, use past tense for actions taken and present tense for Biome behavior, include code examples for rules, and end sentences with periods

Files:

  • .changeset/curvy-worlds-invent.md
crates/**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update inline rustdoc documentation for rules, assists, and their options when adding new features or changing existing features in Rust crates

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Safe` in `declare_lint_rule!` for safe code actions
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).same()` when implementing a rule that matches the behavior of an ESLint rule
📚 Learning: 2025-12-12T10:11:05.564Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-12T10:11:05.564Z
Learning: Create a changeset for user-facing bug fixes and features using `just new-changeset`, selecting appropriate packages and change type (`major`, `minor`, or `patch`)

Applied to files:

  • .changeset/curvy-worlds-invent.md
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Check if a variable is global using the semantic model to avoid false positives

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `ctx.model()` to access semantic model information in a rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).same()` when implementing a rule that matches the behavior of an ESLint rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should perform static analysis of source code to detect invalid or error-prone patterns and emit diagnostics with proposed fixes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Safe` in `declare_lint_rule!` for safe code actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Assist rules should detect refactoring opportunities and emit code action signals

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `Semantic<>` query type to access semantic model information like scopes and declarations

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Set `recommended` field to `false` for new rules in the nursery group

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should check syntax according to language specification and emit error diagnostics

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).inspired()` when implementing a rule inspired by but with different behavior than an ESLint rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `language` to `jsx`, `ts`, or `tsx` for rules that only apply to specific JavaScript dialects

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
🪛 LanguageTool
.changeset/curvy-worlds-invent.md

[style] ~5-~5: Consider using a different verb for a more formal wording.
Context: .../github.com//issues/8491): Fixed the issue with false positive errors fo...

(FIX_RESOLVE)


[typographical] ~9-~9: After the expression ‘for example’ a comma is usually used.
Context: ...ressions in variable declarations. For example Valid: ```jsx let isOne = 1; let isPo...

(COMMA_FOR_EXAMPLE)

⏰ 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). (12)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Validate rules documentation
  • GitHub Check: Test Node.js API
  • GitHub Check: autofix
🔇 Additional comments (1)
crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/valid.jsx (1)

76-94: Nice test coverage!

The new test cases properly cover safe boolean expressions: non-zero numbers, comparison results, double negation, and equality checks. This validates the fix effectively.

Comment on lines +191 to +196
AnyJsLiteralExpression::JsNumberLiteralExpression(num) => {
let value = num.value_token().ok()?;
if value.text_trimmed() == "0" {
return Some(());
}
return None;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# View the implementation of the rule to understand the logic
cat -n crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs | head -n 210 | tail -n 50

Repository: biomejs/biome

Length of output: 3140


Consider additional numeric zero representations in the safety check.

The check value.text_trimmed() == "0" only catches the literal 0. However, 0.0 and -0 are also falsy numeric values that would render in React, but the string comparison would not match them. This creates a potential gap where code like {0.0 && <Component />} or {-0 && <Component />} would not be flagged as unsafe.

Copy link
Member

Choose a reason for hiding this comment

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

I believe the bot is right @dibashthapa

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will have to reproduce this one

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
.changeset/curvy-worlds-invent.md (1)

17-17: Fix JSX syntax error in the valid example.

The string literal is missing a closing quote. The line should be {isOne && "One"} not {isOne && "One }.

🔎 Proposed fix
-return <div> {isOne && "One } { isPositiveNumber && "Is positive" }</div>
+return <div>{isOne && "One"} {isPositiveNumber && "Is positive"}</div>
🧹 Nitpick comments (1)
.changeset/curvy-worlds-invent.md (1)

7-7: Consider rephrasing to follow present-tense convention for Biome behaviour.

The phrasing "This new change will check" uses future tense. Per the changeset guidelines, favour present tense for describing Biome's behaviour (e.g., "Biome now checks").

🔎 Alternative phrasing
-This new change will check for safe boolean expressions in variable declarations.
+Biome now checks for safe boolean expressions in variable declarations.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07c7b5c and 030d68a.

📒 Files selected for processing (1)
  • .changeset/curvy-worlds-invent.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Write changesets that are concise (1-3 sentences), user-focused, use past tense for actions taken and present tense for Biome behavior, include code examples for rules, and end sentences with periods

Files:

  • .changeset/curvy-worlds-invent.md
🧠 Learnings (1)
📚 Learning: 2025-12-12T10:11:05.564Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-12T10:11:05.564Z
Learning: Create a changeset for user-facing bug fixes and features using `just new-changeset`, selecting appropriate packages and change type (`major`, `minor`, or `patch`)

Applied to files:

  • .changeset/curvy-worlds-invent.md
🪛 LanguageTool
.changeset/curvy-worlds-invent.md

[style] ~5-~5: Consider using a different verb for a more formal wording.
Context: .../github.com//issues/8491): Fixed the issue with false positive errors fo...

(FIX_RESOLVE)


[typographical] ~9-~9: After the expression ‘for example’ a comma is usually used.
Context: ...ressions in variable declarations. For example Valid: ```jsx let isOne = 1; let isPo...

(COMMA_FOR_EXAMPLE)

⏰ 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). (5)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: autofix

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 21, 2025

CodSpeed Performance Report

Merging #8537 will not alter performance

Comparing dibashthapa:fix/no-leaked-render (4678d89) with main (b573d14)

Summary

✅ 58 untouched
⏩ 95 skipped1

Footnotes

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

@github-actions github-actions bot added A-CLI Area: CLI A-Project Area: project A-Parser Area: parser A-Tooling Area: internal tools L-CSS Language: CSS L-JSON Language: JSON and super languages A-Diagnostic Area: diagnostocis L-HTML Language: HTML and super languages L-Tailwind Language: Tailwind CSS labels Dec 21, 2025
@github-actions github-actions bot removed A-Project Area: project A-Parser Area: parser A-Tooling Area: internal tools L-CSS Language: CSS A-Diagnostic Area: diagnostocis L-HTML Language: HTML and super languages labels Dec 21, 2025
@github-actions github-actions bot removed the L-Tailwind Language: Tailwind CSS label Dec 21, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.changeset/curvy-worlds-invent.md (2)

7-7: Use present tense for consistency with coding guidelines.

Change "will check" to "checks" to match the preferred tense for describing Biome's behaviour.

🔎 Proposed fix
-This new change will check for safe boolean expressions in variable declarations.
+This new change checks for safe boolean expressions in variable declarations.

5-5: Consider more formal verb choice.

The phrasing could be slightly tightened by using "Resolved" instead of "Fixed" and avoiding redundancy:

🔎 Proposed fix
-Related to [#8491](https://github.com/biomejs/biome/issues/8491): Fixed the issue with false positive errors for safe boolean expressions.
+Related to [#8491](https://github.com/biomejs/biome/issues/8491): Resolved false positive errors for safe boolean expressions.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 030d68a and 10b6a36.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/invalid.jsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (1)
  • .changeset/curvy-worlds-invent.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Write changesets that are concise (1-3 sentences), user-focused, use past tense for actions taken and present tense for Biome behavior, include code examples for rules, and end sentences with periods

Files:

  • .changeset/curvy-worlds-invent.md
🪛 LanguageTool
.changeset/curvy-worlds-invent.md

[style] ~5-~5: Consider using a different verb for a more formal wording.
Context: .../github.com//issues/8491): Fixed the issue with false positive errors fo...

(FIX_RESOLVE)

⏰ 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). (5)
  • GitHub Check: Test Node.js API
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_formatter)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs (1)

194-199: Numeric zero check remains incomplete.

The past review concern is still valid: checking only "0" misses other falsy numeric representations like 0.0, -0, 0x0, 0e0, etc., which would also render in React.

🔎 Suggested fix to handle additional zero representations
-                                    AnyJsLiteralExpression::JsNumberLiteralExpression(num) => {
-                                        let value = num.value_token().ok()?;
-                                        if value.text_trimmed() == "0" {
-                                            return Some(());
-                                        }
-                                        return None;
-                                    }
+                                    AnyJsLiteralExpression::JsNumberLiteralExpression(num) => {
+                                        // Check if the numeric value is zero (including 0.0, -0, 0x0, etc.)
+                                        let value = num.value_token().ok()?;
+                                        if value.text_trimmed().parse::<f64>().ok()
+                                            .map(|n| n == 0.0 || n == -0.0)
+                                            .unwrap_or(false)
+                                        {
+                                            return Some(());
+                                        }
+                                        return None;
+                                    }

Note: This handles all numeric zero representations by parsing as f64 and checking for ±0.

🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs (1)

289-301: Consider removing explicit return for idiomatic Rust.

The function logic is sound and correctly uses the semantic model to resolve variable initialisers. As per coding guidelines, the semantic model approach helps avoid false positives.

Based on learnings, semantic model usage is appropriate here.

Minor style suggestion:

🔎 Optional: Remove explicit return on line 300
     let expr = declarator.initializer()?.expression().ok()?;
-    return Some(expr);
+    Some(expr)
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10b6a36 and b54dcbb.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/invalid.jsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
🧠 Learnings (16)
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Check if a variable is global using the semantic model to avoid false positives

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `ctx.model()` to access semantic model information in a rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).same()` when implementing a rule that matches the behavior of an ESLint rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Safe` in `declare_lint_rule!` for safe code actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Assist rules should detect refactoring opportunities and emit code action signals

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should perform static analysis of source code to detect invalid or error-prone patterns and emit diagnostics with proposed fixes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `Semantic<>` query type to access semantic model information like scopes and declarations

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Unsafe` in `declare_lint_rule!` for unsafe code actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should check syntax according to language specification and emit error diagnostics

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).inspired()` when implementing a rule inspired by but with different behavior than an ESLint rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `language` to `jsx`, `ts`, or `tsx` for rules that only apply to specific JavaScript dialects

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
⏰ 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: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Test Node.js API
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Validate rules documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Documentation
  • GitHub Check: autofix
🔇 Additional comments (5)
crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs (5)

5-10: LGTM!

Import additions align with the semantic model-based refactor. All new imports are used appropriately in the updated logic.


102-102: LGTM!

State type simplification to () is appropriate since the rule only signals presence of an issue, not additional boolean state.


217-217: LGTM!

Return value updates correctly align with the State type change to ().

Also applies to: 228-228


167-180: LGTM!

Updated comments clearly explain the semantic model approach and provide helpful examples of safe vs unsafe patterns.


207-209: This review comment is incorrect. Boolean literals (true/false) are already handled safely by the catch-all at line 201, which correctly marks them as safe since they don't leak values when used with &&. Unrecognised initialiser types (like array/object literals) are intentionally allowed to fall through to line 212–214, where the logic properly flags them as unsafe. The rule's design is sound.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs (1)

194-199: Numeric zero representations still incomplete.

As flagged in the previous review, the check value.text_trimmed() == "0" doesn't catch 0.0 or -0, both of which are falsy and would render in React.

Consider expanding the zero check
 AnyJsLiteralExpression::JsNumberLiteralExpression(num) => {
     let value = num.value_token().ok()?;
-    if value.text_trimmed() == "0" {
+    let text = value.text_trimmed();
+    if text == "0" || text == "0.0" || text == "-0" || text == "-0.0" {
         return Some(());
     }
     return None;
 }

Alternatively, parse the numeric value and check if it's zero:

if let Ok(parsed) = value.text_trimmed().parse::<f64>() {
    if parsed == 0.0 || parsed.is_nan() {
        return Some(());
    }
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b54dcbb and 87d2a58.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
🧠 Learnings (16)
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Check if a variable is global using the semantic model to avoid false positives

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `ctx.model()` to access semantic model information in a rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).same()` when implementing a rule that matches the behavior of an ESLint rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `Semantic<>` query type to access semantic model information like scopes and declarations

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Safe` in `declare_lint_rule!` for safe code actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).inspired()` when implementing a rule inspired by but with different behavior than an ESLint rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Set `recommended` field to `false` for new rules in the nursery group

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Place new rules inside the `nursery` group during development

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should check syntax according to language specification and emit error diagnostics

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `language` to `jsx`, `ts`, or `tsx` for rules that only apply to specific JavaScript dialects

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-12-19T12:53:30.399Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should perform static analysis of source code to detect invalid or error-prone patterns and emit diagnostics with proposed fixes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
⏰ 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). (5)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: autofix
🔇 Additional comments (3)
crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs (3)

5-10: LGTM! Semantic model integration is properly set up.

The imports correctly bring in the semantic model and all required types for the variable resolution logic.


102-102: State type simplified appropriately.

Changing from bool to () is sensible since the rule only signals presence/absence of an issue rather than carrying additional state.


289-298: Well-implemented semantic binding resolution.

The helper correctly uses the semantic model to retrieve variable initialisers. The decision to handle only JsVariableDeclarator and return None for other binding types (parameters, imports) is sound—those cases fall through to the general safety check.

Based on learnings, proper use of the semantic model with model.binding() and declaration resolution.

Comment on lines 167 to 210
if let AnyJsExpression::JsIdentifierExpression(ident) = &left {
let name = ident.name().ok()?;

// Use the semantic model to resolve the variable binding and check
// if it's initialized with a boolean literal. This allows us to
// if it's initialized with safe expressions. This allows us to
// handle cases like:
// let isOpen = false; // This is safe
// let isError = errorCount > 0; // This is safe
// let isEqual = a === b; // This is safe
// let emptyStr = ''; // This is unsafe
// return <div>{isOpen && <Content />}</div>; // This should pass
if let Some(binding) = model.binding(&name)
&& binding
.tree()
.declaration()
.and_then(|declaration| {
if let AnyJsBindingDeclaration::JsVariableDeclarator(declarator) =
declaration
{
Some(declarator)
} else {
None
}
})
.and_then(|declarator| declarator.initializer())
.and_then(|initializer| initializer.expression().ok())
.and_then(|expr| {
if let AnyJsExpression::AnyJsLiteralExpression(literal) = expr {
Some(literal)
} else {
None
}
})
.and_then(|literal| literal.value_token().ok())
.is_some_and(|token| matches!(token.text_trimmed(), "true" | "false"))
{
return None;
// return <div> {isError && <Error />}</div>; // This should pass
// return <div> {isEqual && <Equal />}</div>; // This should pass
// return <div> {emptyStr && <Empty />}</div>; // This should fail

if let Some(variable) = find_variable(model, &name) {
match variable {
AnyJsExpression::AnyJsLiteralExpression(expr) => {
match expr {
AnyJsLiteralExpression::JsStringLiteralExpression(str) => {
if str.inner_string_text().ok()?.text().is_empty() {
return Some(());
}
return None;
}
AnyJsLiteralExpression::JsNullLiteralExpression(_) => {
return Some(());
}
AnyJsLiteralExpression::JsNumberLiteralExpression(num) => {
let value = num.value_token().ok()?;
if value.text_trimmed() == "0" {
return Some(());
}
return None;
}
_ => return None,
};
}
AnyJsExpression::JsUnaryExpression(_)
| AnyJsExpression::JsBinaryExpression(_)
| AnyJsExpression::JsCallExpression(_) => return None,
_ => {}
}
}
}
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 22, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Check if the file exists and view the relevant lines
echo "=== Checking file and code at lines 167-210 ==="
if [ -f "crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs" ]; then
    sed -n '167,210p' crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs
else
    echo "File not found at expected location"
    find . -name "*no_leaked_render*" -type f 2>/dev/null | head -5
fi

echo ""
echo "=== Checking BigInt test cases ==="
find crates/biome_js_analyze/tests -name "*noLeakedRender*" -o -name "*no_leaked_render*" 2>/dev/null | head -5

echo ""
echo "=== Searching for BigInt 0n in test specs ==="
rg "0n" crates/biome_js_analyze/tests/specs/nursery/ 2>/dev/null | grep -i leaked | head -10

echo ""
echo "=== Checking declare_lint_rule! for fix_kind ==="
rg -A 5 "declare_lint_rule!" crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs 2>/dev/null | head -20

Repository: biomejs/biome

Length of output: 3281


🏁 Script executed:

#!/bin/bash

# Check the complete declare_lint_rule! block for fix_kind
echo "=== Full declare_lint_rule! block ==="
rg -A 50 "declare_lint_rule!" crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs 2>/dev/null | grep -E "(declare_lint_rule|fix_kind|name =|version =)" | head -10

# Also check if JsBigintLiteralExpression is handled anywhere
echo ""
echo "=== Checking for BigInt literal handling ==="
rg "JsBigintLiteralExpression" crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs

# Check the test file exists and what's in it
echo ""
echo "=== Test spec file contents (first 50 lines) ==="
if [ -f "crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/valid.js" ]; then
    head -50 crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/valid.js
elif [ -f "crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/valid.ts" ]; then
    head -50 crates/biome_js_analyze/tests/specs/nursery/noLeakedRender/valid.ts
else
    find crates/biome_js_analyze/tests/specs/nursery/noLeakedRender -type f | head -3
fi

Repository: biomejs/biome

Length of output: 457


🏁 Script executed:

#!/bin/bash

# Get the full declare_lint_rule! block up to the closing brace
echo "=== Full declare_lint_rule! macro invocation ==="
awk '/^declare_lint_rule!\s*\{/,/^}/' crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs | head -80

echo ""
echo "=== Checking for fix_kind in the rule ==="
rg "fix_kind" crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs

Repository: biomejs/biome

Length of output: 2409


Specify fix_kind: FixKind::Safe in the macro and handle BigInt 0n literals.

The code correctly catches falsy literals (empty strings, null, numeric 0), but two issues remain:

  1. BigInt 0n is falsy and currently unhandled—it would fall through the match statement and be incorrectly treated as safe.
  2. The declare_lint_rule! macro is missing the fix_kind: FixKind::Safe declaration required for safe code actions (per the linting guidelines for this analyser).

The semantic model integration for variable resolution is solid and follows best practices.

🤖 Prompt for AI Agents
crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs lines 167-210: the
lint currently treats empty string, null, and numeric 0 as falsy but misses
BigInt 0n and the rule macro is missing its fix_kind; add a match arm for
AnyJsLiteralExpression::JsBigIntLiteralExpression (or whatever BigInt literal
variant your AST uses) and treat the token/text "0n" as falsy (return Some(())),
and update the declare_lint_rule! invocation for this rule to include fix_kind:
FixKind::Safe so safe code actions are allowed.

Copy link
Member

Choose a reason for hiding this comment

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

@coderabbitai The rule doesn't implement the action function, which means that it can't have a code fix in its metadata

Copy link
Contributor

Choose a reason for hiding this comment

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

@ematipico, you're absolutely right! Thank you for the clarification. Since this rule only emits diagnostics and doesn't implement the action function to provide code fixes, fix_kind shouldn't be included in the metadata. I apologize for the confusion.

The BigInt 0n concern still stands though—the current match arms handle empty strings, null, and numeric 0, but BigInt literals like 0n (which are falsy) would fall through to the catch-all _ => return None and be treated as safe. If you'd like to handle that edge case, you could add:

AnyJsLiteralExpression::JsBigIntLiteralExpression(bigint) => {
    let value = bigint.value_token().ok()?;
    if value.text_trimmed() == "0n" {
        return Some(());
    }
    return None;
}

But that's optional depending on how common BigInt usage is in your target codebases.


✏️ Learnings added
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:26:56.943Z
Learning: In crates/biome_analyze/**/*analyze/src/**/*.rs, the `fix_kind` field in `declare_lint_rule!` should only be specified when the rule implements the `action` function. Rules that only emit diagnostics without providing code fixes should not include `fix_kind` in their metadata.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Check if a variable is global using the semantic model to avoid false positives

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to 'fix' the code; if a token/node is known to be mandatory but is missing, return `None` instead

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).same()` when implementing a rule that matches the behavior of an ESLint rule

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Safe` in `declare_lint_rule!` for safe code actions

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Unsafe` in `declare_lint_rule!` for unsafe code actions

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should perform static analysis of source code to detect invalid or error-prone patterns and emit diagnostics with proposed fixes

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Implement `action` function in Rule trait to provide code actions

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Assist rules should detect refactoring opportunities and emit code action signals

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should check syntax according to language specification and emit error diagnostics

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Rules should tell the user what they should do to fix the error via code actions or notes

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `ctx.model()` to access semantic model information in a rule

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `Semantic<>` query type to access semantic model information like scopes and declarations

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).inspired()` when implementing a rule inspired by but with different behavior than an ESLint rule

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Add `sources` field with `RuleSource` to cite ESLint or other rules that inspired the implementation

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `language` to `jsx`, `ts`, or `tsx` for rules that only apply to specific JavaScript dialects

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
.changeset/curvy-worlds-invent.md (1)

5-5: Improve phrasing to match changeset convention.

Line 5 currently reads "Related to #8491: Fixed the issue with false positive errors…" Consider restructuring to follow the established pattern and using more formal wording, per your project learnings:

-Related to [#8491](https://github.com/biomejs/biome/issues/8491): Fixed the issue with false positive errors for safe boolean expressions.
+Fixed [#8491](https://github.com/biomejs/biome/issues/8491): false positive errors in safe boolean expressions within variable declarations.

This aligns the changeset format with project conventions and addresses the static analysis suggestion for more formal wording.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87d2a58 and 4678d89.

📒 Files selected for processing (1)
  • .changeset/curvy-worlds-invent.md
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.399Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Add `issue_number` field to `declare_lint_rule!` macro for work-in-progress rules
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: For new nursery rules, send PRs to the maintenance branch `main`
📚 Learning: 2025-12-21T21:15:03.782Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.782Z
Learning: In changesets, start with a link to the issue when fixing a bug (e.g., 'Fixed [#4444](link): ...')

Applied to files:

  • .changeset/curvy-worlds-invent.md
🪛 LanguageTool
.changeset/curvy-worlds-invent.md

[style] ~5-~5: Consider using a different verb for a more formal wording.
Context: .../github.com//issues/8491): Fixed the issue with false positive errors fo...

(FIX_RESOLVE)

⏰ 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). (12)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)

Comment on lines +177 to +179
// return <div> {isError && <Error />}</div>; // This should pass
// return <div> {isEqual && <Equal />}</div>; // This should pass
// return <div> {emptyStr && <Empty />}</div>; // This should fail
Copy link
Member

Choose a reason for hiding this comment

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

To remove?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not actually, this was supposed to be comment for future contributors, so that it makes sense what the code is doing. Maybe i added more noise by doing that

@ematipico should i remove ?

Copy link
Member

Choose a reason for hiding this comment

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

Ah ok, it wasn't clear. I would move the phrasing first, the example afterwards

Comment on lines +191 to +196
AnyJsLiteralExpression::JsNumberLiteralExpression(num) => {
let value = num.value_token().ok()?;
if value.text_trimmed() == "0" {
return Some(());
}
return None;
Copy link
Member

Choose a reason for hiding this comment

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

I believe the bot is right @dibashthapa

Comment on lines 167 to 210
if let AnyJsExpression::JsIdentifierExpression(ident) = &left {
let name = ident.name().ok()?;

// Use the semantic model to resolve the variable binding and check
// if it's initialized with a boolean literal. This allows us to
// if it's initialized with safe expressions. This allows us to
// handle cases like:
// let isOpen = false; // This is safe
// let isError = errorCount > 0; // This is safe
// let isEqual = a === b; // This is safe
// let emptyStr = ''; // This is unsafe
// return <div>{isOpen && <Content />}</div>; // This should pass
if let Some(binding) = model.binding(&name)
&& binding
.tree()
.declaration()
.and_then(|declaration| {
if let AnyJsBindingDeclaration::JsVariableDeclarator(declarator) =
declaration
{
Some(declarator)
} else {
None
}
})
.and_then(|declarator| declarator.initializer())
.and_then(|initializer| initializer.expression().ok())
.and_then(|expr| {
if let AnyJsExpression::AnyJsLiteralExpression(literal) = expr {
Some(literal)
} else {
None
}
})
.and_then(|literal| literal.value_token().ok())
.is_some_and(|token| matches!(token.text_trimmed(), "true" | "false"))
{
return None;
// return <div> {isError && <Error />}</div>; // This should pass
// return <div> {isEqual && <Equal />}</div>; // This should pass
// return <div> {emptyStr && <Empty />}</div>; // This should fail

if let Some(variable) = find_variable(model, &name) {
match variable {
AnyJsExpression::AnyJsLiteralExpression(expr) => {
match expr {
AnyJsLiteralExpression::JsStringLiteralExpression(str) => {
if str.inner_string_text().ok()?.text().is_empty() {
return Some(());
}
return None;
}
AnyJsLiteralExpression::JsNullLiteralExpression(_) => {
return Some(());
}
AnyJsLiteralExpression::JsNumberLiteralExpression(num) => {
let value = num.value_token().ok()?;
if value.text_trimmed() == "0" {
return Some(());
}
return None;
}
_ => return None,
};
}
AnyJsExpression::JsUnaryExpression(_)
| AnyJsExpression::JsBinaryExpression(_)
| AnyJsExpression::JsCallExpression(_) => return None,
_ => {}
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

@coderabbitai The rule doesn't implement the action function, which means that it can't have a code fix in its metadata

'@biomejs/biome': patch
---

Related to [#8491](https://github.com/biomejs/biome/issues/8491): Fixed the issue with false positive errors for safe boolean expressions.
Copy link
Member

Choose a reason for hiding this comment

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

If this PR doesn't close the "related" bug, there's no need to add it to the changeset

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This PR do fix the issue

function MyComponent() {
  const someCondition = !!x;

  return (
    <div>
      {someCondition && "hello"}
      {!!someCondition && "hello"}
    </div>
  )
}

However, it still doesn't addresses the fixes for #8491 (comment)

I couldn't find the perfect way to describe the fixes, hence "Related"

Copy link
Member

Choose a reason for hiding this comment

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

I think it's fine to just mention what this patch fixes. If you want to highlight the issue, which is good, I suggest finding a different wording e.g. "There are still pending fixes. Head to #xxx for more details". "Related #xxxx` doesn't seem useful for our users

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Linter Area: linter L-JavaScript Language: JavaScript and super languages L-JSON Language: JSON and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants