code:
/**
 * @fileoverview Rule to flag non-quoted property names in object literals.
 * @author Mathias Bynens <http://mathiasbynens.be/>
 * @deprecated in ESLint v8.53.0
 */
"use strict";

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

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

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

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

        docs: {
            description: "Require quotes around object literal property names",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/quote-props"
        },

        schema: {
            anyOf: [
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
                        }
                    ],
                    minItems: 0,
                    maxItems: 1
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
                        },
                        {
                            type: "object",
                            properties: {
                                keywords: {
                                    type: "boolean"
                                },
                                unnecessary: {
                                    type: "boolean"
                                },
                                numbers: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                }
            ]
        },

        fixable: "code",
        messages: {
            requireQuotesDueToReservedWord: "Properties should be quoted as '{{property}}' is a reserved word.",
            inconsistentlyQuotedProperty: "Inconsistently quoted property '{{key}}' found.",
            unnecessarilyQuotedProperty: "Unnecessarily quoted property '{{property}}' found.",
            unquotedReservedProperty: "Unquoted reserved word '{{property}}' used as key.",
            unquotedNumericProperty: "Unquoted number literal '{{property}}' used as key.",
            unquotedPropertyFound: "Unquoted property '{{property}}' found.",
            redundantQuoting: "Properties shouldn't be quoted as all quotes are redundant."
        }
    },

    create(context) {

        const MODE = context.options[0],
            KEYWORDS = context.options[1] && context.options[1].keywords,
            CHECK_UNNECESSARY = !context.options[1] || context.options[1].unnecessary !== false,
            NUMBERS = context.options[1] && context.options[1].numbers,

            sourceCode = context.sourceCode;

        /**
         * Checks whether a certain string constitutes an ES3 token
         * @param {string} tokenStr The string to be checked.
         * @returns {boolean} `true` if it is an ES3 token.
         */
        function isKeyword(tokenStr) {
            return keywords.includes(tokenStr);
        }

        /**
         * Checks if an espree-tokenized key has redundant quotes (i.e. whether quotes are unnecessary)
         * @param {string} rawKey The raw key value from the source
         * @param {espreeTokens} tokens The espree-tokenized node key
         * @param {boolean} [skipNumberLiterals=false] Indicates whether number literals should be checked
         * @returns {boolean} Whether or not a key has redundant quotes.
         * @private
         */
        function areQuotesRedundant(rawKey, tokens, skipNumberLiterals) {
            return tokens.length === 1 && tokens[0].start === 0 && tokens[0].end === rawKey.length &&
                (["Identifier", "Keyword", "Null", "Boolean"].includes(tokens[0].type) ||
                (tokens[0].type === "Numeric" && !skipNumberLiterals && String(+tokens[0].value) === tokens[0].value));
        }

        /**
         * Returns a string representation of a property node with quotes removed
         * @param {ASTNode} key Key AST Node, which may or may not be quoted
         * @returns {string} A replacement string for this property
         */
        function getUnquotedKey(key) {
            return key.type === "Identifier" ? key.name : key.value;
        }

        /**
         * Returns a string representation of a property node with quotes added
         * @param {ASTNode} key Key AST Node, which may or may not be quoted
         * @returns {string} A replacement string for this property
         */
        function getQuotedKey(key) {
            if (key.type === "Literal" && typeof key.value === "string") {

                // If the key is already a string literal, don't replace the quotes with double quotes.
                return sourceCode.getText(key);
            }

            // Otherwise, the key is either an identifier or a number literal.
            return `"${key.type === "Identifier" ? key.name : key.value}"`;
        }

        /**
         * Ensures that a property's key is quoted only when necessary
         * @param {ASTNode} node Property AST node
         * @returns {void}
         */
        function checkUnnecessaryQuotes(node) {
            const key = node.key;

            if (node.method || node.computed || node.shorthand) {
                return;
            }

            if (key.type === "Literal" && typeof key.value === "string") {
                let tokens;

                try {
                    tokens = espree.tokenize(key.value);
                } catch {
                    return;
                }

                if (tokens.length !== 1) {
                    return;
                }

                const isKeywordToken = isKeyword(tokens[0].value);

                if (isKeywordToken && KEYWORDS) {
                    return;
                }

                if (CHECK_UNNECESSARY && areQuotesRedundant(key.value, tokens, NUMBERS)) {
                    context.report({
                        node,
                        messageId: "unnecessarilyQuotedProperty",
                        data: { property: key.value },
                        fix: fixer => fixer.replaceText(key, getUnquotedKey(key))
                    });
                }
            } else if (KEYWORDS && key.type === "Identifier" && isKeyword(key.name)) {
                context.report({
                    node,
                    messageId: "unquotedReservedProperty",
                    data: { property: key.name },
                    fix: fixer => fixer.replaceText(key, getQuotedKey(key))
                });
            } else if (NUMBERS && key.type === "Literal" && astUtils.isNumericLiteral(key)) {
                context.report({
                    node,
                    messageId: "unquotedNumericProperty",
                    data: { property: key.value },
                    fix: fixer => fixer.replaceText(key, getQuotedKey(key))
                });
            }
        }

        /**
         * Ensures that a property's key is quoted
         * @param {ASTNode} node Property AST node
         * @returns {void}
         */
        function checkOmittedQuotes(node) {
            const key = node.key;

            if (!node.method && !node.computed && !node.shorthand && !(key.type === "Literal" && typeof key.value === "string")) {
                context.report({
                    node,
                    messageId: "unquotedPropertyFound",
                    data: { property: key.name || key.value },
                    fix: fixer => fixer.replaceText(key, getQuotedKey(key))
                });
            }
        }

        /**
         * Ensures that an object's keys are consistently quoted, optionally checks for redundancy of quotes
         * @param {ASTNode} node Property AST node
         * @param {boolean} checkQuotesRedundancy Whether to check quotes' redundancy
         * @returns {void}
         */
        function checkConsistency(node, checkQuotesRedundancy) {
            const quotedProps = [],
                unquotedProps = [];
            let keywordKeyName = null,
                necessaryQuotes = false;

            node.properties.forEach(property => {
                const key = property.key;

                if (!key || property.method || property.computed || property.shorthand) {
                    return;
                }

                if (key.type === "Literal" && typeof key.value === "string") {

                    quotedProps.push(property);

                    if (checkQuotesRedundancy) {
                        let tokens;

                        try {
                            tokens = espree.tokenize(key.value);
                        } catch {
                            necessaryQuotes = true;
                            return;
                        }

                        necessaryQuotes = necessaryQuotes || !areQuotesRedundant(key.value, tokens) || KEYWORDS && isKeyword(tokens[0].value);
                    }
                } else if (KEYWORDS && checkQuotesRedundancy && key.type === "Identifier" && isKeyword(key.name)) {
                    unquotedProps.push(property);
                    necessaryQuotes = true;
                    keywordKeyName = key.name;
                } else {
                    unquotedProps.push(property);
                }
            });

            if (checkQuotesRedundancy && quotedProps.length && !necessaryQuotes) {
                quotedProps.forEach(property => {
                    context.report({
                        node: property,
                        messageId: "redundantQuoting",
                        fix: fixer => fixer.replaceText(property.key, getUnquotedKey(property.key))
                    });
                });
            } else if (unquotedProps.length && keywordKeyName) {
                unquotedProps.forEach(property => {
                    context.report({
                        node: property,
                        messageId: "requireQuotesDueToReservedWord",
                        data: { property: keywordKeyName },
                        fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key))
                    });
                });
            } else if (quotedProps.length && unquotedProps.length) {
                unquotedProps.forEach(property => {
                    context.report({
                        node: property,
                        messageId: "inconsistentlyQuotedProperty",
                        data: { key: property.key.name || property.key.value },
                        fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key))
                    });
                });
            }
        }

        return {
            Property(node) {
                if (MODE === "always" || !MODE) {
                    checkOmittedQuotes(node);
                }
                if (MODE === "as-needed") {
                    checkUnnecessaryQuotes(node);
                }
            },
            ObjectExpression(node) {
                if (MODE === "consistent") {
                    checkConsistency(node, false);
                }
                if (MODE === "consistent-as-needed") {
                    checkConsistency(node, true);
                }
            }
        };

    }
};


code:
/**
 * @fileoverview A rule to choose between single and double quote marks
 * @author Matt DuVall <http://www.mattduvall.com/>, Brandon Payton
 * @deprecated in ESLint v8.53.0
 */

"use strict";

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

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

//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------

const QUOTE_SETTINGS = {
    double: {
        quote: "\"",
        alternateQuote: "'",
        description: "doublequote"
    },
    single: {
        quote: "'",
        alternateQuote: "\"",
        description: "singlequote"
    },
    backtick: {
        quote: "`",
        alternateQuote: "\"",
        description: "backtick"
    }
};

// An unescaped newline is a newline preceded by an even number of backslashes.
const UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]`, "u");

/**
 * Switches quoting of javascript string between ' " and `
 * escaping and unescaping as necessary.
 * Only escaping of the minimal set of characters is changed.
 * Note: escaping of newlines when switching from backtick to other quotes is not handled.
 * @param {string} str A string to convert.
 * @returns {string} The string with changed quotes.
 * @private
 */
QUOTE_SETTINGS.double.convert =
QUOTE_SETTINGS.single.convert =
QUOTE_SETTINGS.backtick.convert = function(str) {
    const newQuote = this.quote;
    const oldQuote = str[0];

    if (newQuote === oldQuote) {
        return str;
    }
    return newQuote + str.slice(1, -1).replace(/\\(\$\{|\r\n?|\n|.)|["'`]|\$\{|(\r\n?|\n)/gu, (match, escaped, newline) => {
        if (escaped === oldQuote || oldQuote === "`" && escaped === "${") {
            return escaped; // unescape
        }
        if (match === newQuote || newQuote === "`" && match === "${") {
            return `\\${match}`; // escape
        }
        if (newline && oldQuote === "`") {
            return "\\n"; // escape newlines
        }
        return match;
    }) + newQuote;
};

const AVOID_ESCAPE = "avoid-escape";

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

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

        docs: {
            description: "Enforce the consistent use of either backticks, double, or single quotes",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/quotes"
        },

        fixable: "code",

        schema: [
            {
                enum: ["single", "double", "backtick"]
            },
            {
                anyOf: [
                    {
                        enum: ["avoid-escape"]
                    },
                    {
                        type: "object",
                        properties: {
                            avoidEscape: {
                                type: "boolean"
                            },
                            allowTemplateLiterals: {
                                type: "boolean"
                            }
                        },
                        additionalProperties: false
                    }
                ]
            }
        ],

        messages: {
            wrongQuotes: "Strings must use {{description}}."
        }
    },

    create(context) {

        const quoteOption = context.options[0],
            settings = QUOTE_SETTINGS[quoteOption || "double"],
            options = context.options[1],
            allowTemplateLiterals = options && options.allowTemplateLiterals === true,
            sourceCode = context.sourceCode;
        let avoidEscape = options && options.avoidEscape === true;

        // deprecated
        if (options === AVOID_ESCAPE) {
            avoidEscape = true;
        }

        /**
         * Determines if a given node is part of JSX syntax.
         *
         * This function returns `true` in the following cases:
         *
         * - `<div className="foo"></div>` ... If the literal is an attribute value, the parent of the literal is `JSXAttribute`.
         * - `<div>foo</div>` ... If the literal is a text content, the parent of the literal is `JSXElement`.
         * - `<>foo</>` ... If the literal is a text content, the parent of the literal is `JSXFragment`.
         *
         * In particular, this function returns `false` in the following cases:
         *
         * - `<div className={"foo"}></div>`
         * - `<div>{"foo"}</div>`
         *
         * In both cases, inside of the braces is handled as normal JavaScript.
         * The braces are `JSXExpressionContainer` nodes.
         * @param {ASTNode} node The Literal node to check.
         * @returns {boolean} True if the node is a part of JSX, false if not.
         * @private
         */
        function isJSXLiteral(node) {
            return node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment";
        }

        /**
         * Checks whether or not a given node is a directive.
         * The directive is a `ExpressionStatement` which has only a string literal not surrounded by
         * parentheses.
         * @param {ASTNode} node A node to check.
         * @returns {boolean} Whether or not the node is a directive.
         * @private
         */
        function isDirective(node) {
            return (
                node.type === "ExpressionStatement" &&
                node.expression.type === "Literal" &&
                typeof node.expression.value === "string" &&
                !astUtils.isParenthesised(sourceCode, node.expression)
            );
        }

        /**
         * Checks whether a specified node is either part of, or immediately follows a (possibly empty) directive prologue.
         * @see {@link http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive}
         * @param {ASTNode} node A node to check.
         * @returns {boolean} Whether a specified node is either part of, or immediately follows a (possibly empty) directive prologue.
         * @private
         */
        function isExpressionInOrJustAfterDirectivePrologue(node) {
            if (!astUtils.isTopLevelExpressionStatement(node.parent)) {
                return false;
            }
            const block = node.parent.parent;

            // Check the node is at a prologue.
            for (let i = 0; i < block.body.length; ++i) {
                const statement = block.body[i];

                if (statement === node.parent) {
                    return true;
                }
                if (!isDirective(statement)) {
                    break;
                }
            }

            return false;
        }

        /**
         * Checks whether or not a given node is allowed as non backtick.
         * @param {ASTNode} node A node to check.
         * @returns {boolean} Whether or not the node is allowed as non backtick.
         * @private
         */
        function isAllowedAsNonBacktick(node) {
            const parent = node.parent;

            switch (parent.type) {

                // Directive Prologues.
                case "ExpressionStatement":
                    return !astUtils.isParenthesised(sourceCode, node) && isExpressionInOrJustAfterDirectivePrologue(node);

                // LiteralPropertyName.
                case "Property":
                case "PropertyDefinition":
                case "MethodDefinition":
                    return parent.key === node && !parent.computed;

                // ModuleSpecifier.
                case "ImportDeclaration":
                case "ExportNamedDeclaration":
                    return parent.source === node;

                // ModuleExportName or ModuleSpecifier.
                case "ExportAllDeclaration":
                    return parent.exported === node || parent.source === node;

                // ModuleExportName.
                case "ImportSpecifier":
                    return parent.imported === node;

                // ModuleExportName.
                case "ExportSpecifier":
                    return parent.local === node || parent.exported === node;

                // Others don't allow.
                default:
                    return false;
            }
        }

        /**
         * Checks whether or not a given TemplateLiteral node is actually using any of the special features provided by template literal strings.
         * @param {ASTNode} node A TemplateLiteral node to check.
         * @returns {boolean} Whether or not the TemplateLiteral node is using any of the special features provided by template literal strings.
         * @private
         */
        function isUsingFeatureOfTemplateLiteral(node) {
            const hasTag = node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi;

            if (hasTag) {
                return true;
            }

            const hasStringInterpolation = node.expressions.length > 0;

            if (hasStringInterpolation) {
                return true;
            }

            const isMultilineString = node.quasis.length >= 1 && UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw);

            if (isMultilineString) {
                return true;
            }

            return false;
        }

        return {

            Literal(node) {
                const val = node.value,
                    rawVal = node.raw;

                if (settings && typeof val === "string") {
                    let isValid = (quoteOption === "backtick" && isAllowedAsNonBacktick(node)) ||
                        isJSXLiteral(node) ||
                        astUtils.isSurroundedBy(rawVal, settings.quote);

                    if (!isValid && avoidEscape) {
                        isValid = astUtils.isSurroundedBy(rawVal, settings.alternateQuote) && rawVal.includes(settings.quote);
                    }

                    if (!isValid) {
                        context.report({
                            node,
                            messageId: "wrongQuotes",
                            data: {
                                description: settings.description
                            },
                            fix(fixer) {
                                if (quoteOption === "backtick" && astUtils.hasOctalOrNonOctalDecimalEscapeSequence(rawVal)) {

                                    /*
                                     * An octal or non-octal decimal escape sequence in a template literal would
                                     * produce syntax error, even in non-strict mode.
                                     */
                                    return null;
                                }

                                return fixer.replaceText(node, settings.convert(node.raw));
                            }
                        });
                    }
                }
            },

            TemplateLiteral(node) {

                // Don't throw an error if backticks are expected or a template literal feature is in use.
                if (
                    allowTemplateLiterals ||
                    quoteOption === "backtick" ||
                    isUsingFeatureOfTemplateLiteral(node)
                ) {
                    return;
                }

                context.report({
                    node,
                    messageId: "wrongQuotes",
                    data: {
                        description: settings.description
                    },
                    fix(fixer) {
                        if (astUtils.isTopLevelExpressionStatement(node.parent) && !astUtils.isParenthesised(sourceCode, node)) {

                            /*
                             * TemplateLiterals aren't actually directives, but fixing them might turn
                             * them into directives and change the behavior of the code.
                             */
                            return null;
                        }
                        return fixer.replaceText(node, settings.convert(sourceCode.getText(node)));
                    }
                });
            }
        };

    }
};

license: mit


code:
/**
 * @fileoverview Rule to flag use of parseInt without a radix argument
 * @author James Allardice
 */

"use strict";

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

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

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

const MODE_ALWAYS = "always",
    MODE_AS_NEEDED = "as-needed";

const validRadixValues = new Set(Array.from({ length: 37 - 2 }, (_, index) => index + 2));

/**
 * Checks whether a given variable is shadowed or not.
 * @param {eslint-scope.Variable} variable A variable to check.
 * @returns {boolean} `true` if the variable is shadowed.
 */
function isShadowed(variable) {
    return variable.defs.length >= 1;
}

/**
 * Checks whether a given node is a MemberExpression of `parseInt` method or not.
 * @param {ASTNode} node A node to check.
 * @returns {boolean} `true` if the node is a MemberExpression of `parseInt`
 *      method.
 */
function isParseIntMethod(node) {
    return (
        node.type === "MemberExpression" &&
        !node.computed &&
        node.property.type === "Identifier" &&
        node.property.name === "parseInt"
    );
}

/**
 * Checks whether a given node is a valid value of radix or not.
 *
 * The following values are invalid.
 *
 * - A literal except integers between 2 and 36.
 * - undefined.
 * @param {ASTNode} radix A node of radix to check.
 * @returns {boolean} `true` if the node is valid.
 */
function isValidRadix(radix) {
    return !(
        (radix.type === "Literal" && !validRadixValues.has(radix.value)) ||
        (radix.type === "Identifier" && radix.name === "undefined")
    );
}

/**
 * Checks whether a given node is a default value of radix or not.
 * @param {ASTNode} radix A node of radix to check.
 * @returns {boolean} `true` if the node is the literal node of `10`.
 */
function isDefaultRadix(radix) {
    return radix.type === "Literal" && radix.value === 10;
}

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

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

        docs: {
            description: "Enforce the consistent use of the radix argument when using `parseInt()`",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/radix"
        },

        hasSuggestions: true,

        schema: [
            {
                enum: ["always", "as-needed"]
            }
        ],

        messages: {
            missingParameters: "Missing parameters.",
            redundantRadix: "Redundant radix parameter.",
            missingRadix: "Missing radix parameter.",
            invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36.",
            addRadixParameter10: "Add radix parameter `10` for parsing decimal numbers."
        }
    },

    create(context) {
        const mode = context.options[0] || MODE_ALWAYS;
        const sourceCode = context.sourceCode;

        /**
         * Checks the arguments of a given CallExpression node and reports it if it
         * offends this rule.
         * @param {ASTNode} node A CallExpression node to check.
         * @returns {void}
         */
        function checkArguments(node) {
            const args = node.arguments;

            switch (args.length) {
                case 0:
                    context.report({
                        node,
                        messageId: "missingParameters"
                    });
                    break;

                case 1:
                    if (mode === MODE_ALWAYS) {
                        context.report({
                            node,
                            messageId: "missingRadix",
                            suggest: [
                                {
                                    messageId: "addRadixParameter10",
                                    fix(fixer) {
                                        const tokens = sourceCode.getTokens(node);
                                        const lastToken = tokens[tokens.length - 1]; // Parenthesis.
                                        const secondToLastToken = tokens[tokens.length - 2]; // May or may not be a comma.
                                        const hasTrailingComma = secondToLastToken.type === "Punctuator" && secondToLastToken.value === ",";

                                        return fixer.insertTextBefore(lastToken, hasTrailingComma ? " 10," : ", 10");
                                    }
                                }
                            ]
                        });
                    }
                    break;

                default:
                    if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) {
                        context.report({
                            node,
                            messageId: "redundantRadix"
                        });
                    } else if (!isValidRadix(args[1])) {
                        context.report({
                            node,
                            messageId: "invalidRadix"
                        });
                    }
                    break;
            }
        }

        return {
            "Program:exit"(node) {
                const scope = sourceCode.getScope(node);
                let variable;

                // Check `parseInt()`
                variable = astUtils.getVariableByName(scope, "parseInt");
                if (variable && !isShadowed(variable)) {
                    variable.references.forEach(reference => {
                        const idNode = reference.identifier;

                        if (astUtils.isCallee(idNode)) {
                            checkArguments(idNode.parent);
                        }
                    });
                }

                // Check `Number.parseInt()`
                variable = astUtils.getVariableByName(scope, "Number");
                if (variable && !isShadowed(variable)) {
                    variable.references.forEach(reference => {
                        const parentNode = reference.identifier.parent;
                        const maybeCallee = parentNode.parent.type === "ChainExpression"
                            ? parentNode.parent
                            : parentNode;

                        if (isParseIntMethod(parentNode) && astUtils.isCallee(maybeCallee)) {
                            checkArguments(maybeCallee.parent);
                        }
                    });
                }
            }
        };
    }
};


code:
/**
 * @fileoverview disallow assignments that can lead to race conditions due to usage of `await` or `yield`
 * @author Teddy Katz
 * @author Toru Nagashima
 */
"use strict";

/**
 * Make the map from identifiers to each reference.
 * @param {escope.Scope} scope The scope to get references.
 * @param {Map<Identifier, escope.Reference>} [outReferenceMap] The map from identifier nodes to each reference object.
 * @returns {Map<Identifier, escope.Reference>} `referenceMap`.
 */
function createReferenceMap(scope, outReferenceMap = new Map()) {
    for (const reference of scope.references) {
        if (reference.resolved === null) {
            continue;
        }

        outReferenceMap.set(reference.identifier, reference);
    }
    for (const childScope of scope.childScopes) {
        if (childScope.type !== "function") {
            createReferenceMap(childScope, outReferenceMap);
        }
    }

    return outReferenceMap;
}

/**
 * Get `reference.writeExpr` of a given reference.
 * If it's the read reference of MemberExpression in LHS, returns RHS in order to address `a.b = await a`
 * @param {escope.Reference} reference The reference to get.
 * @returns {Expression|null} The `reference.writeExpr`.
 */
function getWriteExpr(reference) {
    if (reference.writeExpr) {
        return reference.writeExpr;
    }
    let node = reference.identifier;

    while (node) {
        const t = node.parent.type;

        if (t === "AssignmentExpression" && node.parent.left === node) {
            return node.parent.right;
        }
        if (t === "MemberExpression" && node.parent.object === node) {
            node = node.parent;
            continue;
        }

        break;
    }

    return null;
}

/**
 * Checks if an expression is a variable that can only be observed within the given function.
 * @param {Variable|null} variable The variable to check
 * @param {boolean} isMemberAccess If `true` then this is a member access.
 * @returns {boolean} `true` if the variable is local to the given function, and is never referenced in a closure.
 */
function isLocalVariableWithoutEscape(variable, isMemberAccess) {
    if (!variable) {
        return false; // A global variable which was not defined.
    }

    // If the reference is a property access and the variable is a parameter, it handles the variable is not local.
    if (isMemberAccess && variable.defs.some(d => d.type === "Parameter")) {
        return false;
    }

    const functionScope = variable.scope.variableScope;

    return variable.references.every(reference =>
        reference.from.variableScope === functionScope);
}

/**
 * Represents segment information.
 */
class SegmentInfo {
    constructor() {
        this.info = new WeakMap();
    }

    /**
     * Initialize the segment information.
     * @param {PathSegment} segment The segment to initialize.
     * @returns {void}
     */
    initialize(segment) {
        const outdatedReadVariables = new Set();
        const freshReadVariables = new Set();

        for (const prevSegment of segment.prevSegments) {
            const info = this.info.get(prevSegment);

            if (info) {
                info.outdatedReadVariables.forEach(Set.prototype.add, outdatedReadVariables);
                info.freshReadVariables.forEach(Set.prototype.add, freshReadVariables);
            }
        }

        this.info.set(segment, { outdatedReadVariables, freshReadVariables });
    }

    /**
     * Mark a given variable as read on given segments.
     * @param {PathSegment[]} segments The segments that it read the variable on.
     * @param {Variable} variable The variable to be read.
     * @returns {void}
     */
    markAsRead(segments, variable) {
        for (const segment of segments) {
            const info = this.info.get(segment);

            if (info) {
                info.freshReadVariables.add(variable);

                // If a variable is freshly read again, then it's no more out-dated.
                info.outdatedReadVariables.delete(variable);
            }
        }
    }

    /**
     * Move `freshReadVariables` to `outdatedReadVariables`.
     * @param {PathSegment[]} segments The segments to process.
     * @returns {void}
     */
    makeOutdated(segments) {
        for (const segment of segments) {
            const info = this.info.get(segment);

            if (info) {
                info.freshReadVariables.forEach(Set.prototype.add, info.outdatedReadVariables);
                info.freshReadVariables.clear();
            }
        }
    }

    /**
     * Check if a given variable is outdated on the current segments.
     * @param {PathSegment[]} segments The current segments.
     * @param {Variable} variable The variable to check.
     * @returns {boolean} `true` if the variable is outdated on the segments.
     */
    isOutdated(segments, variable) {
        for (const segment of segments) {
            const info = this.info.get(segment);

            if (info && info.outdatedReadVariables.has(variable)) {
                return true;
            }
        }
        return false;
    }
}

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

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

        docs: {
            description: "Disallow assignments that can lead to race conditions due to usage of `await` or `yield`",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/require-atomic-updates"
        },

        fixable: null,

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

        messages: {
            nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`.",
            nonAtomicObjectUpdate: "Possible race condition: `{{value}}` might be assigned based on an outdated state of `{{object}}`."
        }
    },

    create(context) {
        const allowProperties = !!context.options[0] && context.options[0].allowProperties;

        const sourceCode = context.sourceCode;
        const assignmentReferences = new Map();
        const segmentInfo = new SegmentInfo();
        let stack = null;

        return {
            onCodePathStart(codePath, node) {
                const scope = sourceCode.getScope(node);
                const shouldVerify =
                    scope.type === "function" &&
                    (scope.block.async || scope.block.generator);

                stack = {
                    upper: stack,
                    codePath,
                    referenceMap: shouldVerify ? createReferenceMap(scope) : null,
                    currentSegments: new Set()
                };
            },
            onCodePathEnd() {
                stack = stack.upper;
            },

            // Initialize the segment information.
            onCodePathSegmentStart(segment) {
                segmentInfo.initialize(segment);
                stack.currentSegments.add(segment);
            },

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

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

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

            // Handle references to prepare verification.
            Identifier(node) {
                const { referenceMap } = stack;
                const reference = referenceMap && referenceMap.get(node);

                // Ignore if this is not a valid variable reference.
                if (!reference) {
                    return;
                }
                const variable = reference.resolved;
                const writeExpr = getWriteExpr(reference);
                const isMemberAccess = reference.identifier.parent.type === "MemberExpression";

                // Add a fresh read variable.
                if (reference.isRead() && !(writeExpr && writeExpr.parent.operator === "=")) {
                    segmentInfo.markAsRead(stack.currentSegments, variable);
                }

                /*
                 * Register the variable to verify after ESLint traversed the `writeExpr` node
                 * if this reference is an assignment to a variable which is referred from other closure.
                 */
                if (writeExpr &&
                    writeExpr.parent.right === writeExpr && // ← exclude variable declarations.
                    !isLocalVariableWithoutEscape(variable, isMemberAccess)
                ) {
                    let refs = assignmentReferences.get(writeExpr);

                    if (!refs) {
                        refs = [];
                        assignmentReferences.set(writeExpr, refs);
                    }

                    refs.push(reference);
                }
            },

            /*
             * Verify assignments.
             * If the reference exists in `outdatedReadVariables` list, report it.
             */
            ":expression:exit"(node) {

                // referenceMap exists if this is in a resumable function scope.
                if (!stack.referenceMap) {
                    return;
                }

                // Mark the read variables on this code path as outdated.
                if (node.type === "AwaitExpression" || node.type === "YieldExpression") {
                    segmentInfo.makeOutdated(stack.currentSegments);
                }

                // Verify.
                const references = assignmentReferences.get(node);

                if (references) {
                    assignmentReferences.delete(node);

                    for (const reference of references) {
                        const variable = reference.resolved;

                        if (segmentInfo.isOutdated(stack.currentSegments, variable)) {
                            if (node.parent.left === reference.identifier) {
                                context.report({
                                    node: node.parent,
                                    messageId: "nonAtomicUpdate",
                                    data: {
                                        value: variable.name
                                    }
                                });
                            } else if (!allowProperties) {
                                context.report({
                                    node: node.parent,
                                    messageId: "nonAtomicObjectUpdate",
                                    data: {
                                        value: sourceCode.getText(node.parent.left),
                                        object: variable.name
                                    }
                                });
                            }

                        }
                    }
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to disallow async functions which have no `await` expression.
 * @author Toru Nagashima
 */

"use strict";

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

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

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

/**
 * Capitalize the 1st letter of the given text.
 * @param {string} text The text to capitalize.
 * @returns {string} The text that the 1st letter was capitalized.
 */
function capitalizeFirstLetter(text) {
    return text[0].toUpperCase() + text.slice(1);
}

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

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

        docs: {
            description: "Disallow async functions which have no `await` expression",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/require-await"
        },

        schema: [],

        messages: {
            missingAwait: "{{name}} has no 'await' expression."
        }
    },

    create(context) {
        const sourceCode = context.sourceCode;
        let scopeInfo = null;

        /**
         * Push the scope info object to the stack.
         * @returns {void}
         */
        function enterFunction() {
            scopeInfo = {
                upper: scopeInfo,
                hasAwait: false
            };
        }

        /**
         * Pop the top scope info object from the stack.
         * Also, it reports the function if needed.
         * @param {ASTNode} node The node to report.
         * @returns {void}
         */
        function exitFunction(node) {
            if (!node.generator && node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) {
                context.report({
                    node,
                    loc: astUtils.getFunctionHeadLoc(node, sourceCode),
                    messageId: "missingAwait",
                    data: {
                        name: capitalizeFirstLetter(
                            astUtils.getFunctionNameWithKind(node)
                        )
                    }
                });
            }

            scopeInfo = scopeInfo.upper;
        }

        return {
            FunctionDeclaration: enterFunction,
            FunctionExpression: enterFunction,
            ArrowFunctionExpression: enterFunction,
            "FunctionDeclaration:exit": exitFunction,
            "FunctionExpression:exit": exitFunction,
            "ArrowFunctionExpression:exit": exitFunction,

            AwaitExpression() {
                if (!scopeInfo) {
                    return;
                }

                scopeInfo.hasAwait = true;
            },
            ForOfStatement(node) {
                if (!scopeInfo) {
                    return;
                }

                if (node.await) {
                    scopeInfo.hasAwait = true;
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to check for jsdoc presence.
 * @author Gyandeep Singh
 * @deprecated in ESLint v5.10.0
 */
"use strict";

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

        docs: {
            description: "Require JSDoc comments",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/require-jsdoc"
        },

        schema: [
            {
                type: "object",
                properties: {
                    require: {
                        type: "object",
                        properties: {
                            ClassDeclaration: {
                                type: "boolean",
                                default: false
                            },
                            MethodDefinition: {
                                type: "boolean",
                                default: false
                            },
                            FunctionDeclaration: {
                                type: "boolean",
                                default: true
                            },
                            ArrowFunctionExpression: {
                                type: "boolean",
                                default: false
                            },
                            FunctionExpression: {
                                type: "boolean",
                                default: false
                            }
                        },
                        additionalProperties: false,
                        default: {}
                    }
                },
                additionalProperties: false
            }
        ],

        deprecated: true,
        replacedBy: [],

        messages: {
            missingJSDocComment: "Missing JSDoc comment."
        }
    },

    create(context) {
        const source = context.sourceCode;
        const DEFAULT_OPTIONS = {
            FunctionDeclaration: true,
            MethodDefinition: false,
            ClassDeclaration: false,
            ArrowFunctionExpression: false,
            FunctionExpression: false
        };
        const options = Object.assign(DEFAULT_OPTIONS, context.options[0] && context.options[0].require);

        /**
         * Report the error message
         * @param {ASTNode} node node to report
         * @returns {void}
         */
        function report(node) {
            context.report({ node, messageId: "missingJSDocComment" });
        }

        /**
         * Check if the jsdoc comment is present or not.
         * @param {ASTNode} node node to examine
         * @returns {void}
         */
        function checkJsDoc(node) {
            const jsdocComment = source.getJSDocComment(node);

            if (!jsdocComment) {
                report(node);
            }
        }

        return {
            FunctionDeclaration(node) {
                if (options.FunctionDeclaration) {
                    checkJsDoc(node);
                }
            },
            FunctionExpression(node) {
                if (
                    (options.MethodDefinition && node.parent.type === "MethodDefinition") ||
                    (options.FunctionExpression && (node.parent.type === "VariableDeclarator" || (node.parent.type === "Property" && node === node.parent.value)))
                ) {
                    checkJsDoc(node);
                }
            },
            ClassDeclaration(node) {
                if (options.ClassDeclaration) {
                    checkJsDoc(node);
                }
            },
            ArrowFunctionExpression(node) {
                if (options.ArrowFunctionExpression && node.parent.type === "VariableDeclarator") {
                    checkJsDoc(node);
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to enforce the use of `u` flag on RegExp.
 * @author Toru Nagashima
 */

"use strict";

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

const {
    CALL,
    CONSTRUCT,
    ReferenceTracker,
    getStringIfConstant
} = require("@eslint-community/eslint-utils");
const astUtils = require("./utils/ast-utils.js");
const { isValidWithUnicodeFlag } = require("./utils/regular-expressions");

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

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

        docs: {
            description: "Enforce the use of `u` or `v` flag on RegExp",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/require-unicode-regexp"
        },

        hasSuggestions: true,

        messages: {
            addUFlag: "Add the 'u' flag.",
            requireUFlag: "Use the 'u' flag."
        },

        schema: []
    },

    create(context) {

        const sourceCode = context.sourceCode;

        return {
            "Literal[regex]"(node) {
                const flags = node.regex.flags || "";

                if (!flags.includes("u") && !flags.includes("v")) {
                    context.report({
                        messageId: "requireUFlag",
                        node,
                        suggest: isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, node.regex.pattern)
                            ? [
                                {
                                    fix(fixer) {
                                        return fixer.insertTextAfter(node, "u");
                                    },
                                    messageId: "addUFlag"
                                }
                            ]
                            : null
                    });
                }
            },

            Program(node) {
                const scope = sourceCode.getScope(node);
                const tracker = new ReferenceTracker(scope);
                const trackMap = {
                    RegExp: { [CALL]: true, [CONSTRUCT]: true }
                };

                for (const { node: refNode } of tracker.iterateGlobalReferences(trackMap)) {
                    const [patternNode, flagsNode] = refNode.arguments;

                    if (patternNode && patternNode.type === "SpreadElement") {
                        continue;
                    }
                    const pattern = getStringIfConstant(patternNode, scope);
                    const flags = getStringIfConstant(flagsNode, scope);

                    if (!flagsNode || (typeof flags === "string" && !flags.includes("u") && !flags.includes("v"))) {
                        context.report({
                            messageId: "requireUFlag",
                            node: refNode,
                            suggest: typeof pattern === "string" && isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, pattern)
                                ? [
                                    {
                                        fix(fixer) {
                                            if (flagsNode) {
                                                if ((flagsNode.type === "Literal" && typeof flagsNode.value === "string") || flagsNode.type === "TemplateLiteral") {
                                                    const flagsNodeText = sourceCode.getText(flagsNode);

                                                    return fixer.replaceText(flagsNode, [
                                                        flagsNodeText.slice(0, flagsNodeText.length - 1),
                                                        flagsNodeText.slice(flagsNodeText.length - 1)
                                                    ].join("u"));
                                                }

                                                // We intentionally don't suggest concatenating + "u" to non-literals
                                                return null;
                                            }

                                            const penultimateToken = sourceCode.getLastToken(refNode, { skip: 1 }); // skip closing parenthesis

                                            return fixer.insertTextAfter(
                                                penultimateToken,
                                                astUtils.isCommaToken(penultimateToken)
                                                    ? ' "u",'
                                                    : ', "u"'
                                            );
                                        },
                                        messageId: "addUFlag"
                                    }
                                ]
                                : null
                        });
                    }
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to flag the generator functions that does not have yield.
 * @author Toru Nagashima
 */

"use strict";

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

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

        docs: {
            description: "Require generator functions to contain `yield`",
            recommended: true,
            url: "https://eslint.org/docs/latest/rules/require-yield"
        },

        schema: [],

        messages: {
            missingYield: "This generator function does not have 'yield'."
        }
    },

    create(context) {
        const stack = [];

        /**
         * If the node is a generator function, start counting `yield` keywords.
         * @param {Node} node A function node to check.
         * @returns {void}
         */
        function beginChecking(node) {
            if (node.generator) {
                stack.push(0);
            }
        }

        /**
         * If the node is a generator function, end counting `yield` keywords, then
         * reports result.
         * @param {Node} node A function node to check.
         * @returns {void}
         */
        function endChecking(node) {
            if (!node.generator) {
                return;
            }

            const countYield = stack.pop();

            if (countYield === 0 && node.body.body.length > 0) {
                context.report({ node, messageId: "missingYield" });
            }
        }

        return {
            FunctionDeclaration: beginChecking,
            "FunctionDeclaration:exit": endChecking,
            FunctionExpression: beginChecking,
            "FunctionExpression:exit": endChecking,

            // Increases the count of `yield` keyword.
            YieldExpression() {

                if (stack.length > 0) {
                    stack[stack.length - 1] += 1;
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Enforce spacing between rest and spread operators and their expressions.
 * @author Kai Cataldo
 * @deprecated in ESLint v8.53.0
 */

"use strict";

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

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

        docs: {
            description: "Enforce spacing between rest and spread operators and their expressions",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/rest-spread-spacing"
        },

        fixable: "whitespace",

        schema: [
            {
                enum: ["always", "never"]
            }
        ],

        messages: {
            unexpectedWhitespace: "Unexpected whitespace after {{type}} operator.",
            expectedWhitespace: "Expected whitespace after {{type}} operator."
        }
    },

    create(context) {
        const sourceCode = context.sourceCode,
            alwaysSpace = context.options[0] === "always";

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

        /**
         * Checks whitespace between rest/spread operators and their expressions
         * @param {ASTNode} node The node to check
         * @returns {void}
         */
        function checkWhiteSpace(node) {
            const operator = sourceCode.getFirstToken(node),
                nextToken = sourceCode.getTokenAfter(operator),
                hasWhitespace = sourceCode.isSpaceBetweenTokens(operator, nextToken);
            let type;

            switch (node.type) {
                case "SpreadElement":
                    type = "spread";
                    if (node.parent.type === "ObjectExpression") {
                        type += " property";
                    }
                    break;
                case "RestElement":
                    type = "rest";
                    if (node.parent.type === "ObjectPattern") {
                        type += " property";
                    }
                    break;
                case "ExperimentalSpreadProperty":
                    type = "spread property";
                    break;
                case "ExperimentalRestProperty":
                    type = "rest property";
                    break;
                default:
                    return;
            }

            if (alwaysSpace && !hasWhitespace) {
                context.report({
                    node,
                    loc: operator.loc,
                    messageId: "expectedWhitespace",
                    data: {
                        type
                    },
                    fix(fixer) {
                        return fixer.replaceTextRange([operator.range[1], nextToken.range[0]], " ");
                    }
                });
            } else if (!alwaysSpace && hasWhitespace) {
                context.report({
                    node,
                    loc: {
                        start: operator.loc.end,
                        end: nextToken.loc.start
                    },
                    messageId: "unexpectedWhitespace",
                    data: {
                        type
                    },
                    fix(fixer) {
                        return fixer.removeRange([operator.range[1], nextToken.range[0]]);
                    }
                });
            }
        }

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

        return {
            SpreadElement: checkWhiteSpace,
            RestElement: checkWhiteSpace,
            ExperimentalSpreadProperty: checkWhiteSpace,
            ExperimentalRestProperty: checkWhiteSpace
        };
    }
};


code:
/**
 * @fileoverview Validates spacing before and after semicolon
 * @author Mathias Schreck
 * @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 semicolons",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/semi-spacing"
        },

        fixable: "whitespace",

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

        messages: {
            unexpectedWhitespaceBefore: "Unexpected whitespace before semicolon.",
            unexpectedWhitespaceAfter: "Unexpected whitespace after semicolon.",
            missingWhitespaceBefore: "Missing whitespace before semicolon.",
            missingWhitespaceAfter: "Missing whitespace after semicolon."
        }
    },

    create(context) {

        const config = context.options[0],
            sourceCode = context.sourceCode;
        let requireSpaceBefore = false,
            requireSpaceAfter = true;

        if (typeof config === "object") {
            requireSpaceBefore = config.before;
            requireSpaceAfter = config.after;
        }

        /**
         * Checks if a given token has leading whitespace.
         * @param {Object} token The token to check.
         * @returns {boolean} True if the given token has leading space, false if not.
         */
        function hasLeadingSpace(token) {
            const tokenBefore = sourceCode.getTokenBefore(token);

            return tokenBefore && astUtils.isTokenOnSameLine(tokenBefore, token) && sourceCode.isSpaceBetweenTokens(tokenBefore, token);
        }

        /**
         * Checks if a given token has trailing whitespace.
         * @param {Object} token The token to check.
         * @returns {boolean} True if the given token has trailing space, false if not.
         */
        function hasTrailingSpace(token) {
            const tokenAfter = sourceCode.getTokenAfter(token);

            return tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter) && sourceCode.isSpaceBetweenTokens(token, tokenAfter);
        }

        /**
         * Checks if the given token is the last token in its line.
         * @param {Token} token The token to check.
         * @returns {boolean} Whether or not the token is the last in its line.
         */
        function isLastTokenInCurrentLine(token) {
            const tokenAfter = sourceCode.getTokenAfter(token);

            return !(tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter));
        }

        /**
         * Checks if the given token is the first token in its line
         * @param {Token} token The token to check.
         * @returns {boolean} Whether or not the token is the first in its line.
         */
        function isFirstTokenInCurrentLine(token) {
            const tokenBefore = sourceCode.getTokenBefore(token);

            return !(tokenBefore && astUtils.isTokenOnSameLine(token, tokenBefore));
        }

        /**
         * Checks if the next token of a given token is a closing parenthesis.
         * @param {Token} token The token to check.
         * @returns {boolean} Whether or not the next token of a given token is a closing parenthesis.
         */
        function isBeforeClosingParen(token) {
            const nextToken = sourceCode.getTokenAfter(token);

            return (nextToken && astUtils.isClosingBraceToken(nextToken) || astUtils.isClosingParenToken(nextToken));
        }

        /**
         * Report location example :
         *
         * for unexpected space `before`
         *
         * var a = 'b'   ;
         *            ^^^
         *
         * for unexpected space `after`
         *
         * var a = 'b';  c = 10;
         *             ^^
         *
         * Reports if the given token has invalid spacing.
         * @param {Token} token The semicolon token to check.
         * @param {ASTNode} node The corresponding node of the token.
         * @returns {void}
         */
        function checkSemicolonSpacing(token, node) {
            if (astUtils.isSemicolonToken(token)) {
                if (hasLeadingSpace(token)) {
                    if (!requireSpaceBefore) {
                        const tokenBefore = sourceCode.getTokenBefore(token);
                        const loc = {
                            start: tokenBefore.loc.end,
                            end: token.loc.start
                        };

                        context.report({
                            node,
                            loc,
                            messageId: "unexpectedWhitespaceBefore",
                            fix(fixer) {

                                return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
                            }
                        });
                    }
                } else {
                    if (requireSpaceBefore) {
                        const loc = token.loc;

                        context.report({
                            node,
                            loc,
                            messageId: "missingWhitespaceBefore",
                            fix(fixer) {
                                return fixer.insertTextBefore(token, " ");
                            }
                        });
                    }
                }

                if (!isFirstTokenInCurrentLine(token) && !isLastTokenInCurrentLine(token) && !isBeforeClosingParen(token)) {
                    if (hasTrailingSpace(token)) {
                        if (!requireSpaceAfter) {
                            const tokenAfter = sourceCode.getTokenAfter(token);
                            const loc = {
                                start: token.loc.end,
                                end: tokenAfter.loc.start
                            };

                            context.report({
                                node,
                                loc,
                                messageId: "unexpectedWhitespaceAfter",
                                fix(fixer) {

                                    return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
                                }
                            });
                        }
                    } else {
                        if (requireSpaceAfter) {
                            const loc = token.loc;

                            context.report({
                                node,
                                loc,
                                messageId: "missingWhitespaceAfter",
                                fix(fixer) {
                                    return fixer.insertTextAfter(token, " ");
                                }
                            });
                        }
                    }
                }
            }
        }

        /**
         * Checks the spacing of the semicolon with the assumption that the last token is the semicolon.
         * @param {ASTNode} node The node to check.
         * @returns {void}
         */
        function checkNode(node) {
            const token = sourceCode.getLastToken(node);

            checkSemicolonSpacing(token, node);
        }

        return {
            VariableDeclaration: checkNode,
            ExpressionStatement: checkNode,
            BreakStatement: checkNode,
            ContinueStatement: checkNode,
            DebuggerStatement: checkNode,
            DoWhileStatement: checkNode,
            ReturnStatement: checkNode,
            ThrowStatement: checkNode,
            ImportDeclaration: checkNode,
            ExportNamedDeclaration: checkNode,
            ExportAllDeclaration: checkNode,
            ExportDefaultDeclaration: checkNode,
            ForStatement(node) {
                if (node.init) {
                    checkSemicolonSpacing(sourceCode.getTokenAfter(node.init), node);
                }

                if (node.test) {
                    checkSemicolonSpacing(sourceCode.getTokenAfter(node.test), node);
                }
            },
            PropertyDefinition: checkNode
        };
    }
};


code:
/**
 * @fileoverview Rule to enforce location of semicolons.
 * @author Toru Nagashima
 * @deprecated in ESLint v8.53.0
 */

"use strict";

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

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

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

const SELECTOR = [
    "BreakStatement", "ContinueStatement", "DebuggerStatement",
    "DoWhileStatement", "ExportAllDeclaration",
    "ExportDefaultDeclaration", "ExportNamedDeclaration",
    "ExpressionStatement", "ImportDeclaration", "ReturnStatement",
    "ThrowStatement", "VariableDeclaration", "PropertyDefinition"
].join(",");

/**
 * Get the child node list of a given node.
 * This returns `BlockStatement#body`, `StaticBlock#body`, `Program#body`,
 * `ClassBody#body`, or `SwitchCase#consequent`.
 * This is used to check whether a node is the first/last child.
 * @param {Node} node A node to get child node list.
 * @returns {Node[]|null} The child node list.
 */
function getChildren(node) {
    const t = node.type;

    if (
        t === "BlockStatement" ||
        t === "StaticBlock" ||
        t === "Program" ||
        t === "ClassBody"
    ) {
        return node.body;
    }
    if (t === "SwitchCase") {
        return node.consequent;
    }
    return null;
}

/**
 * Check whether a given node is the last statement in the parent block.
 * @param {Node} node A node to check.
 * @returns {boolean} `true` if the node is the last statement in the parent block.
 */
function isLastChild(node) {
    const t = node.parent.type;

    if (t === "IfStatement" && node.parent.consequent === node && node.parent.alternate) { // before `else` keyword.
        return true;
    }
    if (t === "DoWhileStatement") { // before `while` keyword.
        return true;
    }
    const nodeList = getChildren(node.parent);

    return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc.
}

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

        docs: {
            description: "Enforce location of semicolons",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/semi-style"
        },

        schema: [{ enum: ["last", "first"] }],
        fixable: "whitespace",

        messages: {
            expectedSemiColon: "Expected this semicolon to be at {{pos}}."
        }
    },

    create(context) {
        const sourceCode = context.sourceCode;
        const option = context.options[0] || "last";

        /**
         * Check the given semicolon token.
         * @param {Token} semiToken The semicolon token to check.
         * @param {"first"|"last"} expected The expected location to check.
         * @returns {void}
         */
        function check(semiToken, expected) {
            const prevToken = sourceCode.getTokenBefore(semiToken);
            const nextToken = sourceCode.getTokenAfter(semiToken);
            const prevIsSameLine = !prevToken || astUtils.isTokenOnSameLine(prevToken, semiToken);
            const nextIsSameLine = !nextToken || astUtils.isTokenOnSameLine(semiToken, nextToken);

            if ((expected === "last" && !prevIsSameLine) || (expected === "first" && !nextIsSameLine)) {
                context.report({
                    loc: semiToken.loc,
                    messageId: "expectedSemiColon",
                    data: {
                        pos: (expected === "last")
                            ? "the end of the previous line"
                            : "the beginning of the next line"
                    },
                    fix(fixer) {
                        if (prevToken && nextToken && sourceCode.commentsExistBetween(prevToken, nextToken)) {
                            return null;
                        }

                        const start = prevToken ? prevToken.range[1] : semiToken.range[0];
                        const end = nextToken ? nextToken.range[0] : semiToken.range[1];
                        const text = (expected === "last") ? ";\n" : "\n;";

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

        return {
            [SELECTOR](node) {
                if (option === "first" && isLastChild(node)) {
                    return;
                }

                const lastToken = sourceCode.getLastToken(node);

                if (astUtils.isSemicolonToken(lastToken)) {
                    check(lastToken, option);
                }
            },

            ForStatement(node) {
                const firstSemi = node.init && sourceCode.getTokenAfter(node.init, astUtils.isSemicolonToken);
                const secondSemi = node.test && sourceCode.getTokenAfter(node.test, astUtils.isSemicolonToken);

                if (firstSemi) {
                    check(firstSemi, "last");
                }
                if (secondSemi) {
                    check(secondSemi, "last");
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to flag missing semicolons.
 * @author Nicholas C. Zakas
 * @deprecated in ESLint v8.53.0
 */
"use strict";

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

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

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

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

        docs: {
            description: "Require or disallow semicolons instead of ASI",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/semi"
        },

        fixable: "code",

        schema: {
            anyOf: [
                {
                    type: "array",
                    items: [
                        {
                            enum: ["never"]
                        },
                        {
                            type: "object",
                            properties: {
                                beforeStatementContinuationChars: {
                                    enum: ["always", "any", "never"]
                                }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always"]
                        },
                        {
                            type: "object",
                            properties: {
                                omitLastInOneLineBlock: { type: "boolean" },
                                omitLastInOneLineClassBody: { type: "boolean" }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                }
            ]
        },

        messages: {
            missingSemi: "Missing semicolon.",
            extraSemi: "Extra semicolon."
        }
    },

    create(context) {

        const OPT_OUT_PATTERN = /^[-[(/+`]/u; // One of [(/+-`
        const unsafeClassFieldNames = new Set(["get", "set", "static"]);
        const unsafeClassFieldFollowers = new Set(["*", "in", "instanceof"]);
        const options = context.options[1];
        const never = context.options[0] === "never";
        const exceptOneLine = Boolean(options && options.omitLastInOneLineBlock);
        const exceptOneLineClassBody = Boolean(options && options.omitLastInOneLineClassBody);
        const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars || "any";
        const sourceCode = context.sourceCode;

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

        /**
         * Reports a semicolon error with appropriate location and message.
         * @param {ASTNode} node The node with an extra or missing semicolon.
         * @param {boolean} missing True if the semicolon is missing.
         * @returns {void}
         */
        function report(node, missing) {
            const lastToken = sourceCode.getLastToken(node);
            let messageId,
                fix,
                loc;

            if (!missing) {
                messageId = "missingSemi";
                loc = {
                    start: lastToken.loc.end,
                    end: astUtils.getNextLocation(sourceCode, lastToken.loc.end)
                };
                fix = function(fixer) {
                    return fixer.insertTextAfter(lastToken, ";");
                };
            } else {
                messageId = "extraSemi";
                loc = lastToken.loc;
                fix = function(fixer) {

                    /*
                     * Expand the replacement range to include the surrounding
                     * tokens to avoid conflicting with no-extra-semi.
                     * https://github.com/eslint/eslint/issues/7928
                     */
                    return new FixTracker(fixer, sourceCode)
                        .retainSurroundingTokens(lastToken)
                        .remove(lastToken);
                };
            }

            context.report({
                node,
                loc,
                messageId,
                fix
            });

        }

        /**
         * Check whether a given semicolon token is redundant.
         * @param {Token} semiToken A semicolon token to check.
         * @returns {boolean} `true` if the next token is `;` or `}`.
         */
        function isRedundantSemi(semiToken) {
            const nextToken = sourceCode.getTokenAfter(semiToken);

            return (
                !nextToken ||
                astUtils.isClosingBraceToken(nextToken) ||
                astUtils.isSemicolonToken(nextToken)
            );
        }

        /**
         * Check whether a given token is the closing brace of an arrow function.
         * @param {Token} lastToken A token to check.
         * @returns {boolean} `true` if the token is the closing brace of an arrow function.
         */
        function isEndOfArrowBlock(lastToken) {
            if (!astUtils.isClosingBraceToken(lastToken)) {
                return false;
            }
            const node = sourceCode.getNodeByRangeIndex(lastToken.range[0]);

            return (
                node.type === "BlockStatement" &&
                node.parent.type === "ArrowFunctionExpression"
            );
        }

        /**
         * Checks if a given PropertyDefinition node followed by a semicolon
         * can safely remove that semicolon. It is not to safe to remove if
         * the class field name is "get", "set", or "static", or if
         * followed by a generator method.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} `true` if the node cannot have the semicolon
         *      removed.
         */
        function maybeClassFieldAsiHazard(node) {

            if (node.type !== "PropertyDefinition") {
                return false;
            }

            /*
             * Computed property names and non-identifiers are always safe
             * as they can be distinguished from keywords easily.
             */
            const needsNameCheck = !node.computed && node.key.type === "Identifier";

            /*
             * Certain names are problematic unless they also have a
             * a way to distinguish between keywords and property
             * names.
             */
            if (needsNameCheck && unsafeClassFieldNames.has(node.key.name)) {

                /*
                 * Special case: If the field name is `static`,
                 * it is only valid if the field is marked as static,
                 * so "static static" is okay but "static" is not.
                 */
                const isStaticStatic = node.static && node.key.name === "static";

                /*
                 * For other unsafe names, we only care if there is no
                 * initializer. No initializer = hazard.
                 */
                if (!isStaticStatic && !node.value) {
                    return true;
                }
            }

            const followingToken = sourceCode.getTokenAfter(node);

            return unsafeClassFieldFollowers.has(followingToken.value);
        }

        /**
         * Check whether a given node is on the same line with the next token.
         * @param {Node} node A statement node to check.
         * @returns {boolean} `true` if the node is on the same line with the next token.
         */
        function isOnSameLineWithNextToken(node) {
            const prevToken = sourceCode.getLastToken(node, 1);
            const nextToken = sourceCode.getTokenAfter(node);

            return !!nextToken && astUtils.isTokenOnSameLine(prevToken, nextToken);
        }

        /**
         * Check whether a given node can connect the next line if the next line is unreliable.
         * @param {Node} node A statement node to check.
         * @returns {boolean} `true` if the node can connect the next line.
         */
        function maybeAsiHazardAfter(node) {
            const t = node.type;

            if (t === "DoWhileStatement" ||
                t === "BreakStatement" ||
                t === "ContinueStatement" ||
                t === "DebuggerStatement" ||
                t === "ImportDeclaration" ||
                t === "ExportAllDeclaration"
            ) {
                return false;
            }
            if (t === "ReturnStatement") {
                return Boolean(node.argument);
            }
            if (t === "ExportNamedDeclaration") {
                return Boolean(node.declaration);
            }
            if (isEndOfArrowBlock(sourceCode.getLastToken(node, 1))) {
                return false;
            }

            return true;
        }

        /**
         * Check whether a given token can connect the previous statement.
         * @param {Token} token A token to check.
         * @returns {boolean} `true` if the token is one of `[`, `(`, `/`, `+`, `-`, ```, `++`, and `--`.
         */
        function maybeAsiHazardBefore(token) {
            return (
                Boolean(token) &&
                OPT_OUT_PATTERN.test(token.value) &&
                token.value !== "++" &&
                token.value !== "--"
            );
        }

        /**
         * Check if the semicolon of a given node is unnecessary, only true if:
         *   - next token is a valid statement divider (`;` or `}`).
         *   - next token is on a new line and the node is not connectable to the new line.
         * @param {Node} node A statement node to check.
         * @returns {boolean} whether the semicolon is unnecessary.
         */
        function canRemoveSemicolon(node) {
            if (isRedundantSemi(sourceCode.getLastToken(node))) {
                return true; // `;;` or `;}`
            }
            if (maybeClassFieldAsiHazard(node)) {
                return false;
            }
            if (isOnSameLineWithNextToken(node)) {
                return false; // One liner.
            }

            // continuation characters should not apply to class fields
            if (
                node.type !== "PropertyDefinition" &&
                beforeStatementContinuationChars === "never" &&
                !maybeAsiHazardAfter(node)
            ) {
                return true; // ASI works. This statement doesn't connect to the next.
            }
            if (!maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) {
                return true; // ASI works. The next token doesn't connect to this statement.
            }

            return false;
        }

        /**
         * Checks a node to see if it's the last item in a one-liner block.
         * Block is any `BlockStatement` or `StaticBlock` node. Block is a one-liner if its
         * braces (and consequently everything between them) are on the same line.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} whether the node is the last item in a one-liner block.
         */
        function isLastInOneLinerBlock(node) {
            const parent = node.parent;
            const nextToken = sourceCode.getTokenAfter(node);

            if (!nextToken || nextToken.value !== "}") {
                return false;
            }

            if (parent.type === "BlockStatement") {
                return parent.loc.start.line === parent.loc.end.line;
            }

            if (parent.type === "StaticBlock") {
                const openingBrace = sourceCode.getFirstToken(parent, { skip: 1 }); // skip the `static` token

                return openingBrace.loc.start.line === parent.loc.end.line;
            }

            return false;
        }

        /**
         * Checks a node to see if it's the last item in a one-liner `ClassBody` node.
         * ClassBody is a one-liner if its braces (and consequently everything between them) are on the same line.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} whether the node is the last item in a one-liner ClassBody.
         */
        function isLastInOneLinerClassBody(node) {
            const parent = node.parent;
            const nextToken = sourceCode.getTokenAfter(node);

            if (!nextToken || nextToken.value !== "}") {
                return false;
            }

            if (parent.type === "ClassBody") {
                return parent.loc.start.line === parent.loc.end.line;
            }

            return false;
        }

        /**
         * Checks a node to see if it's followed by a semicolon.
         * @param {ASTNode} node The node to check.
         * @returns {void}
         */
        function checkForSemicolon(node) {
            const isSemi = astUtils.isSemicolonToken(sourceCode.getLastToken(node));

            if (never) {
                if (isSemi && canRemoveSemicolon(node)) {
                    report(node, true);
                } else if (
                    !isSemi && beforeStatementContinuationChars === "always" &&
                    node.type !== "PropertyDefinition" &&
                    maybeAsiHazardBefore(sourceCode.getTokenAfter(node))
                ) {
                    report(node);
                }
            } else {
                const oneLinerBlock = (exceptOneLine && isLastInOneLinerBlock(node));
                const oneLinerClassBody = (exceptOneLineClassBody && isLastInOneLinerClassBody(node));
                const oneLinerBlockOrClassBody = oneLinerBlock || oneLinerClassBody;

                if (isSemi && oneLinerBlockOrClassBody) {
                    report(node, true);
                } else if (!isSemi && !oneLinerBlockOrClassBody) {
                    report(node);
                }
            }
        }

        /**
         * Checks to see if there's a semicolon after a variable declaration.
         * @param {ASTNode} node The node to check.
         * @returns {void}
         */
        function checkForSemicolonForVariableDeclaration(node) {
            const parent = node.parent;

            if ((parent.type !== "ForStatement" || parent.init !== node) &&
                (!/^For(?:In|Of)Statement/u.test(parent.type) || parent.left !== node)
            ) {
                checkForSemicolon(node);
            }
        }

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

        return {
            VariableDeclaration: checkForSemicolonForVariableDeclaration,
            ExpressionStatement: checkForSemicolon,
            ReturnStatement: checkForSemicolon,
            ThrowStatement: checkForSemicolon,
            DoWhileStatement: checkForSemicolon,
            DebuggerStatement: checkForSemicolon,
            BreakStatement: checkForSemicolon,
            ContinueStatement: checkForSemicolon,
            ImportDeclaration: checkForSemicolon,
            ExportAllDeclaration: checkForSemicolon,
            ExportNamedDeclaration(node) {
                if (!node.declaration) {
                    checkForSemicolon(node);
                }
            },
            ExportDefaultDeclaration(node) {
                if (!/(?:Class|Function)Declaration/u.test(node.declaration.type)) {
                    checkForSemicolon(node);
                }
            },
            PropertyDefinition: checkForSemicolon
        };

    }
};