diff --git a/CHANGELOG.md b/CHANGELOG.md index c0b0fe897666..191961451fce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,16 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b - [noEmptyInterface](https://biomejs.dev/linter/rules/no-empty-interface/) now ignores empty interfaces in ambient modules ([#3110](https://github.com/biomejs/biome/issues/3110)). Contributed by @Conaclos +- [noUnusedVariables](https://biomejs.dev/linter/rules/no-unused-variables/) and [noUnusedFunctionParameters](https://biomejs.dev/linter/rules/no-unused-function-parameters/) no longer report the parameters of a constructor type ([#3135](https://github.com/biomejs/biome/issues/3135)). + + Previously, `arg` was reported as unused in a constructor type like: + + ```ts + export type Classlike = new (arg: unknown) => string; + ``` + + Contributed by @Conaclos + ### Parser #### New features diff --git a/crates/biome_js_analyze/src/lint/correctness/no_unused_variables.rs b/crates/biome_js_analyze/src/lint/correctness/no_unused_variables.rs index 530a592efcd0..36b2123f7ba8 100644 --- a/crates/biome_js_analyze/src/lint/correctness/no_unused_variables.rs +++ b/crates/biome_js_analyze/src/lint/correctness/no_unused_variables.rs @@ -7,7 +7,7 @@ use biome_analyze::{ use biome_console::markup; use biome_js_semantic::ReferencesExtensions; use biome_js_syntax::binding_ext::{ - AnyJsBindingDeclaration, AnyJsIdentifierBinding, JsAnyParameterParentFunction, + AnyJsBindingDeclaration, AnyJsIdentifierBinding, AnyJsParameterParentFunction, }; use biome_js_syntax::declaration_ext::is_in_ambient_context; use biome_js_syntax::{ @@ -114,23 +114,26 @@ pub enum SuggestedFix { } fn is_function_that_is_ok_parameter_not_be_used( - parent_function: &Option, + parent_function: &Option, ) -> bool { matches!( parent_function, Some( // bindings in signatures are ok to not be used - JsAnyParameterParentFunction::TsMethodSignatureClassMember(_) - | JsAnyParameterParentFunction::TsCallSignatureTypeMember(_) - | JsAnyParameterParentFunction::TsConstructSignatureTypeMember(_) - | JsAnyParameterParentFunction::TsConstructorSignatureClassMember(_) - | JsAnyParameterParentFunction::TsMethodSignatureTypeMember(_) - | JsAnyParameterParentFunction::TsSetterSignatureClassMember(_) - | JsAnyParameterParentFunction::TsSetterSignatureTypeMember(_) + AnyJsParameterParentFunction::TsMethodSignatureClassMember(_) + | AnyJsParameterParentFunction::TsCallSignatureTypeMember(_) + | AnyJsParameterParentFunction::TsConstructSignatureTypeMember(_) + | AnyJsParameterParentFunction::TsConstructorSignatureClassMember(_) + | AnyJsParameterParentFunction::TsMethodSignatureTypeMember(_) + | AnyJsParameterParentFunction::TsSetterSignatureClassMember(_) + | AnyJsParameterParentFunction::TsSetterSignatureTypeMember(_) + | AnyJsParameterParentFunction::TsIndexSignatureClassMember(_) // bindings in function types are ok to not be used - | JsAnyParameterParentFunction::TsFunctionType(_) + | AnyJsParameterParentFunction::TsFunctionType(_) + | AnyJsParameterParentFunction::TsConstructorType(_) // binding in declare are ok to not be used - | JsAnyParameterParentFunction::TsDeclareFunctionDeclaration(_) + | AnyJsParameterParentFunction::TsDeclareFunctionDeclaration(_) + | AnyJsParameterParentFunction::TsDeclareFunctionExportDefaultDeclaration(_) ) ) } @@ -285,10 +288,8 @@ impl Rule for NoUnusedVariables { } let binding = ctx.query(); - let name = binding.name_token().ok()?; - let name = name.text_trimmed(); - if name.starts_with('_') { + if binding.name_token().ok()?.text_trimmed().starts_with('_') { return None; } diff --git a/crates/biome_js_analyze/src/lint/nursery/no_unused_function_parameters.rs b/crates/biome_js_analyze/src/lint/nursery/no_unused_function_parameters.rs index c81b29d5b30c..d2d68676fda8 100644 --- a/crates/biome_js_analyze/src/lint/nursery/no_unused_function_parameters.rs +++ b/crates/biome_js_analyze/src/lint/nursery/no_unused_function_parameters.rs @@ -4,7 +4,7 @@ use biome_analyze::{ use biome_console::markup; use biome_js_semantic::ReferencesExtensions; use biome_js_syntax::{ - binding_ext::{AnyJsBindingDeclaration, JsAnyParameterParentFunction}, + binding_ext::{AnyJsBindingDeclaration, AnyJsParameterParentFunction}, JsIdentifierBinding, }; use biome_rowan::{AstNode, BatchMutationExt}; @@ -65,23 +65,26 @@ pub enum SuggestedFix { } fn is_function_that_is_ok_parameter_not_be_used( - parent_function: &Option, + parent_function: &Option, ) -> bool { matches!( parent_function, Some( // bindings in signatures are ok to not be used - JsAnyParameterParentFunction::TsMethodSignatureClassMember(_) - | JsAnyParameterParentFunction::TsCallSignatureTypeMember(_) - | JsAnyParameterParentFunction::TsConstructSignatureTypeMember(_) - | JsAnyParameterParentFunction::TsConstructorSignatureClassMember(_) - | JsAnyParameterParentFunction::TsMethodSignatureTypeMember(_) - | JsAnyParameterParentFunction::TsSetterSignatureClassMember(_) - | JsAnyParameterParentFunction::TsSetterSignatureTypeMember(_) + AnyJsParameterParentFunction::TsMethodSignatureClassMember(_) + | AnyJsParameterParentFunction::TsCallSignatureTypeMember(_) + | AnyJsParameterParentFunction::TsConstructSignatureTypeMember(_) + | AnyJsParameterParentFunction::TsConstructorSignatureClassMember(_) + | AnyJsParameterParentFunction::TsMethodSignatureTypeMember(_) + | AnyJsParameterParentFunction::TsSetterSignatureClassMember(_) + | AnyJsParameterParentFunction::TsSetterSignatureTypeMember(_) + | AnyJsParameterParentFunction::TsIndexSignatureClassMember(_) // bindings in function types are ok to not be used - | JsAnyParameterParentFunction::TsFunctionType(_) + | AnyJsParameterParentFunction::TsFunctionType(_) + | AnyJsParameterParentFunction::TsConstructorType(_) // binding in declare are ok to not be used - | JsAnyParameterParentFunction::TsDeclareFunctionDeclaration(_) + | AnyJsParameterParentFunction::TsDeclareFunctionDeclaration(_) + | AnyJsParameterParentFunction::TsDeclareFunctionExportDefaultDeclaration(_) ) ) } diff --git a/crates/biome_js_analyze/tests/specs/correctness/noUnusedVariables/validType.ts b/crates/biome_js_analyze/tests/specs/correctness/noUnusedVariables/validType.ts new file mode 100644 index 000000000000..b14d53f63f53 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/correctness/noUnusedVariables/validType.ts @@ -0,0 +1 @@ +export type Classlike = new (arg: unknown) => string; \ No newline at end of file diff --git a/crates/biome_js_analyze/tests/specs/correctness/noUnusedVariables/validType.ts.snap b/crates/biome_js_analyze/tests/specs/correctness/noUnusedVariables/validType.ts.snap new file mode 100644 index 000000000000..576c3d277725 --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/correctness/noUnusedVariables/validType.ts.snap @@ -0,0 +1,8 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +expression: validType.ts +--- +# Input +```ts +export type Classlike = new (arg: unknown) => string; +``` diff --git a/crates/biome_js_analyze/tests/specs/nursery/noUnusedFunctionParameters/valid.ts b/crates/biome_js_analyze/tests/specs/nursery/noUnusedFunctionParameters/valid.ts new file mode 100644 index 000000000000..170b7866673e --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/nursery/noUnusedFunctionParameters/valid.ts @@ -0,0 +1 @@ +type Classlike = new (arg: unknown) => string; \ No newline at end of file diff --git a/crates/biome_js_analyze/tests/specs/nursery/noUnusedFunctionParameters/valid.ts.snap b/crates/biome_js_analyze/tests/specs/nursery/noUnusedFunctionParameters/valid.ts.snap new file mode 100644 index 000000000000..cd42ddcdff9b --- /dev/null +++ b/crates/biome_js_analyze/tests/specs/nursery/noUnusedFunctionParameters/valid.ts.snap @@ -0,0 +1,8 @@ +--- +source: crates/biome_js_analyze/tests/spec_tests.rs +expression: valid.ts +--- +# Input +```ts +type Classlike = new (arg: unknown) => string; +``` diff --git a/crates/biome_js_syntax/src/binding_ext.rs b/crates/biome_js_syntax/src/binding_ext.rs index 8e603c5587b0..ca2f61f5d418 100644 --- a/crates/biome_js_syntax/src/binding_ext.rs +++ b/crates/biome_js_syntax/src/binding_ext.rs @@ -410,7 +410,7 @@ impl TsIdentifierBinding { } declare_node_union! { - pub JsAnyParameterParentFunction = + pub AnyJsParameterParentFunction = JsFunctionDeclaration | JsFunctionExpression | JsArrowFunctionExpression @@ -440,7 +440,7 @@ declare_node_union! { | TsCallSignatureTypeMember } -fn parent_function(node: &JsSyntaxNode) -> Option { +fn parent_function(node: &JsSyntaxNode) -> Option { let parent = node.parent()?; match parent.kind() { @@ -448,33 +448,33 @@ fn parent_function(node: &JsSyntaxNode) -> Option // SAFETY: kind check above let parameters = JsParameterList::unwrap_cast(parent).parent::()?; let parent = parameters.syntax.parent()?; - JsAnyParameterParentFunction::cast(parent) + AnyJsParameterParentFunction::cast(parent) } JsSyntaxKind::JS_CONSTRUCTOR_PARAMETER_LIST => { // SAFETY: kind check above let parameters = JsConstructorParameterList::unwrap_cast(parent) .parent::()?; let parent = parameters.syntax().parent()?; - JsAnyParameterParentFunction::cast(parent) + AnyJsParameterParentFunction::cast(parent) } - _ => JsAnyParameterParentFunction::cast(parent), + _ => AnyJsParameterParentFunction::cast(parent), } } impl JsFormalParameter { - pub fn parent_function(&self) -> Option { + pub fn parent_function(&self) -> Option { parent_function(&self.syntax) } } impl JsRestParameter { - pub fn parent_function(&self) -> Option { + pub fn parent_function(&self) -> Option { parent_function(&self.syntax) } } impl TsPropertyParameter { - pub fn parent_function(&self) -> Option { + pub fn parent_function(&self) -> Option { parent_function(&self.syntax) } }