Skip to content

Commit 12d5b42

Browse files
authored
fix(noInvalidUseBeforeDeclaration): ignore valid use before declarations (#8157)
1 parent 748e948 commit 12d5b42

File tree

4 files changed

+59
-9
lines changed

4 files changed

+59
-9
lines changed

.changeset/bright-tires-report.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Fixed [#8148](https://github.com/biomejs/biome/issues/8148). [`noInvalidUseBeforeDeclaration`](https://biomejs.dev/linter/rules/no-invalid-use-before-declaration/) no longer reports some valid use before declarations.
6+
7+
The following code is no longer reported as invalid:
8+
9+
```ts
10+
class classA {
11+
C = C;
12+
}
13+
const C = 0;
14+
```

crates/biome_js_analyze/src/lint/correctness/no_invalid_use_before_declaration.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
use crate::{services::control_flow::AnyJsControlFlowRoot, services::semantic::SemanticServices};
1+
use crate::services::semantic::SemanticServices;
22
use biome_analyze::{Rule, RuleDiagnostic, RuleSource, context::RuleContext, declare_lint_rule};
33
use biome_console::markup;
44
use biome_diagnostics::Severity;
55
use biome_js_syntax::{
6-
AnyJsExportNamedSpecifier, AnyJsIdentifierUsage, JsFileSource, JsVariableDeclarationClause,
7-
TsDeclareStatement,
6+
AnyJsExportNamedSpecifier, AnyJsFunction, AnyJsIdentifierUsage, JsClassDeclaration,
7+
JsConstructorClassMember, JsFileSource, JsGetterClassMember, JsGetterObjectMember,
8+
JsMethodClassMember, JsMethodObjectMember, JsModule, JsScript, JsSetterClassMember,
9+
JsSetterObjectMember, JsStaticInitializationBlockClassMember, JsVariableDeclarationClause,
10+
TsDeclareStatement, TsModuleDeclaration, TsPropertySignatureTypeMember,
811
binding_ext::{AnyJsBindingDeclaration, AnyJsIdentifierBinding},
912
};
10-
use biome_rowan::{AstNode, SyntaxNodeOptionExt, TextRange};
13+
use biome_rowan::{AstNode, SyntaxNodeOptionExt, TextRange, declare_node_union};
1114
use biome_rule_options::no_invalid_use_before_declaration::NoInvalidUseBeforeDeclarationOptions;
1215

1316
declare_lint_rule! {
@@ -126,11 +129,11 @@ impl Rule for NoInvalidUseBeforeDeclaration {
126129
} else {
127130
declaration.range().end()
128131
};
129-
let declaration_control_flow_root = declaration
132+
let declaration_scope = declaration
130133
.syntax()
131134
.ancestors()
132135
.skip(1)
133-
.find(|ancestor| AnyJsControlFlowRoot::can_cast(ancestor.kind()));
136+
.find(|ancestor| AnyJsVariableScope::can_cast(ancestor.kind()));
134137
for reference in binding.all_references() {
135138
if reference.range_start() < declaration_end {
136139
let reference_syntax = reference.syntax();
@@ -154,11 +157,10 @@ impl Rule for NoInvalidUseBeforeDeclaration {
154157
// function f() { X; }
155158
// const X = 0;
156159
// ```
157-
&& (declaration_control_flow_root.is_none() ||
158-
declaration_control_flow_root == reference_syntax
160+
&& declaration_scope == reference_syntax
159161
.ancestors()
160162
.skip(1)
161-
.find(|ancestor| AnyJsControlFlowRoot::can_cast(ancestor.kind()))
163+
.find(|ancestor| AnyJsVariableScope::can_cast(ancestor.kind())
162164
)
163165
// ignore when used as a type.
164166
// For example:
@@ -295,3 +297,21 @@ impl TryFrom<&AnyJsBindingDeclaration> for DeclarationKind {
295297
}
296298
}
297299
}
300+
301+
declare_node_union! {
302+
AnyJsVariableScope =
303+
JsScript
304+
| JsModule
305+
| AnyJsFunction
306+
| JsClassDeclaration
307+
| JsConstructorClassMember
308+
| JsGetterClassMember
309+
| JsGetterObjectMember
310+
| JsMethodClassMember
311+
| JsMethodObjectMember
312+
| JsSetterClassMember
313+
| JsSetterObjectMember
314+
| JsStaticInitializationBlockClassMember
315+
| TsModuleDeclaration
316+
| TsPropertySignatureTypeMember
317+
}

crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ function h() { Y; }; const Y = 0;
1313
function useClassInFunction() {
1414
const instance = new Class();
1515
}
16+
1617
class Class {
1718
static SINGLETON = new Class();
1819
}
20+
21+
class classA {
22+
C = C;
23+
prop = new classB();
24+
}
25+
class classB {}
26+
const C = 0;

crates/biome_js_analyze/tests/specs/correctness/noInvalidUseBeforeDeclaration/valid.js.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@ function h() { Y; }; const Y = 0;
1919
function useClassInFunction() {
2020
const instance = new Class();
2121
}
22+
2223
class Class {
2324
static SINGLETON = new Class();
2425
}
2526
27+
class classA {
28+
C = C;
29+
prop = new classB();
30+
}
31+
class classB {}
32+
const C = 0;
33+
2634
```

0 commit comments

Comments
 (0)