eslint-plugin-lodash
Advanced tools
Comparing version 1.1.1 to 1.2.0
@@ -11,4 +11,15 @@ # Change Log | ||
[unreleased]: https://github.com/wix/eslint-plugin-lodash/compare/v1.1.1...HEAD | ||
[unreleased]: https://github.com/wix/eslint-plugin-lodash/compare/v1.2.0...HEAD | ||
## [1.2.0] - 2016-02-24 | ||
### Fixed | ||
- Fixed `path-style` to report for calls to `matchesProperty`. ([`24d2ba6`][24d2ba6]) | ||
- Fixed shorthand rules to report on more methods and on iteratees that call the shorthand methods (e.g. `_.property`). ([`e42d364`][e42d364]) | ||
[24d2ba6]: https://github.com/wix/eslint-plugin-lodash/commit/24d2ba6e154b8d00691536846e95699380de45bf | ||
[e42d364]: https://github.com/wix/eslint-plugin-lodash/commit/e42d364d82d5e2a4e3b4b2c2c92d4330c9137958 | ||
[1.2.0]: https://github.com/wix/eslint-plugin-lodash/compare/v1.2.0...v1.1.1 | ||
## [1.1.1] - 2016-02-22 | ||
@@ -15,0 +26,0 @@ ### Fixed |
@@ -17,3 +17,2 @@ /** | ||
var supportsProp = require('../util/methodDataUtil').getPropShorthandMethods(settings.version); | ||
@@ -33,24 +32,14 @@ function isExplicitIdentityFunction(iteratee) { | ||
function methodSupportsShorthand(node) { | ||
return _.includes(supportsProp, astUtil.getMethodName(node)); | ||
function usesShorthand(node, iteratee) { | ||
return lodashUtil.methodSupportsShorthand(settings.version, node) && !iteratee; | ||
} | ||
var callExpressionReporters = { | ||
always: function (node, iteratee) { | ||
if (methodSupportsShorthand(node) && canUseIdentityShorthand(iteratee)) { | ||
context.report({ | ||
node: iteratee, | ||
message: 'Prefer omitting the iteratee over a function that returns its argument' | ||
}); | ||
} | ||
}, | ||
never: function (node, iteratee) { | ||
if (methodSupportsShorthand(node) && !iteratee) { | ||
context.report(node.callee.property, 'Do not use the identity shorthand syntax'); | ||
} | ||
} | ||
}; | ||
return { | ||
CallExpression: lodashUtil.getLodashMethodVisitor(settings, callExpressionReporters[context.options[0] || 'always']) | ||
CallExpression: lodashUtil.getShorthandVisitor(context, settings, { | ||
canUseShorthand: canUseIdentityShorthand, | ||
usesShorthand: usesShorthand | ||
}, { | ||
always: 'Prefer omitting the iteratee over a function that returns its argument', | ||
never: 'Do not use the identity shorthand syntax' | ||
}) | ||
}; | ||
@@ -57,0 +46,0 @@ }; |
@@ -13,15 +13,22 @@ /** | ||
var settings = require('../util/settingsUtil').getSettings(context); | ||
var SUPPORT_MATCHES_PROPERTY_STYLE_CB = ['find', 'detect', 'filter', 'select', 'reject', 'findIndex', 'findLastIndex', 'some', 'every']; | ||
function shouldPreferMatches(func) { | ||
function isFunctionDeclarationThatCanUseShorthand(func) { | ||
return astUtil.isEqEqEqToMemberOf(astUtil.getValueReturnedInFirstLine(func), astUtil.getFirstParamName(func), Infinity); | ||
} | ||
function methodSupportsShorthand(node) { | ||
return SUPPORT_MATCHES_PROPERTY_STYLE_CB.indexOf(astUtil.getMethodName(node)) !== -1; | ||
function isCallToLodashMatchesProperty(iteratee) { | ||
return lodashUtil.isLodashCall(iteratee, settings.pragma) && lodashUtil.isCallToMethod(iteratee, settings.version, 'matchesProperty'); | ||
} | ||
function canUseShorthand(iteratee) { | ||
return isFunctionDeclarationThatCanUseShorthand(iteratee) || isCallToLodashMatchesProperty(iteratee); | ||
} | ||
function callHasExtraParamAfterIteratee(node, iteratee) { | ||
return node.arguments[node.arguments.indexOf(iteratee) + 1]; | ||
} | ||
var matchesPropertyChecks = { | ||
3: function (node, iteratee) { | ||
return iteratee && iteratee.type === 'Literal' && node.arguments[node.arguments.indexOf(iteratee) + 1]; | ||
return iteratee && iteratee.type === 'Literal' && callHasExtraParamAfterIteratee(node, iteratee); | ||
}, | ||
@@ -33,18 +40,10 @@ 4: function (node, iteratee) { | ||
var callExpressionReporters = { | ||
always: function (node, iteratee) { | ||
if (methodSupportsShorthand(node) && shouldPreferMatches(iteratee)) { | ||
context.report(node.callee.property, 'Prefer matches property syntax'); | ||
} | ||
}, | ||
never: function (node, iteratee) { | ||
if (matchesPropertyChecks[settings.version](node, iteratee)) { | ||
context.report(node.callee.property, 'Do not use matches property syntax'); | ||
} | ||
} | ||
}; | ||
return { | ||
CallExpression: lodashUtil.getLodashMethodVisitor(settings, callExpressionReporters[context.options[0] || 'always']) | ||
CallExpression: lodashUtil.getShorthandVisitor(context, settings, { | ||
canUseShorthand: canUseShorthand, | ||
usesShorthand: matchesPropertyChecks[settings.version] | ||
}, { | ||
always: 'Prefer matches property syntax', | ||
never: 'Do not use matches property syntax' | ||
}) | ||
}; | ||
@@ -51,0 +50,0 @@ }; |
@@ -12,11 +12,9 @@ /** | ||
var lodashUtil = require('../util/lodashUtil'); | ||
var _ = require('lodash'); | ||
var astUtil = require('../util/astUtil'); | ||
var settingsUtil = require('../util/settingsUtil'); | ||
var settings = settingsUtil.getSettings(context); | ||
var SUPPORT_MATCHES_STYLE_CB = ['find', 'detect', 'filter', 'select', 'reject', 'findIndex', 'findLastIndex', 'some', 'every']; | ||
var DEFAULT_MAX_PROPERTY_PATH_LENGTH = 3; | ||
function isConjunction(exp) { | ||
return exp && exp.type === 'LogicalExpression' && exp.operator === '&&'; | ||
} | ||
var isConjunction = _.matches({type: 'LogicalExpression', operator: '&&'}); | ||
@@ -48,3 +46,3 @@ function canBeObjectLiteralWithShorthandProperty(node, paramName) { | ||
function shouldPreferMatches(func) { | ||
function isFunctionDeclarationThatCanUseShorthand(func) { | ||
var maxPropertyPathLength = context.options[1] || DEFAULT_MAX_PROPERTY_PATH_LENGTH; | ||
@@ -54,21 +52,23 @@ return isConjunctionOfEqEqEqToMemberOf(astUtil.getValueReturnedInFirstLine(func), astUtil.getFirstParamName(func), maxPropertyPathLength); | ||
function methodSupportsShorthand(node) { | ||
return SUPPORT_MATCHES_STYLE_CB.indexOf(astUtil.getMethodName(node)) !== -1; | ||
function isCallToLodashMatches(iteratee) { | ||
return lodashUtil.isLodashCall(iteratee, settings.pragma) && lodashUtil.isCallToMethod(iteratee, settings.version, 'matches'); | ||
} | ||
var callExpressionReporters = { | ||
always: function (node, iteratee) { | ||
if (methodSupportsShorthand(node) && shouldPreferMatches(iteratee)) { | ||
context.report(iteratee, 'Prefer matches syntax'); | ||
} | ||
}, | ||
never: function (node, iteratee) { | ||
if (iteratee && iteratee.type === 'ObjectExpression') { | ||
context.report(iteratee, 'Do not use matches syntax'); | ||
} | ||
} | ||
}; | ||
function canUseShorthand(iteratee) { | ||
return isFunctionDeclarationThatCanUseShorthand(iteratee) || isCallToLodashMatches(iteratee); | ||
} | ||
function usesShorthand(node, iteratee) { | ||
return iteratee && iteratee.type === 'ObjectExpression'; | ||
} | ||
return { | ||
CallExpression: lodashUtil.getLodashMethodVisitor(settings, callExpressionReporters[context.options[0] || 'always']) | ||
CallExpression: lodashUtil.getShorthandVisitor(context, settings, { | ||
canUseShorthand: canUseShorthand, | ||
usesShorthand: usesShorthand | ||
}, { | ||
always: 'Prefer matches syntax', | ||
never: 'Do not use matches syntax' | ||
}) | ||
}; | ||
@@ -75,0 +75,0 @@ }; |
@@ -13,3 +13,6 @@ /** | ||
var settings = require('../util/settingsUtil').getSettings(context); | ||
var objectPathMethods = ['get', 'has', 'hasIn', 'set', 'unset', 'invoke']; | ||
var objectPathMethods = { | ||
regular: {methods: ['get', 'has', 'hasIn', 'set', 'unset', 'invoke'], index: 1}, | ||
higherOrder: {methods: ['property', 'matchesProperty'], index: 0} | ||
}; | ||
var _ = require('lodash'); | ||
@@ -19,6 +22,7 @@ | ||
function getIndexByMethodName(node) { | ||
if (objectPathMethods.some(lodashUtil.isCallToMethod.bind(null, node, settings.version))) { | ||
return 1; | ||
} | ||
return lodashUtil.isCallToMethod(node, settings.version, 'property') ? 0 : -1; | ||
return _.chain(objectPathMethods).find(function (type) { | ||
return type.methods.some(lodashUtil.isCallToMethod.bind(null, node, settings.version)); | ||
}) | ||
.get('index', -1) | ||
.value(); | ||
} | ||
@@ -25,0 +29,0 @@ |
@@ -12,3 +12,2 @@ /** | ||
module.exports = function (context) { | ||
var _ = require('lodash'); | ||
var lodashUtil = require('../util/lodashUtil'); | ||
@@ -18,30 +17,26 @@ var astUtil = require('../util/astUtil'); | ||
var supportsProp = require('../util/methodDataUtil').getPropShorthandMethods(settings.version); | ||
function canUseShorthand(func) { | ||
function isExplicitParamFunction(func) { | ||
return astUtil.isMemberExpOf(astUtil.getValueReturnedInFirstLine(func), astUtil.getFirstParamName(func), Number.MAX_VALUE, false); | ||
} | ||
function methodSupportsShorthand(node) { | ||
return _.includes(supportsProp, astUtil.getMethodName(node)); | ||
function isCallToProperty(node) { | ||
return lodashUtil.isLodashCall(node, settings.pragma) && lodashUtil.isCallToMethod(node, settings.version, 'property'); | ||
} | ||
function usesPropShorthand(node, iteratee) { | ||
function canUseShorthand(node) { | ||
return isCallToProperty(node) || isExplicitParamFunction(node); | ||
} | ||
function usesShorthand(node, iteratee) { | ||
return iteratee && iteratee.type === 'Literal' && !node.arguments[node.arguments.indexOf(iteratee) + 1]; | ||
} | ||
var callExpressionReporters = { | ||
always: function (node, iteratee) { | ||
if (methodSupportsShorthand(node) && canUseShorthand(iteratee)) { | ||
context.report(iteratee, 'Prefer property shorthand syntax'); | ||
} | ||
}, | ||
never: function (node, iteratee) { | ||
if (usesPropShorthand(node, iteratee)) { | ||
context.report(iteratee, 'Do not use property shorthand syntax'); | ||
} | ||
} | ||
}; | ||
return { | ||
CallExpression: lodashUtil.getLodashMethodVisitor(settings, callExpressionReporters[context.options[0] || 'always']) | ||
CallExpression: lodashUtil.getShorthandVisitor(context, settings, { | ||
canUseShorthand: canUseShorthand, | ||
usesShorthand: usesShorthand | ||
}, { | ||
always: 'Prefer property shorthand syntax', | ||
never: 'Do not use property shorthand syntax' | ||
}) | ||
}; | ||
@@ -48,0 +43,0 @@ }; |
@@ -189,2 +189,35 @@ 'use strict'; | ||
/** | ||
* Returns whether the node's method call supports using shorthands in the specified version | ||
* @param {Number} version | ||
* @param {object} node | ||
* @returns {boolean} | ||
*/ | ||
function methodSupportsShorthand(version, node) { | ||
return _.includes(methodDataUtil.getShorthandMethods(version), astUtil.getMethodName(node)); | ||
} | ||
/** | ||
* Gets the context, settings, checks whether shorthand is used and can be used, and messages, and returns a visitor | ||
* @param {RuleContext} context | ||
* @param {LodashSettings} settings | ||
* @param {ShorthandChecks} checks | ||
* @param {ShorthandMessages} messages | ||
* @returns {NodeTypeVisitor} | ||
*/ | ||
function getShorthandVisitor(context, settings, checks, messages) { | ||
return getLodashMethodVisitor(settings, { | ||
always: function (node, iteratee) { | ||
if (methodSupportsShorthand(settings.version, node) && checks.canUseShorthand(iteratee)) { | ||
context.report(iteratee, messages.always); | ||
} | ||
}, | ||
never: function (node, iteratee) { | ||
if (checks.usesShorthand(node, iteratee)) { | ||
context.report(iteratee || node.callee.property, messages.never); | ||
} | ||
} | ||
}[context.options[0] || 'always']); | ||
} | ||
module.exports = { | ||
@@ -205,3 +238,5 @@ isLodashCall: isLodashCall, | ||
isExplicitChainStart: isExplicitChainStart, | ||
getLodashMethodVisitor: getLodashMethodVisitor | ||
getLodashMethodVisitor: getLodashMethodVisitor, | ||
methodSupportsShorthand: methodSupportsShorthand, | ||
getShorthandVisitor: getShorthandVisitor | ||
}; | ||
@@ -218,2 +253,14 @@ | ||
@param {Object} node | ||
*/ | ||
/** | ||
* @typedef {Object} ShorthandChecks | ||
* @property {function} canUseShorthand | ||
* @property {function} usesShorthand | ||
*/ | ||
/** | ||
* @typedef {object} ShorthandMessages | ||
* @property {string} always | ||
* @property {string} never | ||
*/ |
@@ -87,3 +87,3 @@ 'use strict'; | ||
}, | ||
property: [ | ||
shorthand: [ | ||
'dropRightWhile', | ||
@@ -95,3 +95,3 @@ 'dropWhile', | ||
'sortedIndex', | ||
'sortedIndex', | ||
'sortedLastIndex', | ||
'map', | ||
@@ -449,3 +449,3 @@ 'takeRightWhile', | ||
}, | ||
property: [ | ||
shorthand: [ | ||
'differenceBy', | ||
@@ -452,0 +452,0 @@ 'dropRightWhile', |
@@ -55,12 +55,12 @@ 'use strict'; | ||
function getCollectionMethods(version) { | ||
return expandAliases(version, methodDataByVersion[version].property.concat(['reduce', 'reduceRight'])); | ||
return expandAliases(version, methodDataByVersion[version].shorthand.concat(['reduce', 'reduceRight'])); | ||
} | ||
/** | ||
* Gets a list of methods that support property shorthand per version | ||
* Gets a list of methods that support all shorthands per version | ||
* @param {Number} version | ||
* @returns {[string]} | ||
*/ | ||
function getPropShorthandMethods(version) { | ||
return expandAliases(version, methodDataByVersion[version].property); | ||
function getShorthandMethods(version) { | ||
return expandAliases(version, methodDataByVersion[version].shorthand); | ||
} | ||
@@ -135,3 +135,3 @@ | ||
getChainableAliases: getChainableAliases, | ||
getPropShorthandMethods: getPropShorthandMethods, | ||
getShorthandMethods: getShorthandMethods, | ||
getWrapperMethods: getWrapperMethods, | ||
@@ -138,0 +138,0 @@ getCollectionMethods: getCollectionMethods, |
{ | ||
"name": "eslint-plugin-lodash", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"author": "Omer Ganim <ganimomer@gmail.com>", | ||
@@ -5,0 +5,0 @@ "description": "Lodash specific linting rules for ESLint", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
118252
2821