11'use strict' ;
22const { methodCallSelector} = require ( './selectors/index.js' ) ;
3- const { arrayPrototypeMethodSelector, notFunctionSelector, matches } = require ( './selectors/index.js' ) ;
3+ const { arrayPrototypeMethodSelector, notFunctionSelector} = require ( './selectors/index.js' ) ;
44
55const MESSAGE_ID = 'no-reduce' ;
66const messages = {
@@ -14,25 +14,49 @@ const prototypeSelector = method => [
1414 methods : [ 'reduce' , 'reduceRight' ] ,
1515 } ) ,
1616] . join ( '' ) ;
17- const selector = matches ( [
17+ const cases = [
1818 // `array.{reduce,reduceRight}()`
19- [
20- methodCallSelector ( { methods : [ 'reduce' , 'reduceRight' ] , minimumArguments : 1 , maximumArguments : 2 } ) ,
21- notFunctionSelector ( 'arguments.0' ) ,
22- ' > .callee > .property' ,
23- ] . join ( '' ) ,
19+ {
20+ selector : [
21+ methodCallSelector ( { methods : [ 'reduce' , 'reduceRight' ] , minimumArguments : 1 , maximumArguments : 2 } ) ,
22+ notFunctionSelector ( 'arguments.0' ) ,
23+ ] . join ( '' ) ,
24+ getMethodNode : callExpression => callExpression . callee . property ,
25+ isSimpleOperation ( callExpression ) {
26+ const [ callback ] = callExpression . arguments ;
27+
28+ return (
29+ callback
30+ && (
31+ // `array.reduce((accumulator, element) => accumulator + element)`
32+ ( callback . type === 'ArrowFunctionExpression' && callback . body . type === 'BinaryExpression' )
33+ // `array.reduce((accumulator, element) => {return accumulator + element;})`
34+ // `array.reduce(function (accumulator, element){return accumulator + element;})`
35+ || (
36+ ( callback . type === 'ArrowFunctionExpression' || callback . type === 'FunctionExpression' )
37+ && callback . body . type === 'BlockStatement'
38+ && callback . body . body . length === 1
39+ && callback . body . body [ 0 ] . type === 'ReturnStatement'
40+ && callback . body . body [ 0 ] . argument . type === 'BinaryExpression'
41+ )
42+ )
43+ ) ;
44+ } ,
45+ } ,
2446 // `[].{reduce,reduceRight}.call()` and `Array.{reduce,reduceRight}.call()`
25- [
26- prototypeSelector ( 'call' ) ,
27- notFunctionSelector ( 'arguments.1' ) ,
28- ' > .callee > .object > .property' ,
29- ] . join ( '' ) ,
47+ {
48+ selector : [
49+ prototypeSelector ( 'call' ) ,
50+ notFunctionSelector ( 'arguments.1' ) ,
51+ ] . join ( '' ) ,
52+ getMethodNode : callExpression => callExpression . callee . object . property ,
53+ } ,
3054 // `[].{reduce,reduceRight}.apply()` and `Array.{reduce,reduceRight}.apply()`
31- [
32- prototypeSelector ( 'apply' ) ,
33- ' > .callee > .object > .property' ,
34- ] . join ( '' ) ,
35- ] ) ;
55+ {
56+ selector : prototypeSelector ( 'apply' ) ,
57+ getMethodNode : callExpression => callExpression . callee . object . property ,
58+ } ,
59+ ] ;
3660
3761const schema = [
3862 {
@@ -50,35 +74,26 @@ const schema = [
5074/** @param {import('eslint').Rule.RuleContext } context */
5175const create = context => {
5276 const { allowSimpleOperations} = { allowSimpleOperations : true , ...context . options [ 0 ] } ;
77+ const listeners = { } ;
5378
54- return {
55- [ selector ] ( node ) {
56- const callback = node . parent . parent ?. arguments ?. [ 0 ] ?? { } ;
79+ for ( const { selector , getMethodNode , isSimpleOperation } of cases ) {
80+ listeners [ selector ] = callExpression => {
81+ const methodNode = getMethodNode ( callExpression ) ;
5782 const problem = {
58- node,
83+ node : methodNode ,
5984 messageId : MESSAGE_ID ,
60- data : { method : node . name } ,
85+ data : { method : methodNode . name } ,
6186 } ;
6287
63- if ( ! allowSimpleOperations ) {
64- return problem ;
65- }
66-
67- if ( callback . type === 'ArrowFunctionExpression' && callback . body . type === 'BinaryExpression' ) {
68- return ;
69- }
70-
71- if ( ( callback . type === 'ArrowFunctionExpression' || callback . type === 'FunctionExpression' )
72- && callback . body . type === 'BlockStatement'
73- && callback . body . body . length === 1
74- && callback . body . body [ 0 ] . type === 'ReturnStatement'
75- && callback . body . body [ 0 ] . argument . type === 'BinaryExpression' ) {
88+ if ( allowSimpleOperations && isSimpleOperation ?. ( callExpression ) ) {
7689 return ;
7790 }
7891
7992 return problem ;
80- } ,
81- } ;
93+ } ;
94+ }
95+
96+ return listeners ;
8297} ;
8398
8499/** @type {import('eslint').Rule.RuleModule } */
0 commit comments