UNPKG

2.6 kBJavaScriptView Raw
1/**
2 * @fileoverview Checks for unreachable code due to return, throws, break, and continue.
3 * @author Joel Feenstra
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Helpers
9//------------------------------------------------------------------------------
10
11
12function report(context, node, unreachableType) {
13 context.report(node, "Found unexpected statement after a {{type}}.", { type: unreachableType });
14}
15
16
17//------------------------------------------------------------------------------
18// Rule Definition
19//------------------------------------------------------------------------------
20
21module.exports = function(context) {
22
23 function checkForUnreachable(node) {
24 switch (node.type) {
25 case "ReturnStatement":
26 return "return";
27 case "ThrowStatement":
28 return "throw";
29 case "ContinueStatement":
30 return "continue";
31 case "BreakStatement":
32 return "break";
33 default:
34 return false;
35 }
36 }
37
38 /**
39 * Checks if a node is an exception for no-unreachable because of variable/function hoisting
40 * @param {ASTNode} node The AST node to check.
41 * @returns {boolean} if the node doesn't trigger unreachable
42 * @private
43 */
44 function isUnreachableAllowed(node) {
45 return node.type === "FunctionDeclaration" ||
46 node.type === "VariableDeclaration" &&
47 node.declarations.every(function(declaration){
48 return declaration.type === "VariableDeclarator" && declaration.init === null;
49 });
50 }
51
52 /**
53 * Loops through a field of a node and checks if its children fulfill conditions to trigger the unreachable report.
54 * @param {ASTNode} node The AST node to check.
55 * @param {string} field The field that represents the children of the node.
56 * @returns {void}
57 * @private
58 */
59 function checkNodeFieldForUnreachable(node, field) {
60 var i, unreachableType = false;
61 for (i = 1; i < node[field].length; i++) {
62 unreachableType = unreachableType || checkForUnreachable(node[field][i - 1]);
63 if (unreachableType && !isUnreachableAllowed(node[field][i])) {
64 report(context, node[field][i], unreachableType);
65 }
66 }
67 }
68
69 return {
70 "BlockStatement": function(node) {
71 checkNodeFieldForUnreachable(node, "body");
72 },
73
74 "SwitchCase": function(node) {
75 checkNodeFieldForUnreachable(node, "consequent");
76 }
77 };
78
79};