Skip to content

Commit a88e349

Browse files
Sysixcamc314
authored andcommitted
fix(linter): mark isNan and isFinite as dangerous fixes in unicorn/prefer-number-properties (#10706)
I merged after I read about the `parse*` functions. The `isFinite` and `isNaN` should be dangerous fixes: ``` isFinite("0"); // true; coerced to number 0 Number.isFinite("0"); // false isFinite(null); // true; coerced to number 0 Number.isFinite(null); // false ``` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite > As opposed to the global [isNaN()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN) function, the Number.isNaN() method doesn't force-convert the parameter to a number. This makes it safe to pass values that would normally convert to [NaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) but aren't actually the same value as [NaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN). This also means that only values of the Number type that are also [NaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) return true. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
1 parent f4ab05f commit a88e349

File tree

1 file changed

+57
-30
lines changed

1 file changed

+57
-30
lines changed

crates/oxc_linter/src/rules/unicorn/prefer_number_properties.rs

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use oxc_macros::declare_oxc_lint;
77
use oxc_span::{GetSpan, Span};
88
use serde_json::Value;
99

10-
use crate::{AstNode, context::LintContext, globals::GLOBAL_OBJECT_NAMES, rule::Rule};
10+
use crate::{
11+
AstNode, context::LintContext, fixer::RuleFixer, globals::GLOBAL_OBJECT_NAMES, rule::Rule,
12+
};
1113

1214
fn prefer_number_properties_diagnostic(span: Span, method_name: &str) -> OxcDiagnostic {
1315
OxcDiagnostic::warn(format!("Use `Number.{method_name}` instead of the global `{method_name}`"))
@@ -73,7 +75,7 @@ declare_oxc_lint!(
7375
PreferNumberProperties,
7476
unicorn,
7577
restriction,
76-
fix
78+
dangerous_fix
7779
);
7880

7981
impl Rule for PreferNumberProperties {
@@ -124,21 +126,31 @@ impl Rule for PreferNumberProperties {
124126
Some(AstKind::ObjectProperty(_))
125127
))
126128
{
127-
ctx.diagnostic_with_fix(
128-
prefer_number_properties_diagnostic(ident_ref.span, &ident_ref.name),
129-
|fixer| match ctx.nodes().parent_kind(node.id()) {
130-
Some(AstKind::ObjectProperty(object_property))
131-
if object_property.shorthand =>
132-
{
133-
fixer.insert_text_before(
134-
&ident_ref.span,
135-
format!("{}: Number.", ident_ref.name.as_str()),
136-
)
137-
}
138-
Some(_) => fixer.insert_text_before(&ident_ref.span, "Number."),
139-
None => unreachable!(),
140-
},
141-
);
129+
let fixer = |fixer: RuleFixer<'_, 'a>| match ctx.nodes().parent_kind(node.id())
130+
{
131+
Some(AstKind::ObjectProperty(object_property))
132+
if object_property.shorthand =>
133+
{
134+
fixer.insert_text_before(
135+
&ident_ref.span,
136+
format!("{}: Number.", ident_ref.name.as_str()),
137+
)
138+
}
139+
Some(_) => fixer.insert_text_before(&ident_ref.span, "Number."),
140+
None => unreachable!(),
141+
};
142+
143+
if ident_ref.name.as_str() == "isNaN" || ident_ref.name.as_str() == "isFinite" {
144+
ctx.diagnostic_with_dangerous_fix(
145+
prefer_number_properties_diagnostic(ident_ref.span, &ident_ref.name),
146+
fixer,
147+
);
148+
} else {
149+
ctx.diagnostic_with_fix(
150+
prefer_number_properties_diagnostic(ident_ref.span, &ident_ref.name),
151+
fixer,
152+
);
153+
}
142154
}
143155
}
144156
AstKind::CallExpression(call_expr) => {
@@ -153,20 +165,35 @@ impl Rule for PreferNumberProperties {
153165
}
154166
}
155167

156-
ctx.diagnostic_with_fix(
157-
prefer_number_properties_diagnostic(call_expr.callee.span(), ident_name),
158-
|fixer| match &call_expr.callee {
159-
Expression::Identifier(ident) => {
160-
fixer.insert_text_before(&ident.span, "Number.")
161-
}
162-
match_member_expression!(Expression) => {
163-
let member_expr = call_expr.callee.to_member_expression();
168+
let fixer = |fixer: RuleFixer<'_, 'a>| match &call_expr.callee {
169+
Expression::Identifier(ident) => {
170+
fixer.insert_text_before(&ident.span, "Number.")
171+
}
172+
match_member_expression!(Expression) => {
173+
let member_expr = call_expr.callee.to_member_expression();
174+
175+
fixer.replace(member_expr.object().span(), "Number")
176+
}
177+
_ => unreachable!(),
178+
};
164179

165-
fixer.replace(member_expr.object().span(), "Number")
166-
}
167-
_ => unreachable!(),
168-
},
169-
);
180+
if ident_name == "isFinite" || ident_name == "isNaN" {
181+
ctx.diagnostic_with_dangerous_fix(
182+
prefer_number_properties_diagnostic(
183+
call_expr.callee.span(),
184+
ident_name,
185+
),
186+
fixer,
187+
);
188+
} else {
189+
ctx.diagnostic_with_fix(
190+
prefer_number_properties_diagnostic(
191+
call_expr.callee.span(),
192+
ident_name,
193+
),
194+
fixer,
195+
);
196+
}
170197
}
171198
}
172199
_ => {}

0 commit comments

Comments
 (0)