Created
June 4, 2024 14:02
-
-
Save zbeyens/d4a2e70a7bf0687dffc6fbf7265d4ce5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// eslint-plugin-array-methods/rules/prefer-array-immutable-methods.js | |
module.exports = { | |
create: function (context) { | |
return { | |
CallExpression(node) { | |
const sourceCode = context.getSourceCode() | |
if (node.callee.type !== 'MemberExpression') return | |
const { object, property } = node.callee | |
const methodName = property.name | |
// Check if the operation is performed directly on the result of Array.from() or a spread operation | |
const isDirectlyFromArrayOrSpread = | |
(object.type === 'CallExpression' && | |
object.callee.type === 'MemberExpression' && | |
object.callee.object.name === 'Array' && | |
object.callee.property.name === 'from') || | |
(object.type === 'ArrayExpression' && // For spread [...arr] | |
object.elements.length === 1 && | |
object.elements[0].type === 'SpreadElement') | |
if (isDirectlyFromArrayOrSpread) return // Do not report if it's a direct use of Array.from() or spread | |
// Determine the immutable method replacement and check conditions | |
let replacementMethod | |
switch (methodName) { | |
case 'reverse': { | |
if (node.arguments.length === 0) { | |
replacementMethod = 'toReversed' | |
} | |
break | |
} | |
case 'sort': { | |
if (node.arguments.length === 0) { | |
replacementMethod = 'toSorted' | |
} | |
break | |
} | |
case 'splice': { | |
if (node.arguments.length >= 2) { | |
replacementMethod = 'toSpliced' | |
} | |
break | |
} | |
} | |
if (replacementMethod) { | |
const calleeCode = sourceCode.getText(node.callee.object) | |
context.report({ | |
fix(fixer) { | |
if (replacementMethod === 'toSpliced') { | |
const args = sourceCode.getText().substring(node.arguments[0].range[0], node.arguments.at(-1).range[1]) | |
return fixer.replaceText(node, `${calleeCode}.${replacementMethod}(${args})`) | |
} | |
return fixer.replaceText(node, `${calleeCode}.${replacementMethod}()`) | |
}, | |
message: `Use array.${replacementMethod}() instead of array.${methodName}()`, | |
node: node, | |
}) | |
} | |
}, | |
} | |
}, | |
meta: { | |
docs: { | |
category: 'Best Practices', | |
description: 'prefer array immutable methods like toReversed, toSorted, and toSpliced over mutable versions', | |
recommended: false, | |
}, | |
fixable: 'code', // This rule provides automatic fixes | |
schema: [], // No options | |
type: 'suggestion', | |
}, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment