123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 'use strict';
- const {get} = require('lodash');
- const {methodCallSelector} = require('./selectors/index.js');
- const {arrayPrototypeMethodSelector, notFunctionSelector, matches} = require('./selectors/index.js');
- const MESSAGE_ID = 'no-reduce';
- const messages = {
- [MESSAGE_ID]: '`Array#{{method}}()` is not allowed',
- };
- const prototypeSelector = method => [
- methodCallSelector(method),
- arrayPrototypeMethodSelector({
- path: 'callee.object',
- methods: ['reduce', 'reduceRight'],
- }),
- ].join('');
- const selector = matches([
- // `array.{reduce,reduceRight}()`
- [
- methodCallSelector({methods: ['reduce', 'reduceRight'], minimumArguments: 1, maximumArguments: 2}),
- notFunctionSelector('arguments.0'),
- ' > .callee > .property',
- ].join(''),
- // `[].{reduce,reduceRight}.call()` and `Array.{reduce,reduceRight}.call()`
- [
- prototypeSelector('call'),
- notFunctionSelector('arguments.1'),
- ' > .callee > .object > .property',
- ].join(''),
- // `[].{reduce,reduceRight}.apply()` and `Array.{reduce,reduceRight}.apply()`
- [
- prototypeSelector('apply'),
- ' > .callee > .object > .property',
- ].join(''),
- ]);
- const schema = [
- {
- type: 'object',
- additionalProperties: false,
- properties: {
- allowSimpleOperations: {
- type: 'boolean',
- default: true,
- },
- },
- },
- ];
- /** @param {import('eslint').Rule.RuleContext} context */
- const create = context => {
- const {allowSimpleOperations} = {allowSimpleOperations: true, ...context.options[0]};
- return {
- [selector](node) {
- const callback = get(node, 'parent.parent.arguments[0]', {});
- const problem = {
- node,
- messageId: MESSAGE_ID,
- data: {method: node.name},
- };
- if (!allowSimpleOperations) {
- return problem;
- }
- if (callback.type === 'ArrowFunctionExpression' && callback.body.type === 'BinaryExpression') {
- return;
- }
- if ((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') {
- return;
- }
- return problem;
- },
- };
- };
- /** @type {import('eslint').Rule.RuleModule} */
- module.exports = {
- create,
- meta: {
- type: 'suggestion',
- docs: {
- description: 'Disallow `Array#reduce()` and `Array#reduceRight()`.',
- },
- schema,
- messages,
- },
- };
|