/
prefer-times.js
51 lines (46 loc) · 1.99 KB
/
prefer-times.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* @fileoverview Rule to check if a call to _.map should be a call to _.times
*/
'use strict';
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function (context) {
var lodashUtil = require('../util/lodashUtil');
var _ = require('lodash');
var callStack = [];
var lodashPragma = require('../util/settingsUtil').getLodashPragma(context);
function getParamName(paramNode) {
return paramNode.name || paramNode.left.name;
}
function handleFunctionExpression(node) {
if (lodashUtil.isCallToMethod(node.parent, 'map') && (lodashUtil.isLodashCall(node.parent, lodashPragma) || lodashUtil.isLodashWrapper(node.parent, lodashPragma))) {
callStack.push({func: node, params: _.map(node.params, getParamName), anyUsed: false});
}
}
function handleExitFunctionExpression(node) {
var state = _.last(callStack);
if (state && state.func === node) {
callStack.pop();
if (!state.anyUsed) {
context.report(node.parent, 'Prefer _.times over _.map without using arguments');
}
}
}
return {
FunctionExpression: handleFunctionExpression,
ArrowFunctionExpression: handleFunctionExpression,
Identifier: function (node) {
var state = _.last(callStack);
if (state) {
var isIterateeParamDefinition = (node.parent === state.func && _.includes(node.parent.params, node)) ||
(node.parent.type === 'AssignmentPattern' && node.parent.parent === state.func);
if (!isIterateeParamDefinition && _.includes(state.params, node.name)) {
state.anyUsed = true;
}
}
},
'FunctionExpression:exit': handleExitFunctionExpression,
'ArrowFunctionExpression:exit': handleExitFunctionExpression
};
};