quick-lint-js
quick-lint-js copied to clipboard
20$: Detect dead code and unused variables
Create a special diagnostic for dead code and unused variables.
Example:
function f() {
let x = 69; // info: unused variable
return 42;
g(); // info: unreachable code
}
In editors, these diagnostics should be enabled by default. LSP has DiagnosticTag.Unnecessary
, and VS Code probably has an API too.
In the CLI, these diagnostics should be opt-in, or not part of the exit-fail-on set.
(This might need to be split into two or three tasks.)
Another example of redundant code: continue
at the end of a loop:
for (let b of bananas) {
console.log(b);
continue; // redundant
}
Another example of redundant code: true&&
and false||
:
&&true
is not entirely redundant though:
> true && "x"
'x'
> false || "x"
'x'
> "x" && true // <--
true
> "x" || false
'x'
Same with || false
:
> true && null
null
> false || null
null
> null && true
null
> null || false // <--
false
Another example: x === y ? true : false
Another example: returning undefined
explicitly at the end of a function:
function f() {
console.log("hi");
return; // redundant
}
Another example: chained TypeScript null assertions:
let x: int? = 42;
console.log(x!!!);
// ^^ redundant
Another example: empty export
statements:
export {}; // redundant
Another example: final assignment to a local variable which isn't later referenced:
let x = 42;
x = 69; // warning
Another example: self-assignment for local variables:
let x = 1, y = 2;
x = x; // warning
Another example: return
with value in a setter:
class C {
get x() { return this._x; }
set x(v) {
this._x = v;
return v; // warning
}
}
More examples in TypeScript:
x!! // second ! is redundant
x!?.prop // ? is redundant
x!?.() // ?. is redundant
C
will never get executed in the following code, so we should mark it as dead code:
for (A; B; C) {
D;
return E;
}