routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
+127
@@ -0,0 +1,127 @@
|
||||
import {isMethodCall} from './ast/index.js';
|
||||
import {isNodeValueNotFunction, isArrayPrototypeProperty} from './utils/index.js';
|
||||
|
||||
const MESSAGE_ID_REDUCE = 'reduce';
|
||||
const MESSAGE_ID_REDUCE_RIGHT = 'reduceRight';
|
||||
const messages = {
|
||||
[MESSAGE_ID_REDUCE]: '`Array#reduce()` is not allowed. Prefer other types of loop for readability.',
|
||||
[MESSAGE_ID_REDUCE_RIGHT]: '`Array#reduceRight()` is not allowed. Prefer other types of loop for readability. You may want to call `Array#toReversed()` before looping it.',
|
||||
};
|
||||
|
||||
const cases = [
|
||||
// `array.{reduce,reduceRight}()`
|
||||
{
|
||||
test: callExpression =>
|
||||
isMethodCall(callExpression, {
|
||||
methods: ['reduce', 'reduceRight'],
|
||||
minimumArguments: 1,
|
||||
maximumArguments: 2,
|
||||
optionalCall: false,
|
||||
})
|
||||
&& !isNodeValueNotFunction(callExpression.arguments[0]),
|
||||
getMethodNode: callExpression => callExpression.callee.property,
|
||||
isSimpleOperation(callExpression) {
|
||||
const [callback] = callExpression.arguments;
|
||||
|
||||
return (
|
||||
callback
|
||||
&& (
|
||||
// `array.reduce((accumulator, element) => accumulator + element)`
|
||||
(callback.type === 'ArrowFunctionExpression' && callback.body.type === 'BinaryExpression')
|
||||
// `array.reduce((accumulator, element) => {return accumulator + element;})`
|
||||
// `array.reduce(function (accumulator, element){return accumulator + element;})`
|
||||
|| (
|
||||
(callback.type === 'ArrowFunctionExpression' || callback.type === 'FunctionExpression')
|
||||
&& callback.body.type === 'BlockStatement'
|
||||
&& callback.body.body.length === 1
|
||||
&& callback.body.body[0].type === 'ReturnStatement'
|
||||
&& callback.body.body[0].argument.type === 'BinaryExpression'
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
// `[].{reduce,reduceRight}.call()` and `Array.{reduce,reduceRight}.call()`
|
||||
{
|
||||
test: callExpression =>
|
||||
isMethodCall(callExpression, {
|
||||
method: 'call',
|
||||
optionalCall: false,
|
||||
optionalMember: false,
|
||||
})
|
||||
&& isArrayPrototypeProperty(callExpression.callee.object, {
|
||||
properties: ['reduce', 'reduceRight'],
|
||||
})
|
||||
&& (
|
||||
!callExpression.arguments[1]
|
||||
|| !isNodeValueNotFunction(callExpression.arguments[1])
|
||||
),
|
||||
getMethodNode: callExpression => callExpression.callee.object.property,
|
||||
},
|
||||
// `[].{reduce,reduceRight}.apply()` and `Array.{reduce,reduceRight}.apply()`
|
||||
{
|
||||
test: callExpression =>
|
||||
isMethodCall(callExpression, {
|
||||
method: 'apply',
|
||||
optionalCall: false,
|
||||
optionalMember: false,
|
||||
})
|
||||
&& isArrayPrototypeProperty(callExpression.callee.object, {
|
||||
properties: ['reduce', 'reduceRight'],
|
||||
}),
|
||||
getMethodNode: callExpression => callExpression.callee.object.property,
|
||||
},
|
||||
];
|
||||
|
||||
const schema = [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allowSimpleOperations: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow simple reduce operations whose callback body is a single binary expression.',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
/** @param {import('eslint').Rule.RuleContext} context */
|
||||
const create = context => {
|
||||
const {allowSimpleOperations} = context.options[0];
|
||||
|
||||
context.on('CallExpression', function * (callExpression) {
|
||||
for (const {test, getMethodNode, isSimpleOperation} of cases) {
|
||||
if (!test(callExpression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (allowSimpleOperations && isSimpleOperation?.(callExpression)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const methodNode = getMethodNode(callExpression);
|
||||
yield {
|
||||
node: methodNode,
|
||||
messageId: methodNode.name,
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** @type {import('eslint').Rule.RuleModule} */
|
||||
const config = {
|
||||
create,
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Disallow `Array#reduce()` and `Array#reduceRight()`.',
|
||||
recommended: true,
|
||||
},
|
||||
schema,
|
||||
defaultOptions: [{allowSimpleOperations: true}],
|
||||
messages,
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
Reference in New Issue
Block a user