Skip to content

Commit a0e5ab7

Browse files
committed
fix(lint/noUnusedVariables): only exempt interfaces/namespace bindings
1 parent e3a9671 commit a0e5ab7

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

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

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use biome_js_syntax::{
1111
AnyJsExpression, JsClassExpression, JsExport, JsFileSource, JsForStatement,
1212
JsFunctionExpression, JsIdentifierExpression, JsImport, JsModule, JsModuleItemList,
1313
JsSequenceExpression, JsSyntaxKind, JsSyntaxNode, TsConditionalType, TsDeclarationModule,
14-
TsInferType, TsInterfaceDeclaration, TsModuleDeclaration,
14+
TsInferType,
1515
};
1616
use biome_rowan::{AstNode, BatchMutationExt, Direction, SyntaxResult};
1717
use biome_rule_options::no_unused_variables::NoUnusedVariablesOptions;
@@ -413,33 +413,35 @@ impl Rule for NoUnusedVariables {
413413
/// Returns `true` if the file is considered a script
414414
/// and is an interface or namespace
415415
fn is_script_declaration(binding: &AnyJsIdentifierBinding) -> bool {
416+
// Verify this binding is from an interface or namespace
417+
let Some(decl) = binding.declaration() else {
418+
return false;
419+
};
420+
421+
let is_interface_or_namespace = matches!(
422+
decl,
423+
AnyJsBindingDeclaration::TsInterfaceDeclaration(_)
424+
| AnyJsBindingDeclaration::TsModuleDeclaration(_)
425+
);
426+
if !is_interface_or_namespace {
427+
return false;
428+
}
429+
416430
binding
417431
.syntax()
418432
.ancestors()
419433
.find_map(JsModuleItemList::cast)
420434
.is_some_and(|module_list| {
421435
// Only check top-level declarations
422436
let is_top_level = module_list.parent::<JsModule>().is_some();
423-
424437
if !is_top_level {
425438
return false;
426439
}
427440

428-
// Presence of imports/exports means its a module
429-
let has_import_or_export = (&module_list).into_iter().any(|item| {
441+
// If there are imports/exports, it's a module, not a script
442+
!module_list.into_iter().any(|item| {
430443
let kind = item.syntax().kind();
431444
JsImport::can_cast(kind) || JsExport::can_cast(kind)
432-
});
433-
434-
if has_import_or_export {
435-
return false;
436-
}
437-
438-
// We can't determine if an interface/namespace augments a global just from syntax
439-
// so all of them are treated the same
440-
module_list.into_iter().any(|item| {
441-
let kind = item.syntax().kind();
442-
TsInterfaceDeclaration::can_cast(kind) || TsModuleDeclaration::can_cast(kind)
443445
})
444446
})
445447
}

0 commit comments

Comments
 (0)