|                                                                                                                                                                                                 |  | /** * @fileoverview Disallow trailing spaces at the end of lines. * @author Nodeca Team <https://github.com/nodeca>
 * @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: "Disallow trailing whitespace at the end of lines",            recommended: false,            url: "https://eslint.org/docs/latest/rules/no-trailing-spaces"        },
        fixable: "whitespace",
        schema: [            {                type: "object",                properties: {                    skipBlankLines: {                        type: "boolean",                        default: false                    },                    ignoreComments: {                        type: "boolean",                        default: false                    }                },                additionalProperties: false            }        ],
        messages: {            trailingSpace: "Trailing spaces not allowed."        }    },
    create(context) {        const sourceCode = context.sourceCode;
        const BLANK_CLASS = "[ \t\u00a0\u2000-\u200b\u3000]",            SKIP_BLANK = `^${BLANK_CLASS}*$`,            NONBLANK = `${BLANK_CLASS}+$`;
        const options = context.options[0] || {},            skipBlankLines = options.skipBlankLines || false,            ignoreComments = options.ignoreComments || false;
        /**         * Report the error message         * @param {ASTNode} node node to report         * @param {int[]} location range information         * @param {int[]} fixRange Range based on the whole program         * @returns {void}         */        function report(node, location, fixRange) {
            /*             * Passing node is a bit dirty, because message data will contain big             * text in `source`. But... who cares :) ?             * One more kludge will not make worse the bloody wizardry of this             * plugin.             */            context.report({                node,                loc: location,                messageId: "trailingSpace",                fix(fixer) {                    return fixer.removeRange(fixRange);                }            });        }
        /**         * Given a list of comment nodes, return the line numbers for those comments.         * @param {Array} comments An array of comment nodes.         * @returns {number[]} An array of line numbers containing comments.         */        function getCommentLineNumbers(comments) {            const lines = new Set();
            comments.forEach(comment => {                const endLine = comment.type === "Block"                    ? comment.loc.end.line - 1                    : comment.loc.end.line;
                for (let i = comment.loc.start.line; i <= endLine; i++) {                    lines.add(i);                }            });
            return lines;        }
        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------
        return {
            Program: function checkTrailingSpaces(node) {
                /*                 * Let's hack. Since Espree does not return whitespace nodes,                 * fetch the source code and do matching via regexps.                 */
                const re = new RegExp(NONBLANK, "u"),                    skipMatch = new RegExp(SKIP_BLANK, "u"),                    lines = sourceCode.lines,                    linebreaks = sourceCode.getText().match(astUtils.createGlobalLinebreakMatcher()),                    comments = sourceCode.getAllComments(),                    commentLineNumbers = getCommentLineNumbers(comments);
                let totalLength = 0,                    fixRange = [];
                for (let i = 0, ii = lines.length; i < ii; i++) {                    const lineNumber = i + 1;
                    /*                     * Always add linebreak length to line length to accommodate for line break (\n or \r\n)                     * Because during the fix time they also reserve one spot in the array.                     * Usually linebreak length is 2 for \r\n (CRLF) and 1 for \n (LF)                     */                    const linebreakLength = linebreaks && linebreaks[i] ? linebreaks[i].length : 1;                    const lineLength = lines[i].length + linebreakLength;
                    const matches = re.exec(lines[i]);
                    if (matches) {                        const location = {                            start: {                                line: lineNumber,                                column: matches.index                            },                            end: {                                line: lineNumber,                                column: lineLength - linebreakLength                            }                        };
                        const rangeStart = totalLength + location.start.column;                        const rangeEnd = totalLength + location.end.column;                        const containingNode = sourceCode.getNodeByRangeIndex(rangeStart);
                        if (containingNode && containingNode.type === "TemplateElement" &&                          rangeStart > containingNode.parent.range[0] &&                          rangeEnd < containingNode.parent.range[1]) {                            totalLength += lineLength;                            continue;                        }
                        /*                         * If the line has only whitespace, and skipBlankLines                         * is true, don't report it                         */                        if (skipBlankLines && skipMatch.test(lines[i])) {                            totalLength += lineLength;                            continue;                        }
                        fixRange = [rangeStart, rangeEnd];
                        if (!ignoreComments || !commentLineNumbers.has(lineNumber)) {                            report(node, location, fixRange);                        }                    }
                    totalLength += lineLength;                }            }
        };    }};
 |