Skip to content

Commit

Permalink
Merge pull request #1785 from eslint/issue1509
Browse files Browse the repository at this point in the history
Update: Make rules work with arrow functions (fixes #1508, fixes #1509, fixes #1493)
  • Loading branch information
nzakas committed Feb 7, 2015
2 parents c217187 + accca0b commit 9398227
Show file tree
Hide file tree
Showing 64 changed files with 499 additions and 112 deletions.
3 changes: 2 additions & 1 deletion lib/eslint.js
Expand Up @@ -839,10 +839,11 @@ module.exports = (function() {
case "FunctionDeclaration":
return findJSDocComment(node.leadingComments);

case "ArrowFunctionExpression":
case "FunctionExpression":

if (parent.type !== "CallExpression" || parent.callee !== node) {
while (parent && !parent.leadingComments && parent.type !== "FunctionExpression" && parent.type !== "FunctionDeclaration") {
while (parent && !parent.leadingComments && !/Function/.test(parent.type)) {
parent = parent.parent;
}

Expand Down
3 changes: 3 additions & 0 deletions lib/rules/block-scoped-var.js
Expand Up @@ -141,6 +141,9 @@ module.exports = function(context) {
"FunctionExpression": functionHandler,
"FunctionExpression:exit": popScope,

"ArrowFunctionExpression": functionHandler,
"ArrowFunctionExpression:exit": popScope,

"ForStatement": function(node) {
pushScope();
if (node.init && node.init.type === "VariableDeclaration") {
Expand Down
1 change: 1 addition & 0 deletions lib/rules/brace-style.js
Expand Up @@ -188,6 +188,7 @@ module.exports = function(context) {
return {
"FunctionDeclaration": checkBlock("body"),
"FunctionExpression": checkBlock("body"),
"ArrowFunctionExpression": checkBlock("body"),
"IfStatement": checkIfStatement,
"TryStatement": checkTryStatement,
"CatchClause": checkCatchClause,
Expand Down
3 changes: 3 additions & 0 deletions lib/rules/comma-spacing.js
Expand Up @@ -170,6 +170,9 @@ module.exports = function(context) {
"SequenceExpression": function(node) {
validateCommaSpacing(node, "expressions");
},
"ArrowFunctionExpression": function(node) {
validateCommaSpacing(node, "params");
},
"FunctionExpression": function(node) {
validateCommaSpacing(node, "params");
},
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/complexity.js
Expand Up @@ -64,8 +64,10 @@ module.exports = function(context) {
return {
"FunctionDeclaration": startFunction,
"FunctionExpression": startFunction,
"ArrowFunctionExpression": startFunction,
"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction,

"CatchClause": increaseComplexity,
"ConditionalExpression": increaseComplexity,
Expand Down
13 changes: 13 additions & 0 deletions lib/rules/consistent-return.js
Expand Up @@ -16,10 +16,21 @@ module.exports = function(context) {
// Helpers
//--------------------------------------------------------------------------

/**
* Marks entrance into a function by pushing a new object onto the functions
* stack.
* @returns {void}
* @private
*/
function enterFunction() {
functions.push({});
}

/**
* Marks exit of a function by popping off the functions stack.
* @returns {void}
* @private
*/
function exitFunction() {
functions.pop();
}
Expand All @@ -33,8 +44,10 @@ module.exports = function(context) {

"FunctionDeclaration": enterFunction,
"FunctionExpression": enterFunction,
"ArrowFunctionExpression": enterFunction,
"FunctionDeclaration:exit": exitFunction,
"FunctionExpression:exit": exitFunction,
"ArrowFunctionExpression:exit": exitFunction,

"ReturnStatement": function(node) {

Expand Down
10 changes: 10 additions & 0 deletions lib/rules/func-style.js
@@ -1,6 +1,7 @@
/**
* @fileoverview Rule to enforce a particular function style
* @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
*/
"use strict";

Expand All @@ -24,10 +25,19 @@ module.exports = function(context) {
"FunctionExpression": function() {
var parent = context.getAncestors().pop();

if (enforceDeclarations && parent.type === "VariableDeclarator") {
context.report(parent, "Expected a function declaration.");
}
},

"ArrowFunctionExpression": function() {
var parent = context.getAncestors().pop();

if (enforceDeclarations && parent.type === "VariableDeclarator") {
context.report(parent, "Expected a function declaration.");
}
}

};

};
7 changes: 5 additions & 2 deletions lib/rules/handle-callback-err.js
@@ -1,6 +1,7 @@
/**
* @fileoverview Ensure handling of errors when we know they exist.
* @author Jamund Ferguson
* @copyright 2014 Jamund Ferguson. All rights reserved.
*/

"use strict";
Expand Down Expand Up @@ -92,7 +93,7 @@ module.exports = function(context) {
var isAboutError = node.name === callback.errorVariableName;

// we don't consider these use cases as "handling" the error
var doNotCount = ["FunctionDeclaration", "FunctionExpression", "CatchClause"];
var doNotCount = ["FunctionDeclaration", "ArrowFunctionExpression", "FunctionExpression", "CatchClause"];

// make sure this identifier isn't used as part of one of them
var isHandled = doNotCount.indexOf(node.parent.type) === -1;
Expand All @@ -107,9 +108,11 @@ module.exports = function(context) {
return {
"FunctionDeclaration": startFunction,
"FunctionExpression": startFunction,
"ArrowFunctionExpression": startFunction,
"Identifier": checkForError,
"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction
};

};
5 changes: 5 additions & 0 deletions lib/rules/max-depth.js
@@ -1,6 +1,7 @@
/**
* @fileoverview A rule to set the maximum depth block can be nested in a function.
* @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/

"use strict";
Expand Down Expand Up @@ -47,6 +48,7 @@ module.exports = function(context) {
"Program": startFunction,
"FunctionDeclaration": startFunction,
"FunctionExpression": startFunction,
"ArrowFunctionExpression": startFunction,

"IfStatement": pushBlock,
"SwitchStatement": pushBlock,
Expand All @@ -56,6 +58,7 @@ module.exports = function(context) {
"WithStatement": pushBlock,
"ForStatement": pushBlock,
"ForInStatement": pushBlock,
"ForOfStatement": pushBlock,

"IfStatement:exit": popBlock,
"SwitchStatement:exit": popBlock,
Expand All @@ -65,9 +68,11 @@ module.exports = function(context) {
"WithStatement:exit": popBlock,
"ForStatement:exit": popBlock,
"ForInStatement:exit": popBlock,
"ForOfStatement:exit": popBlock,

"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction,
"Program:exit": endFunction
};

Expand Down
49 changes: 34 additions & 15 deletions lib/rules/max-nested-callbacks.js
@@ -1,6 +1,7 @@
/**
* @fileoverview Rule to enforce a maximum number of nested callbacks.
* @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/

"use strict";
Expand All @@ -18,31 +19,49 @@ module.exports = function(context) {
var THRESHOLD = context.options[0];

//--------------------------------------------------------------------------
// Public API
// Helpers
//--------------------------------------------------------------------------

var callbackStack = [];

return {
/**
* Checks a given function node for too many callbacks.
* @param {ASTNode} node The node to check.
* @returns {void}
* @private
*/
function checkFunction(node) {
var parent = node.parent;

"FunctionExpression": function (node) {
var parent = context.getAncestors().pop();
if (parent.type === "CallExpression") {
callbackStack.push(node);
}

if (parent.type === "CallExpression") {
callbackStack.push(node);
}
if (callbackStack.length > THRESHOLD) {
var opts = {num: callbackStack.length, max: THRESHOLD};
context.report(node, "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", opts);
}
}

if (callbackStack.length > THRESHOLD) {
var opts = {num: callbackStack.length, max: THRESHOLD};
context.report(node, "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", opts);
}
},
/**
* Pops the call stack.
* @returns {void}
* @private
*/
function popStack() {
callbackStack.pop();
}

//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------

"FunctionExpression:exit": function() {
callbackStack.pop();
}
return {
"ArrowFunctionExpression": checkFunction,
"ArrowFunctionExpression:exit": popStack,

"FunctionExpression": checkFunction,
"FunctionExpression:exit": popStack
};

};
38 changes: 20 additions & 18 deletions lib/rules/max-params.js
@@ -1,6 +1,8 @@
/**
* @fileoverview Rule to flag when a function has too many parameters
* @author Ilya Volodin
* @copyright 2014 Nicholas C. Zakas. All rights reserved.
* @copyright 2013 Ilya Volodin. All rights reserved.
*/

"use strict";
Expand All @@ -13,25 +15,25 @@ module.exports = function(context) {

var numParams = context.options[0] || 3;

return {

"FunctionDeclaration": function(node) {
if (node.params.length > numParams) {
context.report(node, "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", {
count: node.params.length,
max: numParams
});
}
},

"FunctionExpression": function(node) {
if (node.params.length > numParams) {
context.report(node, "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", {
count: node.params.length,
max: numParams
});
}
/**
* Checks a function to see if it has too many parameters.
* @param {ASTNode} node The node to check.
* @returns {void}
* @private
*/
function checkFunction(node) {
if (node.params.length > numParams) {
context.report(node, "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", {
count: node.params.length,
max: numParams
});
}
}

return {
"FunctionDeclaration": checkFunction,
"ArrowFunctionExpression": checkFunction,
"FunctionExpression": checkFunction
};

};
5 changes: 4 additions & 1 deletion lib/rules/max-statements.js
@@ -1,6 +1,7 @@
/**
* @fileoverview A rule to set the maximum number of statements in a function.
* @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/

"use strict";
Expand Down Expand Up @@ -42,11 +43,13 @@ module.exports = function(context) {
return {
"FunctionDeclaration": startFunction,
"FunctionExpression": startFunction,
"ArrowFunctionExpression": startFunction,

"BlockStatement": countStatements,

"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction
};

};
32 changes: 17 additions & 15 deletions lib/rules/no-constant-condition.js
@@ -1,6 +1,7 @@
/**
* @fileoverview Rule to flag use constant conditions
* @author Christian Schulz <http://rndm.de>
* @copyright 2014 Christian Schulz. All rights reserved.
*/

"use strict";
Expand All @@ -23,21 +24,22 @@ module.exports = function(context) {
*/
function isConstant(node) {
switch (node.type) {
case "Literal":
case "FunctionExpression":
case "ObjectExpression":
case "ArrayExpression":
return true;
case "UnaryExpression":
return isConstant(node.argument);
case "BinaryExpression":
case "LogicalExpression":
return isConstant(node.left) && isConstant(node.right);
case "AssignmentExpression":
return isConstant(node.right);
case "SequenceExpression":
return isConstant(node.expressions[node.expressions.length - 1]);
// no default
case "Literal":
case "ArrowFunctionExpression":
case "FunctionExpression":
case "ObjectExpression":
case "ArrayExpression":
return true;
case "UnaryExpression":
return isConstant(node.argument);
case "BinaryExpression":
case "LogicalExpression":
return isConstant(node.left) && isConstant(node.right);
case "AssignmentExpression":
return isConstant(node.right);
case "SequenceExpression":
return isConstant(node.expressions[node.expressions.length - 1]);
// no default
}
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-empty.js
@@ -1,6 +1,7 @@
/**
* @fileoverview Rule to flag use of an empty block statement
* @author Nicholas C. Zakas
* @copyright Nicholas C. Zakas. All rights reserved.
*/
"use strict";

Expand All @@ -18,7 +19,7 @@ module.exports = function(context) {
parentType = parent.type,
isFinallyBlock = (parentType === "TryStatement") && (parent.finalizer === node);

if (/FunctionExpression|FunctionDeclaration|CatchClause/.test(parentType) ||
if (/Function|CatchClause/.test(parentType) ||
(isFinallyBlock && !parent.handlers.length)) {
return;
}
Expand Down

0 comments on commit 9398227

Please sign in to comment.