code:
/**
 * @fileoverview Rule to forbid or enforce dangling commas.
 * @author Ian Christian Myers
 * @deprecated in ESLint v8.53.0
 */

"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");

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

const DEFAULT_OPTIONS = Object.freeze({
    arrays: "never",
    objects: "never",
    imports: "never",
    exports: "never",
    functions: "never"
});

/**
 * Checks whether or not a trailing comma is allowed in a given node.
 * If the `lastItem` is `RestElement` or `RestProperty`, it disallows trailing commas.
 * @param {ASTNode} lastItem The node of the last element in the given node.
 * @returns {boolean} `true` if a trailing comma is allowed.
 */
function isTrailingCommaAllowed(lastItem) {
    return !(
        lastItem.type === "RestElement" ||
        lastItem.type === "RestProperty" ||
        lastItem.type === "ExperimentalRestProperty"
    );
}

/**
 * Normalize option value.
 * @param {string|Object|undefined} optionValue The 1st option value to normalize.
 * @param {number} ecmaVersion The normalized ECMAScript version.
 * @returns {Object} The normalized option value.
 */
function normalizeOptions(optionValue, ecmaVersion) {
    if (typeof optionValue === "string") {
        return {
            arrays: optionValue,
            objects: optionValue,
            imports: optionValue,
            exports: optionValue,
            functions: ecmaVersion < 2017 ? "ignore" : optionValue
        };
    }
    if (typeof optionValue === "object" && optionValue !== null) {
        return {
            arrays: optionValue.arrays || DEFAULT_OPTIONS.arrays,
            objects: optionValue.objects || DEFAULT_OPTIONS.objects,
            imports: optionValue.imports || DEFAULT_OPTIONS.imports,
            exports: optionValue.exports || DEFAULT_OPTIONS.exports,
            functions: optionValue.functions || DEFAULT_OPTIONS.functions
        };
    }

    return DEFAULT_OPTIONS;
}

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Require or disallow trailing commas",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/comma-dangle"
        },

        fixable: "code",

        schema: {
            definitions: {
                value: {
                    enum: [
                        "always-multiline",
                        "always",
                        "never",
                        "only-multiline"
                    ]
                },
                valueWithIgnore: {
                    enum: [
                        "always-multiline",
                        "always",
                        "ignore",
                        "never",
                        "only-multiline"
                    ]
                }
            },
            type: "array",
            items: [
                {
                    oneOf: [
                        {
                            $ref: "#/definitions/value"
                        },
                        {
                            type: "object",
                            properties: {
                                arrays: { $ref: "#/definitions/valueWithIgnore" },
                                objects: { $ref: "#/definitions/valueWithIgnore" },
                                imports: { $ref: "#/definitions/valueWithIgnore" },
                                exports: { $ref: "#/definitions/valueWithIgnore" },
                                functions: { $ref: "#/definitions/valueWithIgnore" }
                            },
                            additionalProperties: false
                        }
                    ]
                }
            ],
            additionalItems: false
        },

        messages: {
            unexpected: "Unexpected trailing comma.",
            missing: "Missing trailing comma."
        }
    },

    create(context) {
        const options = normalizeOptions(context.options[0], context.languageOptions.ecmaVersion);

        const sourceCode = context.sourceCode;

        /**
         * Gets the last item of the given node.
         * @param {ASTNode} node The node to get.
         * @returns {ASTNode|null} The last node or null.
         */
        function getLastItem(node) {

            /**
             * Returns the last element of an array
             * @param {any[]} array The input array
             * @returns {any} The last element
             */
            function last(array) {
                return array[array.length - 1];
            }

            switch (node.type) {
                case "ObjectExpression":
                case "ObjectPattern":
                    return last(node.properties);
                case "ArrayExpression":
                case "ArrayPattern":
                    return last(node.elements);
                case "ImportDeclaration":
                case "ExportNamedDeclaration":
                    return last(node.specifiers);
                case "FunctionDeclaration":
                case "FunctionExpression":
                case "ArrowFunctionExpression":
                    return last(node.params);
                case "CallExpression":
                case "NewExpression":
                    return last(node.arguments);
                default:
                    return null;
            }
        }

        /**
         * Gets the trailing comma token of the given node.
         * If the trailing comma does not exist, this returns the token which is
         * the insertion point of the trailing comma token.
         * @param {ASTNode} node The node to get.
         * @param {ASTNode} lastItem The last item of the node.
         * @returns {Token} The trailing comma token or the insertion point.
         */
        function getTrailingToken(node, lastItem) {
            switch (node.type) {
                case "ObjectExpression":
                case "ArrayExpression":
                case "CallExpression":
                case "NewExpression":
                    return sourceCode.getLastToken(node, 1);
                default: {
                    const nextToken = sourceCode.getTokenAfter(lastItem);

                    if (astUtils.isCommaToken(nextToken)) {
                        return nextToken;
                    }
                    return sourceCode.getLastToken(lastItem);
                }
            }
        }

        /**
         * Checks whether or not a given node is multiline.
         * This rule handles a given node as multiline when the closing parenthesis
         * and the last element are not on the same line.
         * @param {ASTNode} node A node to check.
         * @returns {boolean} `true` if the node is multiline.
         */
        function isMultiline(node) {
            const lastItem = getLastItem(node);

            if (!lastItem) {
                return false;
            }

            const penultimateToken = getTrailingToken(node, lastItem);
            const lastToken = sourceCode.getTokenAfter(penultimateToken);

            return lastToken.loc.end.line !== penultimateToken.loc.end.line;
        }

        /**
         * Reports a trailing comma if it exists.
         * @param {ASTNode} node A node to check. Its type is one of
         *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
         *   ImportDeclaration, and ExportNamedDeclaration.
         * @returns {void}
         */
        function forbidTrailingComma(node) {
            const lastItem = getLastItem(node);

            if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) {
                return;
            }

            const trailingToken = getTrailingToken(node, lastItem);

            if (astUtils.isCommaToken(trailingToken)) {
                context.report({
                    node: lastItem,
                    loc: trailingToken.loc,
                    messageId: "unexpected",
                    *fix(fixer) {
                        yield fixer.remove(trailingToken);

                        /*
                         * Extend the range of the fix to include surrounding tokens to ensure
                         * that the element after which the comma is removed stays _last_.
                         * This intentionally makes conflicts in fix ranges with rules that may be
                         * adding or removing elements in the same autofix pass.
                         * https://github.com/eslint/eslint/issues/15660
                         */
                        yield fixer.insertTextBefore(sourceCode.getTokenBefore(trailingToken), "");
                        yield fixer.insertTextAfter(sourceCode.getTokenAfter(trailingToken), "");
                    }
                });
            }
        }

        /**
         * Reports the last element of a given node if it does not have a trailing
         * comma.
         *
         * If a given node is `ArrayPattern` which has `RestElement`, the trailing
         * comma is disallowed, so report if it exists.
         * @param {ASTNode} node A node to check. Its type is one of
         *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
         *   ImportDeclaration, and ExportNamedDeclaration.
         * @returns {void}
         */
        function forceTrailingComma(node) {
            const lastItem = getLastItem(node);

            if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) {
                return;
            }
            if (!isTrailingCommaAllowed(lastItem)) {
                forbidTrailingComma(node);
                return;
            }

            const trailingToken = getTrailingToken(node, lastItem);

            if (trailingToken.value !== ",") {
                context.report({
                    node: lastItem,
                    loc: {
                        start: trailingToken.loc.end,
                        end: astUtils.getNextLocation(sourceCode, trailingToken.loc.end)
                    },
                    messageId: "missing",
                    *fix(fixer) {
                        yield fixer.insertTextAfter(trailingToken, ",");

                        /*
                         * Extend the range of the fix to include surrounding tokens to ensure
                         * that the element after which the comma is inserted stays _last_.
                         * This intentionally makes conflicts in fix ranges with rules that may be
                         * adding or removing elements in the same autofix pass.
                         * https://github.com/eslint/eslint/issues/15660
                         */
                        yield fixer.insertTextBefore(trailingToken, "");
                        yield fixer.insertTextAfter(sourceCode.getTokenAfter(trailingToken), "");
                    }
                });
            }
        }

        /**
         * If a given node is multiline, reports the last element of a given node
         * when it does not have a trailing comma.
         * Otherwise, reports a trailing comma if it exists.
         * @param {ASTNode} node A node to check. Its type is one of
         *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
         *   ImportDeclaration, and ExportNamedDeclaration.
         * @returns {void}
         */
        function forceTrailingCommaIfMultiline(node) {
            if (isMultiline(node)) {
                forceTrailingComma(node);
            } else {
                forbidTrailingComma(node);
            }
        }

        /**
         * Only if a given node is not multiline, reports the last element of a given node
         * when it does not have a trailing comma.
         * Otherwise, reports a trailing comma if it exists.
         * @param {ASTNode} node A node to check. Its type is one of
         *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
         *   ImportDeclaration, and ExportNamedDeclaration.
         * @returns {void}
         */
        function allowTrailingCommaIfMultiline(node) {
            if (!isMultiline(node)) {
                forbidTrailingComma(node);
            }
        }

        const predicate = {
            always: forceTrailingComma,
            "always-multiline": forceTrailingCommaIfMultiline,
            "only-multiline": allowTrailingCommaIfMultiline,
            never: forbidTrailingComma,
            ignore() {}
        };

        return {
            ObjectExpression: predicate[options.objects],
            ObjectPattern: predicate[options.objects],

            ArrayExpression: predicate[options.arrays],
            ArrayPattern: predicate[options.arrays],

            ImportDeclaration: predicate[options.imports],

            ExportNamedDeclaration: predicate[options.exports],

            FunctionDeclaration: predicate[options.functions],
            FunctionExpression: predicate[options.functions],
            ArrowFunctionExpression: predicate[options.functions],
            CallExpression: predicate[options.functions],
            NewExpression: predicate[options.functions]
        };
    }
};


code:
/**
 * @fileoverview Comma spacing - validates spacing before and after comma
 * @author Vignesh Anand aka vegetableman.
 * @deprecated in ESLint v8.53.0
 */
"use strict";

const astUtils = require("./utils/ast-utils");

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Enforce consistent spacing before and after commas",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/comma-spacing"
        },

        fixable: "whitespace",

        schema: [
            {
                type: "object",
                properties: {
                    before: {
                        type: "boolean",
                        default: false
                    },
                    after: {
                        type: "boolean",
                        default: true
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            missing: "A space is required {{loc}} ','.",
            unexpected: "There should be no space {{loc}} ','."
        }
    },

    create(context) {

        const sourceCode = context.sourceCode;
        const tokensAndComments = sourceCode.tokensAndComments;

        const options = {
            before: context.options[0] ? context.options[0].before : false,
            after: context.options[0] ? context.options[0].after : true
        };

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

        // list of comma tokens to ignore for the check of leading whitespace
        const commaTokensToIgnore = [];

        /**
         * Reports a spacing error with an appropriate message.
         * @param {ASTNode} node The binary expression node to report.
         * @param {string} loc Is the error "before" or "after" the comma?
         * @param {ASTNode} otherNode The node at the left or right of `node`
         * @returns {void}
         * @private
         */
        function report(node, loc, otherNode) {
            context.report({
                node,
                fix(fixer) {
                    if (options[loc]) {
                        if (loc === "before") {
                            return fixer.insertTextBefore(node, " ");
                        }
                        return fixer.insertTextAfter(node, " ");

                    }
                    let start, end;
                    const newText = "";

                    if (loc === "before") {
                        start = otherNode.range[1];
                        end = node.range[0];
                    } else {
                        start = node.range[1];
                        end = otherNode.range[0];
                    }

                    return fixer.replaceTextRange([start, end], newText);

                },
                messageId: options[loc] ? "missing" : "unexpected",
                data: {
                    loc
                }
            });
        }

        /**
         * Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list.
         * @param {ASTNode} node An ArrayExpression or ArrayPattern node.
         * @returns {void}
         */
        function addNullElementsToIgnoreList(node) {
            let previousToken = sourceCode.getFirstToken(node);

            node.elements.forEach(element => {
                let token;

                if (element === null) {
                    token = sourceCode.getTokenAfter(previousToken);

                    if (astUtils.isCommaToken(token)) {
                        commaTokensToIgnore.push(token);
                    }
                } else {
                    token = sourceCode.getTokenAfter(element);
                }

                previousToken = token;
            });
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        return {
            "Program:exit"() {
                tokensAndComments.forEach((token, i) => {

                    if (!astUtils.isCommaToken(token)) {
                        return;
                    }

                    const previousToken = tokensAndComments[i - 1];
                    const nextToken = tokensAndComments[i + 1];

                    if (
                        previousToken &&
                        !astUtils.isCommaToken(previousToken) && // ignore spacing between two commas

                        /*
                         * `commaTokensToIgnore` are ending commas of `null` elements (array holes/elisions).
                         * In addition to spacing between two commas, this can also ignore:
                         *
                         *   - Spacing after `[` (controlled by array-bracket-spacing)
                         *       Example: [ , ]
                         *                 ^
                         *   - Spacing after a comment (for backwards compatibility, this was possibly unintentional)
                         *       Example: [a, /* * / ,]
                         *                          ^
                         */
                        !commaTokensToIgnore.includes(token) &&

                        astUtils.isTokenOnSameLine(previousToken, token) &&
                        options.before !== sourceCode.isSpaceBetweenTokens(previousToken, token)
                    ) {
                        report(token, "before", previousToken);
                    }

                    if (
                        nextToken &&
                        !astUtils.isCommaToken(nextToken) && // ignore spacing between two commas
                        !astUtils.isClosingParenToken(nextToken) && // controlled by space-in-parens
                        !astUtils.isClosingBracketToken(nextToken) && // controlled by array-bracket-spacing
                        !astUtils.isClosingBraceToken(nextToken) && // controlled by object-curly-spacing
                        !(!options.after && nextToken.type === "Line") && // special case, allow space before line comment
                        astUtils.isTokenOnSameLine(token, nextToken) &&
                        options.after !== sourceCode.isSpaceBetweenTokens(token, nextToken)
                    ) {
                        report(token, "after", nextToken);
                    }
                });
            },
            ArrayExpression: addNullElementsToIgnoreList,
            ArrayPattern: addNullElementsToIgnoreList

        };

    }
};

license: mit


code:
/**
 * @fileoverview Comma style - enforces comma styles of two types: last and first
 * @author Vignesh Anand aka vegetableman
 * @deprecated in ESLint v8.53.0
 */

"use strict";

const astUtils = require("./utils/ast-utils");

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Enforce consistent comma style",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/comma-style"
        },

        fixable: "code",

        schema: [
            {
                enum: ["first", "last"]
            },
            {
                type: "object",
                properties: {
                    exceptions: {
                        type: "object",
                        additionalProperties: {
                            type: "boolean"
                        }
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.",
            expectedCommaFirst: "',' should be placed first.",
            expectedCommaLast: "',' should be placed last."
        }
    },

    create(context) {
        const style = context.options[0] || "last",
            sourceCode = context.sourceCode;
        const exceptions = {
            ArrayPattern: true,
            ArrowFunctionExpression: true,
            CallExpression: true,
            FunctionDeclaration: true,
            FunctionExpression: true,
            ImportDeclaration: true,
            ObjectPattern: true,
            NewExpression: true
        };

        if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) {
            const keys = Object.keys(context.options[1].exceptions);

            for (let i = 0; i < keys.length; i++) {
                exceptions[keys[i]] = context.options[1].exceptions[keys[i]];
            }
        }

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

        /**
         * Modified text based on the style
         * @param {string} styleType Style type
         * @param {string} text Source code text
         * @returns {string} modified text
         * @private
         */
        function getReplacedText(styleType, text) {
            switch (styleType) {
                case "between":
                    return `,${text.replace(astUtils.LINEBREAK_MATCHER, "")}`;

                case "first":
                    return `${text},`;

                case "last":
                    return `,${text}`;

                default:
                    return "";
            }
        }

        /**
         * Determines the fixer function for a given style.
         * @param {string} styleType comma style
         * @param {ASTNode} previousItemToken The token to check.
         * @param {ASTNode} commaToken The token to check.
         * @param {ASTNode} currentItemToken The token to check.
         * @returns {Function} Fixer function
         * @private
         */
        function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) {
            const text =
                sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) +
                sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]);
            const range = [previousItemToken.range[1], currentItemToken.range[0]];

            return function(fixer) {
                return fixer.replaceTextRange(range, getReplacedText(styleType, text));
            };
        }

        /**
         * Validates the spacing around single items in lists.
         * @param {Token} previousItemToken The last token from the previous item.
         * @param {Token} commaToken The token representing the comma.
         * @param {Token} currentItemToken The first token of the current item.
         * @param {Token} reportItem The item to use when reporting an error.
         * @returns {void}
         * @private
         */
        function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) {

            // if single line
            if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
                    astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {

                // do nothing.

            } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
                    !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {

                const comment = sourceCode.getCommentsAfter(commaToken)[0];
                const styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment)
                    ? style
                    : "between";

                // lone comma
                context.report({
                    node: reportItem,
                    loc: commaToken.loc,
                    messageId: "unexpectedLineBeforeAndAfterComma",
                    fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken)
                });

            } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {

                context.report({
                    node: reportItem,
                    loc: commaToken.loc,
                    messageId: "expectedCommaFirst",
                    fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
                });

            } else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {

                context.report({
                    node: reportItem,
                    loc: commaToken.loc,
                    messageId: "expectedCommaLast",
                    fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
                });
            }
        }

        /**
         * Checks the comma placement with regards to a declaration/property/element
         * @param {ASTNode} node The binary expression node to check
         * @param {string} property The property of the node containing child nodes.
         * @private
         * @returns {void}
         */
        function validateComma(node, property) {
            const items = node[property],
                arrayLiteral = (node.type === "ArrayExpression" || node.type === "ArrayPattern");

            if (items.length > 1 || arrayLiteral) {

                // seed as opening [
                let previousItemToken = sourceCode.getFirstToken(node);

                items.forEach(item => {
                    const commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken,
                        currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken),
                        reportItem = item || currentItemToken;

                    /*
                     * This works by comparing three token locations:
                     * - previousItemToken is the last token of the previous item
                     * - commaToken is the location of the comma before the current item
                     * - currentItemToken is the first token of the current item
                     *
                     * These values get switched around if item is undefined.
                     * previousItemToken will refer to the last token not belonging
                     * to the current item, which could be a comma or an opening
                     * square bracket. currentItemToken could be a comma.
                     *
                     * All comparisons are done based on these tokens directly, so
                     * they are always valid regardless of an undefined item.
                     */
                    if (astUtils.isCommaToken(commaToken)) {
                        validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem);
                    }

                    if (item) {
                        const tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken);

                        previousItemToken = tokenAfterItem
                            ? sourceCode.getTokenBefore(tokenAfterItem)
                            : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1];
                    } else {
                        previousItemToken = currentItemToken;
                    }
                });

                /*
                 * Special case for array literals that have empty last items, such
                 * as [ 1, 2, ]. These arrays only have two items show up in the
                 * AST, so we need to look at the token to verify that there's no
                 * dangling comma.
                 */
                if (arrayLiteral) {

                    const lastToken = sourceCode.getLastToken(node),
                        nextToLastToken = sourceCode.getTokenBefore(lastToken);

                    if (astUtils.isCommaToken(nextToLastToken)) {
                        validateCommaItemSpacing(
                            sourceCode.getTokenBefore(nextToLastToken),
                            nextToLastToken,
                            lastToken,
                            lastToken
                        );
                    }
                }
            }
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        const nodes = {};

        if (!exceptions.VariableDeclaration) {
            nodes.VariableDeclaration = function(node) {
                validateComma(node, "declarations");
            };
        }
        if (!exceptions.ObjectExpression) {
            nodes.ObjectExpression = function(node) {
                validateComma(node, "properties");
            };
        }
        if (!exceptions.ObjectPattern) {
            nodes.ObjectPattern = function(node) {
                validateComma(node, "properties");
            };
        }
        if (!exceptions.ArrayExpression) {
            nodes.ArrayExpression = function(node) {
                validateComma(node, "elements");
            };
        }
        if (!exceptions.ArrayPattern) {
            nodes.ArrayPattern = function(node) {
                validateComma(node, "elements");
            };
        }
        if (!exceptions.FunctionDeclaration) {
            nodes.FunctionDeclaration = function(node) {
                validateComma(node, "params");
            };
        }
        if (!exceptions.FunctionExpression) {
            nodes.FunctionExpression = function(node) {
                validateComma(node, "params");
            };
        }
        if (!exceptions.ArrowFunctionExpression) {
            nodes.ArrowFunctionExpression = function(node) {
                validateComma(node, "params");
            };
        }
        if (!exceptions.CallExpression) {
            nodes.CallExpression = function(node) {
                validateComma(node, "arguments");
            };
        }
        if (!exceptions.ImportDeclaration) {
            nodes.ImportDeclaration = function(node) {
                validateComma(node, "specifiers");
            };
        }
        if (!exceptions.NewExpression) {
            nodes.NewExpression = function(node) {
                validateComma(node, "arguments");
            };
        }

        return nodes;
    }
};


code:
/**
 * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity.
 * Counts the number of if, conditional, for, while, try, switch/case,
 * @author Patrick Brosset
 */

"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");
const { upperCaseFirst } = require("../shared/string-utils");

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce a maximum cyclomatic complexity allowed in a program",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/complexity"
        },

        schema: [
            {
                oneOf: [
                    {
                        type: "integer",
                        minimum: 0
                    },
                    {
                        type: "object",
                        properties: {
                            maximum: {
                                type: "integer",
                                minimum: 0
                            },
                            max: {
                                type: "integer",
                                minimum: 0
                            }
                        },
                        additionalProperties: false
                    }
                ]
            }
        ],

        messages: {
            complex: "{{name}} has a complexity of {{complexity}}. Maximum allowed is {{max}}."
        }
    },

    create(context) {
        const option = context.options[0];
        let THRESHOLD = 20;

        if (
            typeof option === "object" &&
            (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
        ) {
            THRESHOLD = option.maximum || option.max;
        } else if (typeof option === "number") {
            THRESHOLD = option;
        }

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

        // Using a stack to store complexity per code path
        const complexities = [];

        /**
         * Increase the complexity of the code path in context
         * @returns {void}
         * @private
         */
        function increaseComplexity() {
            complexities[complexities.length - 1]++;
        }

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

        return {

            onCodePathStart() {

                // The initial complexity is 1, representing one execution path in the CodePath
                complexities.push(1);
            },

            // Each branching in the code adds 1 to the complexity
            CatchClause: increaseComplexity,
            ConditionalExpression: increaseComplexity,
            LogicalExpression: increaseComplexity,
            ForStatement: increaseComplexity,
            ForInStatement: increaseComplexity,
            ForOfStatement: increaseComplexity,
            IfStatement: increaseComplexity,
            WhileStatement: increaseComplexity,
            DoWhileStatement: increaseComplexity,

            // Avoid `default`
            "SwitchCase[test]": increaseComplexity,

            // Logical assignment operators have short-circuiting behavior
            AssignmentExpression(node) {
                if (astUtils.isLogicalAssignmentOperator(node.operator)) {
                    increaseComplexity();
                }
            },

            onCodePathEnd(codePath, node) {
                const complexity = complexities.pop();

                /*
                 * This rule only evaluates complexity of functions, so "program" is excluded.
                 * Class field initializers and class static blocks are implicit functions. Therefore,
                 * they shouldn't contribute to the enclosing function's complexity, but their
                 * own complexity should be evaluated.
                 */
                if (
                    codePath.origin !== "function" &&
                    codePath.origin !== "class-field-initializer" &&
                    codePath.origin !== "class-static-block"
                ) {
                    return;
                }

                if (complexity > THRESHOLD) {
                    let name;

                    if (codePath.origin === "class-field-initializer") {
                        name = "class field initializer";
                    } else if (codePath.origin === "class-static-block") {
                        name = "class static block";
                    } else {
                        name = astUtils.getFunctionNameWithKind(node);
                    }

                    context.report({
                        node,
                        messageId: "complex",
                        data: {
                            name: upperCaseFirst(name),
                            complexity,
                            max: THRESHOLD
                        }
                    });
                }
            }
        };

    }
};


code:
/**
 * @fileoverview Disallows or enforces spaces inside computed properties.
 * @author Jamund Ferguson
 * @deprecated in ESLint v8.53.0
 */
"use strict";

const astUtils = require("./utils/ast-utils");

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        deprecated: true,
        replacedBy: [],
        type: "layout",

        docs: {
            description: "Enforce consistent spacing inside computed property brackets",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/computed-property-spacing"
        },

        fixable: "whitespace",

        schema: [
            {
                enum: ["always", "never"]
            },
            {
                type: "object",
                properties: {
                    enforceForClassMembers: {
                        type: "boolean",
                        default: true
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.",
            unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.",

            missingSpaceBefore: "A space is required before '{{tokenValue}}'.",
            missingSpaceAfter: "A space is required after '{{tokenValue}}'."
        }
    },

    create(context) {
        const sourceCode = context.sourceCode;
        const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never"
        const enforceForClassMembers = !context.options[1] || context.options[1].enforceForClassMembers;

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

        /**
         * Reports that there shouldn't be a space after the first token
         * @param {ASTNode} node The node to report in the event of an error.
         * @param {Token} token The token to use for the report.
         * @param {Token} tokenAfter The token after `token`.
         * @returns {void}
         */
        function reportNoBeginningSpace(node, token, tokenAfter) {
            context.report({
                node,
                loc: { start: token.loc.end, end: tokenAfter.loc.start },
                messageId: "unexpectedSpaceAfter",
                data: {
                    tokenValue: token.value
                },
                fix(fixer) {
                    return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
                }
            });
        }

        /**
         * Reports that there shouldn't be a space before the last token
         * @param {ASTNode} node The node to report in the event of an error.
         * @param {Token} token The token to use for the report.
         * @param {Token} tokenBefore The token before `token`.
         * @returns {void}
         */
        function reportNoEndingSpace(node, token, tokenBefore) {
            context.report({
                node,
                loc: { start: tokenBefore.loc.end, end: token.loc.start },
                messageId: "unexpectedSpaceBefore",
                data: {
                    tokenValue: token.value
                },
                fix(fixer) {
                    return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
                }
            });
        }

        /**
         * Reports that there should be a space after the first token
         * @param {ASTNode} node The node to report in the event of an error.
         * @param {Token} token The token to use for the report.
         * @returns {void}
         */
        function reportRequiredBeginningSpace(node, token) {
            context.report({
                node,
                loc: token.loc,
                messageId: "missingSpaceAfter",
                data: {
                    tokenValue: token.value
                },
                fix(fixer) {
                    return fixer.insertTextAfter(token, " ");
                }
            });
        }

        /**
         * Reports that there should be a space before the last token
         * @param {ASTNode} node The node to report in the event of an error.
         * @param {Token} token The token to use for the report.
         * @returns {void}
         */
        function reportRequiredEndingSpace(node, token) {
            context.report({
                node,
                loc: token.loc,
                messageId: "missingSpaceBefore",
                data: {
                    tokenValue: token.value
                },
                fix(fixer) {
                    return fixer.insertTextBefore(token, " ");
                }
            });
        }

        /**
         * Returns a function that checks the spacing of a node on the property name
         * that was passed in.
         * @param {string} propertyName The property on the node to check for spacing
         * @returns {Function} A function that will check spacing on a node
         */
        function checkSpacing(propertyName) {
            return function(node) {
                if (!node.computed) {
                    return;
                }

                const property = node[propertyName];

                const before = sourceCode.getTokenBefore(property, astUtils.isOpeningBracketToken),
                    first = sourceCode.getTokenAfter(before, { includeComments: true }),
                    after = sourceCode.getTokenAfter(property, astUtils.isClosingBracketToken),
                    last = sourceCode.getTokenBefore(after, { includeComments: true });

                if (astUtils.isTokenOnSameLine(before, first)) {
                    if (propertyNameMustBeSpaced) {
                        if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) {
                            reportRequiredBeginningSpace(node, before);
                        }
                    } else {
                        if (sourceCode.isSpaceBetweenTokens(before, first)) {
                            reportNoBeginningSpace(node, before, first);
                        }
                    }
                }

                if (astUtils.isTokenOnSameLine(last, after)) {
                    if (propertyNameMustBeSpaced) {
                        if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) {
                            reportRequiredEndingSpace(node, after);
                        }
                    } else {
                        if (sourceCode.isSpaceBetweenTokens(last, after)) {
                            reportNoEndingSpace(node, after, last);
                        }
                    }
                }
            };
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        const listeners = {
            Property: checkSpacing("key"),
            MemberExpression: checkSpacing("property")
        };

        if (enforceForClassMembers) {
            listeners.MethodDefinition =
                listeners.PropertyDefinition = listeners.Property;
        }

        return listeners;

    }
};


code:
/**
 * @fileoverview Rule to flag consistent return values
 * @author Nicholas C. Zakas
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");
const { upperCaseFirst } = require("../shared/string-utils");

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

/**
 * Checks all segments in a set and returns true if all are unreachable.
 * @param {Set<CodePathSegment>} segments The segments to check.
 * @returns {boolean} True if all segments are unreachable; false otherwise.
 */
function areAllSegmentsUnreachable(segments) {

    for (const segment of segments) {
        if (segment.reachable) {
            return false;
        }
    }

    return true;
}

/**
 * Checks whether a given node is a `constructor` method in an ES6 class
 * @param {ASTNode} node A node to check
 * @returns {boolean} `true` if the node is a `constructor` method
 */
function isClassConstructor(node) {
    return node.type === "FunctionExpression" &&
        node.parent &&
        node.parent.type === "MethodDefinition" &&
        node.parent.kind === "constructor";
}

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Require `return` statements to either always or never specify values",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/consistent-return"
        },

        schema: [{
            type: "object",
            properties: {
                treatUndefinedAsUnspecified: {
                    type: "boolean",
                    default: false
                }
            },
            additionalProperties: false
        }],

        messages: {
            missingReturn: "Expected to return a value at the end of {{name}}.",
            missingReturnValue: "{{name}} expected a return value.",
            unexpectedReturnValue: "{{name}} expected no return value."
        }
    },

    create(context) {
        const options = context.options[0] || {};
        const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true;
        let funcInfo = null;

        /**
         * Checks whether of not the implicit returning is consistent if the last
         * code path segment is reachable.
         * @param {ASTNode} node A program/function node to check.
         * @returns {void}
         */
        function checkLastSegment(node) {
            let loc, name;

            /*
             * Skip if it expected no return value or unreachable.
             * When unreachable, all paths are returned or thrown.
             */
            if (!funcInfo.hasReturnValue ||
                areAllSegmentsUnreachable(funcInfo.currentSegments) ||
                astUtils.isES5Constructor(node) ||
                isClassConstructor(node)
            ) {
                return;
            }

            // Adjust a location and a message.
            if (node.type === "Program") {

                // The head of program.
                loc = { line: 1, column: 0 };
                name = "program";
            } else if (node.type === "ArrowFunctionExpression") {

                // `=>` token
                loc = context.sourceCode.getTokenBefore(node.body, astUtils.isArrowToken).loc;
            } else if (
                node.parent.type === "MethodDefinition" ||
                (node.parent.type === "Property" && node.parent.method)
            ) {

                // Method name.
                loc = node.parent.key.loc;
            } else {

                // Function name or `function` keyword.
                loc = (node.id || context.sourceCode.getFirstToken(node)).loc;
            }

            if (!name) {
                name = astUtils.getFunctionNameWithKind(node);
            }

            // Reports.
            context.report({
                node,
                loc,
                messageId: "missingReturn",
                data: { name }
            });
        }

        return {

            // Initializes/Disposes state of each code path.
            onCodePathStart(codePath, node) {
                funcInfo = {
                    upper: funcInfo,
                    codePath,
                    hasReturn: false,
                    hasReturnValue: false,
                    messageId: "",
                    node,
                    currentSegments: new Set()
                };
            },
            onCodePathEnd() {
                funcInfo = funcInfo.upper;
            },

            onUnreachableCodePathSegmentStart(segment) {
                funcInfo.currentSegments.add(segment);
            },

            onUnreachableCodePathSegmentEnd(segment) {
                funcInfo.currentSegments.delete(segment);
            },

            onCodePathSegmentStart(segment) {
                funcInfo.currentSegments.add(segment);
            },

            onCodePathSegmentEnd(segment) {
                funcInfo.currentSegments.delete(segment);
            },

            // Reports a given return statement if it's inconsistent.
            ReturnStatement(node) {
                const argument = node.argument;
                let hasReturnValue = Boolean(argument);

                if (treatUndefinedAsUnspecified && hasReturnValue) {
                    hasReturnValue = !astUtils.isSpecificId(argument, "undefined") && argument.operator !== "void";
                }

                if (!funcInfo.hasReturn) {
                    funcInfo.hasReturn = true;
                    funcInfo.hasReturnValue = hasReturnValue;
                    funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue";
                    funcInfo.data = {
                        name: funcInfo.node.type === "Program"
                            ? "Program"
                            : upperCaseFirst(astUtils.getFunctionNameWithKind(funcInfo.node))
                    };
                } else if (funcInfo.hasReturnValue !== hasReturnValue) {
                    context.report({
                        node,
                        messageId: funcInfo.messageId,
                        data: funcInfo.data
                    });
                }
            },

            // Reports a given program/function if the implicit returning is not consistent.
            "Program:exit": checkLastSegment,
            "FunctionDeclaration:exit": checkLastSegment,
            "FunctionExpression:exit": checkLastSegment,
            "ArrowFunctionExpression:exit": checkLastSegment
        };
    }
};


code:
/**
 * @fileoverview Rule to enforce consistent naming of "this" context variables
 * @author Raphael Pigulla
 */
"use strict";

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce consistent naming when capturing the current execution context",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/consistent-this"
        },

        schema: {
            type: "array",
            items: {
                type: "string",
                minLength: 1
            },
            uniqueItems: true
        },

        messages: {
            aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.",
            unexpectedAlias: "Unexpected alias '{{name}}' for 'this'."
        }
    },

    create(context) {
        let aliases = [];
        const sourceCode = context.sourceCode;

        if (context.options.length === 0) {
            aliases.push("that");
        } else {
            aliases = context.options;
        }

        /**
         * Reports that a variable declarator or assignment expression is assigning
         * a non-'this' value to the specified alias.
         * @param {ASTNode} node The assigning node.
         * @param {string} name the name of the alias that was incorrectly used.
         * @returns {void}
         */
        function reportBadAssignment(node, name) {
            context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } });
        }

        /**
         * Checks that an assignment to an identifier only assigns 'this' to the
         * appropriate alias, and the alias is only assigned to 'this'.
         * @param {ASTNode} node The assigning node.
         * @param {Identifier} name The name of the variable assigned to.
         * @param {Expression} value The value of the assignment.
         * @returns {void}
         */
        function checkAssignment(node, name, value) {
            const isThis = value.type === "ThisExpression";

            if (aliases.includes(name)) {
                if (!isThis || node.operator && node.operator !== "=") {
                    reportBadAssignment(node, name);
                }
            } else if (isThis) {
                context.report({ node, messageId: "unexpectedAlias", data: { name } });
            }
        }

        /**
         * Ensures that a variable declaration of the alias in a program or function
         * is assigned to the correct value.
         * @param {string} alias alias the check the assignment of.
         * @param {Object} scope scope of the current code we are checking.
         * @private
         * @returns {void}
         */
        function checkWasAssigned(alias, scope) {
            const variable = scope.set.get(alias);

            if (!variable) {
                return;
            }

            if (variable.defs.some(def => def.node.type === "VariableDeclarator" &&
                def.node.init !== null)) {
                return;
            }

            /*
             * The alias has been declared and not assigned: check it was
             * assigned later in the same scope.
             */
            if (!variable.references.some(reference => {
                const write = reference.writeExpr;

                return (
                    reference.from === scope &&
                    write && write.type === "ThisExpression" &&
                    write.parent.operator === "="
                );
            })) {
                variable.defs.map(def => def.node).forEach(node => {
                    reportBadAssignment(node, alias);
                });
            }
        }

        /**
         * Check each alias to ensure that is was assigned to the correct value.
         * @param {ASTNode} node The node that represents the scope to check.
         * @returns {void}
         */
        function ensureWasAssigned(node) {
            const scope = sourceCode.getScope(node);

            aliases.forEach(alias => {
                checkWasAssigned(alias, scope);
            });
        }

        return {
            "Program:exit": ensureWasAssigned,
            "FunctionExpression:exit": ensureWasAssigned,
            "FunctionDeclaration:exit": ensureWasAssigned,

            VariableDeclarator(node) {
                const id = node.id;
                const isDestructuring =
                    id.type === "ArrayPattern" || id.type === "ObjectPattern";

                if (node.init !== null && !isDestructuring) {
                    checkAssignment(node, id.name, node.init);
                }
            },

            AssignmentExpression(node) {
                if (node.left.type === "Identifier") {
                    checkAssignment(node, node.left.name, node.right);
                }
            }
        };

    }
};


code:
/**
 * @fileoverview A rule to verify `super()` callings in constructor.
 * @author Toru Nagashima
 */

"use strict";

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

/**
 * Checks all segments in a set and returns true if any are reachable.
 * @param {Set<CodePathSegment>} segments The segments to check.
 * @returns {boolean} True if any segment is reachable; false otherwise.
 */
function isAnySegmentReachable(segments) {

    for (const segment of segments) {
        if (segment.reachable) {
            return true;
        }
    }

    return false;
}

/**
 * Checks whether or not a given node is a constructor.
 * @param {ASTNode} node A node to check. This node type is one of
 *   `Program`, `FunctionDeclaration`, `FunctionExpression`, and
 *   `ArrowFunctionExpression`.
 * @returns {boolean} `true` if the node is a constructor.
 */
function isConstructorFunction(node) {
    return (
        node.type === "FunctionExpression" &&
        node.parent.type === "MethodDefinition" &&
        node.parent.kind === "constructor"
    );
}

/**
 * Checks whether a given node can be a constructor or not.
 * @param {ASTNode} node A node to check.
 * @returns {boolean} `true` if the node can be a constructor.
 */
function isPossibleConstructor(node) {
    if (!node) {
        return false;
    }

    switch (node.type) {
        case "ClassExpression":
        case "FunctionExpression":
        case "ThisExpression":
        case "MemberExpression":
        case "CallExpression":
        case "NewExpression":
        case "ChainExpression":
        case "YieldExpression":
        case "TaggedTemplateExpression":
        case "MetaProperty":
            return true;

        case "Identifier":
            return node.name !== "undefined";

        case "AssignmentExpression":
            if (["=", "&&="].includes(node.operator)) {
                return isPossibleConstructor(node.right);
            }

            if (["||=", "??="].includes(node.operator)) {
                return (
                    isPossibleConstructor(node.left) ||
                    isPossibleConstructor(node.right)
                );
            }

            /**
             * All other assignment operators are mathematical assignment operators (arithmetic or bitwise).
             * An assignment expression with a mathematical operator can either evaluate to a primitive value,
             * or throw, depending on the operands. Thus, it cannot evaluate to a constructor function.
             */
            return false;

        case "LogicalExpression":

            /*
             * If the && operator short-circuits, the left side was falsy and therefore not a constructor, and if
             * it doesn't short-circuit, it takes the value from the right side, so the right side must always be a
             * possible constructor. A future improvement could verify that the left side could be truthy by
             * excluding falsy literals.
             */
            if (node.operator === "&&") {
                return isPossibleConstructor(node.right);
            }

            return (
                isPossibleConstructor(node.left) ||
                isPossibleConstructor(node.right)
            );

        case "ConditionalExpression":
            return (
                isPossibleConstructor(node.alternate) ||
                isPossibleConstructor(node.consequent)
            );

        case "SequenceExpression": {
            const lastExpression = node.expressions[node.expressions.length - 1];

            return isPossibleConstructor(lastExpression);
        }

        default:
            return false;
    }
}

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "problem",

        docs: {
            description: "Require `super()` calls in constructors",
            recommended: true,
            url: "https://eslint.org/docs/latest/rules/constructor-super"
        },

        schema: [],

        messages: {
            missingSome: "Lacked a call of 'super()' in some code paths.",
            missingAll: "Expected to call 'super()'.",

            duplicate: "Unexpected duplicate 'super()'.",
            badSuper: "Unexpected 'super()' because 'super' is not a constructor.",
            unexpected: "Unexpected 'super()'."
        }
    },

    create(context) {

        /*
         * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]}
         * Information for each constructor.
         * - upper:      Information of the upper constructor.
         * - hasExtends: A flag which shows whether own class has a valid `extends`
         *               part.
         * - scope:      The scope of own class.
         * - codePath:   The code path object of the constructor.
         */
        let funcInfo = null;

        /*
         * {Map<string, {calledInSomePaths: boolean, calledInEveryPaths: boolean}>}
         * Information for each code path segment.
         * - calledInSomePaths:  A flag of be called `super()` in some code paths.
         * - calledInEveryPaths: A flag of be called `super()` in all code paths.
         * - validNodes:
         */
        let segInfoMap = Object.create(null);

        /**
         * Gets the flag which shows `super()` is called in some paths.
         * @param {CodePathSegment} segment A code path segment to get.
         * @returns {boolean} The flag which shows `super()` is called in some paths
         */
        function isCalledInSomePath(segment) {
            return segment.reachable && segInfoMap[segment.id].calledInSomePaths;
        }

        /**
         * Gets the flag which shows `super()` is called in all paths.
         * @param {CodePathSegment} segment A code path segment to get.
         * @returns {boolean} The flag which shows `super()` is called in all paths.
         */
        function isCalledInEveryPath(segment) {

            /*
             * If specific segment is the looped segment of the current segment,
             * skip the segment.
             * If not skipped, this never becomes true after a loop.
             */
            if (segment.nextSegments.length === 1 &&
                segment.nextSegments[0].isLoopedPrevSegment(segment)
            ) {
                return true;
            }
            return segment.reachable && segInfoMap[segment.id].calledInEveryPaths;
        }

        return {

            /**
             * Stacks a constructor information.
             * @param {CodePath} codePath A code path which was started.
             * @param {ASTNode} node The current node.
             * @returns {void}
             */
            onCodePathStart(codePath, node) {
                if (isConstructorFunction(node)) {

                    // Class > ClassBody > MethodDefinition > FunctionExpression
                    const classNode = node.parent.parent.parent;
                    const superClass = classNode.superClass;

                    funcInfo = {
                        upper: funcInfo,
                        isConstructor: true,
                        hasExtends: Boolean(superClass),
                        superIsConstructor: isPossibleConstructor(superClass),
                        codePath,
                        currentSegments: new Set()
                    };
                } else {
                    funcInfo = {
                        upper: funcInfo,
                        isConstructor: false,
                        hasExtends: false,
                        superIsConstructor: false,
                        codePath,
                        currentSegments: new Set()
                    };
                }
            },

            /**
             * Pops a constructor information.
             * And reports if `super()` lacked.
             * @param {CodePath} codePath A code path which was ended.
             * @param {ASTNode} node The current node.
             * @returns {void}
             */
            onCodePathEnd(codePath, node) {
                const hasExtends = funcInfo.hasExtends;

                // Pop.
                funcInfo = funcInfo.upper;

                if (!hasExtends) {
                    return;
                }

                // Reports if `super()` lacked.
                const segments = codePath.returnedSegments;
                const calledInEveryPaths = segments.every(isCalledInEveryPath);
                const calledInSomePaths = segments.some(isCalledInSomePath);

                if (!calledInEveryPaths) {
                    context.report({
                        messageId: calledInSomePaths
                            ? "missingSome"
                            : "missingAll",
                        node: node.parent
                    });
                }
            },

            /**
             * Initialize information of a given code path segment.
             * @param {CodePathSegment} segment A code path segment to initialize.
             * @returns {void}
             */
            onCodePathSegmentStart(segment) {

                funcInfo.currentSegments.add(segment);

                if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
                    return;
                }

                // Initialize info.
                const info = segInfoMap[segment.id] = {
                    calledInSomePaths: false,
                    calledInEveryPaths: false,
                    validNodes: []
                };

                // When there are previous segments, aggregates these.
                const prevSegments = segment.prevSegments;

                if (prevSegments.length > 0) {
                    info.calledInSomePaths = prevSegments.some(isCalledInSomePath);
                    info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath);
                }
            },

            onUnreachableCodePathSegmentStart(segment) {
                funcInfo.currentSegments.add(segment);
            },

            onUnreachableCodePathSegmentEnd(segment) {
                funcInfo.currentSegments.delete(segment);
            },

            onCodePathSegmentEnd(segment) {
                funcInfo.currentSegments.delete(segment);
            },

            /**
             * Update information of the code path segment when a code path was
             * looped.
             * @param {CodePathSegment} fromSegment The code path segment of the
             *      end of a loop.
             * @param {CodePathSegment} toSegment A code path segment of the head
             *      of a loop.
             * @returns {void}
             */
            onCodePathSegmentLoop(fromSegment, toSegment) {
                if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
                    return;
                }

                // Update information inside of the loop.
                const isRealLoop = toSegment.prevSegments.length >= 2;

                funcInfo.codePath.traverseSegments(
                    { first: toSegment, last: fromSegment },
                    segment => {
                        const info = segInfoMap[segment.id];
                        const prevSegments = segment.prevSegments;

                        // Updates flags.
                        info.calledInSomePaths = prevSegments.some(isCalledInSomePath);
                        info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath);

                        // If flags become true anew, reports the valid nodes.
                        if (info.calledInSomePaths || isRealLoop) {
                            const nodes = info.validNodes;

                            info.validNodes = [];

                            for (let i = 0; i < nodes.length; ++i) {
                                const node = nodes[i];

                                context.report({
                                    messageId: "duplicate",
                                    node
                                });
                            }
                        }
                    }
                );
            },

            /**
             * Checks for a call of `super()`.
             * @param {ASTNode} node A CallExpression node to check.
             * @returns {void}
             */
            "CallExpression:exit"(node) {
                if (!(funcInfo && funcInfo.isConstructor)) {
                    return;
                }

                // Skips except `super()`.
                if (node.callee.type !== "Super") {
                    return;
                }

                // Reports if needed.
                if (funcInfo.hasExtends) {
                    const segments = funcInfo.currentSegments;
                    let duplicate = false;
                    let info = null;

                    for (const segment of segments) {

                        if (segment.reachable) {
                            info = segInfoMap[segment.id];

                            duplicate = duplicate || info.calledInSomePaths;
                            info.calledInSomePaths = info.calledInEveryPaths = true;
                        }
                    }

                    if (info) {
                        if (duplicate) {
                            context.report({
                                messageId: "duplicate",
                                node
                            });
                        } else if (!funcInfo.superIsConstructor) {
                            context.report({
                                messageId: "badSuper",
                                node
                            });
                        } else {
                            info.validNodes.push(node);
                        }
                    }
                } else if (isAnySegmentReachable(funcInfo.currentSegments)) {
                    context.report({
                        messageId: "unexpected",
                        node
                    });
                }
            },

            /**
             * Set the mark to the returned path as `super()` was called.
             * @param {ASTNode} node A ReturnStatement node to check.
             * @returns {void}
             */
            ReturnStatement(node) {
                if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
                    return;
                }

                // Skips if no argument.
                if (!node.argument) {
                    return;
                }

                // Returning argument is a substitute of 'super()'.
                const segments = funcInfo.currentSegments;

                for (const segment of segments) {

                    if (segment.reachable) {
                        const info = segInfoMap[segment.id];

                        info.calledInSomePaths = info.calledInEveryPaths = true;
                    }
                }
            },

            /**
             * Resets state.
             * @returns {void}
             */
            "Program:exit"() {
                segInfoMap = Object.create(null);
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to flag statements without curly braces
 * @author Nicholas C. Zakas
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce consistent brace style for all control statements",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/curly"
        },

        schema: {
            anyOf: [
                {
                    type: "array",
                    items: [
                        {
                            enum: ["all"]
                        }
                    ],
                    minItems: 0,
                    maxItems: 1
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["multi", "multi-line", "multi-or-nest"]
                        },
                        {
                            enum: ["consistent"]
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                }
            ]
        },

        fixable: "code",

        messages: {
            missingCurlyAfter: "Expected { after '{{name}}'.",
            missingCurlyAfterCondition: "Expected { after '{{name}}' condition.",
            unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.",
            unexpectedCurlyAfterCondition: "Unnecessary { after '{{name}}' condition."
        }
    },

    create(context) {

        const multiOnly = (context.options[0] === "multi");
        const multiLine = (context.options[0] === "multi-line");
        const multiOrNest = (context.options[0] === "multi-or-nest");
        const consistent = (context.options[1] === "consistent");

        const sourceCode = context.sourceCode;

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

        /**
         * Determines if a given node is a one-liner that's on the same line as it's preceding code.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code.
         * @private
         */
        function isCollapsedOneLiner(node) {
            const before = sourceCode.getTokenBefore(node);
            const last = sourceCode.getLastToken(node);
            const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last;

            return before.loc.start.line === lastExcludingSemicolon.loc.end.line;
        }

        /**
         * Determines if a given node is a one-liner.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} True if the node is a one-liner.
         * @private
         */
        function isOneLiner(node) {
            if (node.type === "EmptyStatement") {
                return true;
            }

            const first = sourceCode.getFirstToken(node);
            const last = sourceCode.getLastToken(node);
            const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last;

            return first.loc.start.line === lastExcludingSemicolon.loc.end.line;
        }

        /**
         * Determines if the given node is a lexical declaration (let, const, function, or class)
         * @param {ASTNode} node The node to check
         * @returns {boolean} True if the node is a lexical declaration
         * @private
         */
        function isLexicalDeclaration(node) {
            if (node.type === "VariableDeclaration") {
                return node.kind === "const" || node.kind === "let";
            }

            return node.type === "FunctionDeclaration" || node.type === "ClassDeclaration";
        }

        /**
         * Checks if the given token is an `else` token or not.
         * @param {Token} token The token to check.
         * @returns {boolean} `true` if the token is an `else` token.
         */
        function isElseKeywordToken(token) {
            return token.value === "else" && token.type === "Keyword";
        }

        /**
         * Determines whether the given node has an `else` keyword token as the first token after.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} `true` if the node is followed by an `else` keyword token.
         */
        function isFollowedByElseKeyword(node) {
            const nextToken = sourceCode.getTokenAfter(node);

            return Boolean(nextToken) && isElseKeywordToken(nextToken);
        }

        /**
         * Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError.
         * @param {Token} closingBracket The } token
         * @returns {boolean} `true` if a semicolon needs to be inserted after the last statement in the block.
         */
        function needsSemicolon(closingBracket) {
            const tokenBefore = sourceCode.getTokenBefore(closingBracket);
            const tokenAfter = sourceCode.getTokenAfter(closingBracket);
            const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]);

            if (astUtils.isSemicolonToken(tokenBefore)) {

                // If the last statement already has a semicolon, don't add another one.
                return false;
            }

            if (!tokenAfter) {

                // If there are no statements after this block, there is no need to add a semicolon.
                return false;
            }

            if (lastBlockNode.type === "BlockStatement" && lastBlockNode.parent.type !== "FunctionExpression" && lastBlockNode.parent.type !== "ArrowFunctionExpression") {

                /*
                 * If the last node surrounded by curly brackets is a BlockStatement (other than a FunctionExpression or an ArrowFunctionExpression),
                 * don't insert a semicolon. Otherwise, the semicolon would be parsed as a separate statement, which would cause
                 * a SyntaxError if it was followed by `else`.
                 */
                return false;
            }

            if (tokenBefore.loc.end.line === tokenAfter.loc.start.line) {

                // If the next token is on the same line, insert a semicolon.
                return true;
            }

            if (/^[([/`+-]/u.test(tokenAfter.value)) {

                // If the next token starts with a character that would disrupt ASI, insert a semicolon.
                return true;
            }

            if (tokenBefore.type === "Punctuator" && (tokenBefore.value === "++" || tokenBefore.value === "--")) {

                // If the last token is ++ or --, insert a semicolon to avoid disrupting ASI.
                return true;
            }

            // Otherwise, do not insert a semicolon.
            return false;
        }

        /**
         * Determines whether the code represented by the given node contains an `if` statement
         * that would become associated with an `else` keyword directly appended to that code.
         *
         * Examples where it returns `true`:
         *
         *    if (a)
         *        foo();
         *
         *    if (a) {
         *        foo();
         *    }
         *
         *    if (a)
         *        foo();
         *    else if (b)
         *        bar();
         *
         *    while (a)
         *        if (b)
         *            if(c)
         *                foo();
         *            else
         *                bar();
         *
         * Examples where it returns `false`:
         *
         *    if (a)
         *        foo();
         *    else
         *        bar();
         *
         *    while (a) {
         *        if (b)
         *            if(c)
         *                foo();
         *            else
         *                bar();
         *    }
         *
         *    while (a)
         *        if (b) {
         *            if(c)
         *                foo();
         *        }
         *        else
         *            bar();
         * @param {ASTNode} node Node representing the code to check.
         * @returns {boolean} `true` if an `if` statement within the code would become associated with an `else` appended to that code.
         */
        function hasUnsafeIf(node) {
            switch (node.type) {
                case "IfStatement":
                    if (!node.alternate) {
                        return true;
                    }
                    return hasUnsafeIf(node.alternate);
                case "ForStatement":
                case "ForInStatement":
                case "ForOfStatement":
                case "LabeledStatement":
                case "WithStatement":
                case "WhileStatement":
                    return hasUnsafeIf(node.body);
                default:
                    return false;
            }
        }

        /**
         * Determines whether the existing curly braces around the single statement are necessary to preserve the semantics of the code.
         * The braces, which make the given block body, are necessary in either of the following situations:
         *
         * 1. The statement is a lexical declaration.
         * 2. Without the braces, an `if` within the statement would become associated with an `else` after the closing brace:
         *
         *     if (a) {
         *         if (b)
         *             foo();
         *     }
         *     else
         *         bar();
         *
         *     if (a)
         *         while (b)
         *             while (c) {
         *                 while (d)
         *                     if (e)
         *                         while(f)
         *                             foo();
         *            }
         *     else
         *         bar();
         * @param {ASTNode} node `BlockStatement` body with exactly one statement directly inside. The statement can have its own nested statements.
         * @returns {boolean} `true` if the braces are necessary - removing them (replacing the given `BlockStatement` body with its single statement content)
         * would change the semantics of the code or produce a syntax error.
         */
        function areBracesNecessary(node) {
            const statement = node.body[0];

            return isLexicalDeclaration(statement) ||
                hasUnsafeIf(statement) && isFollowedByElseKeyword(node);
        }

        /**
         * Prepares to check the body of a node to see if it's a block statement.
         * @param {ASTNode} node The node to report if there's a problem.
         * @param {ASTNode} body The body node to check for blocks.
         * @param {string} name The name to report if there's a problem.
         * @param {{ condition: boolean }} opts Options to pass to the report functions
         * @returns {Object} a prepared check object, with "actual", "expected", "check" properties.
         *   "actual" will be `true` or `false` whether the body is already a block statement.
         *   "expected" will be `true` or `false` if the body should be a block statement or not, or
         *   `null` if it doesn't matter, depending on the rule options. It can be modified to change
         *   the final behavior of "check".
         *   "check" will be a function reporting appropriate problems depending on the other
         *   properties.
         */
        function prepareCheck(node, body, name, opts) {
            const hasBlock = (body.type === "BlockStatement");
            let expected = null;

            if (hasBlock && (body.body.length !== 1 || areBracesNecessary(body))) {
                expected = true;
            } else if (multiOnly) {
                expected = false;
            } else if (multiLine) {
                if (!isCollapsedOneLiner(body)) {
                    expected = true;
                }

                // otherwise, the body is allowed to have braces or not to have braces

            } else if (multiOrNest) {
                if (hasBlock) {
                    const statement = body.body[0];
                    const leadingCommentsInBlock = sourceCode.getCommentsBefore(statement);

                    expected = !isOneLiner(statement) || leadingCommentsInBlock.length > 0;
                } else {
                    expected = !isOneLiner(body);
                }
            } else {

                // default "all"
                expected = true;
            }

            return {
                actual: hasBlock,
                expected,
                check() {
                    if (this.expected !== null && this.expected !== this.actual) {
                        if (this.expected) {
                            context.report({
                                node,
                                loc: body.loc,
                                messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter",
                                data: {
                                    name
                                },
                                fix: fixer => fixer.replaceText(body, `{${sourceCode.getText(body)}}`)
                            });
                        } else {
                            context.report({
                                node,
                                loc: body.loc,
                                messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter",
                                data: {
                                    name
                                },
                                fix(fixer) {

                                    /*
                                     * `do while` expressions sometimes need a space to be inserted after `do`.
                                     * e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)`
                                     */
                                    const needsPrecedingSpace = node.type === "DoWhileStatement" &&
                                        sourceCode.getTokenBefore(body).range[1] === body.range[0] &&
                                        !astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(body, { skip: 1 }));

                                    const openingBracket = sourceCode.getFirstToken(body);
                                    const closingBracket = sourceCode.getLastToken(body);
                                    const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket);

                                    if (needsSemicolon(closingBracket)) {

                                        /*
                                         * If removing braces would cause a SyntaxError due to multiple statements on the same line (or
                                         * change the semantics of the code due to ASI), don't perform a fix.
                                         */
                                        return null;
                                    }

                                    const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) +
                                        sourceCode.getText(lastTokenInBlock) +
                                        sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]);

                                    return fixer.replaceText(body, (needsPrecedingSpace ? " " : "") + resultingBodyText);
                                }
                            });
                        }
                    }
                }
            };
        }

        /**
         * Prepares to check the bodies of a "if", "else if" and "else" chain.
         * @param {ASTNode} node The first IfStatement node of the chain.
         * @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more
         *   information.
         */
        function prepareIfChecks(node) {
            const preparedChecks = [];

            for (let currentNode = node; currentNode; currentNode = currentNode.alternate) {
                preparedChecks.push(prepareCheck(currentNode, currentNode.consequent, "if", { condition: true }));
                if (currentNode.alternate && currentNode.alternate.type !== "IfStatement") {
                    preparedChecks.push(prepareCheck(currentNode, currentNode.alternate, "else"));
                    break;
                }
            }

            if (consistent) {

                /*
                 * If any node should have or already have braces, make sure they
                 * all have braces.
                 * If all nodes shouldn't have braces, make sure they don't.
                 */
                const expected = preparedChecks.some(preparedCheck => {
                    if (preparedCheck.expected !== null) {
                        return preparedCheck.expected;
                    }
                    return preparedCheck.actual;
                });

                preparedChecks.forEach(preparedCheck => {
                    preparedCheck.expected = expected;
                });
            }

            return preparedChecks;
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        return {
            IfStatement(node) {
                const parent = node.parent;
                const isElseIf = parent.type === "IfStatement" && parent.alternate === node;

                if (!isElseIf) {

                    // This is a top `if`, check the whole `if-else-if` chain
                    prepareIfChecks(node).forEach(preparedCheck => {
                        preparedCheck.check();
                    });
                }

                // Skip `else if`, it's already checked (when the top `if` was visited)
            },

            WhileStatement(node) {
                prepareCheck(node, node.body, "while", { condition: true }).check();
            },

            DoWhileStatement(node) {
                prepareCheck(node, node.body, "do").check();
            },

            ForStatement(node) {
                prepareCheck(node, node.body, "for", { condition: true }).check();
            },

            ForInStatement(node) {
                prepareCheck(node, node.body, "for-in").check();
            },

            ForOfStatement(node) {
                prepareCheck(node, node.body, "for-of").check();
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to enforce default clauses in switch statements to be last
 * @author Milos Djermanovic
 */

"use strict";

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce default clauses in switch statements to be last",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/default-case-last"
        },

        schema: [],

        messages: {
            notLast: "Default clause should be the last clause."
        }
    },

    create(context) {
        return {
            SwitchStatement(node) {
                const cases = node.cases,
                    indexOfDefault = cases.findIndex(c => c.test === null);

                if (indexOfDefault !== -1 && indexOfDefault !== cases.length - 1) {
                    const defaultClause = cases[indexOfDefault];

                    context.report({ node: defaultClause, messageId: "notLast" });
                }
            }
        };
    }
};


code:
/**
 * @fileoverview require default case in switch statements
 * @author Aliaksei Shytkin
 */
"use strict";

const DEFAULT_COMMENT_PATTERN = /^no default$/iu;

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

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Require `default` cases in `switch` statements",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/default-case"
        },

        schema: [{
            type: "object",
            properties: {
                commentPattern: {
                    type: "string"
                }
            },
            additionalProperties: false
        }],

        messages: {
            missingDefaultCase: "Expected a default case."
        }
    },

    create(context) {
        const options = context.options[0] || {};
        const commentPattern = options.commentPattern
            ? new RegExp(options.commentPattern, "u")
            : DEFAULT_COMMENT_PATTERN;

        const sourceCode = context.sourceCode;

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

        /**
         * Shortcut to get last element of array
         * @param {*[]} collection Array
         * @returns {any} Last element
         */
        function last(collection) {
            return collection[collection.length - 1];
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        return {

            SwitchStatement(node) {

                if (!node.cases.length) {

                    /*
                     * skip check of empty switch because there is no easy way
                     * to extract comments inside it now
                     */
                    return;
                }

                const hasDefault = node.cases.some(v => v.test === null);

                if (!hasDefault) {

                    let comment;

                    const lastCase = last(node.cases);
                    const comments = sourceCode.getCommentsAfter(lastCase);

                    if (comments.length) {
                        comment = last(comments);
                    }

                    if (!comment || !commentPattern.test(comment.value.trim())) {
                        context.report({ node, messageId: "missingDefaultCase" });
                    }
                }
            }
        };
    }
};


code:
/**
 * @fileoverview enforce default parameters to be last
 * @author Chiawen Chen
 */

"use strict";

/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce default parameters to be last",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/default-param-last"
        },

        schema: [],

        messages: {
            shouldBeLast: "Default parameters should be last."
        }
    },

    create(context) {

        /**
         * Handler for function contexts.
         * @param {ASTNode} node function node
         * @returns {void}
         */
        function handleFunction(node) {
            let hasSeenPlainParam = false;

            for (let i = node.params.length - 1; i >= 0; i -= 1) {
                const param = node.params[i];

                if (
                    param.type !== "AssignmentPattern" &&
                    param.type !== "RestElement"
                ) {
                    hasSeenPlainParam = true;
                    continue;
                }

                if (hasSeenPlainParam && param.type === "AssignmentPattern") {
                    context.report({
                        node: param,
                        messageId: "shouldBeLast"
                    });
                }
            }
        }

        return {
            FunctionDeclaration: handleFunction,
            FunctionExpression: handleFunction,
            ArrowFunctionExpression: handleFunction
        };
    }
};