canonical
Version:
Canonical code style linter and formatter for JavaScript, SCSS, CSS and JSON.
45 lines (38 loc) • 1.92 kB
JavaScript
/**
* @fileoverview Rule to check if a call to _.forEach should be a call to _.filter
*/
;
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function (context) {
var lodashUtil = require('../util/lodashUtil');
var astUtil = require('../util/astUtil');
var settings = require('../util/settingsUtil').getSettings(context);
var DEFAULT_MAX_PROPERTY_PATH_LENGTH = 3;
var maxPropertyPathLength = parseInt(context.options[0], 10) || DEFAULT_MAX_PROPERTY_PATH_LENGTH;
function isIfWithoutElse(statement) {
return statement && statement.type === 'IfStatement' && !statement.alternate;
}
function canBeShorthand(exp, paramName) {
return astUtil.isIdentifierOfParam(exp, paramName) ||
astUtil.isMemberExpOf(exp, paramName, maxPropertyPathLength) || astUtil.isNegationOfParamMember(exp, paramName, maxPropertyPathLength) ||
astUtil.isEqEqEqToMemberOf(exp, paramName, maxPropertyPathLength) || astUtil.isNotEqEqToMemberOf(exp, paramName, maxPropertyPathLength);
}
function onlyHasSimplifiableIf(func) {
var firstLine = astUtil.getFirstFunctionLine(func);
return func && astUtil.hasOnlyOneStatement(func) && func.params.length === 1 && isIfWithoutElse(firstLine) && canBeShorthand(firstLine.test, astUtil.getFirstParamName(func));
}
return {
CallExpression: lodashUtil.getLodashMethodVisitor(settings, function (node, iteratee) {
if (lodashUtil.isCallToMethod(node, settings.version, 'forEach') && onlyHasSimplifiableIf(iteratee)) {
context.report(node, 'Prefer _.filter or _.some over an if statement inside a _.forEach');
}
})
};
};
module.exports.schema = [
{
type: 'integer'
}
];