canonical
Version:
Canonical code style linter and formatter for JavaScript, SCSS and CSS.
58 lines (53 loc) • 2.03 kB
JavaScript
/**
* @fileoverview Rule to check if an "&&" experssion should be a call to _.get or _.has
*/
;
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function (context) {
var _ = require('lodash');
var astUtil = require('../util/astUtil');
var lodashUtil = require('../util/lodashUtil');
var callStack = [];
function handleExitOfFunctionWithBlock(node) {
var functionNode = callStack.pop();
var last = _.last(callStack);
if (!functionNode.found && _.get(last, 'node.type') === 'CallExpression') {
context.report(node, 'Do not use _.' + astUtil.getMethodName(last.node) + ' without returning a value');
}
if (last && last.node === node.parent) {
callStack.pop();
}
}
function addToCallStackIfCollectionMethod(node) {
if (node.parent.type === 'CallExpression' && lodashUtil.isLodashCollectionMethod(node.parent)) {
callStack.push({node: node.parent});
}
}
return {
FunctionExpression: function (node) {
addToCallStackIfCollectionMethod(node);
callStack.push({node: node, found: false});
},
'FunctionExpression:exit': handleExitOfFunctionWithBlock,
ArrowFunctionExpression: function (node) {
addToCallStackIfCollectionMethod(node);
if (node.body.type === 'BlockStatement') {
callStack.push({node: node, found: false});
}
},
'ArrowFunctionExpression:exit': function (node) {
var last = _.last(callStack);
if (last && last.node === node) {
handleExitOfFunctionWithBlock(node);
}
},
ReturnStatement: function () {
var last = _.last(callStack);
if (last) {
last.found = true;
}
}
};
};