<commit_before>/**
 * @fileoverview Checks for unreachable code due to return, throws, break, and continue.
 * @author <NAME>
 */
"use strict";

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------


function report(context, node, unreachableType) {
    context.report(node, "Found unexpected statement after a {{type}}.", { type: unreachableType });
}


//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {

    function checkForUnreachable(node) {
        switch (node.type) {
        case "ReturnStatement":
            return "return";
        case "ThrowStatement":
            return "throw";
        case "ContinueStatement":
            return "continue";
        case "BreakStatement":
            return "break";
        default:
            return false;
        }
    }

    /**
     * Checks if a node is an exception for no-unreachable because of variable/function hoisting
     * @param {ASTNode} node
     * @returns {boolean} if the node doesn't trigger unreachable
     */
    function isUnreachableAllowed(node) {
        // check for FunctionDeclaration
        var isAllowed = node.type === "FunctionDeclaration";

        if (!isAllowed && node.type === "VariableDeclaration") {
            // check that every declaration is variable declaration with no init
            isAllowed = node.declarations.every(function(declaration){
                return declaration.type === "VariableDeclarator" && declaration.init === null;
            });
        }

        return isAllowed;
    }

    /**
     * Loops through a field of a node and checks if its children fulfill conditions to trigger the unreachable report.
     * @param {ASTNode} node
     * @param {string} field
     */
    function checkNodeFieldForUnreachable(node, field) {
        var i, unreachableType = false;
        for (i = 1; i < node[field].length; i++) {
            unreachableType = unreachableType || checkForUnreachable(node[field][i - 1]);
            if (unreachableType && !isUnreachableAllowed(node[field][i])) {
                report(context, node[field][i], unreachableType);
            }
        }
    }

    return {
        "BlockStatement": function(node) {
            checkNodeFieldForUnreachable(node, "body");
        },

        "SwitchCase": function(node) {
            checkNodeFieldForUnreachable(node, "consequent");
        }
    };

};<commit_msg>#586 refactor based on https://github.com/eslint/eslint/pull/590#discussion_r9476367<commit_after>/**
 * @fileoverview Checks for unreachable code due to return, throws, break, and continue.
 * @author <NAME>
 */
"use strict";

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------


function report(context, node, unreachableType) {
    context.report(node, "Found unexpected statement after a {{type}}.", { type: unreachableType });
}


//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {

    function checkForUnreachable(node) {
        switch (node.type) {
        case "ReturnStatement":
            return "return";
        case "ThrowStatement":
            return "throw";
        case "ContinueStatement":
            return "continue";
        case "BreakStatement":
            return "break";
        default:
            return false;
        }
    }

    /**
     * Checks if a node is an exception for no-unreachable because of variable/function hoisting
     * @param {ASTNode} node
     * @returns {boolean} if the node doesn't trigger unreachable
     */
    function isUnreachableAllowed(node) {
        return node.type === "FunctionDeclaration" ||
            node.type === "VariableDeclaration" &&
            node.declarations.every(function(declaration){
                return declaration.type === "VariableDeclarator" && declaration.init === null;
            });
    }

    /**
     * Loops through a field of a node and checks if its children fulfill conditions to trigger the unreachable report.
     * @param {ASTNode} node
     * @param {string} field
     */
    function checkNodeFieldForUnreachable(node, field) {
        var i, unreachableType = false;
        for (i = 1; i < node[field].length; i++) {
            unreachableType = unreachableType || checkForUnreachable(node[field][i - 1]);
            if (unreachableType && !isUnreachableAllowed(node[field][i])) {
                report(context, node[field][i], unreachableType);
            }
        }
    }

    return {
        "BlockStatement": function(node) {
            checkNodeFieldForUnreachable(node, "body");
        },

        "SwitchCase": function(node) {
            checkNodeFieldForUnreachable(node, "consequent");
        }
    };

};
{'fraction_non_alphanumeric': 0.22254335260115607, 'fraction_numerical': 0.0032755298651252407, 'mean_word_length': 1.5955, 'pattern_counts': {'":': 12, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4483053', 'n_tokens_mistral': 1276, 'n_tokens_neox': 1244, 'n_words': 327}