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

feat: add suggestions to use-isnan in binary expressions #17996

Merged
merged 13 commits into from Jan 29, 2024
31 changes: 29 additions & 2 deletions lib/rules/use-isnan.js
Expand Up @@ -34,6 +34,7 @@ function isNaNIdentifier(node) {
/** @type {import('../shared/types').Rule} */
module.exports = {
meta: {
hasSuggestions: true,
type: "problem",

docs: {
Expand Down Expand Up @@ -63,14 +64,17 @@ module.exports = {
comparisonWithNaN: "Use the isNaN function to compare with NaN.",
switchNaN: "'switch(NaN)' can never match a case clause. Use Number.isNaN instead of the switch.",
caseNaN: "'case NaN' can never match. Use Number.isNaN before the switch.",
indexOfNaN: "Array prototype method '{{ methodName }}' cannot find NaN."
indexOfNaN: "Array prototype method '{{ methodName }}' cannot find NaN.",
replaceWithIsNaN: "Replace with Number.isNaN."
}
},

create(context) {

const enforceForSwitchCase = !context.options[0] || context.options[0].enforceForSwitchCase;
const enforceForIndexOf = context.options[0] && context.options[0].enforceForIndexOf;
const sourceCode = context.getSourceCode();
StyleShit marked this conversation as resolved.
Show resolved Hide resolved
const fixableOperators = new Set(["==", "===", "!=", "!=="]);

/**
* Checks the given `BinaryExpression` node for `foo === NaN` and other comparisons.
Expand All @@ -82,7 +86,30 @@ module.exports = {
/^(?:[<>]|[!=]=)=?$/u.test(node.operator) &&
(isNaNIdentifier(node.left) || isNaNIdentifier(node.right))
) {
context.report({ node, messageId: "comparisonWithNaN" });
const isFixable = fixableOperators.has(node.operator);

if (isFixable) {
context.report({
node,
messageId: "comparisonWithNaN",
suggest: [
{
messageId: "replaceWithIsNaN",
fix(fixer) {
const comparedValue = isNaNIdentifier(node.left) ? node.right : node.left;
const shouldNegate = node.operator[0] === "!";

const negation = shouldNegate ? "!" : "";
const comparedValueText = sourceCode.getText(comparedValue);

return fixer.replaceText(node, `${negation}Number.isNaN(${comparedValueText})`);
StyleShit marked this conversation as resolved.
Show resolved Hide resolved
}
}
]
});
} else {
context.report({ node, messageId: "comparisonWithNaN" });
}
}
}

Expand Down