eslint-plugin-lodash
Version:
Lodash specific linting rules for ESLint
101 lines (84 loc) • 4.09 kB
JavaScript
/**
* @fileoverview Rule to check if the matches shorthand can be used
*/
'use strict';
/**
* @fileoverview Rule to check if the matches shorthand can be used
*/
// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
module.exports = {
meta: {
schema: [{
enum: ['always', 'never']
}, {
type: 'integer',
minimum: 1
}, {
type: 'boolean'
}, {
type: 'object',
properties: {
onlyLiterals: {
type: 'boolean'
}
}
}]
},
create: function create(context) {
var matches = require('lodash/matches');
var _require = require('../util/lodashUtil');
var isCallToLodashMethod = _require.isCallToLodashMethod;
var getShorthandVisitors = _require.getShorthandVisitors;
var _require2 = require('../util/astUtil');
var isEqEqEq = _require2.isEqEqEq;
var isMemberExpOf = _require2.isMemberExpOf;
var isEqEqEqToMemberOf = _require2.isEqEqEqToMemberOf;
var getValueReturnedInFirstStatement = _require2.getValueReturnedInFirstStatement;
var getFirstParamName = _require2.getFirstParamName;
var _require3 = require('../util/settingsUtil');
var isEcmaFeatureOn = _require3.isEcmaFeatureOn;
var DEFAULT_MAX_PROPERTY_PATH_LENGTH = 3;
var onlyLiterals = context.options[3] && context.options[3].onlyLiterals;
var isConjunction = matches({ type: 'LogicalExpression', operator: '&&' });
function canBeObjectLiteralWithShorthandProperty(node, paramName) {
return isEcmaFeatureOn(context, 'objectLiteralShorthandProperties') && isEqEqEq(node) && (isMemberExpOf(node.left, paramName, { maxLength: 1 }) && node.left.property.type === 'Identifier' && node.right.type === 'Identifier' && node.left.property.name === node.right.name || isMemberExpOf(node.right, paramName, { maxLength: 1 }) && node.right.property.type === 'Identifier' && node.left.type === 'Identifier' && node.right.property.name === node.left.name);
}
function isConjunctionOfEqEqEqToMemberOf(exp, paramName, maxLength) {
var allowComputed = context.options[2] && isEcmaFeatureOn(context, 'objectLiteralComputedProperties');
if (isConjunction(exp) || canBeObjectLiteralWithShorthandProperty(exp, paramName)) {
var checkStack = [exp];
var curr = void 0;
var allParamMemberEq = true;
curr = checkStack.pop();
while (curr) {
if (isConjunction(curr)) {
checkStack.push(curr.left, curr.right);
} else if (!isEqEqEqToMemberOf(curr, paramName, { maxLength: maxLength, allowComputed: allowComputed, onlyLiterals: onlyLiterals })) {
allParamMemberEq = false;
}
curr = checkStack.pop();
}
return allParamMemberEq;
}
}
function isFunctionDeclarationThatCanUseShorthand(func) {
var maxPropertyPathLength = context.options[1] || DEFAULT_MAX_PROPERTY_PATH_LENGTH;
return isConjunctionOfEqEqEqToMemberOf(getValueReturnedInFirstStatement(func), getFirstParamName(func), maxPropertyPathLength);
}
function canUseShorthand(iteratee) {
return isFunctionDeclarationThatCanUseShorthand(iteratee) || isCallToLodashMethod(iteratee, 'matches', context);
}
function usesShorthand(node, iteratee) {
return iteratee && iteratee.type === 'ObjectExpression';
}
return getShorthandVisitors(context, {
canUseShorthand: canUseShorthand,
usesShorthand: usesShorthand
}, {
always: 'Prefer matches syntax',
never: 'Do not use matches syntax'
});
}
};