-
-
Notifications
You must be signed in to change notification settings - Fork 794
fix(noInvalidUseBeforeDeclaration): ignore valid use before declarations #8157
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: e67d0c9 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 |
997a9d5 to
9474ebd
Compare
| // function f() { X; } | ||
| // const X = 0; | ||
| // ``` | ||
| && (declaration_control_flow_root.is_none() || |
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.
I removed the declaration_scope.is_none() condition because it is completely useless.
9474ebd to
e67d0c9
Compare
WalkthroughReplaces 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
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. 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: 0
🧹 Nitpick comments (4)
.changeset/bright-tires-report.md (1)
9-14: Minor: Consider usingjsinstead oftsfor the code fence.The example is valid JavaScript and doesn't require TypeScript-specific syntax, so marking it as
jswould be more precise. That said,tsis 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 lookupThe 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 sameancestors().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‑checkAnyJsVariableScopemembership and consider a brief doc commentThe new
AnyJsVariableScopeunion looks like a good capture of “roots that delay evaluation” (scripts/modules, functions, classes and TS modules/members), and it matches the cases exercised invalid.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 scenariosThese additions hit exactly the tricky spots: a class referencing itself in a static field, and a class field referencing a later class and
constfrom 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
⛔ Files ignored due to path filters (1)
crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js.snapis excluded by!**/*.snapand 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 consistentAll the newly imported syntax nodes (
AnyJsFunction, class/object members, TS nodes,AnyJsIdentifierUsage, anddeclare_node_union) are exercised below and line up with the newAnyJsVariableScopeunion and usage checks. Nothing obvious missing or unused from this block.Also applies to: 13-13
CodSpeed Performance ReportMerging #8157 will not alter performanceComparing Summary
Footnotes
|
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: 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 positiveUsing
AnyJsVariableScope::can_caston 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 newclassAtest no longer get reported. If you fancy a tiny tidy‑up, you could extract the repeatedancestors().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
⛔ Files ignored due to path filters (1)
crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js.snapis excluded by!**/*.snapand 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 solidThe added
Class/classAscenarios 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 usageThe extra Js*/Ts* node imports and
declare_node_unionline up with the newAnyJsVariableScopedefinition and its use inrun; nothing appears unused or missing.
301-317: AnyJsVariableScope composition looks appropriate for variable‑scope rootsThe
AnyJsVariableScopeunion 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 oldAnyJsControlFlowRootdefinition to ensure you haven’t unintentionally dropped or added a variant beyondJsClassDeclaration..changeset/bright-tires-report.md (1)
1-14: Changeset accurately captures the behaviour changeNice concise note and example; it mirrors the new
valid.jsscenario and makes the scope of the fix clear for users scanning the changelog.
Summary
Fix #8148
The bug was caused by the fact that
JsClassDeclarationis not part ofAnyJsControlFlowRoot.I introduced a new node union
AnyJsVariableScopethat corresponds toAnyJsControlFlowRootwithJsClassDeclarationadded.I wonder if we could replace
JsStaticInitializationBlockClassMemberbyJsClassDeclarationinAnyJsControlFlowRoot.Test Plan
I added a test.
Docs
I added a changset.