UNPKG

eslint-plugin-lodash

Version:

Lodash specific linting rules for ESLint

90 lines (72 loc) 3.19 kB
/** * @fileoverview Rule to check if the expression could be better expressed as a chain */ 'use strict'; /** * @fileoverview Rule to check if the expression could be better expressed as a chain */ //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { schema: [{ enum: ['always', 'never'] }, { type: 'integer', minimum: 2 }] }, create: function create(context) { var _require = require('../util/lodashUtil'); var isLodashCall = _require.isLodashCall; var getLodashImportVisitors = _require.getLodashImportVisitors; var isLodashChainStart = _require.isLodashChainStart; var getImportedLodashMethod = _require.getImportedLodashMethod; var isChainBreaker = _require.isChainBreaker; var _require2 = require('../util/astUtil'); var getCaller = _require2.getCaller; var isMethodCall = _require2.isMethodCall; var isObjectOfMethodCall = _require2.isObjectOfMethodCall; var _require3 = require('../util/ruleUtil'); var combineVisitorObjects = _require3.combineVisitorObjects; var DEFAULT_LENGTH = 3; var _require$getSettings = require('../util/settingsUtil').getSettings(context); var pragma = _require$getSettings.pragma; var version = _require$getSettings.version; var negate = require('lodash/negate'); var mode = context.options[0] || 'never'; var ruleDepth = parseInt(context.options[1], 10) || DEFAULT_LENGTH; var isEndOfChain = negate(isObjectOfMethodCall); function isBeforeChainBreaker(node) { return isChainBreaker(node.parent.parent, version); } function isNestedNLevels(node, n) { if (n === 0) { return true; } else if (isLodashCall(node, pragma, context) || getImportedLodashMethod(context, node)) { return isNestedNLevels(node.arguments[0], n - 1); } } var callExpressionVisitors = { always: function always(node) { if (isNestedNLevels(node, ruleDepth)) { context.report(getCaller(node.arguments[0]), 'Prefer chaining to composition'); } else if (isLodashChainStart(node, pragma, context)) { var firstCall = node.parent.parent; if (isMethodCall(firstCall) && (isEndOfChain(firstCall) || isBeforeChainBreaker(firstCall))) { context.report(firstCall, 'Do not use chain syntax for single method'); } } }, never: function never(node) { if (isLodashChainStart(node, pragma, context)) { context.report(node, 'Prefer composition to Lodash chaining'); } } }; return combineVisitorObjects({ CallExpression: callExpressionVisitors[mode] }, getLodashImportVisitors(context)); } };