Skip to content
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

refactor(linter): improve labels and help message for eslint/no-useless-constructor #6389

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions crates/oxc_linter/src/rules/eslint/no_useless_constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,34 @@ use oxc_ast::{
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use oxc_span::{GetSpan, Span};

use crate::{context::LintContext, rule::Rule, AstNode};

/// ```js
/// class A { constructor(){} }
/// ```
fn no_empty_constructor(constructor_span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Empty constructors are unnecessary")
.with_label(constructor_span)
.with_help("Remove the constructor or add code to it.")
}
fn no_redundant_super_call(constructor_span: Span) -> OxcDiagnostic {

/// ```js
/// class A { }
/// class B extends A {
/// constructor() {
/// super();
/// }
/// }
/// ```
fn no_redundant_super_call(constructor_span: Span, super_span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Redundant super call in constructor")
.with_label(constructor_span).with_help("Constructors of subclasses invoke super() automatically if they are empty. Remove this constructor or add code to it.")
.with_labels([
constructor_span.primary_label("This constructor is unnecessary,"),
super_span.label("because it only passes arguments through to the superclass"),
])
.with_help("Subclasses automatically use the constructor of their superclass, making this redundant.\nRemove this constructor or add code to it.")
}

#[derive(Debug, Default, Clone)]
Expand Down Expand Up @@ -165,9 +181,10 @@ fn lint_redundant_super_call<'a>(
&& !is_overriding(params)
&& (is_spread_arguments(super_args) || is_passing_through(params, super_args))
{
ctx.diagnostic_with_fix(no_redundant_super_call(constructor.span), |fixer| {
fixer.delete_range(constructor.span)
});
ctx.diagnostic_with_fix(
no_redundant_super_call(constructor.key.span(), super_call.span()),
|fixer| fixer.delete_range(constructor.span),
);
}
}

Expand Down Expand Up @@ -276,6 +293,11 @@ fn test() {
"class A { constructor(){} }",
"class A { 'constructor'(){} }",
"class A extends B { constructor() { super(); } }",
"class A extends B {
constructor() {
super();
}
}",
"class A extends B { constructor(foo){ super(foo); } }",
"class A extends B { constructor(foo, bar){ super(foo, bar); } }",
"class A extends B { constructor(...args){ super(...args); } }",
Expand Down
63 changes: 49 additions & 14 deletions crates/oxc_linter/src/snapshots/no_useless_constructor.snap
Original file line number Diff line number Diff line change
Expand Up @@ -18,51 +18,86 @@ source: crates/oxc_linter/src/tester.rs
⚠ eslint(no-useless-constructor): Redundant super call in constructor
╭─[no_useless_constructor.tsx:1:21]
1 │ class A extends B { constructor() { super(); } }
· ──────────────────────────
· ─────┬───── ───┬───
· │ ╰── because it only passes arguments through to the superclass
· ╰── This constructor is unnecessary,
╰────
help: Constructors of subclasses invoke super() automatically if they are empty. Remove this constructor or add code to it.
help: Subclasses automatically use the constructor of their superclass, making this redundant.
Remove this constructor or add code to it.

⚠ eslint(no-useless-constructor): Redundant super call in constructor
╭─[no_useless_constructor.tsx:2:5]
1 │ class A extends B {
2 │ constructor() {
· ─────┬─────
· ╰── This constructor is unnecessary,
3 │ super();
· ───┬───
· ╰── because it only passes arguments through to the superclass
4 │ }
╰────
help: Subclasses automatically use the constructor of their superclass, making this redundant.
Remove this constructor or add code to it.

⚠ eslint(no-useless-constructor): Redundant super call in constructor
╭─[no_useless_constructor.tsx:1:21]
1 │ class A extends B { constructor(foo){ super(foo); } }
· ───────────────────────────────
· ─────┬───── ─────┬────
· │ ╰── because it only passes arguments through to the superclass
· ╰── This constructor is unnecessary,
╰────
help: Constructors of subclasses invoke super() automatically if they are empty. Remove this constructor or add code to it.
help: Subclasses automatically use the constructor of their superclass, making this redundant.
Remove this constructor or add code to it.

⚠ eslint(no-useless-constructor): Redundant super call in constructor
╭─[no_useless_constructor.tsx:1:21]
1 │ class A extends B { constructor(foo, bar){ super(foo, bar); } }
· ─────────────────────────────────────────
· ─────┬───── ───────┬───────
· │ ╰── because it only passes arguments through to the superclass
· ╰── This constructor is unnecessary,
╰────
help: Constructors of subclasses invoke super() automatically if they are empty. Remove this constructor or add code to it.
help: Subclasses automatically use the constructor of their superclass, making this redundant.
Remove this constructor or add code to it.

⚠ eslint(no-useless-constructor): Redundant super call in constructor
╭─[no_useless_constructor.tsx:1:21]
1 │ class A extends B { constructor(...args){ super(...args); } }
· ───────────────────────────────────────
· ─────┬───── ───────┬──────
· │ ╰── because it only passes arguments through to the superclass
· ╰── This constructor is unnecessary,
╰────
help: Constructors of subclasses invoke super() automatically if they are empty. Remove this constructor or add code to it.
help: Subclasses automatically use the constructor of their superclass, making this redundant.
Remove this constructor or add code to it.

⚠ eslint(no-useless-constructor): Redundant super call in constructor
╭─[no_useless_constructor.tsx:1:23]
1 │ class A extends B.C { constructor() { super(...arguments); } }
· ──────────────────────────────────────
· ─────┬───── ─────────┬─────────
· │ ╰── because it only passes arguments through to the superclass
· ╰── This constructor is unnecessary,
╰────
help: Constructors of subclasses invoke super() automatically if they are empty. Remove this constructor or add code to it.
help: Subclasses automatically use the constructor of their superclass, making this redundant.
Remove this constructor or add code to it.

⚠ eslint(no-useless-constructor): Redundant super call in constructor
╭─[no_useless_constructor.tsx:1:21]
1 │ class A extends B { constructor(a, b, ...c) { super(...arguments); } }
· ────────────────────────────────────────────────
· ─────┬───── ─────────┬─────────
· │ ╰── because it only passes arguments through to the superclass
· ╰── This constructor is unnecessary,
╰────
help: Constructors of subclasses invoke super() automatically if they are empty. Remove this constructor or add code to it.
help: Subclasses automatically use the constructor of their superclass, making this redundant.
Remove this constructor or add code to it.

⚠ eslint(no-useless-constructor): Redundant super call in constructor
╭─[no_useless_constructor.tsx:1:21]
1 │ class A extends B { constructor(a, b, ...c) { super(a, b, ...c); } }
· ──────────────────────────────────────────────
· ─────┬───── ────────┬────────
· │ ╰── because it only passes arguments through to the superclass
· ╰── This constructor is unnecessary,
╰────
help: Constructors of subclasses invoke super() automatically if they are empty. Remove this constructor or add code to it.
help: Subclasses automatically use the constructor of their superclass, making this redundant.
Remove this constructor or add code to it.

⚠ eslint(no-useless-constructor): Empty constructors are unnecessary
╭─[no_useless_constructor.tsx:1:11]
Expand Down