code:
/**
 * @fileoverview A rule to control the style of variable initializations.
 * @author Colin Ihrig
 */

"use strict";

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

/**
 * Checks whether or not a given node is a for loop.
 * @param {ASTNode} block A node to check.
 * @returns {boolean} `true` when the node is a for loop.
 */
function isForLoop(block) {
    return block.type === "ForInStatement" ||
    block.type === "ForOfStatement" ||
    block.type === "ForStatement";
}

/**
 * Checks whether or not a given declarator node has its initializer.
 * @param {ASTNode} node A declarator node to check.
 * @returns {boolean} `true` when the node has its initializer.
 */
function isInitialized(node) {
    const declaration = node.parent;
    const block = declaration.parent;

    if (isForLoop(block)) {
        if (block.type === "ForStatement") {
            return block.init === declaration;
        }
        return block.left === declaration;
    }
    return Boolean(node.init);
}

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

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

        docs: {
            description: "Require or disallow initialization in variable declarations",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/init-declarations"
        },

        schema: {
            anyOf: [
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always"]
                        }
                    ],
                    minItems: 0,
                    maxItems: 1
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["never"]
                        },
                        {
                            type: "object",
                            properties: {
                                ignoreForLoopInit: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        }
                    ],
                    minItems: 0,
                    maxItems: 2
                }
            ]
        },
        messages: {
            initialized: "Variable '{{idName}}' should be initialized on declaration.",
            notInitialized: "Variable '{{idName}}' should not be initialized on declaration."
        }
    },

    create(context) {

        const MODE_ALWAYS = "always",
            MODE_NEVER = "never";

        const mode = context.options[0] || MODE_ALWAYS;
        const params = context.options[1] || {};

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

        return {
            "VariableDeclaration:exit"(node) {

                const kind = node.kind,
                    declarations = node.declarations;

                for (let i = 0; i < declarations.length; ++i) {
                    const declaration = declarations[i],
                        id = declaration.id,
                        initialized = isInitialized(declaration),
                        isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent);
                    let messageId = "";

                    if (mode === MODE_ALWAYS && !initialized) {
                        messageId = "initialized";
                    } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) {
                        messageId = "notInitialized";
                    }

                    if (id.type === "Identifier" && messageId) {
                        context.report({
                            node: declaration,
                            messageId,
                            data: {
                                idName: id.name
                            }
                        });
                    }
                }
            }
        };
    }
};


code:
/**
 * @fileoverview A rule to ensure consistent quotes used in jsx syntax.
 * @author Mathias Schreck <https://github.com/lo1tuma>
 * @deprecated in ESLint v8.53.0
 */

"use strict";

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

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

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

const QUOTE_SETTINGS = {
    "prefer-double": {
        quote: "\"",
        description: "singlequote",
        convert(str) {
            return str.replace(/'/gu, "\"");
        }
    },
    "prefer-single": {
        quote: "'",
        description: "doublequote",
        convert(str) {
            return str.replace(/"/gu, "'");
        }
    }
};

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

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

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

        fixable: "whitespace",

        schema: [
            {
                enum: ["prefer-single", "prefer-double"]
            }
        ],
        messages: {
            unexpected: "Unexpected usage of {{description}}."
        }
    },

    create(context) {
        const quoteOption = context.options[0] || "prefer-double",
            setting = QUOTE_SETTINGS[quoteOption];

        /**
         * Checks if the given string literal node uses the expected quotes
         * @param {ASTNode} node A string literal node.
         * @returns {boolean} Whether or not the string literal used the expected quotes.
         * @public
         */
        function usesExpectedQuotes(node) {
            return node.value.includes(setting.quote) || astUtils.isSurroundedBy(node.raw, setting.quote);
        }

        return {
            JSXAttribute(node) {
                const attributeValue = node.value;

                if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) {
                    context.report({
                        node: attributeValue,
                        messageId: "unexpected",
                        data: {
                            description: setting.description
                        },
                        fix(fixer) {
                            return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw));
                        }
                    });
                }
            }
        };
    }
};

license: mit


code:
/**
 * @fileoverview Rule to specify spacing of object literal keys and values
 * @author Brandon Mills
 * @deprecated in ESLint v8.53.0
 */
"use strict";

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

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

/**
 * Checks whether a string contains a line terminator as defined in
 * http://www.ecma-international.org/ecma-262/5.1/#sec-7.3
 * @param {string} str String to test.
 * @returns {boolean} True if str contains a line terminator.
 */
function containsLineTerminator(str) {
    return astUtils.LINEBREAK_MATCHER.test(str);
}

/**
 * Gets the last element of an array.
 * @param {Array} arr An array.
 * @returns {any} Last element of arr.
 */
function last(arr) {
    return arr[arr.length - 1];
}

/**
 * Checks whether a node is contained on a single line.
 * @param {ASTNode} node AST Node being evaluated.
 * @returns {boolean} True if the node is a single line.
 */
function isSingleLine(node) {
    return (node.loc.end.line === node.loc.start.line);
}

/**
 * Checks whether the properties on a single line.
 * @param {ASTNode[]} properties List of Property AST nodes.
 * @returns {boolean} True if all properties is on a single line.
 */
function isSingleLineProperties(properties) {
    const [firstProp] = properties,
        lastProp = last(properties);

    return firstProp.loc.start.line === lastProp.loc.end.line;
}

/**
 * Initializes a single option property from the configuration with defaults for undefined values
 * @param {Object} toOptions Object to be initialized
 * @param {Object} fromOptions Object to be initialized from
 * @returns {Object} The object with correctly initialized options and values
 */
function initOptionProperty(toOptions, fromOptions) {
    toOptions.mode = fromOptions.mode || "strict";

    // Set value of beforeColon
    if (typeof fromOptions.beforeColon !== "undefined") {
        toOptions.beforeColon = +fromOptions.beforeColon;
    } else {
        toOptions.beforeColon = 0;
    }

    // Set value of afterColon
    if (typeof fromOptions.afterColon !== "undefined") {
        toOptions.afterColon = +fromOptions.afterColon;
    } else {
        toOptions.afterColon = 1;
    }

    // Set align if exists
    if (typeof fromOptions.align !== "undefined") {
        if (typeof fromOptions.align === "object") {
            toOptions.align = fromOptions.align;
        } else { // "string"
            toOptions.align = {
                on: fromOptions.align,
                mode: toOptions.mode,
                beforeColon: toOptions.beforeColon,
                afterColon: toOptions.afterColon
            };
        }
    }

    return toOptions;
}

/**
 * Initializes all the option values (singleLine, multiLine and align) from the configuration with defaults for undefined values
 * @param {Object} toOptions Object to be initialized
 * @param {Object} fromOptions Object to be initialized from
 * @returns {Object} The object with correctly initialized options and values
 */
function initOptions(toOptions, fromOptions) {
    if (typeof fromOptions.align === "object") {

        // Initialize the alignment configuration
        toOptions.align = initOptionProperty({}, fromOptions.align);
        toOptions.align.on = fromOptions.align.on || "colon";
        toOptions.align.mode = fromOptions.align.mode || "strict";

        toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions));
        toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions));

    } else { // string or undefined
        toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions));
        toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions));

        // If alignment options are defined in multiLine, pull them out into the general align configuration
        if (toOptions.multiLine.align) {
            toOptions.align = {
                on: toOptions.multiLine.align.on,
                mode: toOptions.multiLine.align.mode || toOptions.multiLine.mode,
                beforeColon: toOptions.multiLine.align.beforeColon,
                afterColon: toOptions.multiLine.align.afterColon
            };
        }
    }

    return toOptions;
}

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

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

        docs: {
            description: "Enforce consistent spacing between keys and values in object literal properties",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/key-spacing"
        },

        fixable: "whitespace",

        schema: [{
            anyOf: [
                {
                    type: "object",
                    properties: {
                        align: {
                            anyOf: [
                                {
                                    enum: ["colon", "value"]
                                },
                                {
                                    type: "object",
                                    properties: {
                                        mode: {
                                            enum: ["strict", "minimum"]
                                        },
                                        on: {
                                            enum: ["colon", "value"]
                                        },
                                        beforeColon: {
                                            type: "boolean"
                                        },
                                        afterColon: {
                                            type: "boolean"
                                        }
                                    },
                                    additionalProperties: false
                                }
                            ]
                        },
                        mode: {
                            enum: ["strict", "minimum"]
                        },
                        beforeColon: {
                            type: "boolean"
                        },
                        afterColon: {
                            type: "boolean"
                        }
                    },
                    additionalProperties: false
                },
                {
                    type: "object",
                    properties: {
                        singleLine: {
                            type: "object",
                            properties: {
                                mode: {
                                    enum: ["strict", "minimum"]
                                },
                                beforeColon: {
                                    type: "boolean"
                                },
                                afterColon: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        },
                        multiLine: {
                            type: "object",
                            properties: {
                                align: {
                                    anyOf: [
                                        {
                                            enum: ["colon", "value"]
                                        },
                                        {
                                            type: "object",
                                            properties: {
                                                mode: {
                                                    enum: ["strict", "minimum"]
                                                },
                                                on: {
                                                    enum: ["colon", "value"]
                                                },
                                                beforeColon: {
                                                    type: "boolean"
                                                },
                                                afterColon: {
                                                    type: "boolean"
                                                }
                                            },
                                            additionalProperties: false
                                        }
                                    ]
                                },
                                mode: {
                                    enum: ["strict", "minimum"]
                                },
                                beforeColon: {
                                    type: "boolean"
                                },
                                afterColon: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        }
                    },
                    additionalProperties: false
                },
                {
                    type: "object",
                    properties: {
                        singleLine: {
                            type: "object",
                            properties: {
                                mode: {
                                    enum: ["strict", "minimum"]
                                },
                                beforeColon: {
                                    type: "boolean"
                                },
                                afterColon: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        },
                        multiLine: {
                            type: "object",
                            properties: {
                                mode: {
                                    enum: ["strict", "minimum"]
                                },
                                beforeColon: {
                                    type: "boolean"
                                },
                                afterColon: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        },
                        align: {
                            type: "object",
                            properties: {
                                mode: {
                                    enum: ["strict", "minimum"]
                                },
                                on: {
                                    enum: ["colon", "value"]
                                },
                                beforeColon: {
                                    type: "boolean"
                                },
                                afterColon: {
                                    type: "boolean"
                                }
                            },
                            additionalProperties: false
                        }
                    },
                    additionalProperties: false
                }
            ]
        }],
        messages: {
            extraKey: "Extra space after {{computed}}key '{{key}}'.",
            extraValue: "Extra space before value for {{computed}}key '{{key}}'.",
            missingKey: "Missing space after {{computed}}key '{{key}}'.",
            missingValue: "Missing space before value for {{computed}}key '{{key}}'."
        }
    },

    create(context) {

        /**
         * OPTIONS
         * "key-spacing": [2, {
         *     beforeColon: false,
         *     afterColon: true,
         *     align: "colon" // Optional, or "value"
         * }
         */
        const options = context.options[0] || {},
            ruleOptions = initOptions({}, options),
            multiLineOptions = ruleOptions.multiLine,
            singleLineOptions = ruleOptions.singleLine,
            alignmentOptions = ruleOptions.align || null;

        const sourceCode = context.sourceCode;

        /**
         * Determines if the given property is key-value property.
         * @param {ASTNode} property Property node to check.
         * @returns {boolean} Whether the property is a key-value property.
         */
        function isKeyValueProperty(property) {
            return !(
                (property.method ||
                property.shorthand ||
                property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadElement"
            );
        }

        /**
         * Starting from the given node (a property.key node here) looks forward
         * until it finds the colon punctuator and returns it.
         * @param {ASTNode} node The node to start looking from.
         * @returns {ASTNode} The colon punctuator.
         */
        function getNextColon(node) {
            return sourceCode.getTokenAfter(node, astUtils.isColonToken);
        }

        /**
         * Starting from the given node (a property.key node here) looks forward
         * until it finds the last token before a colon punctuator and returns it.
         * @param {ASTNode} node The node to start looking from.
         * @returns {ASTNode} The last token before a colon punctuator.
         */
        function getLastTokenBeforeColon(node) {
            const colonToken = getNextColon(node);

            return sourceCode.getTokenBefore(colonToken);
        }

        /**
         * Starting from the given node (a property.key node here) looks forward
         * until it finds the first token after a colon punctuator and returns it.
         * @param {ASTNode} node The node to start looking from.
         * @returns {ASTNode} The first token after a colon punctuator.
         */
        function getFirstTokenAfterColon(node) {
            const colonToken = getNextColon(node);

            return sourceCode.getTokenAfter(colonToken);
        }

        /**
         * Checks whether a property is a member of the property group it follows.
         * @param {ASTNode} lastMember The last Property known to be in the group.
         * @param {ASTNode} candidate The next Property that might be in the group.
         * @returns {boolean} True if the candidate property is part of the group.
         */
        function continuesPropertyGroup(lastMember, candidate) {
            const groupEndLine = lastMember.loc.start.line,
                candidateValueStartLine = (isKeyValueProperty(candidate) ? getFirstTokenAfterColon(candidate.key) : candidate).loc.start.line;

            if (candidateValueStartLine - groupEndLine <= 1) {
                return true;
            }

            /*
             * Check that the first comment is adjacent to the end of the group, the
             * last comment is adjacent to the candidate property, and that successive
             * comments are adjacent to each other.
             */
            const leadingComments = sourceCode.getCommentsBefore(candidate);

            if (
                leadingComments.length &&
                leadingComments[0].loc.start.line - groupEndLine <= 1 &&
                candidateValueStartLine - last(leadingComments).loc.end.line <= 1
            ) {
                for (let i = 1; i < leadingComments.length; i++) {
                    if (leadingComments[i].loc.start.line - leadingComments[i - 1].loc.end.line > 1) {
                        return false;
                    }
                }
                return true;
            }

            return false;
        }

        /**
         * Gets an object literal property's key as the identifier name or string value.
         * @param {ASTNode} property Property node whose key to retrieve.
         * @returns {string} The property's key.
         */
        function getKey(property) {
            const key = property.key;

            if (property.computed) {
                return sourceCode.getText().slice(key.range[0], key.range[1]);
            }
            return astUtils.getStaticPropertyName(property);
        }

        /**
         * Reports an appropriately-formatted error if spacing is incorrect on one
         * side of the colon.
         * @param {ASTNode} property Key-value pair in an object literal.
         * @param {string} side Side being verified - either "key" or "value".
         * @param {string} whitespace Actual whitespace string.
         * @param {int} expected Expected whitespace length.
         * @param {string} mode Value of the mode as "strict" or "minimum"
         * @returns {void}
         */
        function report(property, side, whitespace, expected, mode) {
            const diff = whitespace.length - expected;

            if ((
                diff && mode === "strict" ||
                diff < 0 && mode === "minimum" ||
                diff > 0 && !expected && mode === "minimum") &&
                !(expected && containsLineTerminator(whitespace))
            ) {
                const nextColon = getNextColon(property.key),
                    tokenBeforeColon = sourceCode.getTokenBefore(nextColon, { includeComments: true }),
                    tokenAfterColon = sourceCode.getTokenAfter(nextColon, { includeComments: true }),
                    isKeySide = side === "key",
                    isExtra = diff > 0,
                    diffAbs = Math.abs(diff),
                    spaces = Array(diffAbs + 1).join(" ");

                const locStart = isKeySide ? tokenBeforeColon.loc.end : nextColon.loc.start;
                const locEnd = isKeySide ? nextColon.loc.start : tokenAfterColon.loc.start;
                const missingLoc = isKeySide ? tokenBeforeColon.loc : tokenAfterColon.loc;
                const loc = isExtra ? { start: locStart, end: locEnd } : missingLoc;

                let fix;

                if (isExtra) {
                    let range;

                    // Remove whitespace
                    if (isKeySide) {
                        range = [tokenBeforeColon.range[1], tokenBeforeColon.range[1] + diffAbs];
                    } else {
                        range = [tokenAfterColon.range[0] - diffAbs, tokenAfterColon.range[0]];
                    }
                    fix = function(fixer) {
                        return fixer.removeRange(range);
                    };
                } else {

                    // Add whitespace
                    if (isKeySide) {
                        fix = function(fixer) {
                            return fixer.insertTextAfter(tokenBeforeColon, spaces);
                        };
                    } else {
                        fix = function(fixer) {
                            return fixer.insertTextBefore(tokenAfterColon, spaces);
                        };
                    }
                }

                let messageId = "";

                if (isExtra) {
                    messageId = side === "key" ? "extraKey" : "extraValue";
                } else {
                    messageId = side === "key" ? "missingKey" : "missingValue";
                }

                context.report({
                    node: property[side],
                    loc,
                    messageId,
                    data: {
                        computed: property.computed ? "computed " : "",
                        key: getKey(property)
                    },
                    fix
                });
            }
        }

        /**
         * Gets the number of characters in a key, including quotes around string
         * keys and braces around computed property keys.
         * @param {ASTNode} property Property of on object literal.
         * @returns {int} Width of the key.
         */
        function getKeyWidth(property) {
            const startToken = sourceCode.getFirstToken(property);
            const endToken = getLastTokenBeforeColon(property.key);

            return getGraphemeCount(sourceCode.getText().slice(startToken.range[0], endToken.range[1]));
        }

        /**
         * Gets the whitespace around the colon in an object literal property.
         * @param {ASTNode} property Property node from an object literal.
         * @returns {Object} Whitespace before and after the property's colon.
         */
        function getPropertyWhitespace(property) {
            const whitespace = /(\s*):(\s*)/u.exec(sourceCode.getText().slice(
                property.key.range[1], property.value.range[0]
            ));

            if (whitespace) {
                return {
                    beforeColon: whitespace[1],
                    afterColon: whitespace[2]
                };
            }
            return null;
        }

        /**
         * Creates groups of properties.
         * @param {ASTNode} node ObjectExpression node being evaluated.
         * @returns {Array<ASTNode[]>} Groups of property AST node lists.
         */
        function createGroups(node) {
            if (node.properties.length === 1) {
                return [node.properties];
            }

            return node.properties.reduce((groups, property) => {
                const currentGroup = last(groups),
                    prev = last(currentGroup);

                if (!prev || continuesPropertyGroup(prev, property)) {
                    currentGroup.push(property);
                } else {
                    groups.push([property]);
                }

                return groups;
            }, [
                []
            ]);
        }

        /**
         * Verifies correct vertical alignment of a group of properties.
         * @param {ASTNode[]} properties List of Property AST nodes.
         * @returns {void}
         */
        function verifyGroupAlignment(properties) {
            const length = properties.length,
                widths = properties.map(getKeyWidth), // Width of keys, including quotes
                align = alignmentOptions.on; // "value" or "colon"
            let targetWidth = Math.max(...widths),
                beforeColon, afterColon, mode;

            if (alignmentOptions && length > 1) { // When aligning values within a group, use the alignment configuration.
                beforeColon = alignmentOptions.beforeColon;
                afterColon = alignmentOptions.afterColon;
                mode = alignmentOptions.mode;
            } else {
                beforeColon = multiLineOptions.beforeColon;
                afterColon = multiLineOptions.afterColon;
                mode = alignmentOptions.mode;
            }

            // Conditionally include one space before or after colon
            targetWidth += (align === "colon" ? beforeColon : afterColon);

            for (let i = 0; i < length; i++) {
                const property = properties[i];
                const whitespace = getPropertyWhitespace(property);

                if (whitespace) { // Object literal getters/setters lack a colon
                    const width = widths[i];

                    if (align === "value") {
                        report(property, "key", whitespace.beforeColon, beforeColon, mode);
                        report(property, "value", whitespace.afterColon, targetWidth - width, mode);
                    } else { // align = "colon"
                        report(property, "key", whitespace.beforeColon, targetWidth - width, mode);
                        report(property, "value", whitespace.afterColon, afterColon, mode);
                    }
                }
            }
        }

        /**
         * Verifies spacing of property conforms to specified options.
         * @param {ASTNode} node Property node being evaluated.
         * @param {Object} lineOptions Configured singleLine or multiLine options
         * @returns {void}
         */
        function verifySpacing(node, lineOptions) {
            const actual = getPropertyWhitespace(node);

            if (actual) { // Object literal getters/setters lack colons
                report(node, "key", actual.beforeColon, lineOptions.beforeColon, lineOptions.mode);
                report(node, "value", actual.afterColon, lineOptions.afterColon, lineOptions.mode);
            }
        }

        /**
         * Verifies spacing of each property in a list.
         * @param {ASTNode[]} properties List of Property AST nodes.
         * @param {Object} lineOptions Configured singleLine or multiLine options
         * @returns {void}
         */
        function verifyListSpacing(properties, lineOptions) {
            const length = properties.length;

            for (let i = 0; i < length; i++) {
                verifySpacing(properties[i], lineOptions);
            }
        }

        /**
         * Verifies vertical alignment, taking into account groups of properties.
         * @param {ASTNode} node ObjectExpression node being evaluated.
         * @returns {void}
         */
        function verifyAlignment(node) {
            createGroups(node).forEach(group => {
                const properties = group.filter(isKeyValueProperty);

                if (properties.length > 0 && isSingleLineProperties(properties)) {
                    verifyListSpacing(properties, multiLineOptions);
                } else {
                    verifyGroupAlignment(properties);
                }
            });
        }

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

        if (alignmentOptions) { // Verify vertical alignment

            return {
                ObjectExpression(node) {
                    if (isSingleLine(node)) {
                        verifyListSpacing(node.properties.filter(isKeyValueProperty), singleLineOptions);
                    } else {
                        verifyAlignment(node);
                    }
                }
            };

        }

        // Obey beforeColon and afterColon in each property as configured
        return {
            Property(node) {
                verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions);
            }
        };

    }
};


code:
/**
 * @fileoverview Rule to enforce spacing before and after keywords.
 * @author Toru Nagashima
 * @deprecated in ESLint v8.53.0
 */

"use strict";

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

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

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

const PREV_TOKEN = /^[)\]}>]$/u;
const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/u;
const PREV_TOKEN_M = /^[)\]}>*]$/u;
const NEXT_TOKEN_M = /^[{*]$/u;
const TEMPLATE_OPEN_PAREN = /\$\{$/u;
const TEMPLATE_CLOSE_PAREN = /^\}/u;
const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template|PrivateIdentifier)$/u;
const KEYS = keywords.concat(["as", "async", "await", "from", "get", "let", "of", "set", "yield"]);

// check duplications.
(function() {
    KEYS.sort();
    for (let i = 1; i < KEYS.length; ++i) {
        if (KEYS[i] === KEYS[i - 1]) {
            throw new Error(`Duplication was found in the keyword list: ${KEYS[i]}`);
        }
    }
}());

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

/**
 * Checks whether or not a given token is a "Template" token ends with "${".
 * @param {Token} token A token to check.
 * @returns {boolean} `true` if the token is a "Template" token ends with "${".
 */
function isOpenParenOfTemplate(token) {
    return token.type === "Template" && TEMPLATE_OPEN_PAREN.test(token.value);
}

/**
 * Checks whether or not a given token is a "Template" token starts with "}".
 * @param {Token} token A token to check.
 * @returns {boolean} `true` if the token is a "Template" token starts with "}".
 */
function isCloseParenOfTemplate(token) {
    return token.type === "Template" && TEMPLATE_CLOSE_PAREN.test(token.value);
}

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

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

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

        fixable: "whitespace",

        schema: [
            {
                type: "object",
                properties: {
                    before: { type: "boolean", default: true },
                    after: { type: "boolean", default: true },
                    overrides: {
                        type: "object",
                        properties: KEYS.reduce((retv, key) => {
                            retv[key] = {
                                type: "object",
                                properties: {
                                    before: { type: "boolean" },
                                    after: { type: "boolean" }
                                },
                                additionalProperties: false
                            };
                            return retv;
                        }, {}),
                        additionalProperties: false
                    }
                },
                additionalProperties: false
            }
        ],
        messages: {
            expectedBefore: "Expected space(s) before \"{{value}}\".",
            expectedAfter: "Expected space(s) after \"{{value}}\".",
            unexpectedBefore: "Unexpected space(s) before \"{{value}}\".",
            unexpectedAfter: "Unexpected space(s) after \"{{value}}\"."
        }
    },

    create(context) {
        const sourceCode = context.sourceCode;

        const tokensToIgnore = new WeakSet();

        /**
         * Reports a given token if there are not space(s) before the token.
         * @param {Token} token A token to report.
         * @param {RegExp} pattern A pattern of the previous token to check.
         * @returns {void}
         */
        function expectSpaceBefore(token, pattern) {
            const prevToken = sourceCode.getTokenBefore(token);

            if (prevToken &&
                (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) &&
                !isOpenParenOfTemplate(prevToken) &&
                !tokensToIgnore.has(prevToken) &&
                astUtils.isTokenOnSameLine(prevToken, token) &&
                !sourceCode.isSpaceBetweenTokens(prevToken, token)
            ) {
                context.report({
                    loc: token.loc,
                    messageId: "expectedBefore",
                    data: token,
                    fix(fixer) {
                        return fixer.insertTextBefore(token, " ");
                    }
                });
            }
        }

        /**
         * Reports a given token if there are space(s) before the token.
         * @param {Token} token A token to report.
         * @param {RegExp} pattern A pattern of the previous token to check.
         * @returns {void}
         */
        function unexpectSpaceBefore(token, pattern) {
            const prevToken = sourceCode.getTokenBefore(token);

            if (prevToken &&
                (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) &&
                !isOpenParenOfTemplate(prevToken) &&
                !tokensToIgnore.has(prevToken) &&
                astUtils.isTokenOnSameLine(prevToken, token) &&
                sourceCode.isSpaceBetweenTokens(prevToken, token)
            ) {
                context.report({
                    loc: { start: prevToken.loc.end, end: token.loc.start },
                    messageId: "unexpectedBefore",
                    data: token,
                    fix(fixer) {
                        return fixer.removeRange([prevToken.range[1], token.range[0]]);
                    }
                });
            }
        }

        /**
         * Reports a given token if there are not space(s) after the token.
         * @param {Token} token A token to report.
         * @param {RegExp} pattern A pattern of the next token to check.
         * @returns {void}
         */
        function expectSpaceAfter(token, pattern) {
            const nextToken = sourceCode.getTokenAfter(token);

            if (nextToken &&
                (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) &&
                !isCloseParenOfTemplate(nextToken) &&
                !tokensToIgnore.has(nextToken) &&
                astUtils.isTokenOnSameLine(token, nextToken) &&
                !sourceCode.isSpaceBetweenTokens(token, nextToken)
            ) {
                context.report({
                    loc: token.loc,
                    messageId: "expectedAfter",
                    data: token,
                    fix(fixer) {
                        return fixer.insertTextAfter(token, " ");
                    }
                });
            }
        }

        /**
         * Reports a given token if there are space(s) after the token.
         * @param {Token} token A token to report.
         * @param {RegExp} pattern A pattern of the next token to check.
         * @returns {void}
         */
        function unexpectSpaceAfter(token, pattern) {
            const nextToken = sourceCode.getTokenAfter(token);

            if (nextToken &&
                (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) &&
                !isCloseParenOfTemplate(nextToken) &&
                !tokensToIgnore.has(nextToken) &&
                astUtils.isTokenOnSameLine(token, nextToken) &&
                sourceCode.isSpaceBetweenTokens(token, nextToken)
            ) {

                context.report({
                    loc: { start: token.loc.end, end: nextToken.loc.start },
                    messageId: "unexpectedAfter",
                    data: token,
                    fix(fixer) {
                        return fixer.removeRange([token.range[1], nextToken.range[0]]);
                    }
                });
            }
        }

        /**
         * Parses the option object and determines check methods for each keyword.
         * @param {Object|undefined} options The option object to parse.
         * @returns {Object} - Normalized option object.
         *      Keys are keywords (there are for every keyword).
         *      Values are instances of `{"before": function, "after": function}`.
         */
        function parseOptions(options = {}) {
            const before = options.before !== false;
            const after = options.after !== false;
            const defaultValue = {
                before: before ? expectSpaceBefore : unexpectSpaceBefore,
                after: after ? expectSpaceAfter : unexpectSpaceAfter
            };
            const overrides = (options && options.overrides) || {};
            const retv = Object.create(null);

            for (let i = 0; i < KEYS.length; ++i) {
                const key = KEYS[i];
                const override = overrides[key];

                if (override) {
                    const thisBefore = ("before" in override) ? override.before : before;
                    const thisAfter = ("after" in override) ? override.after : after;

                    retv[key] = {
                        before: thisBefore ? expectSpaceBefore : unexpectSpaceBefore,
                        after: thisAfter ? expectSpaceAfter : unexpectSpaceAfter
                    };
                } else {
                    retv[key] = defaultValue;
                }
            }

            return retv;
        }

        const checkMethodMap = parseOptions(context.options[0]);

        /**
         * Reports a given token if usage of spacing followed by the token is
         * invalid.
         * @param {Token} token A token to report.
         * @param {RegExp} [pattern] Optional. A pattern of the previous
         *      token to check.
         * @returns {void}
         */
        function checkSpacingBefore(token, pattern) {
            checkMethodMap[token.value].before(token, pattern || PREV_TOKEN);
        }

        /**
         * Reports a given token if usage of spacing preceded by the token is
         * invalid.
         * @param {Token} token A token to report.
         * @param {RegExp} [pattern] Optional. A pattern of the next
         *      token to check.
         * @returns {void}
         */
        function checkSpacingAfter(token, pattern) {
            checkMethodMap[token.value].after(token, pattern || NEXT_TOKEN);
        }

        /**
         * Reports a given token if usage of spacing around the token is invalid.
         * @param {Token} token A token to report.
         * @returns {void}
         */
        function checkSpacingAround(token) {
            checkSpacingBefore(token);
            checkSpacingAfter(token);
        }

        /**
         * Reports the first token of a given node if the first token is a keyword
         * and usage of spacing around the token is invalid.
         * @param {ASTNode|null} node A node to report.
         * @returns {void}
         */
        function checkSpacingAroundFirstToken(node) {
            const firstToken = node && sourceCode.getFirstToken(node);

            if (firstToken && firstToken.type === "Keyword") {
                checkSpacingAround(firstToken);
            }
        }

        /**
         * Reports the first token of a given node if the first token is a keyword
         * and usage of spacing followed by the token is invalid.
         *
         * This is used for unary operators (e.g. `typeof`), `function`, and `super`.
         * Other rules are handling usage of spacing preceded by those keywords.
         * @param {ASTNode|null} node A node to report.
         * @returns {void}
         */
        function checkSpacingBeforeFirstToken(node) {
            const firstToken = node && sourceCode.getFirstToken(node);

            if (firstToken && firstToken.type === "Keyword") {
                checkSpacingBefore(firstToken);
            }
        }

        /**
         * Reports the previous token of a given node if the token is a keyword and
         * usage of spacing around the token is invalid.
         * @param {ASTNode|null} node A node to report.
         * @returns {void}
         */
        function checkSpacingAroundTokenBefore(node) {
            if (node) {
                const token = sourceCode.getTokenBefore(node, astUtils.isKeywordToken);

                checkSpacingAround(token);
            }
        }

        /**
         * Reports `async` or `function` keywords of a given node if usage of
         * spacing around those keywords is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForFunction(node) {
            const firstToken = node && sourceCode.getFirstToken(node);

            if (firstToken &&
                ((firstToken.type === "Keyword" && firstToken.value === "function") ||
                firstToken.value === "async")
            ) {
                checkSpacingBefore(firstToken);
            }
        }

        /**
         * Reports `class` and `extends` keywords of a given node if usage of
         * spacing around those keywords is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForClass(node) {
            checkSpacingAroundFirstToken(node);
            checkSpacingAroundTokenBefore(node.superClass);
        }

        /**
         * Reports `if` and `else` keywords of a given node if usage of spacing
         * around those keywords is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForIfStatement(node) {
            checkSpacingAroundFirstToken(node);
            checkSpacingAroundTokenBefore(node.alternate);
        }

        /**
         * Reports `try`, `catch`, and `finally` keywords of a given node if usage
         * of spacing around those keywords is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForTryStatement(node) {
            checkSpacingAroundFirstToken(node);
            checkSpacingAroundFirstToken(node.handler);
            checkSpacingAroundTokenBefore(node.finalizer);
        }

        /**
         * Reports `do` and `while` keywords of a given node if usage of spacing
         * around those keywords is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForDoWhileStatement(node) {
            checkSpacingAroundFirstToken(node);
            checkSpacingAroundTokenBefore(node.test);
        }

        /**
         * Reports `for` and `in` keywords of a given node if usage of spacing
         * around those keywords is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForForInStatement(node) {
            checkSpacingAroundFirstToken(node);

            const inToken = sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken);
            const previousToken = sourceCode.getTokenBefore(inToken);

            if (previousToken.type !== "PrivateIdentifier") {
                checkSpacingBefore(inToken);
            }

            checkSpacingAfter(inToken);
        }

        /**
         * Reports `for` and `of` keywords of a given node if usage of spacing
         * around those keywords is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForForOfStatement(node) {
            if (node.await) {
                checkSpacingBefore(sourceCode.getFirstToken(node, 0));
                checkSpacingAfter(sourceCode.getFirstToken(node, 1));
            } else {
                checkSpacingAroundFirstToken(node);
            }

            const ofToken = sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken);
            const previousToken = sourceCode.getTokenBefore(ofToken);

            if (previousToken.type !== "PrivateIdentifier") {
                checkSpacingBefore(ofToken);
            }

            checkSpacingAfter(ofToken);
        }

        /**
         * Reports `import`, `export`, `as`, and `from` keywords of a given node if
         * usage of spacing around those keywords is invalid.
         *
         * This rule handles the `*` token in module declarations.
         *
         *     import*as A from "./a"; /*error Expected space(s) after "import".
         *                               error Expected space(s) before "as".
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForModuleDeclaration(node) {
            const firstToken = sourceCode.getFirstToken(node);

            checkSpacingBefore(firstToken, PREV_TOKEN_M);
            checkSpacingAfter(firstToken, NEXT_TOKEN_M);

            if (node.type === "ExportDefaultDeclaration") {
                checkSpacingAround(sourceCode.getTokenAfter(firstToken));
            }

            if (node.type === "ExportAllDeclaration" && node.exported) {
                const asToken = sourceCode.getTokenBefore(node.exported);

                checkSpacingBefore(asToken, PREV_TOKEN_M);
                checkSpacingAfter(asToken, NEXT_TOKEN_M);
            }

            if (node.source) {
                const fromToken = sourceCode.getTokenBefore(node.source);

                checkSpacingBefore(fromToken, PREV_TOKEN_M);
                checkSpacingAfter(fromToken, NEXT_TOKEN_M);
            }
        }

        /**
         * Reports `as` keyword of a given node if usage of spacing around this
         * keyword is invalid.
         * @param {ASTNode} node An `ImportSpecifier` node to check.
         * @returns {void}
         */
        function checkSpacingForImportSpecifier(node) {
            if (node.imported.range[0] !== node.local.range[0]) {
                const asToken = sourceCode.getTokenBefore(node.local);

                checkSpacingBefore(asToken, PREV_TOKEN_M);
            }
        }

        /**
         * Reports `as` keyword of a given node if usage of spacing around this
         * keyword is invalid.
         * @param {ASTNode} node An `ExportSpecifier` node to check.
         * @returns {void}
         */
        function checkSpacingForExportSpecifier(node) {
            if (node.local.range[0] !== node.exported.range[0]) {
                const asToken = sourceCode.getTokenBefore(node.exported);

                checkSpacingBefore(asToken, PREV_TOKEN_M);
                checkSpacingAfter(asToken, NEXT_TOKEN_M);
            }
        }

        /**
         * Reports `as` keyword of a given node if usage of spacing around this
         * keyword is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForImportNamespaceSpecifier(node) {
            const asToken = sourceCode.getFirstToken(node, 1);

            checkSpacingBefore(asToken, PREV_TOKEN_M);
        }

        /**
         * Reports `static`, `get`, and `set` keywords of a given node if usage of
         * spacing around those keywords is invalid.
         * @param {ASTNode} node A node to report.
         * @throws {Error} If unable to find token get, set, or async beside method name.
         * @returns {void}
         */
        function checkSpacingForProperty(node) {
            if (node.static) {
                checkSpacingAroundFirstToken(node);
            }
            if (node.kind === "get" ||
                node.kind === "set" ||
                (
                    (node.method || node.type === "MethodDefinition") &&
                    node.value.async
                )
            ) {
                const token = sourceCode.getTokenBefore(
                    node.key,
                    tok => {
                        switch (tok.value) {
                            case "get":
                            case "set":
                            case "async":
                                return true;
                            default:
                                return false;
                        }
                    }
                );

                if (!token) {
                    throw new Error("Failed to find token get, set, or async beside method name");
                }

                checkSpacingAround(token);
            }
        }

        /**
         * Reports `await` keyword of a given node if usage of spacing before
         * this keyword is invalid.
         * @param {ASTNode} node A node to report.
         * @returns {void}
         */
        function checkSpacingForAwaitExpression(node) {
            checkSpacingBefore(sourceCode.getFirstToken(node));
        }

        return {

            // Statements
            DebuggerStatement: checkSpacingAroundFirstToken,
            WithStatement: checkSpacingAroundFirstToken,

            // Statements - Control flow
            BreakStatement: checkSpacingAroundFirstToken,
            ContinueStatement: checkSpacingAroundFirstToken,
            ReturnStatement: checkSpacingAroundFirstToken,
            ThrowStatement: checkSpacingAroundFirstToken,
            TryStatement: checkSpacingForTryStatement,

            // Statements - Choice
            IfStatement: checkSpacingForIfStatement,
            SwitchStatement: checkSpacingAroundFirstToken,
            SwitchCase: checkSpacingAroundFirstToken,

            // Statements - Loops
            DoWhileStatement: checkSpacingForDoWhileStatement,
            ForInStatement: checkSpacingForForInStatement,
            ForOfStatement: checkSpacingForForOfStatement,
            ForStatement: checkSpacingAroundFirstToken,
            WhileStatement: checkSpacingAroundFirstToken,

            // Statements - Declarations
            ClassDeclaration: checkSpacingForClass,
            ExportNamedDeclaration: checkSpacingForModuleDeclaration,
            ExportDefaultDeclaration: checkSpacingForModuleDeclaration,
            ExportAllDeclaration: checkSpacingForModuleDeclaration,
            FunctionDeclaration: checkSpacingForFunction,
            ImportDeclaration: checkSpacingForModuleDeclaration,
            VariableDeclaration: checkSpacingAroundFirstToken,

            // Expressions
            ArrowFunctionExpression: checkSpacingForFunction,
            AwaitExpression: checkSpacingForAwaitExpression,
            ClassExpression: checkSpacingForClass,
            FunctionExpression: checkSpacingForFunction,
            NewExpression: checkSpacingBeforeFirstToken,
            Super: checkSpacingBeforeFirstToken,
            ThisExpression: checkSpacingBeforeFirstToken,
            UnaryExpression: checkSpacingBeforeFirstToken,
            YieldExpression: checkSpacingBeforeFirstToken,

            // Others
            ImportSpecifier: checkSpacingForImportSpecifier,
            ExportSpecifier: checkSpacingForExportSpecifier,
            ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier,
            MethodDefinition: checkSpacingForProperty,
            PropertyDefinition: checkSpacingForProperty,
            StaticBlock: checkSpacingAroundFirstToken,
            Property: checkSpacingForProperty,

            // To avoid conflicts with `space-infix-ops`, e.g. `a > this.b`
            "BinaryExpression[operator='>']"(node) {
                const operatorToken = sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken);

                tokensToIgnore.add(operatorToken);
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to enforce the position of line comments
 * @author Alberto Rodríguez
 */
"use strict";

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

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

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

        docs: {
            description: "Enforce position of line comments",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/line-comment-position"
        },

        schema: [
            {
                oneOf: [
                    {
                        enum: ["above", "beside"]
                    },
                    {
                        type: "object",
                        properties: {
                            position: {
                                enum: ["above", "beside"]
                            },
                            ignorePattern: {
                                type: "string"
                            },
                            applyDefaultPatterns: {
                                type: "boolean"
                            },
                            applyDefaultIgnorePatterns: {
                                type: "boolean"
                            }
                        },
                        additionalProperties: false
                    }
                ]
            }
        ],
        messages: {
            above: "Expected comment to be above code.",
            beside: "Expected comment to be beside code."
        }
    },

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

        let above,
            ignorePattern,
            applyDefaultIgnorePatterns = true;

        if (!options || typeof options === "string") {
            above = !options || options === "above";

        } else {
            above = !options.position || options.position === "above";
            ignorePattern = options.ignorePattern;

            if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) {
                applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns;
            } else {
                applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false;
            }
        }

        const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
        const fallThroughRegExp = /^\s*falls?\s?through/u;
        const customIgnoreRegExp = new RegExp(ignorePattern, "u");
        const sourceCode = context.sourceCode;

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

        return {
            Program() {
                const comments = sourceCode.getAllComments();

                comments.filter(token => token.type === "Line").forEach(node => {
                    if (applyDefaultIgnorePatterns && (defaultIgnoreRegExp.test(node.value) || fallThroughRegExp.test(node.value))) {
                        return;
                    }

                    if (ignorePattern && customIgnoreRegExp.test(node.value)) {
                        return;
                    }

                    const previous = sourceCode.getTokenBefore(node, { includeComments: true });
                    const isOnSameLine = previous && previous.loc.end.line === node.loc.start.line;

                    if (above) {
                        if (isOnSameLine) {
                            context.report({
                                node,
                                messageId: "above"
                            });
                        }
                    } else {
                        if (!isOnSameLine) {
                            context.report({
                                node,
                                messageId: "beside"
                            });
                        }
                    }
                });
            }
        };
    }
};


code:
/**
 * @fileoverview Rule to enforce a single linebreak style.
 * @author Erik Mueller
 * @deprecated in ESLint v8.53.0
 */

"use strict";

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

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 linebreak style",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/linebreak-style"
        },

        fixable: "whitespace",

        schema: [
            {
                enum: ["unix", "windows"]
            }
        ],
        messages: {
            expectedLF: "Expected linebreaks to be 'LF' but found 'CRLF'.",
            expectedCRLF: "Expected linebreaks to be 'CRLF' but found 'LF'."
        }
    },

    create(context) {
        const sourceCode = context.sourceCode;

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

        /**
         * Builds a fix function that replaces text at the specified range in the source text.
         * @param {int[]} range The range to replace
         * @param {string} text The text to insert.
         * @returns {Function} Fixer function
         * @private
         */
        function createFix(range, text) {
            return function(fixer) {
                return fixer.replaceTextRange(range, text);
            };
        }

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

        return {
            Program: function checkForLinebreakStyle(node) {
                const linebreakStyle = context.options[0] || "unix",
                    expectedLF = linebreakStyle === "unix",
                    expectedLFChars = expectedLF ? "\n" : "\r\n",
                    source = sourceCode.getText(),
                    pattern = astUtils.createGlobalLinebreakMatcher();
                let match;

                let i = 0;

                while ((match = pattern.exec(source)) !== null) {
                    i++;
                    if (match[0] === expectedLFChars) {
                        continue;
                    }

                    const index = match.index;
                    const range = [index, index + match[0].length];

                    context.report({
                        node,
                        loc: {
                            start: {
                                line: i,
                                column: sourceCode.lines[i - 1].length
                            },
                            end: {
                                line: i + 1,
                                column: 0
                            }
                        },
                        messageId: expectedLF ? "expectedLF" : "expectedCRLF",
                        fix: createFix(range, expectedLFChars)
                    });
                }
            }
        };
    }
};


code:
/**
 * @fileoverview Enforces empty lines around comments.
 * @author Jamund Ferguson
 * @deprecated in ESLint v8.53.0
 */
"use strict";

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

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

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

/**
 * Return an array with any line numbers that are empty.
 * @param {Array} lines An array of each line of the file.
 * @returns {Array} An array of line numbers.
 */
function getEmptyLineNums(lines) {
    const emptyLines = lines.map((line, i) => ({
        code: line.trim(),
        num: i + 1
    })).filter(line => !line.code).map(line => line.num);

    return emptyLines;
}

/**
 * Return an array with any line numbers that contain comments.
 * @param {Array} comments An array of comment tokens.
 * @returns {Array} An array of line numbers.
 */
function getCommentLineNums(comments) {
    const lines = [];

    comments.forEach(token => {
        const start = token.loc.start.line;
        const end = token.loc.end.line;

        lines.push(start, end);
    });
    return lines;
}

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

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

        docs: {
            description: "Require empty lines around comments",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/lines-around-comment"
        },

        fixable: "whitespace",

        schema: [
            {
                type: "object",
                properties: {
                    beforeBlockComment: {
                        type: "boolean",
                        default: true
                    },
                    afterBlockComment: {
                        type: "boolean",
                        default: false
                    },
                    beforeLineComment: {
                        type: "boolean",
                        default: false
                    },
                    afterLineComment: {
                        type: "boolean",
                        default: false
                    },
                    allowBlockStart: {
                        type: "boolean",
                        default: false
                    },
                    allowBlockEnd: {
                        type: "boolean",
                        default: false
                    },
                    allowClassStart: {
                        type: "boolean"
                    },
                    allowClassEnd: {
                        type: "boolean"
                    },
                    allowObjectStart: {
                        type: "boolean"
                    },
                    allowObjectEnd: {
                        type: "boolean"
                    },
                    allowArrayStart: {
                        type: "boolean"
                    },
                    allowArrayEnd: {
                        type: "boolean"
                    },
                    ignorePattern: {
                        type: "string"
                    },
                    applyDefaultIgnorePatterns: {
                        type: "boolean"
                    },
                    afterHashbangComment: {
                        type: "boolean",
                        default: false
                    }
                },
                additionalProperties: false
            }
        ],
        messages: {
            after: "Expected line after comment.",
            before: "Expected line before comment."
        }
    },

    create(context) {

        const options = Object.assign({}, context.options[0]);
        const ignorePattern = options.ignorePattern;
        const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
        const customIgnoreRegExp = new RegExp(ignorePattern, "u");
        const applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false;

        options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true;

        const sourceCode = context.sourceCode;

        const lines = sourceCode.lines,
            numLines = lines.length + 1,
            comments = sourceCode.getAllComments(),
            commentLines = getCommentLineNums(comments),
            emptyLines = getEmptyLineNums(lines),
            commentAndEmptyLines = new Set(commentLines.concat(emptyLines));

        /**
         * Returns whether or not comments are on lines starting with or ending with code
         * @param {token} token The comment token to check.
         * @returns {boolean} True if the comment is not alone.
         */
        function codeAroundComment(token) {
            let currentToken = token;

            do {
                currentToken = sourceCode.getTokenBefore(currentToken, { includeComments: true });
            } while (currentToken && astUtils.isCommentToken(currentToken));

            if (currentToken && astUtils.isTokenOnSameLine(currentToken, token)) {
                return true;
            }

            currentToken = token;
            do {
                currentToken = sourceCode.getTokenAfter(currentToken, { includeComments: true });
            } while (currentToken && astUtils.isCommentToken(currentToken));

            if (currentToken && astUtils.isTokenOnSameLine(token, currentToken)) {
                return true;
            }

            return false;
        }

        /**
         * Returns whether or not comments are inside a node type or not.
         * @param {ASTNode} parent The Comment parent node.
         * @param {string} nodeType The parent type to check against.
         * @returns {boolean} True if the comment is inside nodeType.
         */
        function isParentNodeType(parent, nodeType) {
            return parent.type === nodeType ||
                (parent.body && parent.body.type === nodeType) ||
                (parent.consequent && parent.consequent.type === nodeType);
        }

        /**
         * Returns the parent node that contains the given token.
         * @param {token} token The token to check.
         * @returns {ASTNode|null} The parent node that contains the given token.
         */
        function getParentNodeOfToken(token) {
            const node = sourceCode.getNodeByRangeIndex(token.range[0]);

            /*
             * For the purpose of this rule, the comment token is in a `StaticBlock` node only
             * if it's inside the braces of that `StaticBlock` node.
             *
             * Example where this function returns `null`:
             *
             *   static
             *   // comment
             *   {
             *   }
             *
             * Example where this function returns `StaticBlock` node:
             *
             *   static
             *   {
             *   // comment
             *   }
             *
             */
            if (node && node.type === "StaticBlock") {
                const openingBrace = sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token

                return token.range[0] >= openingBrace.range[0]
                    ? node
                    : null;
            }

            return node;
        }

        /**
         * Returns whether or not comments are at the parent start or not.
         * @param {token} token The Comment token.
         * @param {string} nodeType The parent type to check against.
         * @returns {boolean} True if the comment is at parent start.
         */
        function isCommentAtParentStart(token, nodeType) {
            const parent = getParentNodeOfToken(token);

            if (parent && isParentNodeType(parent, nodeType)) {
                let parentStartNodeOrToken = parent;

                if (parent.type === "StaticBlock") {
                    parentStartNodeOrToken = sourceCode.getFirstToken(parent, { skip: 1 }); // opening brace of the static block
                } else if (parent.type === "SwitchStatement") {
                    parentStartNodeOrToken = sourceCode.getTokenAfter(parent.discriminant, {
                        filter: astUtils.isOpeningBraceToken
                    }); // opening brace of the switch statement
                }

                return token.loc.start.line - parentStartNodeOrToken.loc.start.line === 1;
            }

            return false;
        }

        /**
         * Returns whether or not comments are at the parent end or not.
         * @param {token} token The Comment token.
         * @param {string} nodeType The parent type to check against.
         * @returns {boolean} True if the comment is at parent end.
         */
        function isCommentAtParentEnd(token, nodeType) {
            const parent = getParentNodeOfToken(token);

            return !!parent && isParentNodeType(parent, nodeType) &&
                    parent.loc.end.line - token.loc.end.line === 1;
        }

        /**
         * Returns whether or not comments are at the block start or not.
         * @param {token} token The Comment token.
         * @returns {boolean} True if the comment is at block start.
         */
        function isCommentAtBlockStart(token) {
            return (
                isCommentAtParentStart(token, "ClassBody") ||
                isCommentAtParentStart(token, "BlockStatement") ||
                isCommentAtParentStart(token, "StaticBlock") ||
                isCommentAtParentStart(token, "SwitchCase") ||
                isCommentAtParentStart(token, "SwitchStatement")
            );
        }

        /**
         * Returns whether or not comments are at the block end or not.
         * @param {token} token The Comment token.
         * @returns {boolean} True if the comment is at block end.
         */
        function isCommentAtBlockEnd(token) {
            return (
                isCommentAtParentEnd(token, "ClassBody") ||
                isCommentAtParentEnd(token, "BlockStatement") ||
                isCommentAtParentEnd(token, "StaticBlock") ||
                isCommentAtParentEnd(token, "SwitchCase") ||
                isCommentAtParentEnd(token, "SwitchStatement")
            );
        }

        /**
         * Returns whether or not comments are at the class start or not.
         * @param {token} token The Comment token.
         * @returns {boolean} True if the comment is at class start.
         */
        function isCommentAtClassStart(token) {
            return isCommentAtParentStart(token, "ClassBody");
        }

        /**
         * Returns whether or not comments are at the class end or not.
         * @param {token} token The Comment token.
         * @returns {boolean} True if the comment is at class end.
         */
        function isCommentAtClassEnd(token) {
            return isCommentAtParentEnd(token, "ClassBody");
        }

        /**
         * Returns whether or not comments are at the object start or not.
         * @param {token} token The Comment token.
         * @returns {boolean} True if the comment is at object start.
         */
        function isCommentAtObjectStart(token) {
            return isCommentAtParentStart(token, "ObjectExpression") || isCommentAtParentStart(token, "ObjectPattern");
        }

        /**
         * Returns whether or not comments are at the object end or not.
         * @param {token} token The Comment token.
         * @returns {boolean} True if the comment is at object end.
         */
        function isCommentAtObjectEnd(token) {
            return isCommentAtParentEnd(token, "ObjectExpression") || isCommentAtParentEnd(token, "ObjectPattern");
        }

        /**
         * Returns whether or not comments are at the array start or not.
         * @param {token} token The Comment token.
         * @returns {boolean} True if the comment is at array start.
         */
        function isCommentAtArrayStart(token) {
            return isCommentAtParentStart(token, "ArrayExpression") || isCommentAtParentStart(token, "ArrayPattern");
        }

        /**
         * Returns whether or not comments are at the array end or not.
         * @param {token} token The Comment token.
         * @returns {boolean} True if the comment is at array end.
         */
        function isCommentAtArrayEnd(token) {
            return isCommentAtParentEnd(token, "ArrayExpression") || isCommentAtParentEnd(token, "ArrayPattern");
        }

        /**
         * Checks if a comment token has lines around it (ignores inline comments)
         * @param {token} token The Comment token.
         * @param {Object} opts Options to determine the newline.
         * @param {boolean} opts.after Should have a newline after this line.
         * @param {boolean} opts.before Should have a newline before this line.
         * @returns {void}
         */
        function checkForEmptyLine(token, opts) {
            if (applyDefaultIgnorePatterns && defaultIgnoreRegExp.test(token.value)) {
                return;
            }

            if (ignorePattern && customIgnoreRegExp.test(token.value)) {
                return;
            }

            let after = opts.after,
                before = opts.before;

            const prevLineNum = token.loc.start.line - 1,
                nextLineNum = token.loc.end.line + 1,
                commentIsNotAlone = codeAroundComment(token);

            const blockStartAllowed = options.allowBlockStart &&
                    isCommentAtBlockStart(token) &&
                    !(options.allowClassStart === false &&
                    isCommentAtClassStart(token)),
                blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(token) && !(options.allowClassEnd === false && isCommentAtClassEnd(token)),
                classStartAllowed = options.allowClassStart && isCommentAtClassStart(token),
                classEndAllowed = options.allowClassEnd && isCommentAtClassEnd(token),
                objectStartAllowed = options.allowObjectStart && isCommentAtObjectStart(token),
                objectEndAllowed = options.allowObjectEnd && isCommentAtObjectEnd(token),
                arrayStartAllowed = options.allowArrayStart && isCommentAtArrayStart(token),
                arrayEndAllowed = options.allowArrayEnd && isCommentAtArrayEnd(token);

            const exceptionStartAllowed = blockStartAllowed || classStartAllowed || objectStartAllowed || arrayStartAllowed;
            const exceptionEndAllowed = blockEndAllowed || classEndAllowed || objectEndAllowed || arrayEndAllowed;

            // ignore top of the file and bottom of the file
            if (prevLineNum < 1) {
                before = false;
            }
            if (nextLineNum >= numLines) {
                after = false;
            }

            // we ignore all inline comments
            if (commentIsNotAlone) {
                return;
            }

            const previousTokenOrComment = sourceCode.getTokenBefore(token, { includeComments: true });
            const nextTokenOrComment = sourceCode.getTokenAfter(token, { includeComments: true });

            // check for newline before
            if (!exceptionStartAllowed && before && !commentAndEmptyLines.has(prevLineNum) &&
                    !(astUtils.isCommentToken(previousTokenOrComment) && astUtils.isTokenOnSameLine(previousTokenOrComment, token))) {
                const lineStart = token.range[0] - token.loc.start.column;
                const range = [lineStart, lineStart];

                context.report({
                    node: token,
                    messageId: "before",
                    fix(fixer) {
                        return fixer.insertTextBeforeRange(range, "\n");
                    }
                });
            }

            // check for newline after
            if (!exceptionEndAllowed && after && !commentAndEmptyLines.has(nextLineNum) &&
                    !(astUtils.isCommentToken(nextTokenOrComment) && astUtils.isTokenOnSameLine(token, nextTokenOrComment))) {
                context.report({
                    node: token,
                    messageId: "after",
                    fix(fixer) {
                        return fixer.insertTextAfter(token, "\n");
                    }
                });
            }

        }

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

        return {
            Program() {
                comments.forEach(token => {
                    if (token.type === "Line") {
                        if (options.beforeLineComment || options.afterLineComment) {
                            checkForEmptyLine(token, {
                                after: options.afterLineComment,
                                before: options.beforeLineComment
                            });
                        }
                    } else if (token.type === "Block") {
                        if (options.beforeBlockComment || options.afterBlockComment) {
                            checkForEmptyLine(token, {
                                after: options.afterBlockComment,
                                before: options.beforeBlockComment
                            });
                        }
                    } else if (token.type === "Shebang") {
                        if (options.afterHashbangComment) {
                            checkForEmptyLine(token, {
                                after: options.afterHashbangComment,
                                before: false
                            });
                        }
                    }
                });
            }
        };
    }
};


code:
/**
 * @fileoverview Require or disallow newlines around directives.
 * @author Kai Cataldo
 * @deprecated in ESLint v4.0.0
 */

"use strict";

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

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

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

        docs: {
            description: "Require or disallow newlines around directives",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/lines-around-directive"
        },

        schema: [{
            oneOf: [
                {
                    enum: ["always", "never"]
                },
                {
                    type: "object",
                    properties: {
                        before: {
                            enum: ["always", "never"]
                        },
                        after: {
                            enum: ["always", "never"]
                        }
                    },
                    additionalProperties: false,
                    minProperties: 2
                }
            ]
        }],

        fixable: "whitespace",
        messages: {
            expected: "Expected newline {{location}} \"{{value}}\" directive.",
            unexpected: "Unexpected newline {{location}} \"{{value}}\" directive."
        },
        deprecated: true,
        replacedBy: ["padding-line-between-statements"]
    },

    create(context) {
        const sourceCode = context.sourceCode;
        const config = context.options[0] || "always";
        const expectLineBefore = typeof config === "string" ? config : config.before;
        const expectLineAfter = typeof config === "string" ? config : config.after;

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

        /**
         * Check if node is preceded by a blank newline.
         * @param {ASTNode} node Node to check.
         * @returns {boolean} Whether or not the passed in node is preceded by a blank newline.
         */
        function hasNewlineBefore(node) {
            const tokenBefore = sourceCode.getTokenBefore(node, { includeComments: true });
            const tokenLineBefore = tokenBefore ? tokenBefore.loc.end.line : 0;

            return node.loc.start.line - tokenLineBefore >= 2;
        }

        /**
         * Gets the last token of a node that is on the same line as the rest of the node.
         * This will usually be the last token of the node, but it will be the second-to-last token if the node has a trailing
         * semicolon on a different line.
         * @param {ASTNode} node A directive node
         * @returns {Token} The last token of the node on the line
         */
        function getLastTokenOnLine(node) {
            const lastToken = sourceCode.getLastToken(node);
            const secondToLastToken = sourceCode.getTokenBefore(lastToken);

            return astUtils.isSemicolonToken(lastToken) && lastToken.loc.start.line > secondToLastToken.loc.end.line
                ? secondToLastToken
                : lastToken;
        }

        /**
         * Check if node is followed by a blank newline.
         * @param {ASTNode} node Node to check.
         * @returns {boolean} Whether or not the passed in node is followed by a blank newline.
         */
        function hasNewlineAfter(node) {
            const lastToken = getLastTokenOnLine(node);
            const tokenAfter = sourceCode.getTokenAfter(lastToken, { includeComments: true });

            return tokenAfter.loc.start.line - lastToken.loc.end.line >= 2;
        }

        /**
         * Report errors for newlines around directives.
         * @param {ASTNode} node Node to check.
         * @param {string} location Whether the error was found before or after the directive.
         * @param {boolean} expected Whether or not a newline was expected or unexpected.
         * @returns {void}
         */
        function reportError(node, location, expected) {
            context.report({
                node,
                messageId: expected ? "expected" : "unexpected",
                data: {
                    value: node.expression.value,
                    location
                },
                fix(fixer) {
                    const lastToken = getLastTokenOnLine(node);

                    if (expected) {
                        return location === "before" ? fixer.insertTextBefore(node, "\n") : fixer.insertTextAfter(lastToken, "\n");
                    }
                    return fixer.removeRange(location === "before" ? [node.range[0] - 1, node.range[0]] : [lastToken.range[1], lastToken.range[1] + 1]);
                }
            });
        }

        /**
         * Check lines around directives in node
         * @param {ASTNode} node node to check
         * @returns {void}
         */
        function checkDirectives(node) {
            const directives = astUtils.getDirectivePrologue(node);

            if (!directives.length) {
                return;
            }

            const firstDirective = directives[0];
            const leadingComments = sourceCode.getCommentsBefore(firstDirective);

            /*
             * Only check before the first directive if it is preceded by a comment or if it is at the top of
             * the file and expectLineBefore is set to "never". This is to not force a newline at the top of
             * the file if there are no comments as well as for compatibility with padded-blocks.
             */
            if (leadingComments.length) {
                if (expectLineBefore === "always" && !hasNewlineBefore(firstDirective)) {
                    reportError(firstDirective, "before", true);
                }

                if (expectLineBefore === "never" && hasNewlineBefore(firstDirective)) {
                    reportError(firstDirective, "before", false);
                }
            } else if (
                node.type === "Program" &&
                expectLineBefore === "never" &&
                !leadingComments.length &&
                hasNewlineBefore(firstDirective)
            ) {
                reportError(firstDirective, "before", false);
            }

            const lastDirective = directives[directives.length - 1];
            const statements = node.type === "Program" ? node.body : node.body.body;

            /*
             * Do not check after the last directive if the body only
             * contains a directive prologue and isn't followed by a comment to ensure
             * this rule behaves well with padded-blocks.
             */
            if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) {
                return;
            }

            if (expectLineAfter === "always" && !hasNewlineAfter(lastDirective)) {
                reportError(lastDirective, "after", true);
            }

            if (expectLineAfter === "never" && hasNewlineAfter(lastDirective)) {
                reportError(lastDirective, "after", false);
            }
        }

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

        return {
            Program: checkDirectives,
            FunctionDeclaration: checkDirectives,
            FunctionExpression: checkDirectives,
            ArrowFunctionExpression: checkDirectives
        };
    }
};