Skip to content

Commit

Permalink
fix(noUnusedVariables): don't report params in contructor types
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Jun 10, 2024
1 parent 68c891a commit 58b997c
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 33 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 15 additions & 14 deletions crates/biome_js_analyze/src/lint/correctness/no_unused_variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -114,23 +114,26 @@ pub enum SuggestedFix {
}

fn is_function_that_is_ok_parameter_not_be_used(
parent_function: &Option<JsAnyParameterParentFunction>,
parent_function: &Option<AnyJsParameterParentFunction>,
) -> 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(_)
)
)
}
Expand Down Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -65,23 +65,26 @@ pub enum SuggestedFix {
}

fn is_function_that_is_ok_parameter_not_be_used(
parent_function: &Option<JsAnyParameterParentFunction>,
parent_function: &Option<AnyJsParameterParentFunction>,
) -> 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(_)
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Classlike = new (arg: unknown) => string;
Original file line number Diff line number Diff line change
@@ -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;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type Classlike = new (arg: unknown) => string;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: valid.ts
---
# Input
```ts
type Classlike = new (arg: unknown) => string;
```
16 changes: 8 additions & 8 deletions crates/biome_js_syntax/src/binding_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ impl TsIdentifierBinding {
}

declare_node_union! {
pub JsAnyParameterParentFunction =
pub AnyJsParameterParentFunction =
JsFunctionDeclaration
| JsFunctionExpression
| JsArrowFunctionExpression
Expand Down Expand Up @@ -440,41 +440,41 @@ declare_node_union! {
| TsCallSignatureTypeMember
}

fn parent_function(node: &JsSyntaxNode) -> Option<JsAnyParameterParentFunction> {
fn parent_function(node: &JsSyntaxNode) -> Option<AnyJsParameterParentFunction> {
let parent = node.parent()?;

match parent.kind() {
JsSyntaxKind::JS_PARAMETER_LIST => {
// SAFETY: kind check above
let parameters = JsParameterList::unwrap_cast(parent).parent::<JsParameters>()?;
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::<JsConstructorParameters>()?;
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<JsAnyParameterParentFunction> {
pub fn parent_function(&self) -> Option<AnyJsParameterParentFunction> {
parent_function(&self.syntax)
}
}

impl JsRestParameter {
pub fn parent_function(&self) -> Option<JsAnyParameterParentFunction> {
pub fn parent_function(&self) -> Option<AnyJsParameterParentFunction> {
parent_function(&self.syntax)
}
}

impl TsPropertyParameter {
pub fn parent_function(&self) -> Option<JsAnyParameterParentFunction> {
pub fn parent_function(&self) -> Option<AnyJsParameterParentFunction> {
parent_function(&self.syntax)
}
}

0 comments on commit 58b997c

Please sign in to comment.