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

Skip to content

Conversation

@Conaclos
Copy link
Member

Summary

Fix #8148

The bug was caused by the fact that JsClassDeclaration is not part of AnyJsControlFlowRoot.
I introduced a new node union AnyJsVariableScope that corresponds to AnyJsControlFlowRoot with JsClassDeclaration added.

I wonder if we could replace JsStaticInitializationBlockClassMember by JsClassDeclaration in AnyJsControlFlowRoot.

Test Plan

I added a test.

Docs

I added a changset.

@changeset-bot
Copy link

changeset-bot bot commented Nov 18, 2025

🦋 Changeset detected

Latest commit: e67d0c9

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

@Conaclos Conaclos changed the title fix(noInvalidUseBeforeDeclaration): don't report valid use befroe declarations fix(noInvalidUseBeforeDeclaration): ignore valid use-before declarations Nov 18, 2025
@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Nov 18, 2025
@Conaclos Conaclos changed the title fix(noInvalidUseBeforeDeclaration): ignore valid use-before declarations fix(noInvalidUseBeforeDeclaration): ignore valid use before declarations Nov 18, 2025
@Conaclos Conaclos force-pushed the conaclos/noInvalidUseBeforeDeclaration-8148 branch from 997a9d5 to 9474ebd Compare November 18, 2025 18:13
// function f() { X; }
// const X = 0;
// ```
&& (declaration_control_flow_root.is_none() ||
Copy link
Member Author

Choose a reason for hiding this comment

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

I removed the declaration_scope.is_none() condition because it is completely useless.

@Conaclos Conaclos force-pushed the conaclos/noInvalidUseBeforeDeclaration-8148 branch from 9474ebd to e67d0c9 Compare November 18, 2025 18:16
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

Replaces use of AnyJsControlFlowRoot with a new AnyJsVariableScope union in the noInvalidUseBeforeDeclaration lint. Scope checks now use AnyJsVariableScope.can_cast and ancestor-based comparisons against declaration_scope, covering scripts, modules, functions, class members and TypeScript module/property members. Adds the AnyJsVariableScope public union and adjusts the lint logic accordingly. Adds a test demonstrating class value usages (e.g. static field initialiser referencing the class) are no longer reported as invalid.

Possibly related PRs

Suggested reviewers

  • dyc3
  • ematipico

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: fixing the noInvalidUseBeforeDeclaration rule to properly ignore valid uses before declarations.
Description check ✅ Passed The description clearly relates to the changeset, explaining the bug fix, the root cause, the solution via AnyJsVariableScope, and mentioning tests and a changeset entry.
Linked Issues check ✅ Passed The PR properly addresses issue #8148 by fixing the noInvalidUseBeforeDeclaration rule to stop incorrectly reporting valid class value references.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the noInvalidUseBeforeDeclaration rule: the linter rule fix, test cases, and changeset documentation.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch conaclos/noInvalidUseBeforeDeclaration-8148

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
.changeset/bright-tires-report.md (1)

9-14: Minor: Consider using js instead of ts for the code fence.

The example is valid JavaScript and doesn't require TypeScript-specific syntax, so marking it as js would be more precise. That said, ts is not incorrect since all valid JS is valid TS.

-```ts
+```js
 class classA {
 	C = C;
 }
 const C = 0;
-```
+```
crates/biome_js_analyze/src/lint/correctness/no_invalid_use_before_declaration.rs (2)

132-137: Factor out the repeated variable-scope ancestor lookup

The new declaration_scope / reference-scope comparison looks like the right mechanism to avoid cross‑scope false positives, and it should address the class value cases nicely. You are, however, repeating the same ancestors().skip(1).find(|a| AnyJsVariableScope::can_cast(a.kind())) pattern twice.

A small helper would tighten things up and make future tweaks to the scope definition less error‑prone, e.g.:

+fn variable_scope(node: &SyntaxNode) -> Option<SyntaxNode> {
+    node.ancestors().skip(1).find(|ancestor| AnyJsVariableScope::can_cast(ancestor.kind()))
+}
+
-            let declaration_scope = declaration
-                .syntax()
-                .ancestors()
-                .skip(1)
-                .find(|ancestor| AnyJsVariableScope::can_cast(ancestor.kind()));
+            let declaration_scope = variable_scope(declaration.syntax());
...
-                            declaration_scope == reference_syntax
-                                .ancestors()
-                                .skip(1)
-                                .find(|ancestor| AnyJsVariableScope::can_cast(ancestor.kind()))
+                            declaration_scope == variable_scope(reference_syntax)

Not a blocker, but it makes the intent a bit clearer for the next person reading the rule.

Also applies to: 160-165


301-318: Double‑check AnyJsVariableScope membership and consider a brief doc comment

The new AnyJsVariableScope union looks like a good capture of “roots that delay evaluation” (scripts/modules, functions, classes and TS modules/members), and it matches the cases exercised in valid.js.

Two small suggestions:

  • Sanity‑check that this union covers all the places we want to treat as separate variable scopes for this rule (e.g. whatever node actually contains class field initialisers in your AST, if that is not always the class itself).
  • Consider a short comment above the union explaining the intent (“Node kinds that define a separate value scope for noInvalidUseBeforeDeclaration”), so future rules do not accidentally misuse or extend it in the wrong direction.

Behaviour‑wise this looks sound; this is more about maintainability and future you not having to re‑reverse‑engineer the rationale.

crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js (1)

17-19: New valid cases nicely exercise the class value scenarios

These additions hit exactly the tricky spots: a class referencing itself in a static field, and a class field referencing a later class and const from the outer scope. That should keep the regression in #8148 firmly nailed down.

If you feel like being extra paranoid later, a variant using a static { ... } block would round out the coverage, but what you have here is already solid.

Also applies to: 21-26

📜 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 748e948 and 997a9d5.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (3)
  • .changeset/bright-tires-report.md (1 hunks)
  • crates/biome_js_analyze/src/lint/correctness/no_invalid_use_before_declaration.rs (4 hunks)
  • crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.

Applied to files:

  • .changeset/bright-tires-report.md
⏰ 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_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: autofix
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
🔇 Additional comments (2)
.changeset/bright-tires-report.md (1)

1-14: Changeset looks great.

The format is correct, the issue reference is clear, and the example effectively demonstrates the resolved false positive. Ship it! ✅

crates/biome_js_analyze/src/lint/correctness/no_invalid_use_before_declaration.rs (1)

6-10: Imports for new scope/usage types look consistent

All the newly imported syntax nodes (AnyJsFunction, class/object members, TS nodes, AnyJsIdentifierUsage, and declare_node_union) are exercised below and line up with the new AnyJsVariableScope union and usage checks. Nothing obvious missing or unused from this block.

Also applies to: 13-13

@codspeed-hq
Copy link

codspeed-hq bot commented Nov 18, 2025

CodSpeed Performance Report

Merging #8157 will not alter performance

Comparing conaclos/noInvalidUseBeforeDeclaration-8148 (e67d0c9) with main (2dd38cf)1

Summary

✅ 58 untouched
⏩ 95 skipped2

Footnotes

  1. No successful run was found on main (748e948) during the generation of this report, so 2dd38cf was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 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.

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)
crates/biome_js_analyze/src/lint/correctness/no_invalid_use_before_declaration.rs (1)

132-137: Scope computation via AnyJsVariableScope fixes the class‑field false positive

Using AnyJsVariableScope::can_cast on both the declaration and reference ancestor chains cleanly separates references inside class bodies (or other scope roots) from top‑level declarations, so patterns like the new classA test no longer get reported. If you fancy a tiny tidy‑up, you could extract the repeated ancestors().skip(1).find(|ancestor| AnyJsVariableScope::can_cast(ancestor.kind())) into a helper, but it’s purely cosmetic.

Also applies to: 160-164

📜 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 997a9d5 and e67d0c9.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (3)
  • .changeset/bright-tires-report.md (1 hunks)
  • crates/biome_js_analyze/src/lint/correctness/no_invalid_use_before_declaration.rs (4 hunks)
  • crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.

Applied to files:

  • .changeset/bright-tires-report.md
⏰ 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: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test Node.js API
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
🔇 Additional comments (4)
crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js (1)

16-26: New class-based regression examples look solid

The added Class/classA scenarios neatly cover self‑referential static initialisers and class fields using later declarations, which is exactly the sort of valid use‑before‑declaration this rule should now accept. No further tweaks needed here.

crates/biome_js_analyze/src/lint/correctness/no_invalid_use_before_declaration.rs (2)

1-13: Import updates match the new scope union usage

The extra Js*/Ts* node imports and declare_node_union line up with the new AnyJsVariableScope definition and its use in run; nothing appears unused or missing.


301-317: AnyJsVariableScope composition looks appropriate for variable‑scope roots

The AnyJsVariableScope union matches the intended “variable scope roots” set (scripts, modules, functions, classes, relevant class/object members, TS modules/property members) and provides a nice central hook for this and any future rules that need the same notion of scope. Worth just double‑checking against the old AnyJsControlFlowRoot definition to ensure you haven’t unintentionally dropped or added a variant beyond JsClassDeclaration.

.changeset/bright-tires-report.md (1)

1-14: Changeset accurately captures the behaviour change

Nice concise note and example; it mirrors the new valid.js scenario and makes the scope of the fix clear for users scanning the changelog.

@Conaclos Conaclos merged commit 12d5b42 into main Nov 18, 2025
18 checks passed
@Conaclos Conaclos deleted the conaclos/noInvalidUseBeforeDeclaration-8148 branch November 18, 2025 21:12
@github-actions github-actions bot mentioned this pull request Nov 19, 2025
ematipico pushed a commit to hamirmahal/biome that referenced this pull request Nov 19, 2025
l0ngvh pushed a commit to l0ngvh/biome that referenced this pull request Dec 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💅 noInvalidUseBeforeDeclaration: class value references should not be reported

3 participants