mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.8 KiB
98 lines
2.8 KiB
/**
|
|
* @fileoverview Checks for unreachable code due to return, throws, break, and continue.
|
|
* @author Joel Feenstra
|
|
*/
|
|
"use strict";
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Helpers
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
function report(context, node, unreachableType) {
|
|
var keyword;
|
|
switch (unreachableType) {
|
|
case "BreakStatement":
|
|
keyword = "break";
|
|
break;
|
|
case "ContinueStatement":
|
|
keyword = "continue";
|
|
break;
|
|
case "ReturnStatement":
|
|
keyword = "return";
|
|
break;
|
|
case "ThrowStatement":
|
|
keyword = "throw";
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
context.report(node, "Found unexpected statement after a {{type}}.", { type: keyword });
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Rule Definition
|
|
//------------------------------------------------------------------------------
|
|
|
|
module.exports = function(context) {
|
|
|
|
/**
|
|
* Checks if a node is an exception for no-unreachable because of variable/function hoisting
|
|
* @param {ASTNode} node The AST node to check.
|
|
* @returns {boolean} if the node doesn't trigger unreachable
|
|
* @private
|
|
*/
|
|
function isUnreachableAllowed(node) {
|
|
return node.type === "FunctionDeclaration" ||
|
|
node.type === "VariableDeclaration" &&
|
|
node.declarations.every(function(declaration) {
|
|
return declaration.type === "VariableDeclarator" && declaration.init === null;
|
|
});
|
|
}
|
|
|
|
/*
|
|
* Verifies that the given node is the last node or followed exclusively by
|
|
* hoisted declarations
|
|
* @param {ASTNode} node Node that should be the last node
|
|
* @returns {void}
|
|
* @private
|
|
*/
|
|
function checkNode(node) {
|
|
var parent = context.getAncestors().pop();
|
|
var field, i, sibling;
|
|
|
|
switch (parent.type) {
|
|
case "SwitchCase":
|
|
field = "consequent";
|
|
break;
|
|
case "Program":
|
|
case "BlockStatement":
|
|
field = "body";
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
for (i = parent[field].length - 1; i >= 0; i--) {
|
|
sibling = parent[field][i];
|
|
if (sibling === node) {
|
|
return; // Found the last reachable statement, all done
|
|
}
|
|
|
|
if (!isUnreachableAllowed(sibling)) {
|
|
report(context, sibling, node.type);
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
"ReturnStatement": checkNode,
|
|
"ThrowStatement": checkNode,
|
|
"ContinueStatement": checkNode,
|
|
"BreakStatement": checkNode
|
|
};
|
|
|
|
};
|
|
|
|
module.exports.schema = [];
|
|
|