An error occurred while loading the file. Please try again.
init-declarations.js 4.36 KiB
/**
 * @fileoverview A rule to control the style of variable initializations.
 * @author Colin Ihrig
 */
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
 * Checks whether or not a given node is a for loop.
 * @param {ASTNode} block A node to check.
 * @returns {boolean} `true` when the node is a for loop.
function isForLoop(block) {
    return block.type === "ForInStatement" ||
    block.type === "ForOfStatement" ||
    block.type === "ForStatement";
/**
 * Checks whether or not a given declarator node has its initializer.
 * @param {ASTNode} node A declarator node to check.
 * @returns {boolean} `true` when the node has its initializer.
function isInitialized(node) {
    const declaration = node.parent;
    const block = declaration.parent;
    if (isForLoop(block)) {
        if (block.type === "ForStatement") {
            return block.init === declaration;
        return block.left === declaration;
    return Boolean(node.init);
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
    meta: {
        type: "suggestion",
        docs: {
            description: "require or disallow initialization in variable declarations",
            category: "Variables",
            recommended: false,
            url: "https://eslint.org/docs/rules/init-declarations"
        schema: {
            anyOf: [
                    type: "array",
                    items: [
                            enum: ["always"]
                    minItems: 0,
                    maxItems: 1
                    type: "array",
                    items: [
{ enum: ["never"] }, { type: "object", properties: { ignoreForLoopInit: { type: "boolean" } }, additionalProperties: false } ], minItems: 0, maxItems: 2 } ] }, messages: { initialized: "Variable '{{idName}}' should be initialized on declaration.", notInitialized: "Variable '{{idName}}' should not be initialized on declaration." } }, create(context) { const MODE_ALWAYS = "always", MODE_NEVER = "never"; const mode = context.options[0] || MODE_ALWAYS; const params = context.options[1] || {}; //-------------------------------------------------------------------------- // Public API //-------------------------------------------------------------------------- return { "VariableDeclaration:exit"(node) { const kind = node.kind, declarations = node.declarations; for (let i = 0; i < declarations.length; ++i) { const declaration = declarations[i], id = declaration.id, initialized = isInitialized(declaration), isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent); let messageId = ""; if (mode === MODE_ALWAYS && !initialized) { messageId = "initialized"; } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) { messageId = "notInitialized"; } if (id.type === "Identifier" && messageId) { context.report({ node: declaration, messageId, data: { idName: id.name } }); } } } }; } };