mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 21:54:36 +03:00
feat(es/lints): Improve error messages (#4142)
This commit is contained in:
parent
4e07a29112
commit
0f92eda0c7
@ -2,71 +2,95 @@
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
1 | if (foo == NaN) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
3 | if (NaN == foo) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
5 | if (foo != NaN) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return true
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
7 | if (foo == Number.NaN) {}
|
||||
: ^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^|^^^^^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
9 | if (foo != Number.NaN) {}
|
||||
: ^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^|^^^^^^^^
|
||||
: `-- this will always return true
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
11 | if (foo == Number['NaN']) {}
|
||||
: ^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^|^^^^^^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
20 | myArray.indexOf(NaN);
|
||||
: ^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^|^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
22 | myArray.lastIndexOf(NaN);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^|^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
24 | myArray.lastIndexOf(Number.NaN);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
26 | myArray.lastIndexOf(Number['NaN']);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
33 | case NaN:
|
||||
: ^^^
|
||||
: ^|^
|
||||
: `-- this will never match the discriminant
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
41 | switch (NaN) {
|
||||
: ^^^
|
||||
: ^|^
|
||||
: `-- this will never match the test of any case
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
@ -2,47 +2,63 @@
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
1 | if (foo == NaN) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
3 | if (NaN == foo) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
5 | if (foo != NaN) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return true
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
7 | if (foo == Number.NaN) {}
|
||||
: ^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^|^^^^^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
9 | if (foo != Number.NaN) {}
|
||||
: ^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^|^^^^^^^^
|
||||
: `-- this will always return true
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
11 | if (foo == Number['NaN']) {}
|
||||
: ^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^|^^^^^^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
33 | case NaN:
|
||||
: ^^^
|
||||
: ^|^
|
||||
: `-- this will never match the discriminant
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
41 | switch (NaN) {
|
||||
: ^^^
|
||||
: ^|^
|
||||
: `-- this will never match the test of any case
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
@ -2,59 +2,79 @@
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
1 | if (foo == NaN) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
3 | if (NaN == foo) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
5 | if (foo != NaN) {}
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will always return true
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
7 | if (foo == Number.NaN) {}
|
||||
: ^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^|^^^^^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
9 | if (foo != Number.NaN) {}
|
||||
: ^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^|^^^^^^^^
|
||||
: `-- this will always return true
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
11 | if (foo == Number['NaN']) {}
|
||||
: ^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^|^^^^^^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
20 | myArray.indexOf(NaN);
|
||||
: ^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^|^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
22 | myArray.lastIndexOf(NaN);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^|^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
24 | myArray.lastIndexOf(Number.NaN);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
26 | myArray.lastIndexOf(Number['NaN']);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
@ -2,41 +2,55 @@
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
1 | switch (NaN as any) {
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will never match the test of any case
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
2 | case NaN as any:
|
||||
: ^^^^^^^^^^
|
||||
: ^^^^^|^^^^
|
||||
: `-- this will never match the discriminant
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
3 | case Number.NaN as any:
|
||||
: ^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^|^^^^^^^^
|
||||
: `-- this will never match the discriminant
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
8 | if (foo == Number.NaN as any) {}
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^|^^^^^^^^^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
10 | myArray.lastIndexOf(NaN as any);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
12 | myArray.lastIndexOf(Number.NaN as any);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
14 | myArray.lastIndexOf(Number['NaN'] as any);
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
: ^^^^^^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^^^^^^
|
||||
: `-- this will always return -1
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
@ -2,5 +2,7 @@
|
||||
x Use the isNaN function to compare with NaN
|
||||
,----
|
||||
1 | if (a == NaN) {}
|
||||
: ^^^^^^^^
|
||||
: ^^^^|^^^
|
||||
: `-- this will always return false
|
||||
`----
|
||||
help: NaN is a special value and `NaN == NaN` is false
|
||||
|
@ -1,3 +1,6 @@
|
||||
#![cfg_attr(feature = "non_critical_lints", deny(unused))]
|
||||
#![cfg_attr(feature = "non_critical_lints", deny(clippy::all))]
|
||||
|
||||
pub mod config;
|
||||
pub mod rule;
|
||||
pub mod rules;
|
||||
|
@ -10,12 +10,12 @@ use crate::{
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
enum EqeqeqMode {
|
||||
enum EqEqEqMode {
|
||||
Always,
|
||||
Never,
|
||||
}
|
||||
|
||||
impl Default for EqeqeqMode {
|
||||
impl Default for EqEqEqMode {
|
||||
fn default() -> Self {
|
||||
Self::Always
|
||||
}
|
||||
@ -24,7 +24,7 @@ impl Default for EqeqeqMode {
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct EqeqeqConfig {
|
||||
#[serde(default)]
|
||||
mode: EqeqeqMode,
|
||||
mode: EqEqEqMode,
|
||||
}
|
||||
|
||||
pub fn eqeqeq(config: &RuleConfig<EqeqeqConfig>) -> Option<Box<dyn Rule>> {
|
||||
@ -37,7 +37,7 @@ pub fn eqeqeq(config: &RuleConfig<EqeqeqConfig>) -> Option<Box<dyn Rule>> {
|
||||
#[derive(Debug, Default)]
|
||||
struct Eqeqeq {
|
||||
expected_reaction: LintRuleReaction,
|
||||
mode: EqeqeqMode,
|
||||
mode: EqEqEqMode,
|
||||
}
|
||||
|
||||
impl Eqeqeq {
|
||||
@ -65,22 +65,22 @@ impl Eqeqeq {
|
||||
fn check(&self, span: Span, bin_op: &BinaryOp) {
|
||||
match bin_op {
|
||||
op!("==") => {
|
||||
if let EqeqeqMode::Always = self.mode {
|
||||
if let EqEqEqMode::Always = self.mode {
|
||||
self.emit_report(span, "==", "===");
|
||||
}
|
||||
}
|
||||
op!("!=") => {
|
||||
if let EqeqeqMode::Always = self.mode {
|
||||
if let EqEqEqMode::Always = self.mode {
|
||||
self.emit_report(span, "!=", "!==");
|
||||
}
|
||||
}
|
||||
op!("===") => {
|
||||
if let EqeqeqMode::Never = self.mode {
|
||||
if let EqEqEqMode::Never = self.mode {
|
||||
self.emit_report(span, "===", "==");
|
||||
}
|
||||
}
|
||||
op!("!==") => {
|
||||
if let EqeqeqMode::Never = self.mode {
|
||||
if let EqEqEqMode::Never = self.mode {
|
||||
self.emit_report(span, "!==", "!=");
|
||||
}
|
||||
}
|
||||
|
@ -62,19 +62,22 @@ impl UseIsNan {
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_report(&self, span: Span) {
|
||||
HANDLER.with(|handler| match self.expected_reaction {
|
||||
LintRuleReaction::Error => {
|
||||
handler.struct_span_err(span, MESSAGE).emit();
|
||||
fn emit_report(&self, span: Span, label_msg: &str) {
|
||||
HANDLER.with(|handler| {
|
||||
match self.expected_reaction {
|
||||
LintRuleReaction::Error => handler.struct_span_err(span, MESSAGE),
|
||||
LintRuleReaction::Warning => handler.struct_span_warn(span, MESSAGE),
|
||||
_ => {
|
||||
return;
|
||||
}
|
||||
LintRuleReaction::Warning => {
|
||||
handler.struct_span_warn(span, MESSAGE).emit();
|
||||
}
|
||||
_ => {}
|
||||
.span_label(span, label_msg)
|
||||
.help("NaN is a special value and `NaN == NaN` is false")
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
|
||||
fn check(&self, expr_span: Option<Span>, expr: &Expr) {
|
||||
fn check(&self, expr_span: Option<Span>, expr: &Expr, label_msg: &str) {
|
||||
match expr {
|
||||
Expr::TsAs(TsAsExpr {
|
||||
expr,
|
||||
@ -88,13 +91,13 @@ impl UseIsNan {
|
||||
..
|
||||
}) = type_ann.as_ref()
|
||||
{
|
||||
self.check(expr_span.or(Some(*span)), expr.as_ref());
|
||||
self.check(expr_span.or(Some(*span)), expr.as_ref(), label_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Expr::Ident(ident) => {
|
||||
if &*ident.sym == "NaN" {
|
||||
self.emit_report(expr_span.unwrap_or(ident.span));
|
||||
self.emit_report(expr_span.unwrap_or(ident.span), label_msg);
|
||||
}
|
||||
}
|
||||
Expr::Member(MemberExpr {
|
||||
@ -113,13 +116,13 @@ impl UseIsNan {
|
||||
match prop {
|
||||
MemberProp::Ident(ident) => {
|
||||
if &*ident.sym == "NaN" {
|
||||
self.emit_report(expr_span.unwrap_or(*span));
|
||||
self.emit_report(expr_span.unwrap_or(*span), label_msg);
|
||||
}
|
||||
}
|
||||
MemberProp::Computed(ComputedPropName { expr, .. }) => {
|
||||
if let Expr::Lit(Lit::Str(Str { value, .. })) = expr.as_ref() {
|
||||
if &*value == "NaN" {
|
||||
self.emit_report(expr_span.unwrap_or(*span));
|
||||
self.emit_report(expr_span.unwrap_or(*span), label_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,8 +139,13 @@ impl UseIsNan {
|
||||
impl Visit for UseIsNan {
|
||||
fn visit_bin_expr(&mut self, bin_expr: &BinExpr) {
|
||||
if let op!("==") | op!("!=") = bin_expr.op {
|
||||
self.check(Some(bin_expr.span), bin_expr.left.as_ref());
|
||||
self.check(Some(bin_expr.span), bin_expr.right.as_ref());
|
||||
let label_msg = if bin_expr.op == op!("==") {
|
||||
"this will always return false"
|
||||
} else {
|
||||
"this will always return true"
|
||||
};
|
||||
self.check(Some(bin_expr.span), bin_expr.left.as_ref(), label_msg);
|
||||
self.check(Some(bin_expr.span), bin_expr.right.as_ref(), label_msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +161,7 @@ impl Visit for UseIsNan {
|
||||
|
||||
if sym == "indexOf" || sym == "lastIndexOf" {
|
||||
if let Some(ExprOrSpread { expr, .. }) = call_expr.args.first() {
|
||||
self.check(Some(call_expr.span), expr);
|
||||
self.check(Some(call_expr.span), expr, "this will always return -1");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,7 +174,11 @@ impl Visit for UseIsNan {
|
||||
fn visit_switch_case(&mut self, switch_case: &SwitchCase) {
|
||||
if self.enforce_for_switch_case {
|
||||
if let Some(test) = &switch_case.test {
|
||||
self.check(None, test.as_ref());
|
||||
self.check(
|
||||
None,
|
||||
test.as_ref(),
|
||||
"this will never match the discriminant",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +187,11 @@ impl Visit for UseIsNan {
|
||||
|
||||
fn visit_switch_stmt(&mut self, switch_stmt: &SwitchStmt) {
|
||||
if self.enforce_for_switch_case {
|
||||
self.check(None, switch_stmt.discriminant.as_ref());
|
||||
self.check(
|
||||
None,
|
||||
switch_stmt.discriminant.as_ref(),
|
||||
"this will never match the test of any case",
|
||||
);
|
||||
}
|
||||
|
||||
switch_stmt.visit_children_with(self);
|
||||
|
Loading…
Reference in New Issue
Block a user