feat: docker compose maybe
This commit is contained in:
		
							
								
								
									
										26
									
								
								node_modules/eslint/lib/api.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								node_modules/eslint/lib/api.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Expose out ESLint and CLI to require.
 | 
			
		||||
 * @author Ian Christian Myers
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const { ESLint } = require("./eslint");
 | 
			
		||||
const { Linter } = require("./linter");
 | 
			
		||||
const { RuleTester } = require("./rule-tester");
 | 
			
		||||
const { SourceCode } = require("./source-code");
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Exports
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    Linter,
 | 
			
		||||
    ESLint,
 | 
			
		||||
    RuleTester,
 | 
			
		||||
    SourceCode
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1078
									
								
								node_modules/eslint/lib/cli-engine/cli-engine.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1078
									
								
								node_modules/eslint/lib/cli-engine/cli-engine.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										547
									
								
								node_modules/eslint/lib/cli-engine/file-enumerator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										547
									
								
								node_modules/eslint/lib/cli-engine/file-enumerator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,547 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview `FileEnumerator` class.
 | 
			
		||||
 *
 | 
			
		||||
 * `FileEnumerator` class has two responsibilities:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Find target files by processing glob patterns.
 | 
			
		||||
 * 2. Tie each target file and appropriate configuration.
 | 
			
		||||
 *
 | 
			
		||||
 * It provides a method:
 | 
			
		||||
 *
 | 
			
		||||
 * - `iterateFiles(patterns)`
 | 
			
		||||
 *     Iterate files which are matched by given patterns together with the
 | 
			
		||||
 *     corresponded configuration. This is for `CLIEngine#executeOnFiles()`.
 | 
			
		||||
 *     While iterating files, it loads the configuration file of each directory
 | 
			
		||||
 *     before iterate files on the directory, so we can use the configuration
 | 
			
		||||
 *     files to determine target files.
 | 
			
		||||
 *
 | 
			
		||||
 * @example
 | 
			
		||||
 * const enumerator = new FileEnumerator();
 | 
			
		||||
 * const linter = new Linter();
 | 
			
		||||
 *
 | 
			
		||||
 * for (const { config, filePath } of enumerator.iterateFiles(["*.js"])) {
 | 
			
		||||
 *     const code = fs.readFileSync(filePath, "utf8");
 | 
			
		||||
 *     const messages = linter.verify(code, config, filePath);
 | 
			
		||||
 *
 | 
			
		||||
 *     console.log(messages);
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * @author Toru Nagashima <https://github.com/mysticatea>
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const fs = require("fs");
 | 
			
		||||
const path = require("path");
 | 
			
		||||
const getGlobParent = require("glob-parent");
 | 
			
		||||
const isGlob = require("is-glob");
 | 
			
		||||
const escapeRegExp = require("escape-string-regexp");
 | 
			
		||||
const { Minimatch } = require("minimatch");
 | 
			
		||||
 | 
			
		||||
const {
 | 
			
		||||
    Legacy: {
 | 
			
		||||
        IgnorePattern,
 | 
			
		||||
        CascadingConfigArrayFactory
 | 
			
		||||
    }
 | 
			
		||||
} = require("@eslint/eslintrc");
 | 
			
		||||
const debug = require("debug")("eslint:file-enumerator");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const minimatchOpts = { dot: true, matchBase: true };
 | 
			
		||||
const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/u;
 | 
			
		||||
const NONE = 0;
 | 
			
		||||
const IGNORED_SILENTLY = 1;
 | 
			
		||||
const IGNORED = 2;
 | 
			
		||||
 | 
			
		||||
// For VSCode intellisense
 | 
			
		||||
/** @typedef {ReturnType<CascadingConfigArrayFactory.getConfigArrayForFile>} ConfigArray */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {Object} FileEnumeratorOptions
 | 
			
		||||
 * @property {CascadingConfigArrayFactory} [configArrayFactory] The factory for config arrays.
 | 
			
		||||
 * @property {string} [cwd] The base directory to start lookup.
 | 
			
		||||
 * @property {string[]} [extensions] The extensions to match files for directory patterns.
 | 
			
		||||
 * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
 | 
			
		||||
 * @property {boolean} [ignore] The flag to check ignored files.
 | 
			
		||||
 * @property {string[]} [rulePaths] The value of `--rulesdir` option.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {Object} FileAndConfig
 | 
			
		||||
 * @property {string} filePath The path to a target file.
 | 
			
		||||
 * @property {ConfigArray} config The config entries of that file.
 | 
			
		||||
 * @property {boolean} ignored If `true` then this file should be ignored and warned because it was directly specified.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {Object} FileEntry
 | 
			
		||||
 * @property {string} filePath The path to a target file.
 | 
			
		||||
 * @property {ConfigArray} config The config entries of that file.
 | 
			
		||||
 * @property {NONE|IGNORED_SILENTLY|IGNORED} flag The flag.
 | 
			
		||||
 * - `NONE` means the file is a target file.
 | 
			
		||||
 * - `IGNORED_SILENTLY` means the file should be ignored silently.
 | 
			
		||||
 * - `IGNORED` means the file should be ignored and warned because it was directly specified.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {Object} FileEnumeratorInternalSlots
 | 
			
		||||
 * @property {CascadingConfigArrayFactory} configArrayFactory The factory for config arrays.
 | 
			
		||||
 * @property {string} cwd The base directory to start lookup.
 | 
			
		||||
 * @property {RegExp|null} extensionRegExp The RegExp to test if a string ends with specific file extensions.
 | 
			
		||||
 * @property {boolean} globInputPaths Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
 | 
			
		||||
 * @property {boolean} ignoreFlag The flag to check ignored files.
 | 
			
		||||
 * @property {(filePath:string, dot:boolean) => boolean} defaultIgnores The default predicate function to ignore files.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @type {WeakMap<FileEnumerator, FileEnumeratorInternalSlots>} */
 | 
			
		||||
const internalSlotsMap = new WeakMap();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a string is a glob pattern or not.
 | 
			
		||||
 * @param {string} pattern A glob pattern.
 | 
			
		||||
 * @returns {boolean} `true` if the string is a glob pattern.
 | 
			
		||||
 */
 | 
			
		||||
function isGlobPattern(pattern) {
 | 
			
		||||
    return isGlob(path.sep === "\\" ? pattern.replace(/\\/gu, "/") : pattern);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get stats of a given path.
 | 
			
		||||
 * @param {string} filePath The path to target file.
 | 
			
		||||
 * @throws {Error} As may be thrown by `fs.statSync`.
 | 
			
		||||
 * @returns {fs.Stats|null} The stats.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function statSafeSync(filePath) {
 | 
			
		||||
    try {
 | 
			
		||||
        return fs.statSync(filePath);
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
 | 
			
		||||
        /* c8 ignore next */
 | 
			
		||||
        if (error.code !== "ENOENT") {
 | 
			
		||||
            throw error;
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get filenames in a given path to a directory.
 | 
			
		||||
 * @param {string} directoryPath The path to target directory.
 | 
			
		||||
 * @throws {Error} As may be thrown by `fs.readdirSync`.
 | 
			
		||||
 * @returns {import("fs").Dirent[]} The filenames.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function readdirSafeSync(directoryPath) {
 | 
			
		||||
    try {
 | 
			
		||||
        return fs.readdirSync(directoryPath, { withFileTypes: true });
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
 | 
			
		||||
        /* c8 ignore next */
 | 
			
		||||
        if (error.code !== "ENOENT") {
 | 
			
		||||
            throw error;
 | 
			
		||||
        }
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a `RegExp` object to detect extensions.
 | 
			
		||||
 * @param {string[] | null} extensions The extensions to create.
 | 
			
		||||
 * @returns {RegExp | null} The created `RegExp` object or null.
 | 
			
		||||
 */
 | 
			
		||||
function createExtensionRegExp(extensions) {
 | 
			
		||||
    if (extensions) {
 | 
			
		||||
        const normalizedExts = extensions.map(ext => escapeRegExp(
 | 
			
		||||
            ext.startsWith(".")
 | 
			
		||||
                ? ext.slice(1)
 | 
			
		||||
                : ext
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
        return new RegExp(
 | 
			
		||||
            `.\\.(?:${normalizedExts.join("|")})$`,
 | 
			
		||||
            "u"
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when no files match a glob.
 | 
			
		||||
 */
 | 
			
		||||
class NoFilesFoundError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} pattern The glob pattern which was not found.
 | 
			
		||||
     * @param {boolean} globDisabled If `true` then the pattern was a glob pattern, but glob was disabled.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(pattern, globDisabled) {
 | 
			
		||||
        super(`No files matching '${pattern}' were found${globDisabled ? " (glob was disabled)" : ""}.`);
 | 
			
		||||
        this.messageTemplate = "file-not-found";
 | 
			
		||||
        this.messageData = { pattern, globDisabled };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when there are files matched by a glob, but all of them have been ignored.
 | 
			
		||||
 */
 | 
			
		||||
class AllFilesIgnoredError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} pattern The glob pattern which was not found.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(pattern) {
 | 
			
		||||
        super(`All files matched by '${pattern}' are ignored.`);
 | 
			
		||||
        this.messageTemplate = "all-files-ignored";
 | 
			
		||||
        this.messageData = { pattern };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class provides the functionality that enumerates every file which is
 | 
			
		||||
 * matched by given glob patterns and that configuration.
 | 
			
		||||
 */
 | 
			
		||||
class FileEnumerator {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initialize this enumerator.
 | 
			
		||||
     * @param {FileEnumeratorOptions} options The options.
 | 
			
		||||
     */
 | 
			
		||||
    constructor({
 | 
			
		||||
        cwd = process.cwd(),
 | 
			
		||||
        configArrayFactory = new CascadingConfigArrayFactory({
 | 
			
		||||
            cwd,
 | 
			
		||||
            getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
 | 
			
		||||
            getEslintAllConfig: () => require("@eslint/js").configs.all
 | 
			
		||||
        }),
 | 
			
		||||
        extensions = null,
 | 
			
		||||
        globInputPaths = true,
 | 
			
		||||
        errorOnUnmatchedPattern = true,
 | 
			
		||||
        ignore = true
 | 
			
		||||
    } = {}) {
 | 
			
		||||
        internalSlotsMap.set(this, {
 | 
			
		||||
            configArrayFactory,
 | 
			
		||||
            cwd,
 | 
			
		||||
            defaultIgnores: IgnorePattern.createDefaultIgnore(cwd),
 | 
			
		||||
            extensionRegExp: createExtensionRegExp(extensions),
 | 
			
		||||
            globInputPaths,
 | 
			
		||||
            errorOnUnmatchedPattern,
 | 
			
		||||
            ignoreFlag: ignore
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if a given file is target or not.
 | 
			
		||||
     * @param {string} filePath The path to a candidate file.
 | 
			
		||||
     * @param {ConfigArray} [providedConfig] Optional. The configuration for the file.
 | 
			
		||||
     * @returns {boolean} `true` if the file is a target.
 | 
			
		||||
     */
 | 
			
		||||
    isTargetPath(filePath, providedConfig) {
 | 
			
		||||
        const {
 | 
			
		||||
            configArrayFactory,
 | 
			
		||||
            extensionRegExp
 | 
			
		||||
        } = internalSlotsMap.get(this);
 | 
			
		||||
 | 
			
		||||
        // If `--ext` option is present, use it.
 | 
			
		||||
        if (extensionRegExp) {
 | 
			
		||||
            return extensionRegExp.test(filePath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // `.js` file is target by default.
 | 
			
		||||
        if (filePath.endsWith(".js")) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // use `overrides[].files` to check additional targets.
 | 
			
		||||
        const config =
 | 
			
		||||
            providedConfig ||
 | 
			
		||||
            configArrayFactory.getConfigArrayForFile(
 | 
			
		||||
                filePath,
 | 
			
		||||
                { ignoreNotFoundError: true }
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        return config.isAdditionalTargetPath(filePath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Iterate files which are matched by given glob patterns.
 | 
			
		||||
     * @param {string|string[]} patternOrPatterns The glob patterns to iterate files.
 | 
			
		||||
     * @throws {NoFilesFoundError|AllFilesIgnoredError} On an unmatched pattern.
 | 
			
		||||
     * @returns {IterableIterator<FileAndConfig>} The found files.
 | 
			
		||||
     */
 | 
			
		||||
    *iterateFiles(patternOrPatterns) {
 | 
			
		||||
        const { globInputPaths, errorOnUnmatchedPattern } = internalSlotsMap.get(this);
 | 
			
		||||
        const patterns = Array.isArray(patternOrPatterns)
 | 
			
		||||
            ? patternOrPatterns
 | 
			
		||||
            : [patternOrPatterns];
 | 
			
		||||
 | 
			
		||||
        debug("Start to iterate files: %o", patterns);
 | 
			
		||||
 | 
			
		||||
        // The set of paths to remove duplicate.
 | 
			
		||||
        const set = new Set();
 | 
			
		||||
 | 
			
		||||
        for (const pattern of patterns) {
 | 
			
		||||
            let foundRegardlessOfIgnored = false;
 | 
			
		||||
            let found = false;
 | 
			
		||||
 | 
			
		||||
            // Skip empty string.
 | 
			
		||||
            if (!pattern) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Iterate files of this pattern.
 | 
			
		||||
            for (const { config, filePath, flag } of this._iterateFiles(pattern)) {
 | 
			
		||||
                foundRegardlessOfIgnored = true;
 | 
			
		||||
                if (flag === IGNORED_SILENTLY) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                found = true;
 | 
			
		||||
 | 
			
		||||
                // Remove duplicate paths while yielding paths.
 | 
			
		||||
                if (!set.has(filePath)) {
 | 
			
		||||
                    set.add(filePath);
 | 
			
		||||
                    yield {
 | 
			
		||||
                        config,
 | 
			
		||||
                        filePath,
 | 
			
		||||
                        ignored: flag === IGNORED
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Raise an error if any files were not found.
 | 
			
		||||
            if (errorOnUnmatchedPattern) {
 | 
			
		||||
                if (!foundRegardlessOfIgnored) {
 | 
			
		||||
                    throw new NoFilesFoundError(
 | 
			
		||||
                        pattern,
 | 
			
		||||
                        !globInputPaths && isGlob(pattern)
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                if (!found) {
 | 
			
		||||
                    throw new AllFilesIgnoredError(pattern);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        debug(`Complete iterating files: ${JSON.stringify(patterns)}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Iterate files which are matched by a given glob pattern.
 | 
			
		||||
     * @param {string} pattern The glob pattern to iterate files.
 | 
			
		||||
     * @returns {IterableIterator<FileEntry>} The found files.
 | 
			
		||||
     */
 | 
			
		||||
    _iterateFiles(pattern) {
 | 
			
		||||
        const { cwd, globInputPaths } = internalSlotsMap.get(this);
 | 
			
		||||
        const absolutePath = path.resolve(cwd, pattern);
 | 
			
		||||
        const isDot = dotfilesPattern.test(pattern);
 | 
			
		||||
        const stat = statSafeSync(absolutePath);
 | 
			
		||||
 | 
			
		||||
        if (stat && stat.isDirectory()) {
 | 
			
		||||
            return this._iterateFilesWithDirectory(absolutePath, isDot);
 | 
			
		||||
        }
 | 
			
		||||
        if (stat && stat.isFile()) {
 | 
			
		||||
            return this._iterateFilesWithFile(absolutePath);
 | 
			
		||||
        }
 | 
			
		||||
        if (globInputPaths && isGlobPattern(pattern)) {
 | 
			
		||||
            return this._iterateFilesWithGlob(pattern, isDot);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Iterate a file which is matched by a given path.
 | 
			
		||||
     * @param {string} filePath The path to the target file.
 | 
			
		||||
     * @returns {IterableIterator<FileEntry>} The found files.
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    _iterateFilesWithFile(filePath) {
 | 
			
		||||
        debug(`File: ${filePath}`);
 | 
			
		||||
 | 
			
		||||
        const { configArrayFactory } = internalSlotsMap.get(this);
 | 
			
		||||
        const config = configArrayFactory.getConfigArrayForFile(filePath);
 | 
			
		||||
        const ignored = this._isIgnoredFile(filePath, { config, direct: true });
 | 
			
		||||
        const flag = ignored ? IGNORED : NONE;
 | 
			
		||||
 | 
			
		||||
        return [{ config, filePath, flag }];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Iterate files in a given path.
 | 
			
		||||
     * @param {string} directoryPath The path to the target directory.
 | 
			
		||||
     * @param {boolean} dotfiles If `true` then it doesn't skip dot files by default.
 | 
			
		||||
     * @returns {IterableIterator<FileEntry>} The found files.
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    _iterateFilesWithDirectory(directoryPath, dotfiles) {
 | 
			
		||||
        debug(`Directory: ${directoryPath}`);
 | 
			
		||||
 | 
			
		||||
        return this._iterateFilesRecursive(
 | 
			
		||||
            directoryPath,
 | 
			
		||||
            { dotfiles, recursive: true, selector: null }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Iterate files which are matched by a given glob pattern.
 | 
			
		||||
     * @param {string} pattern The glob pattern to iterate files.
 | 
			
		||||
     * @param {boolean} dotfiles If `true` then it doesn't skip dot files by default.
 | 
			
		||||
     * @returns {IterableIterator<FileEntry>} The found files.
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    _iterateFilesWithGlob(pattern, dotfiles) {
 | 
			
		||||
        debug(`Glob: ${pattern}`);
 | 
			
		||||
 | 
			
		||||
        const { cwd } = internalSlotsMap.get(this);
 | 
			
		||||
        const directoryPath = path.resolve(cwd, getGlobParent(pattern));
 | 
			
		||||
        const absolutePath = path.resolve(cwd, pattern);
 | 
			
		||||
        const globPart = absolutePath.slice(directoryPath.length + 1);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * recursive if there are `**` or path separators in the glob part.
 | 
			
		||||
         * Otherwise, patterns such as `src/*.js`, it doesn't need recursive.
 | 
			
		||||
         */
 | 
			
		||||
        const recursive = /\*\*|\/|\\/u.test(globPart);
 | 
			
		||||
        const selector = new Minimatch(absolutePath, minimatchOpts);
 | 
			
		||||
 | 
			
		||||
        debug(`recursive? ${recursive}`);
 | 
			
		||||
 | 
			
		||||
        return this._iterateFilesRecursive(
 | 
			
		||||
            directoryPath,
 | 
			
		||||
            { dotfiles, recursive, selector }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Iterate files in a given path.
 | 
			
		||||
     * @param {string} directoryPath The path to the target directory.
 | 
			
		||||
     * @param {Object} options The options to iterate files.
 | 
			
		||||
     * @param {boolean} [options.dotfiles] If `true` then it doesn't skip dot files by default.
 | 
			
		||||
     * @param {boolean} [options.recursive] If `true` then it dives into sub directories.
 | 
			
		||||
     * @param {InstanceType<Minimatch>} [options.selector] The matcher to choose files.
 | 
			
		||||
     * @returns {IterableIterator<FileEntry>} The found files.
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    *_iterateFilesRecursive(directoryPath, options) {
 | 
			
		||||
        debug(`Enter the directory: ${directoryPath}`);
 | 
			
		||||
        const { configArrayFactory } = internalSlotsMap.get(this);
 | 
			
		||||
 | 
			
		||||
        /** @type {ConfigArray|null} */
 | 
			
		||||
        let config = null;
 | 
			
		||||
 | 
			
		||||
        // Enumerate the files of this directory.
 | 
			
		||||
        for (const entry of readdirSafeSync(directoryPath)) {
 | 
			
		||||
            const filePath = path.join(directoryPath, entry.name);
 | 
			
		||||
            const fileInfo = entry.isSymbolicLink() ? statSafeSync(filePath) : entry;
 | 
			
		||||
 | 
			
		||||
            if (!fileInfo) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Check if the file is matched.
 | 
			
		||||
            if (fileInfo.isFile()) {
 | 
			
		||||
                if (!config) {
 | 
			
		||||
                    config = configArrayFactory.getConfigArrayForFile(
 | 
			
		||||
                        filePath,
 | 
			
		||||
 | 
			
		||||
                        /*
 | 
			
		||||
                         * We must ignore `ConfigurationNotFoundError` at this
 | 
			
		||||
                         * point because we don't know if target files exist in
 | 
			
		||||
                         * this directory.
 | 
			
		||||
                         */
 | 
			
		||||
                        { ignoreNotFoundError: true }
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                const matched = options.selector
 | 
			
		||||
 | 
			
		||||
                    // Started with a glob pattern; choose by the pattern.
 | 
			
		||||
                    ? options.selector.match(filePath)
 | 
			
		||||
 | 
			
		||||
                    // Started with a directory path; choose by file extensions.
 | 
			
		||||
                    : this.isTargetPath(filePath, config);
 | 
			
		||||
 | 
			
		||||
                if (matched) {
 | 
			
		||||
                    const ignored = this._isIgnoredFile(filePath, { ...options, config });
 | 
			
		||||
                    const flag = ignored ? IGNORED_SILENTLY : NONE;
 | 
			
		||||
 | 
			
		||||
                    debug(`Yield: ${entry.name}${ignored ? " but ignored" : ""}`);
 | 
			
		||||
                    yield {
 | 
			
		||||
                        config: configArrayFactory.getConfigArrayForFile(filePath),
 | 
			
		||||
                        filePath,
 | 
			
		||||
                        flag
 | 
			
		||||
                    };
 | 
			
		||||
                } else {
 | 
			
		||||
                    debug(`Didn't match: ${entry.name}`);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            // Dive into the sub directory.
 | 
			
		||||
            } else if (options.recursive && fileInfo.isDirectory()) {
 | 
			
		||||
                if (!config) {
 | 
			
		||||
                    config = configArrayFactory.getConfigArrayForFile(
 | 
			
		||||
                        filePath,
 | 
			
		||||
                        { ignoreNotFoundError: true }
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                const ignored = this._isIgnoredFile(
 | 
			
		||||
                    filePath + path.sep,
 | 
			
		||||
                    { ...options, config }
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                if (!ignored) {
 | 
			
		||||
                    yield* this._iterateFilesRecursive(filePath, options);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        debug(`Leave the directory: ${directoryPath}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if a given file should be ignored.
 | 
			
		||||
     * @param {string} filePath The path to a file to check.
 | 
			
		||||
     * @param {Object} options Options
 | 
			
		||||
     * @param {ConfigArray} [options.config] The config for this file.
 | 
			
		||||
     * @param {boolean} [options.dotfiles] If `true` then this is not ignore dot files by default.
 | 
			
		||||
     * @param {boolean} [options.direct] If `true` then this is a direct specified file.
 | 
			
		||||
     * @returns {boolean} `true` if the file should be ignored.
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    _isIgnoredFile(filePath, {
 | 
			
		||||
        config: providedConfig,
 | 
			
		||||
        dotfiles = false,
 | 
			
		||||
        direct = false
 | 
			
		||||
    }) {
 | 
			
		||||
        const {
 | 
			
		||||
            configArrayFactory,
 | 
			
		||||
            defaultIgnores,
 | 
			
		||||
            ignoreFlag
 | 
			
		||||
        } = internalSlotsMap.get(this);
 | 
			
		||||
 | 
			
		||||
        if (ignoreFlag) {
 | 
			
		||||
            const config =
 | 
			
		||||
                providedConfig ||
 | 
			
		||||
                configArrayFactory.getConfigArrayForFile(
 | 
			
		||||
                    filePath,
 | 
			
		||||
                    { ignoreNotFoundError: true }
 | 
			
		||||
                );
 | 
			
		||||
            const ignores =
 | 
			
		||||
                config.extractConfig(filePath).ignores || defaultIgnores;
 | 
			
		||||
 | 
			
		||||
            return ignores(filePath, dotfiles);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return !direct && defaultIgnores(filePath, dotfiles);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = { FileEnumerator };
 | 
			
		||||
							
								
								
									
										60
									
								
								node_modules/eslint/lib/cli-engine/formatters/checkstyle.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								node_modules/eslint/lib/cli-engine/formatters/checkstyle.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview CheckStyle XML reporter
 | 
			
		||||
 * @author Ian Christian Myers
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const xmlEscape = require("../xml-escape");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helper Functions
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the severity of warning or error
 | 
			
		||||
 * @param {Object} message message object to examine
 | 
			
		||||
 * @returns {string} severity level
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function getMessageType(message) {
 | 
			
		||||
    if (message.fatal || message.severity === 2) {
 | 
			
		||||
        return "error";
 | 
			
		||||
    }
 | 
			
		||||
    return "warning";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
 | 
			
		||||
    let output = "";
 | 
			
		||||
 | 
			
		||||
    output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
 | 
			
		||||
    output += "<checkstyle version=\"4.3\">";
 | 
			
		||||
 | 
			
		||||
    results.forEach(result => {
 | 
			
		||||
        const messages = result.messages;
 | 
			
		||||
 | 
			
		||||
        output += `<file name="${xmlEscape(result.filePath)}">`;
 | 
			
		||||
 | 
			
		||||
        messages.forEach(message => {
 | 
			
		||||
            output += [
 | 
			
		||||
                `<error line="${xmlEscape(message.line || 0)}"`,
 | 
			
		||||
                `column="${xmlEscape(message.column || 0)}"`,
 | 
			
		||||
                `severity="${xmlEscape(getMessageType(message))}"`,
 | 
			
		||||
                `message="${xmlEscape(message.message)}${message.ruleId ? ` (${message.ruleId})` : ""}"`,
 | 
			
		||||
                `source="${message.ruleId ? xmlEscape(`eslint.rules.${message.ruleId}`) : ""}" />`
 | 
			
		||||
            ].join(" ");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        output += "</file>";
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    output += "</checkstyle>";
 | 
			
		||||
 | 
			
		||||
    return output;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										60
									
								
								node_modules/eslint/lib/cli-engine/formatters/compact.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								node_modules/eslint/lib/cli-engine/formatters/compact.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Compact reporter
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helper Functions
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the severity of warning or error
 | 
			
		||||
 * @param {Object} message message object to examine
 | 
			
		||||
 * @returns {string} severity level
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function getMessageType(message) {
 | 
			
		||||
    if (message.fatal || message.severity === 2) {
 | 
			
		||||
        return "Error";
 | 
			
		||||
    }
 | 
			
		||||
    return "Warning";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
 | 
			
		||||
    let output = "",
 | 
			
		||||
        total = 0;
 | 
			
		||||
 | 
			
		||||
    results.forEach(result => {
 | 
			
		||||
 | 
			
		||||
        const messages = result.messages;
 | 
			
		||||
 | 
			
		||||
        total += messages.length;
 | 
			
		||||
 | 
			
		||||
        messages.forEach(message => {
 | 
			
		||||
 | 
			
		||||
            output += `${result.filePath}: `;
 | 
			
		||||
            output += `line ${message.line || 0}`;
 | 
			
		||||
            output += `, col ${message.column || 0}`;
 | 
			
		||||
            output += `, ${getMessageType(message)}`;
 | 
			
		||||
            output += ` - ${message.message}`;
 | 
			
		||||
            output += message.ruleId ? ` (${message.ruleId})` : "";
 | 
			
		||||
            output += "\n";
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (total > 0) {
 | 
			
		||||
        output += `\n${total} problem${total !== 1 ? "s" : ""}`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return output;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										46
									
								
								node_modules/eslint/lib/cli-engine/formatters/formatters-meta.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								node_modules/eslint/lib/cli-engine/formatters/formatters-meta.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "name": "checkstyle",
 | 
			
		||||
        "description": "Outputs results to the [Checkstyle](https://checkstyle.sourceforge.io/) format."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "compact",
 | 
			
		||||
        "description": "Human-readable output format. Mimics the default output of JSHint."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "html",
 | 
			
		||||
        "description": "Outputs results to HTML. The `html` formatter is useful for visual presentation in the browser."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "jslint-xml",
 | 
			
		||||
        "description": "Outputs results to format compatible with the [JSLint Jenkins plugin](https://plugins.jenkins.io/jslint/)."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "json-with-metadata",
 | 
			
		||||
        "description": "Outputs JSON-serialized results. The `json-with-metadata` provides the same linting results as the [`json`](#json) formatter with additional metadata about the rules applied. The linting results are included in the `results` property and the rules metadata is included in the `metadata` property.\n\nAlternatively, you can use the [ESLint Node.js API](../../integrate/nodejs-api) to programmatically use ESLint."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "json",
 | 
			
		||||
        "description": "Outputs JSON-serialized results. The `json` formatter is useful when you want to programmatically work with the CLI's linting results.\n\nAlternatively, you can use the [ESLint Node.js API](../../integrate/nodejs-api) to programmatically use ESLint."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "junit",
 | 
			
		||||
        "description": "Outputs results to format compatible with the [JUnit Jenkins plugin](https://plugins.jenkins.io/junit/)."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "stylish",
 | 
			
		||||
        "description": "Human-readable output format. This is the default formatter."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "tap",
 | 
			
		||||
        "description": "Outputs results to the [Test Anything Protocol (TAP)](https://testanything.org/) specification format."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "unix",
 | 
			
		||||
        "description": "Outputs results to a format similar to many commands in UNIX-like systems. Parsable with tools such as [grep](https://www.gnu.org/software/grep/manual/grep.html), [sed](https://www.gnu.org/software/sed/manual/sed.html), and [awk](https://www.gnu.org/software/gawk/manual/gawk.html)."
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "visualstudio",
 | 
			
		||||
        "description": "Outputs results to format compatible with the integrated terminal of the [Visual Studio](https://visualstudio.microsoft.com/) IDE. When using Visual Studio, you can click on the linting results in the integrated terminal to go to the issue in the source code."
 | 
			
		||||
    }
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										351
									
								
								node_modules/eslint/lib/cli-engine/formatters/html.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										351
									
								
								node_modules/eslint/lib/cli-engine/formatters/html.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,351 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview HTML reporter
 | 
			
		||||
 * @author Julian Laval
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const encodeHTML = (function() {
 | 
			
		||||
    const encodeHTMLRules = {
 | 
			
		||||
        "&": "&",
 | 
			
		||||
        "<": "<",
 | 
			
		||||
        ">": ">",
 | 
			
		||||
        '"': """,
 | 
			
		||||
        "'": "'"
 | 
			
		||||
    };
 | 
			
		||||
    const matchHTML = /[&<>"']/ug;
 | 
			
		||||
 | 
			
		||||
    return function(code) {
 | 
			
		||||
        return code
 | 
			
		||||
            ? code.toString().replace(matchHTML, m => encodeHTMLRules[m] || m)
 | 
			
		||||
            : "";
 | 
			
		||||
    };
 | 
			
		||||
}());
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the final HTML document.
 | 
			
		||||
 * @param {Object} it data for the document.
 | 
			
		||||
 * @returns {string} HTML document.
 | 
			
		||||
 */
 | 
			
		||||
function pageTemplate(it) {
 | 
			
		||||
    const { reportColor, reportSummary, date, results } = it;
 | 
			
		||||
 | 
			
		||||
    return `
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <meta charset="UTF-8">
 | 
			
		||||
        <title>ESLint Report</title>
 | 
			
		||||
        <link rel="icon" type="image/png" sizes="any" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAHaAAAB2gGFomX7AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABD1JREFUWMPFl11sk2UUx3/nbYtjxS1MF7MLMTECMgSTtSSyrQkLhAj7UBPnDSEGoxegGzMwojhXVpmTAA5iYpSoMQa8GBhFOrMFk03buei6yRAlcmOM0SEmU9d90b19jxcM1o5+sGnsc/e+z/l6ztf/HFFVMnns6QieeOCHBePGsHM+wrOtvLG2C4WRVDSSygNV7sCjlspxwDnPB44aols/DXk+mbMBmx/6OseITF1CuOtfevkPh2Uu+/jbdX8lujSScRlT5r7/QDlAfsRmfzmpnkQ/H3H13gf6bBrBn1uqK8WylgEnU8eZmk1repbfchJG1TyKyIKEwuBHFd3lD3naY3O1siiwXsVoBV2VgM1ht/QQUJk2ByqKghsQziYQ8ifKgexIXmuyzC4r67Y7R+xPAfuB/Nn3Cpva+0s7khpQVtZtd4bt51BWxtBYAiciprG7c7D4SixzU9PYalDL6110Ifb/w8W9eY7JqFeFHbO8fPGyLHwwFHJNJTSgwtVTB9oaw9BlQ+tO93vOxypoaQnfEYlI43SeCHDC4TDq9+51/h5fxr33q0ZfV9g04wat9Q943rjJgCp3952W2i8Bi6eDvdsfKj0cK/DYMRyXL4/sUJUmIHd2zYMezsvLaamp4WpcWN3BXSiHpuMwbGbZlnZ8tXY4rgosy+G7oRwQ0cAsd28YGgqfU5UjCZQDLALxDg+Hv/P5Rqvj4hwrS8izXzWb4spwc1GgENFnkpWRzxeuB+ssUHgLdb9UVdt8vpGdKQpze7n7y1U3DBChNRUuqOo9c+0+qpKKxyZqtAIYla7gY4JszAAQri93BSsMRZoyBcUC+w3Q3AyOA4sNhAOZ0q7Iq0b2vUNvK5zPgP+/H8+Zetdoa6uOikhdGurxebwvJY8Iz3V1rTMNAH+opEuQj5KTT/qA1yC+wyUjBm12OidaUtCcPNNX2h0Hx2JG69VulANZAJZJwfU7rzd/FHixuXniTdM0m4GtSQT7bTartqEh9yfImUEzkwKZmTwmo5a5JwkYBfcDL01/RkR5y8iWhtPBknB8ZxwtU9UjwOrrKCeizzc25nTGg1F/turEHoU9wMLpDvWKf8DTmNCAKnd/tqUTF4ElMXJ+A5rWDJS+41WsGWzALhJ+ErBWrLj9g+pqojHxlXJX8HGUg0BsR/x1yhxf3jm4cSzpQFLp6tmi6PEE7g1ZhtZ91ufpSZUAFa6gC+UoQslNaSmypT1U8mHKiUgEKS8KfgF4EpYunFI16tsHin+OG0LcgQK7yj7g6cSzpva2D3hKVNG0Y3mVO1BkqfSlmJrHBQ4uvM12gJHc6ETW8HZVfMRmXvyxxNC1Z/o839zyXlDuCr4nsC11J+MXueaVJWn6yPv+/pJtc9oLTNN4AeTvNGByd3rlhE2x9s5pLwDoHCy+grDzWmOZ95lUtLYj5Bma126Y8eX0/zj/ADxGyViSg4BXAAAAAElFTkSuQmCC">
 | 
			
		||||
        <link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PScwIDAgMjk0LjgyNSAyNTguOTgyJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPg0KPHBhdGggZmlsbD0nIzgwODBGMicgZD0nTTk3LjAyMSw5OS4wMTZsNDguNDMyLTI3Ljk2MmMxLjIxMi0wLjcsMi43MDYtMC43LDMuOTE4LDBsNDguNDMzLDI3Ljk2MiBjMS4yMTEsMC43LDEuOTU5LDEuOTkzLDEuOTU5LDMuMzkzdjU1LjkyNGMwLDEuMzk5LTAuNzQ4LDIuNjkzLTEuOTU5LDMuMzk0bC00OC40MzMsMjcuOTYyYy0xLjIxMiwwLjctMi43MDYsMC43LTMuOTE4LDAgbC00OC40MzItMjcuOTYyYy0xLjIxMi0wLjctMS45NTktMS45OTQtMS45NTktMy4zOTR2LTU1LjkyNEM5NS4wNjMsMTAxLjAwOSw5NS44MSw5OS43MTYsOTcuMDIxLDk5LjAxNicvPg0KPHBhdGggZmlsbD0nIzRCMzJDMycgZD0nTTI3My4zMzYsMTI0LjQ4OEwyMTUuNDY5LDIzLjgxNmMtMi4xMDItMy42NC01Ljk4NS02LjMyNS0xMC4xODgtNi4zMjVIODkuNTQ1IGMtNC4yMDQsMC04LjA4OCwyLjY4NS0xMC4xOSw2LjMyNWwtNTcuODY3LDEwMC40NWMtMi4xMDIsMy42NDEtMi4xMDIsOC4yMzYsMCwxMS44NzdsNTcuODY3LDk5Ljg0NyBjMi4xMDIsMy42NCw1Ljk4Niw1LjUwMSwxMC4xOSw1LjUwMWgxMTUuNzM1YzQuMjAzLDAsOC4wODctMS44MDUsMTAuMTg4LTUuNDQ2bDU3Ljg2Ny0xMDAuMDEgQzI3NS40MzksMTMyLjM5NiwyNzUuNDM5LDEyOC4xMjgsMjczLjMzNiwxMjQuNDg4IE0yMjUuNDE5LDE3Mi44OThjMCwxLjQ4LTAuODkxLDIuODQ5LTIuMTc0LDMuNTlsLTczLjcxLDQyLjUyNyBjLTEuMjgyLDAuNzQtMi44ODgsMC43NC00LjE3LDBsLTczLjc2Ny00Mi41MjdjLTEuMjgyLTAuNzQxLTIuMTc5LTIuMTA5LTIuMTc5LTMuNTlWODcuODQzYzAtMS40ODEsMC44ODQtMi44NDksMi4xNjctMy41OSBsNzMuNzA3LTQyLjUyN2MxLjI4Mi0wLjc0MSwyLjg4Ni0wLjc0MSw0LjE2OCwwbDczLjc3Miw0Mi41MjdjMS4yODMsMC43NDEsMi4xODYsMi4xMDksMi4xODYsMy41OVYxNzIuODk4eicvPg0KPC9zdmc+">
 | 
			
		||||
        <style>
 | 
			
		||||
            body {
 | 
			
		||||
                font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
 | 
			
		||||
                font-size: 16px;
 | 
			
		||||
                font-weight: normal;
 | 
			
		||||
                margin: 0;
 | 
			
		||||
                padding: 0;
 | 
			
		||||
                color: #333;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #overview {
 | 
			
		||||
                padding: 20px 30px;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            td,
 | 
			
		||||
            th {
 | 
			
		||||
                padding: 5px 10px;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            h1 {
 | 
			
		||||
                margin: 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            table {
 | 
			
		||||
                margin: 30px;
 | 
			
		||||
                width: calc(100% - 60px);
 | 
			
		||||
                max-width: 1000px;
 | 
			
		||||
                border-radius: 5px;
 | 
			
		||||
                border: 1px solid #ddd;
 | 
			
		||||
                border-spacing: 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            th {
 | 
			
		||||
                font-weight: 400;
 | 
			
		||||
                font-size: medium;
 | 
			
		||||
                text-align: left;
 | 
			
		||||
                cursor: pointer;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            td.clr-1,
 | 
			
		||||
            td.clr-2,
 | 
			
		||||
            th span {
 | 
			
		||||
                font-weight: 700;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            th span {
 | 
			
		||||
                float: right;
 | 
			
		||||
                margin-left: 20px;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            th span::after {
 | 
			
		||||
                content: "";
 | 
			
		||||
                clear: both;
 | 
			
		||||
                display: block;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tr:last-child td {
 | 
			
		||||
                border-bottom: none;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tr td:first-child,
 | 
			
		||||
            tr td:last-child {
 | 
			
		||||
                color: #9da0a4;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #overview.bg-0,
 | 
			
		||||
            tr.bg-0 th {
 | 
			
		||||
                color: #468847;
 | 
			
		||||
                background: #dff0d8;
 | 
			
		||||
                border-bottom: 1px solid #d6e9c6;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #overview.bg-1,
 | 
			
		||||
            tr.bg-1 th {
 | 
			
		||||
                color: #f0ad4e;
 | 
			
		||||
                background: #fcf8e3;
 | 
			
		||||
                border-bottom: 1px solid #fbeed5;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #overview.bg-2,
 | 
			
		||||
            tr.bg-2 th {
 | 
			
		||||
                color: #b94a48;
 | 
			
		||||
                background: #f2dede;
 | 
			
		||||
                border-bottom: 1px solid #eed3d7;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            td {
 | 
			
		||||
                border-bottom: 1px solid #ddd;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            td.clr-1 {
 | 
			
		||||
                color: #f0ad4e;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            td.clr-2 {
 | 
			
		||||
                color: #b94a48;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            td a {
 | 
			
		||||
                color: #3a33d1;
 | 
			
		||||
                text-decoration: none;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            td a:hover {
 | 
			
		||||
                color: #272296;
 | 
			
		||||
                text-decoration: underline;
 | 
			
		||||
            }
 | 
			
		||||
        </style>
 | 
			
		||||
    </head>
 | 
			
		||||
    <body>
 | 
			
		||||
        <div id="overview" class="bg-${reportColor}">
 | 
			
		||||
            <h1>ESLint Report</h1>
 | 
			
		||||
            <div>
 | 
			
		||||
                <span>${reportSummary}</span> - Generated on ${date}
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <table>
 | 
			
		||||
            <tbody>
 | 
			
		||||
                ${results}
 | 
			
		||||
            </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
        <script type="text/javascript">
 | 
			
		||||
            var groups = document.querySelectorAll("tr[data-group]");
 | 
			
		||||
            for (i = 0; i < groups.length; i++) {
 | 
			
		||||
                groups[i].addEventListener("click", function() {
 | 
			
		||||
                    var inGroup = document.getElementsByClassName(this.getAttribute("data-group"));
 | 
			
		||||
                    this.innerHTML = (this.innerHTML.indexOf("+") > -1) ? this.innerHTML.replace("+", "-") : this.innerHTML.replace("-", "+");
 | 
			
		||||
                    for (var j = 0; j < inGroup.length; j++) {
 | 
			
		||||
                        inGroup[j].style.display = (inGroup[j].style.display !== "none") ? "none" : "table-row";
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        </script>
 | 
			
		||||
    </body>
 | 
			
		||||
</html>
 | 
			
		||||
`.trimStart();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Given a word and a count, append an s if count is not one.
 | 
			
		||||
 * @param {string} word A word in its singular form.
 | 
			
		||||
 * @param {int} count A number controlling whether word should be pluralized.
 | 
			
		||||
 * @returns {string} The original word with an s on the end if count is not one.
 | 
			
		||||
 */
 | 
			
		||||
function pluralize(word, count) {
 | 
			
		||||
    return (count === 1 ? word : `${word}s`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Renders text along the template of x problems (x errors, x warnings)
 | 
			
		||||
 * @param {string} totalErrors Total errors
 | 
			
		||||
 * @param {string} totalWarnings Total warnings
 | 
			
		||||
 * @returns {string} The formatted string, pluralized where necessary
 | 
			
		||||
 */
 | 
			
		||||
function renderSummary(totalErrors, totalWarnings) {
 | 
			
		||||
    const totalProblems = totalErrors + totalWarnings;
 | 
			
		||||
    let renderedText = `${totalProblems} ${pluralize("problem", totalProblems)}`;
 | 
			
		||||
 | 
			
		||||
    if (totalProblems !== 0) {
 | 
			
		||||
        renderedText += ` (${totalErrors} ${pluralize("error", totalErrors)}, ${totalWarnings} ${pluralize("warning", totalWarnings)})`;
 | 
			
		||||
    }
 | 
			
		||||
    return renderedText;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the color based on whether there are errors/warnings...
 | 
			
		||||
 * @param {string} totalErrors Total errors
 | 
			
		||||
 * @param {string} totalWarnings Total warnings
 | 
			
		||||
 * @returns {int} The color code (0 = green, 1 = yellow, 2 = red)
 | 
			
		||||
 */
 | 
			
		||||
function renderColor(totalErrors, totalWarnings) {
 | 
			
		||||
    if (totalErrors !== 0) {
 | 
			
		||||
        return 2;
 | 
			
		||||
    }
 | 
			
		||||
    if (totalWarnings !== 0) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get HTML (table row) describing a single message.
 | 
			
		||||
 * @param {Object} it data for the message.
 | 
			
		||||
 * @returns {string} HTML (table row) describing the message.
 | 
			
		||||
 */
 | 
			
		||||
function messageTemplate(it) {
 | 
			
		||||
    const {
 | 
			
		||||
        parentIndex,
 | 
			
		||||
        lineNumber,
 | 
			
		||||
        columnNumber,
 | 
			
		||||
        severityNumber,
 | 
			
		||||
        severityName,
 | 
			
		||||
        message,
 | 
			
		||||
        ruleUrl,
 | 
			
		||||
        ruleId
 | 
			
		||||
    } = it;
 | 
			
		||||
 | 
			
		||||
    return `
 | 
			
		||||
<tr style="display: none;" class="f-${parentIndex}">
 | 
			
		||||
    <td>${lineNumber}:${columnNumber}</td>
 | 
			
		||||
    <td class="clr-${severityNumber}">${severityName}</td>
 | 
			
		||||
    <td>${encodeHTML(message)}</td>
 | 
			
		||||
    <td>
 | 
			
		||||
        <a href="${ruleUrl ? ruleUrl : ""}" target="_blank" rel="noopener noreferrer">${ruleId ? ruleId : ""}</a>
 | 
			
		||||
    </td>
 | 
			
		||||
</tr>
 | 
			
		||||
`.trimStart();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get HTML (table rows) describing the messages.
 | 
			
		||||
 * @param {Array} messages Messages.
 | 
			
		||||
 * @param {int} parentIndex Index of the parent HTML row.
 | 
			
		||||
 * @param {Object} rulesMeta Dictionary containing metadata for each rule executed by the analysis.
 | 
			
		||||
 * @returns {string} HTML (table rows) describing the messages.
 | 
			
		||||
 */
 | 
			
		||||
function renderMessages(messages, parentIndex, rulesMeta) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get HTML (table row) describing a message.
 | 
			
		||||
     * @param {Object} message Message.
 | 
			
		||||
     * @returns {string} HTML (table row) describing a message.
 | 
			
		||||
     */
 | 
			
		||||
    return messages.map(message => {
 | 
			
		||||
        const lineNumber = message.line || 0;
 | 
			
		||||
        const columnNumber = message.column || 0;
 | 
			
		||||
        let ruleUrl;
 | 
			
		||||
 | 
			
		||||
        if (rulesMeta) {
 | 
			
		||||
            const meta = rulesMeta[message.ruleId];
 | 
			
		||||
 | 
			
		||||
            if (meta && meta.docs && meta.docs.url) {
 | 
			
		||||
                ruleUrl = meta.docs.url;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return messageTemplate({
 | 
			
		||||
            parentIndex,
 | 
			
		||||
            lineNumber,
 | 
			
		||||
            columnNumber,
 | 
			
		||||
            severityNumber: message.severity,
 | 
			
		||||
            severityName: message.severity === 1 ? "Warning" : "Error",
 | 
			
		||||
            message: message.message,
 | 
			
		||||
            ruleId: message.ruleId,
 | 
			
		||||
            ruleUrl
 | 
			
		||||
        });
 | 
			
		||||
    }).join("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get HTML (table row) describing the result for a single file.
 | 
			
		||||
 * @param {Object} it data for the file.
 | 
			
		||||
 * @returns {string} HTML (table row) describing the result for the file.
 | 
			
		||||
 */
 | 
			
		||||
function resultTemplate(it) {
 | 
			
		||||
    const { color, index, filePath, summary } = it;
 | 
			
		||||
 | 
			
		||||
    return `
 | 
			
		||||
<tr class="bg-${color}" data-group="f-${index}">
 | 
			
		||||
    <th colspan="4">
 | 
			
		||||
        [+] ${encodeHTML(filePath)}
 | 
			
		||||
        <span>${encodeHTML(summary)}</span>
 | 
			
		||||
    </th>
 | 
			
		||||
</tr>
 | 
			
		||||
`.trimStart();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Render the results.
 | 
			
		||||
 * @param {Array} results Test results.
 | 
			
		||||
 * @param {Object} rulesMeta Dictionary containing metadata for each rule executed by the analysis.
 | 
			
		||||
 * @returns {string} HTML string describing the results.
 | 
			
		||||
 */
 | 
			
		||||
function renderResults(results, rulesMeta) {
 | 
			
		||||
    return results.map((result, index) => resultTemplate({
 | 
			
		||||
        index,
 | 
			
		||||
        color: renderColor(result.errorCount, result.warningCount),
 | 
			
		||||
        filePath: result.filePath,
 | 
			
		||||
        summary: renderSummary(result.errorCount, result.warningCount)
 | 
			
		||||
    }) + renderMessages(result.messages, index, rulesMeta)).join("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results, data) {
 | 
			
		||||
    let totalErrors,
 | 
			
		||||
        totalWarnings;
 | 
			
		||||
 | 
			
		||||
    const metaData = data ? data.rulesMeta : {};
 | 
			
		||||
 | 
			
		||||
    totalErrors = 0;
 | 
			
		||||
    totalWarnings = 0;
 | 
			
		||||
 | 
			
		||||
    // Iterate over results to get totals
 | 
			
		||||
    results.forEach(result => {
 | 
			
		||||
        totalErrors += result.errorCount;
 | 
			
		||||
        totalWarnings += result.warningCount;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return pageTemplate({
 | 
			
		||||
        date: new Date(),
 | 
			
		||||
        reportColor: renderColor(totalErrors, totalWarnings),
 | 
			
		||||
        reportSummary: renderSummary(totalErrors, totalWarnings),
 | 
			
		||||
        results: renderResults(results, metaData)
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										41
									
								
								node_modules/eslint/lib/cli-engine/formatters/jslint-xml.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								node_modules/eslint/lib/cli-engine/formatters/jslint-xml.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview JSLint XML reporter
 | 
			
		||||
 * @author Ian Christian Myers
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const xmlEscape = require("../xml-escape");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
 | 
			
		||||
    let output = "";
 | 
			
		||||
 | 
			
		||||
    output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
 | 
			
		||||
    output += "<jslint>";
 | 
			
		||||
 | 
			
		||||
    results.forEach(result => {
 | 
			
		||||
        const messages = result.messages;
 | 
			
		||||
 | 
			
		||||
        output += `<file name="${result.filePath}">`;
 | 
			
		||||
 | 
			
		||||
        messages.forEach(message => {
 | 
			
		||||
            output += [
 | 
			
		||||
                `<issue line="${message.line}"`,
 | 
			
		||||
                `char="${message.column}"`,
 | 
			
		||||
                `evidence="${xmlEscape(message.source || "")}"`,
 | 
			
		||||
                `reason="${xmlEscape(message.message || "")}${message.ruleId ? ` (${message.ruleId})` : ""}" />`
 | 
			
		||||
            ].join(" ");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        output += "</file>";
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    output += "</jslint>";
 | 
			
		||||
 | 
			
		||||
    return output;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										16
									
								
								node_modules/eslint/lib/cli-engine/formatters/json-with-metadata.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								node_modules/eslint/lib/cli-engine/formatters/json-with-metadata.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview JSON reporter, including rules metadata
 | 
			
		||||
 * @author Chris Meyer
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results, data) {
 | 
			
		||||
    return JSON.stringify({
 | 
			
		||||
        results,
 | 
			
		||||
        metadata: data
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										13
									
								
								node_modules/eslint/lib/cli-engine/formatters/json.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								node_modules/eslint/lib/cli-engine/formatters/json.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview JSON reporter
 | 
			
		||||
 * @author Burak Yigit Kaya aka BYK
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
    return JSON.stringify(results);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										82
									
								
								node_modules/eslint/lib/cli-engine/formatters/junit.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								node_modules/eslint/lib/cli-engine/formatters/junit.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview jUnit Reporter
 | 
			
		||||
 * @author Jamund Ferguson
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const xmlEscape = require("../xml-escape");
 | 
			
		||||
const path = require("path");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helper Functions
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the severity of warning or error
 | 
			
		||||
 * @param {Object} message message object to examine
 | 
			
		||||
 * @returns {string} severity level
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function getMessageType(message) {
 | 
			
		||||
    if (message.fatal || message.severity === 2) {
 | 
			
		||||
        return "Error";
 | 
			
		||||
    }
 | 
			
		||||
    return "Warning";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a full file path without extension
 | 
			
		||||
 * @param {string} filePath input file path
 | 
			
		||||
 * @returns {string} file path without extension
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function pathWithoutExt(filePath) {
 | 
			
		||||
    return path.join(path.dirname(filePath), path.basename(filePath, path.extname(filePath)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
 | 
			
		||||
    let output = "";
 | 
			
		||||
 | 
			
		||||
    output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 | 
			
		||||
    output += "<testsuites>\n";
 | 
			
		||||
 | 
			
		||||
    results.forEach(result => {
 | 
			
		||||
 | 
			
		||||
        const messages = result.messages;
 | 
			
		||||
        const classname = pathWithoutExt(result.filePath);
 | 
			
		||||
 | 
			
		||||
        if (messages.length > 0) {
 | 
			
		||||
            output += `<testsuite package="org.eslint" time="0" tests="${messages.length}" errors="${messages.length}" name="${result.filePath}">\n`;
 | 
			
		||||
            messages.forEach(message => {
 | 
			
		||||
                const type = message.fatal ? "error" : "failure";
 | 
			
		||||
 | 
			
		||||
                output += `<testcase time="0" name="org.eslint.${message.ruleId || "unknown"}" classname="${classname}">`;
 | 
			
		||||
                output += `<${type} message="${xmlEscape(message.message || "")}">`;
 | 
			
		||||
                output += "<![CDATA[";
 | 
			
		||||
                output += `line ${message.line || 0}, col `;
 | 
			
		||||
                output += `${message.column || 0}, ${getMessageType(message)}`;
 | 
			
		||||
                output += ` - ${xmlEscape(message.message || "")}`;
 | 
			
		||||
                output += (message.ruleId ? ` (${message.ruleId})` : "");
 | 
			
		||||
                output += "]]>";
 | 
			
		||||
                output += `</${type}>`;
 | 
			
		||||
                output += "</testcase>\n";
 | 
			
		||||
            });
 | 
			
		||||
            output += "</testsuite>\n";
 | 
			
		||||
        } else {
 | 
			
		||||
            output += `<testsuite package="org.eslint" time="0" tests="1" errors="0" name="${result.filePath}">\n`;
 | 
			
		||||
            output += `<testcase time="0" name="${result.filePath}" classname="${classname}" />\n`;
 | 
			
		||||
            output += "</testsuite>\n";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    output += "</testsuites>\n";
 | 
			
		||||
 | 
			
		||||
    return output;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										101
									
								
								node_modules/eslint/lib/cli-engine/formatters/stylish.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								node_modules/eslint/lib/cli-engine/formatters/stylish.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Stylish reporter
 | 
			
		||||
 * @author Sindre Sorhus
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const chalk = require("chalk"),
 | 
			
		||||
    stripAnsi = require("strip-ansi"),
 | 
			
		||||
    table = require("text-table");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Given a word and a count, append an s if count is not one.
 | 
			
		||||
 * @param {string} word A word in its singular form.
 | 
			
		||||
 * @param {int} count A number controlling whether word should be pluralized.
 | 
			
		||||
 * @returns {string} The original word with an s on the end if count is not one.
 | 
			
		||||
 */
 | 
			
		||||
function pluralize(word, count) {
 | 
			
		||||
    return (count === 1 ? word : `${word}s`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
 | 
			
		||||
    let output = "\n",
 | 
			
		||||
        errorCount = 0,
 | 
			
		||||
        warningCount = 0,
 | 
			
		||||
        fixableErrorCount = 0,
 | 
			
		||||
        fixableWarningCount = 0,
 | 
			
		||||
        summaryColor = "yellow";
 | 
			
		||||
 | 
			
		||||
    results.forEach(result => {
 | 
			
		||||
        const messages = result.messages;
 | 
			
		||||
 | 
			
		||||
        if (messages.length === 0) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        errorCount += result.errorCount;
 | 
			
		||||
        warningCount += result.warningCount;
 | 
			
		||||
        fixableErrorCount += result.fixableErrorCount;
 | 
			
		||||
        fixableWarningCount += result.fixableWarningCount;
 | 
			
		||||
 | 
			
		||||
        output += `${chalk.underline(result.filePath)}\n`;
 | 
			
		||||
 | 
			
		||||
        output += `${table(
 | 
			
		||||
            messages.map(message => {
 | 
			
		||||
                let messageType;
 | 
			
		||||
 | 
			
		||||
                if (message.fatal || message.severity === 2) {
 | 
			
		||||
                    messageType = chalk.red("error");
 | 
			
		||||
                    summaryColor = "red";
 | 
			
		||||
                } else {
 | 
			
		||||
                    messageType = chalk.yellow("warning");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return [
 | 
			
		||||
                    "",
 | 
			
		||||
                    message.line || 0,
 | 
			
		||||
                    message.column || 0,
 | 
			
		||||
                    messageType,
 | 
			
		||||
                    message.message.replace(/([^ ])\.$/u, "$1"),
 | 
			
		||||
                    chalk.dim(message.ruleId || "")
 | 
			
		||||
                ];
 | 
			
		||||
            }),
 | 
			
		||||
            {
 | 
			
		||||
                align: ["", "r", "l"],
 | 
			
		||||
                stringLength(str) {
 | 
			
		||||
                    return stripAnsi(str).length;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        ).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/u, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const total = errorCount + warningCount;
 | 
			
		||||
 | 
			
		||||
    if (total > 0) {
 | 
			
		||||
        output += chalk[summaryColor].bold([
 | 
			
		||||
            "\u2716 ", total, pluralize(" problem", total),
 | 
			
		||||
            " (", errorCount, pluralize(" error", errorCount), ", ",
 | 
			
		||||
            warningCount, pluralize(" warning", warningCount), ")\n"
 | 
			
		||||
        ].join(""));
 | 
			
		||||
 | 
			
		||||
        if (fixableErrorCount > 0 || fixableWarningCount > 0) {
 | 
			
		||||
            output += chalk[summaryColor].bold([
 | 
			
		||||
                "  ", fixableErrorCount, pluralize(" error", fixableErrorCount), " and ",
 | 
			
		||||
                fixableWarningCount, pluralize(" warning", fixableWarningCount),
 | 
			
		||||
                " potentially fixable with the `--fix` option.\n"
 | 
			
		||||
            ].join(""));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Resets output color, for prevent change on top level
 | 
			
		||||
    return total > 0 ? chalk.reset(output) : "";
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										95
									
								
								node_modules/eslint/lib/cli-engine/formatters/tap.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								node_modules/eslint/lib/cli-engine/formatters/tap.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview TAP reporter
 | 
			
		||||
 * @author Jonathan Kingston
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const yaml = require("js-yaml");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helper Functions
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a canonical error level string based upon the error message passed in.
 | 
			
		||||
 * @param {Object} message Individual error message provided by eslint
 | 
			
		||||
 * @returns {string} Error level string
 | 
			
		||||
 */
 | 
			
		||||
function getMessageType(message) {
 | 
			
		||||
    if (message.fatal || message.severity === 2) {
 | 
			
		||||
        return "error";
 | 
			
		||||
    }
 | 
			
		||||
    return "warning";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Takes in a JavaScript object and outputs a TAP diagnostics string
 | 
			
		||||
 * @param {Object} diagnostic JavaScript object to be embedded as YAML into output.
 | 
			
		||||
 * @returns {string} diagnostics string with YAML embedded - TAP version 13 compliant
 | 
			
		||||
 */
 | 
			
		||||
function outputDiagnostics(diagnostic) {
 | 
			
		||||
    const prefix = "  ";
 | 
			
		||||
    let output = `${prefix}---\n`;
 | 
			
		||||
 | 
			
		||||
    output += prefix + yaml.dump(diagnostic).split("\n").join(`\n${prefix}`);
 | 
			
		||||
    output += "...\n";
 | 
			
		||||
    return output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
    let output = `TAP version 13\n1..${results.length}\n`;
 | 
			
		||||
 | 
			
		||||
    results.forEach((result, id) => {
 | 
			
		||||
        const messages = result.messages;
 | 
			
		||||
        let testResult = "ok";
 | 
			
		||||
        let diagnostics = {};
 | 
			
		||||
 | 
			
		||||
        if (messages.length > 0) {
 | 
			
		||||
            messages.forEach(message => {
 | 
			
		||||
                const severity = getMessageType(message);
 | 
			
		||||
                const diagnostic = {
 | 
			
		||||
                    message: message.message,
 | 
			
		||||
                    severity,
 | 
			
		||||
                    data: {
 | 
			
		||||
                        line: message.line || 0,
 | 
			
		||||
                        column: message.column || 0,
 | 
			
		||||
                        ruleId: message.ruleId || ""
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                // This ensures a warning message is not flagged as error
 | 
			
		||||
                if (severity === "error") {
 | 
			
		||||
                    testResult = "not ok";
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If we have multiple messages place them under a messages key
 | 
			
		||||
                 * The first error will be logged as message key
 | 
			
		||||
                 * This is to adhere to TAP 13 loosely defined specification of having a message key
 | 
			
		||||
                 */
 | 
			
		||||
                if ("message" in diagnostics) {
 | 
			
		||||
                    if (typeof diagnostics.messages === "undefined") {
 | 
			
		||||
                        diagnostics.messages = [];
 | 
			
		||||
                    }
 | 
			
		||||
                    diagnostics.messages.push(diagnostic);
 | 
			
		||||
                } else {
 | 
			
		||||
                    diagnostics = diagnostic;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        output += `${testResult} ${id + 1} - ${result.filePath}\n`;
 | 
			
		||||
 | 
			
		||||
        // If we have an error include diagnostics
 | 
			
		||||
        if (messages.length > 0) {
 | 
			
		||||
            output += outputDiagnostics(diagnostics);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return output;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										58
									
								
								node_modules/eslint/lib/cli-engine/formatters/unix.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								node_modules/eslint/lib/cli-engine/formatters/unix.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview unix-style formatter.
 | 
			
		||||
 * @author oshi-shinobu
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helper Functions
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a canonical error level string based upon the error message passed in.
 | 
			
		||||
 * @param {Object} message Individual error message provided by eslint
 | 
			
		||||
 * @returns {string} Error level string
 | 
			
		||||
 */
 | 
			
		||||
function getMessageType(message) {
 | 
			
		||||
    if (message.fatal || message.severity === 2) {
 | 
			
		||||
        return "Error";
 | 
			
		||||
    }
 | 
			
		||||
    return "Warning";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
 | 
			
		||||
    let output = "",
 | 
			
		||||
        total = 0;
 | 
			
		||||
 | 
			
		||||
    results.forEach(result => {
 | 
			
		||||
 | 
			
		||||
        const messages = result.messages;
 | 
			
		||||
 | 
			
		||||
        total += messages.length;
 | 
			
		||||
 | 
			
		||||
        messages.forEach(message => {
 | 
			
		||||
 | 
			
		||||
            output += `${result.filePath}:`;
 | 
			
		||||
            output += `${message.line || 0}:`;
 | 
			
		||||
            output += `${message.column || 0}:`;
 | 
			
		||||
            output += ` ${message.message} `;
 | 
			
		||||
            output += `[${getMessageType(message)}${message.ruleId ? `/${message.ruleId}` : ""}]`;
 | 
			
		||||
            output += "\n";
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (total > 0) {
 | 
			
		||||
        output += `\n${total} problem${total !== 1 ? "s" : ""}`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return output;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										63
									
								
								node_modules/eslint/lib/cli-engine/formatters/visualstudio.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								node_modules/eslint/lib/cli-engine/formatters/visualstudio.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Visual Studio compatible formatter
 | 
			
		||||
 * @author Ronald Pijnacker
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helper Functions
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the severity of warning or error
 | 
			
		||||
 * @param {Object} message message object to examine
 | 
			
		||||
 * @returns {string} severity level
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function getMessageType(message) {
 | 
			
		||||
    if (message.fatal || message.severity === 2) {
 | 
			
		||||
        return "error";
 | 
			
		||||
    }
 | 
			
		||||
    return "warning";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = function(results) {
 | 
			
		||||
 | 
			
		||||
    let output = "",
 | 
			
		||||
        total = 0;
 | 
			
		||||
 | 
			
		||||
    results.forEach(result => {
 | 
			
		||||
 | 
			
		||||
        const messages = result.messages;
 | 
			
		||||
 | 
			
		||||
        total += messages.length;
 | 
			
		||||
 | 
			
		||||
        messages.forEach(message => {
 | 
			
		||||
 | 
			
		||||
            output += result.filePath;
 | 
			
		||||
            output += `(${message.line || 0}`;
 | 
			
		||||
            output += message.column ? `,${message.column}` : "";
 | 
			
		||||
            output += `): ${getMessageType(message)}`;
 | 
			
		||||
            output += message.ruleId ? ` ${message.ruleId}` : "";
 | 
			
		||||
            output += ` : ${message.message}`;
 | 
			
		||||
            output += "\n";
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (total === 0) {
 | 
			
		||||
        output += "no problems";
 | 
			
		||||
    } else {
 | 
			
		||||
        output += `\n${total} problem${total !== 1 ? "s" : ""}`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return output;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										35
									
								
								node_modules/eslint/lib/cli-engine/hash.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								node_modules/eslint/lib/cli-engine/hash.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Defining the hashing function in one place.
 | 
			
		||||
 * @author Michael Ficarra
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const murmur = require("imurmurhash");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Private
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * hash the given string
 | 
			
		||||
 * @param {string} str the string to hash
 | 
			
		||||
 * @returns {string} the hash
 | 
			
		||||
 */
 | 
			
		||||
function hash(str) {
 | 
			
		||||
    return murmur(str).result().toString(36);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = hash;
 | 
			
		||||
							
								
								
									
										7
									
								
								node_modules/eslint/lib/cli-engine/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								node_modules/eslint/lib/cli-engine/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const { CLIEngine } = require("./cli-engine");
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    CLIEngine
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										191
									
								
								node_modules/eslint/lib/cli-engine/lint-result-cache.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								node_modules/eslint/lib/cli-engine/lint-result-cache.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,191 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Utility for caching lint results.
 | 
			
		||||
 * @author Kevin Partington
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const assert = require("assert");
 | 
			
		||||
const fs = require("fs");
 | 
			
		||||
const fileEntryCache = require("file-entry-cache");
 | 
			
		||||
const stringify = require("json-stable-stringify-without-jsonify");
 | 
			
		||||
const pkg = require("../../package.json");
 | 
			
		||||
const hash = require("./hash");
 | 
			
		||||
 | 
			
		||||
const debug = require("debug")("eslint:lint-result-cache");
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const configHashCache = new WeakMap();
 | 
			
		||||
const nodeVersion = process && process.version;
 | 
			
		||||
 | 
			
		||||
const validCacheStrategies = ["metadata", "content"];
 | 
			
		||||
const invalidCacheStrategyErrorMessage = `Cache strategy must be one of: ${validCacheStrategies
 | 
			
		||||
    .map(strategy => `"${strategy}"`)
 | 
			
		||||
    .join(", ")}`;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests whether a provided cacheStrategy is valid
 | 
			
		||||
 * @param {string} cacheStrategy The cache strategy to use
 | 
			
		||||
 * @returns {boolean} true if `cacheStrategy` is one of `validCacheStrategies`; false otherwise
 | 
			
		||||
 */
 | 
			
		||||
function isValidCacheStrategy(cacheStrategy) {
 | 
			
		||||
    return (
 | 
			
		||||
        validCacheStrategies.includes(cacheStrategy)
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Calculates the hash of the config
 | 
			
		||||
 * @param {ConfigArray} config The config.
 | 
			
		||||
 * @returns {string} The hash of the config
 | 
			
		||||
 */
 | 
			
		||||
function hashOfConfigFor(config) {
 | 
			
		||||
    if (!configHashCache.has(config)) {
 | 
			
		||||
        configHashCache.set(config, hash(`${pkg.version}_${nodeVersion}_${stringify(config)}`));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return configHashCache.get(config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Lint result cache. This wraps around the file-entry-cache module,
 | 
			
		||||
 * transparently removing properties that are difficult or expensive to
 | 
			
		||||
 * serialize and adding them back in on retrieval.
 | 
			
		||||
 */
 | 
			
		||||
class LintResultCache {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new LintResultCache instance.
 | 
			
		||||
     * @param {string} cacheFileLocation The cache file location.
 | 
			
		||||
     * @param {"metadata" | "content"} cacheStrategy The cache strategy to use.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(cacheFileLocation, cacheStrategy) {
 | 
			
		||||
        assert(cacheFileLocation, "Cache file location is required");
 | 
			
		||||
        assert(cacheStrategy, "Cache strategy is required");
 | 
			
		||||
        assert(
 | 
			
		||||
            isValidCacheStrategy(cacheStrategy),
 | 
			
		||||
            invalidCacheStrategyErrorMessage
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        debug(`Caching results to ${cacheFileLocation}`);
 | 
			
		||||
 | 
			
		||||
        const useChecksum = cacheStrategy === "content";
 | 
			
		||||
 | 
			
		||||
        debug(
 | 
			
		||||
            `Using "${cacheStrategy}" strategy to detect changes`
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        this.fileEntryCache = fileEntryCache.create(
 | 
			
		||||
            cacheFileLocation,
 | 
			
		||||
            void 0,
 | 
			
		||||
            useChecksum
 | 
			
		||||
        );
 | 
			
		||||
        this.cacheFileLocation = cacheFileLocation;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieve cached lint results for a given file path, if present in the
 | 
			
		||||
     * cache. If the file is present and has not been changed, rebuild any
 | 
			
		||||
     * missing result information.
 | 
			
		||||
     * @param {string} filePath The file for which to retrieve lint results.
 | 
			
		||||
     * @param {ConfigArray} config The config of the file.
 | 
			
		||||
     * @returns {Object|null} The rebuilt lint results, or null if the file is
 | 
			
		||||
     *   changed or not in the filesystem.
 | 
			
		||||
     */
 | 
			
		||||
    getCachedLintResults(filePath, config) {
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Cached lint results are valid if and only if:
 | 
			
		||||
         * 1. The file is present in the filesystem
 | 
			
		||||
         * 2. The file has not changed since the time it was previously linted
 | 
			
		||||
         * 3. The ESLint configuration has not changed since the time the file
 | 
			
		||||
         *    was previously linted
 | 
			
		||||
         * If any of these are not true, we will not reuse the lint results.
 | 
			
		||||
         */
 | 
			
		||||
        const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath);
 | 
			
		||||
        const hashOfConfig = hashOfConfigFor(config);
 | 
			
		||||
        const changed =
 | 
			
		||||
            fileDescriptor.changed ||
 | 
			
		||||
            fileDescriptor.meta.hashOfConfig !== hashOfConfig;
 | 
			
		||||
 | 
			
		||||
        if (fileDescriptor.notFound) {
 | 
			
		||||
            debug(`File not found on the file system: ${filePath}`);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (changed) {
 | 
			
		||||
            debug(`Cache entry not found or no longer valid: ${filePath}`);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If source is present but null, need to reread the file from the filesystem.
 | 
			
		||||
        if (
 | 
			
		||||
            fileDescriptor.meta.results &&
 | 
			
		||||
            fileDescriptor.meta.results.source === null
 | 
			
		||||
        ) {
 | 
			
		||||
            debug(`Rereading cached result source from filesystem: ${filePath}`);
 | 
			
		||||
            fileDescriptor.meta.results.source = fs.readFileSync(filePath, "utf-8");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return fileDescriptor.meta.results;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the cached lint results for a given file path, after removing any
 | 
			
		||||
     * information that will be both unnecessary and difficult to serialize.
 | 
			
		||||
     * Avoids caching results with an "output" property (meaning fixes were
 | 
			
		||||
     * applied), to prevent potentially incorrect results if fixes are not
 | 
			
		||||
     * written to disk.
 | 
			
		||||
     * @param {string} filePath The file for which to set lint results.
 | 
			
		||||
     * @param {ConfigArray} config The config of the file.
 | 
			
		||||
     * @param {Object} result The lint result to be set for the file.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    setCachedLintResults(filePath, config, result) {
 | 
			
		||||
        if (result && Object.prototype.hasOwnProperty.call(result, "output")) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath);
 | 
			
		||||
 | 
			
		||||
        if (fileDescriptor && !fileDescriptor.notFound) {
 | 
			
		||||
            debug(`Updating cached result: ${filePath}`);
 | 
			
		||||
 | 
			
		||||
            // Serialize the result, except that we want to remove the file source if present.
 | 
			
		||||
            const resultToSerialize = Object.assign({}, result);
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Set result.source to null.
 | 
			
		||||
             * In `getCachedLintResults`, if source is explicitly null, we will
 | 
			
		||||
             * read the file from the filesystem to set the value again.
 | 
			
		||||
             */
 | 
			
		||||
            if (Object.prototype.hasOwnProperty.call(resultToSerialize, "source")) {
 | 
			
		||||
                resultToSerialize.source = null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fileDescriptor.meta.results = resultToSerialize;
 | 
			
		||||
            fileDescriptor.meta.hashOfConfig = hashOfConfigFor(config);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Persists the in-memory cache to disk.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    reconcile() {
 | 
			
		||||
        debug(`Persisting cached results: ${this.cacheFileLocation}`);
 | 
			
		||||
        this.fileEntryCache.reconcile();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = LintResultCache;
 | 
			
		||||
							
								
								
									
										46
									
								
								node_modules/eslint/lib/cli-engine/load-rules.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								node_modules/eslint/lib/cli-engine/load-rules.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Module for loading rules from files and directories.
 | 
			
		||||
 * @author Michael Ficarra
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const fs = require("fs"),
 | 
			
		||||
    path = require("path");
 | 
			
		||||
 | 
			
		||||
const rulesDirCache = {};
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Load all rule modules from specified directory.
 | 
			
		||||
 * @param {string} relativeRulesDir Path to rules directory, may be relative.
 | 
			
		||||
 * @param {string} cwd Current working directory
 | 
			
		||||
 * @returns {Object} Loaded rule modules.
 | 
			
		||||
 */
 | 
			
		||||
module.exports = function(relativeRulesDir, cwd) {
 | 
			
		||||
    const rulesDir = path.resolve(cwd, relativeRulesDir);
 | 
			
		||||
 | 
			
		||||
    // cache will help performance as IO operation are expensive
 | 
			
		||||
    if (rulesDirCache[rulesDir]) {
 | 
			
		||||
        return rulesDirCache[rulesDir];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const rules = Object.create(null);
 | 
			
		||||
 | 
			
		||||
    fs.readdirSync(rulesDir).forEach(file => {
 | 
			
		||||
        if (path.extname(file) !== ".js") {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        rules[file.slice(0, -3)] = require(path.join(rulesDir, file));
 | 
			
		||||
    });
 | 
			
		||||
    rulesDirCache[rulesDir] = rules;
 | 
			
		||||
 | 
			
		||||
    return rules;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										34
									
								
								node_modules/eslint/lib/cli-engine/xml-escape.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								node_modules/eslint/lib/cli-engine/xml-escape.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview XML character escaper
 | 
			
		||||
 * @author George Chung
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the escaped value for a character
 | 
			
		||||
 * @param {string} s string to examine
 | 
			
		||||
 * @returns {string} severity level
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
module.exports = function(s) {
 | 
			
		||||
    return (`${s}`).replace(/[<>&"'\x00-\x1F\x7F\u0080-\uFFFF]/gu, c => { // eslint-disable-line no-control-regex -- Converting controls to entities
 | 
			
		||||
        switch (c) {
 | 
			
		||||
            case "<":
 | 
			
		||||
                return "<";
 | 
			
		||||
            case ">":
 | 
			
		||||
                return ">";
 | 
			
		||||
            case "&":
 | 
			
		||||
                return "&";
 | 
			
		||||
            case "\"":
 | 
			
		||||
                return """;
 | 
			
		||||
            case "'":
 | 
			
		||||
                return "'";
 | 
			
		||||
            default:
 | 
			
		||||
                return `&#${c.charCodeAt(0)};`;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										452
									
								
								node_modules/eslint/lib/cli.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										452
									
								
								node_modules/eslint/lib/cli.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,452 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Main CLI object.
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * NOTE: The CLI object should *not* call process.exit() directly. It should only return
 | 
			
		||||
 * exit codes. This allows other programs to use the CLI object and still control
 | 
			
		||||
 * when the program exits.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const fs = require("fs"),
 | 
			
		||||
    path = require("path"),
 | 
			
		||||
    { promisify } = require("util"),
 | 
			
		||||
    { ESLint } = require("./eslint"),
 | 
			
		||||
    { FlatESLint, shouldUseFlatConfig } = require("./eslint/flat-eslint"),
 | 
			
		||||
    createCLIOptions = require("./options"),
 | 
			
		||||
    log = require("./shared/logging"),
 | 
			
		||||
    RuntimeInfo = require("./shared/runtime-info");
 | 
			
		||||
const { Legacy: { naming } } = require("@eslint/eslintrc");
 | 
			
		||||
const { ModuleImporter } = require("@humanwhocodes/module-importer");
 | 
			
		||||
 | 
			
		||||
const debug = require("debug")("eslint:cli");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Types
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @typedef {import("./eslint/eslint").ESLintOptions} ESLintOptions */
 | 
			
		||||
/** @typedef {import("./eslint/eslint").LintMessage} LintMessage */
 | 
			
		||||
/** @typedef {import("./eslint/eslint").LintResult} LintResult */
 | 
			
		||||
/** @typedef {import("./options").ParsedCLIOptions} ParsedCLIOptions */
 | 
			
		||||
/** @typedef {import("./shared/types").ResultsMeta} ResultsMeta */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const mkdir = promisify(fs.mkdir);
 | 
			
		||||
const stat = promisify(fs.stat);
 | 
			
		||||
const writeFile = promisify(fs.writeFile);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Predicate function for whether or not to apply fixes in quiet mode.
 | 
			
		||||
 * If a message is a warning, do not apply a fix.
 | 
			
		||||
 * @param {LintMessage} message The lint result.
 | 
			
		||||
 * @returns {boolean} True if the lint message is an error (and thus should be
 | 
			
		||||
 * autofixed), false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
function quietFixPredicate(message) {
 | 
			
		||||
    return message.severity === 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Translates the CLI options into the options expected by the ESLint constructor.
 | 
			
		||||
 * @param {ParsedCLIOptions} cliOptions The CLI options to translate.
 | 
			
		||||
 * @param {"flat"|"eslintrc"} [configType="eslintrc"] The format of the
 | 
			
		||||
 *      config to generate.
 | 
			
		||||
 * @returns {Promise<ESLintOptions>} The options object for the ESLint constructor.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
async function translateOptions({
 | 
			
		||||
    cache,
 | 
			
		||||
    cacheFile,
 | 
			
		||||
    cacheLocation,
 | 
			
		||||
    cacheStrategy,
 | 
			
		||||
    config,
 | 
			
		||||
    configLookup,
 | 
			
		||||
    env,
 | 
			
		||||
    errorOnUnmatchedPattern,
 | 
			
		||||
    eslintrc,
 | 
			
		||||
    ext,
 | 
			
		||||
    fix,
 | 
			
		||||
    fixDryRun,
 | 
			
		||||
    fixType,
 | 
			
		||||
    global,
 | 
			
		||||
    ignore,
 | 
			
		||||
    ignorePath,
 | 
			
		||||
    ignorePattern,
 | 
			
		||||
    inlineConfig,
 | 
			
		||||
    parser,
 | 
			
		||||
    parserOptions,
 | 
			
		||||
    plugin,
 | 
			
		||||
    quiet,
 | 
			
		||||
    reportUnusedDisableDirectives,
 | 
			
		||||
    resolvePluginsRelativeTo,
 | 
			
		||||
    rule,
 | 
			
		||||
    rulesdir,
 | 
			
		||||
    warnIgnored
 | 
			
		||||
}, configType) {
 | 
			
		||||
 | 
			
		||||
    let overrideConfig, overrideConfigFile;
 | 
			
		||||
    const importer = new ModuleImporter();
 | 
			
		||||
 | 
			
		||||
    if (configType === "flat") {
 | 
			
		||||
        overrideConfigFile = (typeof config === "string") ? config : !configLookup;
 | 
			
		||||
        if (overrideConfigFile === false) {
 | 
			
		||||
            overrideConfigFile = void 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let globals = {};
 | 
			
		||||
 | 
			
		||||
        if (global) {
 | 
			
		||||
            globals = global.reduce((obj, name) => {
 | 
			
		||||
                if (name.endsWith(":true")) {
 | 
			
		||||
                    obj[name.slice(0, -5)] = "writable";
 | 
			
		||||
                } else {
 | 
			
		||||
                    obj[name] = "readonly";
 | 
			
		||||
                }
 | 
			
		||||
                return obj;
 | 
			
		||||
            }, globals);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        overrideConfig = [{
 | 
			
		||||
            languageOptions: {
 | 
			
		||||
                globals,
 | 
			
		||||
                parserOptions: parserOptions || {}
 | 
			
		||||
            },
 | 
			
		||||
            rules: rule ? rule : {}
 | 
			
		||||
        }];
 | 
			
		||||
 | 
			
		||||
        if (parser) {
 | 
			
		||||
            overrideConfig[0].languageOptions.parser = await importer.import(parser);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (plugin) {
 | 
			
		||||
            const plugins = {};
 | 
			
		||||
 | 
			
		||||
            for (const pluginName of plugin) {
 | 
			
		||||
 | 
			
		||||
                const shortName = naming.getShorthandName(pluginName, "eslint-plugin");
 | 
			
		||||
                const longName = naming.normalizePackageName(pluginName, "eslint-plugin");
 | 
			
		||||
 | 
			
		||||
                plugins[shortName] = await importer.import(longName);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            overrideConfig[0].plugins = plugins;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        overrideConfigFile = config;
 | 
			
		||||
 | 
			
		||||
        overrideConfig = {
 | 
			
		||||
            env: env && env.reduce((obj, name) => {
 | 
			
		||||
                obj[name] = true;
 | 
			
		||||
                return obj;
 | 
			
		||||
            }, {}),
 | 
			
		||||
            globals: global && global.reduce((obj, name) => {
 | 
			
		||||
                if (name.endsWith(":true")) {
 | 
			
		||||
                    obj[name.slice(0, -5)] = "writable";
 | 
			
		||||
                } else {
 | 
			
		||||
                    obj[name] = "readonly";
 | 
			
		||||
                }
 | 
			
		||||
                return obj;
 | 
			
		||||
            }, {}),
 | 
			
		||||
            ignorePatterns: ignorePattern,
 | 
			
		||||
            parser,
 | 
			
		||||
            parserOptions,
 | 
			
		||||
            plugins: plugin,
 | 
			
		||||
            rules: rule
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const options = {
 | 
			
		||||
        allowInlineConfig: inlineConfig,
 | 
			
		||||
        cache,
 | 
			
		||||
        cacheLocation: cacheLocation || cacheFile,
 | 
			
		||||
        cacheStrategy,
 | 
			
		||||
        errorOnUnmatchedPattern,
 | 
			
		||||
        fix: (fix || fixDryRun) && (quiet ? quietFixPredicate : true),
 | 
			
		||||
        fixTypes: fixType,
 | 
			
		||||
        ignore,
 | 
			
		||||
        overrideConfig,
 | 
			
		||||
        overrideConfigFile,
 | 
			
		||||
        reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (configType === "flat") {
 | 
			
		||||
        options.ignorePatterns = ignorePattern;
 | 
			
		||||
        options.warnIgnored = warnIgnored;
 | 
			
		||||
    } else {
 | 
			
		||||
        options.resolvePluginsRelativeTo = resolvePluginsRelativeTo;
 | 
			
		||||
        options.rulePaths = rulesdir;
 | 
			
		||||
        options.useEslintrc = eslintrc;
 | 
			
		||||
        options.extensions = ext;
 | 
			
		||||
        options.ignorePath = ignorePath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return options;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Count error messages.
 | 
			
		||||
 * @param {LintResult[]} results The lint results.
 | 
			
		||||
 * @returns {{errorCount:number;fatalErrorCount:number,warningCount:number}} The number of error messages.
 | 
			
		||||
 */
 | 
			
		||||
function countErrors(results) {
 | 
			
		||||
    let errorCount = 0;
 | 
			
		||||
    let fatalErrorCount = 0;
 | 
			
		||||
    let warningCount = 0;
 | 
			
		||||
 | 
			
		||||
    for (const result of results) {
 | 
			
		||||
        errorCount += result.errorCount;
 | 
			
		||||
        fatalErrorCount += result.fatalErrorCount;
 | 
			
		||||
        warningCount += result.warningCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return { errorCount, fatalErrorCount, warningCount };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given file path is a directory or not.
 | 
			
		||||
 * @param {string} filePath The path to a file to check.
 | 
			
		||||
 * @returns {Promise<boolean>} `true` if the given path is a directory.
 | 
			
		||||
 */
 | 
			
		||||
async function isDirectory(filePath) {
 | 
			
		||||
    try {
 | 
			
		||||
        return (await stat(filePath)).isDirectory();
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        if (error.code === "ENOENT" || error.code === "ENOTDIR") {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        throw error;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Outputs the results of the linting.
 | 
			
		||||
 * @param {ESLint} engine The ESLint instance to use.
 | 
			
		||||
 * @param {LintResult[]} results The results to print.
 | 
			
		||||
 * @param {string} format The name of the formatter to use or the path to the formatter.
 | 
			
		||||
 * @param {string} outputFile The path for the output file.
 | 
			
		||||
 * @param {ResultsMeta} resultsMeta Warning count and max threshold.
 | 
			
		||||
 * @returns {Promise<boolean>} True if the printing succeeds, false if not.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
async function printResults(engine, results, format, outputFile, resultsMeta) {
 | 
			
		||||
    let formatter;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        formatter = await engine.loadFormatter(format);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        log.error(e.message);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const output = await formatter.format(results, resultsMeta);
 | 
			
		||||
 | 
			
		||||
    if (output) {
 | 
			
		||||
        if (outputFile) {
 | 
			
		||||
            const filePath = path.resolve(process.cwd(), outputFile);
 | 
			
		||||
 | 
			
		||||
            if (await isDirectory(filePath)) {
 | 
			
		||||
                log.error("Cannot write to output file path, it is a directory: %s", outputFile);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                await mkdir(path.dirname(filePath), { recursive: true });
 | 
			
		||||
                await writeFile(filePath, output);
 | 
			
		||||
            } catch (ex) {
 | 
			
		||||
                log.error("There was a problem writing the output file:\n%s", ex);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            log.info(output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Encapsulates all CLI behavior for eslint. Makes it easier to test as well as
 | 
			
		||||
 * for other Node.js programs to effectively run the CLI.
 | 
			
		||||
 */
 | 
			
		||||
const cli = {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Executes the CLI based on an array of arguments that is passed in.
 | 
			
		||||
     * @param {string|Array|Object} args The arguments to process.
 | 
			
		||||
     * @param {string} [text] The text to lint (used for TTY).
 | 
			
		||||
     * @param {boolean} [allowFlatConfig] Whether or not to allow flat config.
 | 
			
		||||
     * @returns {Promise<number>} The exit code for the operation.
 | 
			
		||||
     */
 | 
			
		||||
    async execute(args, text, allowFlatConfig) {
 | 
			
		||||
        if (Array.isArray(args)) {
 | 
			
		||||
            debug("CLI args: %o", args.slice(2));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Before doing anything, we need to see if we are using a
 | 
			
		||||
         * flat config file. If so, then we need to change the way command
 | 
			
		||||
         * line args are parsed. This is temporary, and when we fully
 | 
			
		||||
         * switch to flat config we can remove this logic.
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        const usingFlatConfig = allowFlatConfig && await shouldUseFlatConfig();
 | 
			
		||||
 | 
			
		||||
        debug("Using flat config?", usingFlatConfig);
 | 
			
		||||
 | 
			
		||||
        const CLIOptions = createCLIOptions(usingFlatConfig);
 | 
			
		||||
 | 
			
		||||
        /** @type {ParsedCLIOptions} */
 | 
			
		||||
        let options;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            options = CLIOptions.parse(args);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            debug("Error parsing CLI options:", error.message);
 | 
			
		||||
 | 
			
		||||
            let errorMessage = error.message;
 | 
			
		||||
 | 
			
		||||
            if (usingFlatConfig) {
 | 
			
		||||
                errorMessage += "\nYou're using eslint.config.js, some command line flags are no longer available. Please see https://eslint.org/docs/latest/use/command-line-interface for details.";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            log.error(errorMessage);
 | 
			
		||||
            return 2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const files = options._;
 | 
			
		||||
        const useStdin = typeof text === "string";
 | 
			
		||||
 | 
			
		||||
        if (options.help) {
 | 
			
		||||
            log.info(CLIOptions.generateHelp());
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (options.version) {
 | 
			
		||||
            log.info(RuntimeInfo.version());
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (options.envInfo) {
 | 
			
		||||
            try {
 | 
			
		||||
                log.info(RuntimeInfo.environment());
 | 
			
		||||
                return 0;
 | 
			
		||||
            } catch (err) {
 | 
			
		||||
                debug("Error retrieving environment info");
 | 
			
		||||
                log.error(err.message);
 | 
			
		||||
                return 2;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (options.printConfig) {
 | 
			
		||||
            if (files.length) {
 | 
			
		||||
                log.error("The --print-config option must be used with exactly one file name.");
 | 
			
		||||
                return 2;
 | 
			
		||||
            }
 | 
			
		||||
            if (useStdin) {
 | 
			
		||||
                log.error("The --print-config option is not available for piped-in code.");
 | 
			
		||||
                return 2;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const engine = usingFlatConfig
 | 
			
		||||
                ? new FlatESLint(await translateOptions(options, "flat"))
 | 
			
		||||
                : new ESLint(await translateOptions(options));
 | 
			
		||||
            const fileConfig =
 | 
			
		||||
                await engine.calculateConfigForFile(options.printConfig);
 | 
			
		||||
 | 
			
		||||
            log.info(JSON.stringify(fileConfig, null, "  "));
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        debug(`Running on ${useStdin ? "text" : "files"}`);
 | 
			
		||||
 | 
			
		||||
        if (options.fix && options.fixDryRun) {
 | 
			
		||||
            log.error("The --fix option and the --fix-dry-run option cannot be used together.");
 | 
			
		||||
            return 2;
 | 
			
		||||
        }
 | 
			
		||||
        if (useStdin && options.fix) {
 | 
			
		||||
            log.error("The --fix option is not available for piped-in code; use --fix-dry-run instead.");
 | 
			
		||||
            return 2;
 | 
			
		||||
        }
 | 
			
		||||
        if (options.fixType && !options.fix && !options.fixDryRun) {
 | 
			
		||||
            log.error("The --fix-type option requires either --fix or --fix-dry-run.");
 | 
			
		||||
            return 2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const ActiveESLint = usingFlatConfig ? FlatESLint : ESLint;
 | 
			
		||||
 | 
			
		||||
        const engine = new ActiveESLint(await translateOptions(options, usingFlatConfig ? "flat" : "eslintrc"));
 | 
			
		||||
        let results;
 | 
			
		||||
 | 
			
		||||
        if (useStdin) {
 | 
			
		||||
            results = await engine.lintText(text, {
 | 
			
		||||
                filePath: options.stdinFilename,
 | 
			
		||||
 | 
			
		||||
                // flatConfig respects CLI flag and constructor warnIgnored, eslintrc forces true for backwards compatibility
 | 
			
		||||
                warnIgnored: usingFlatConfig ? void 0 : true
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            results = await engine.lintFiles(files);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (options.fix) {
 | 
			
		||||
            debug("Fix mode enabled - applying fixes");
 | 
			
		||||
            await ActiveESLint.outputFixes(results);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let resultsToPrint = results;
 | 
			
		||||
 | 
			
		||||
        if (options.quiet) {
 | 
			
		||||
            debug("Quiet mode enabled - filtering out warnings");
 | 
			
		||||
            resultsToPrint = ActiveESLint.getErrorResults(resultsToPrint);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const resultCounts = countErrors(results);
 | 
			
		||||
        const tooManyWarnings = options.maxWarnings >= 0 && resultCounts.warningCount > options.maxWarnings;
 | 
			
		||||
        const resultsMeta = tooManyWarnings
 | 
			
		||||
            ? {
 | 
			
		||||
                maxWarningsExceeded: {
 | 
			
		||||
                    maxWarnings: options.maxWarnings,
 | 
			
		||||
                    foundWarnings: resultCounts.warningCount
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            : {};
 | 
			
		||||
 | 
			
		||||
        if (await printResults(engine, resultsToPrint, options.format, options.outputFile, resultsMeta)) {
 | 
			
		||||
 | 
			
		||||
            // Errors and warnings from the original unfiltered results should determine the exit code
 | 
			
		||||
            const shouldExitForFatalErrors =
 | 
			
		||||
                options.exitOnFatalError && resultCounts.fatalErrorCount > 0;
 | 
			
		||||
 | 
			
		||||
            if (!resultCounts.errorCount && tooManyWarnings) {
 | 
			
		||||
                log.error(
 | 
			
		||||
                    "ESLint found too many warnings (maximum: %s).",
 | 
			
		||||
                    options.maxWarnings
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (shouldExitForFatalErrors) {
 | 
			
		||||
                return 2;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (resultCounts.errorCount || tooManyWarnings) ? 1 : 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 2;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = cli;
 | 
			
		||||
							
								
								
									
										67
									
								
								node_modules/eslint/lib/config/default-config.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								node_modules/eslint/lib/config/default-config.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Default configuration
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const Rules = require("../rules");
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
exports.defaultConfig = [
 | 
			
		||||
    {
 | 
			
		||||
        plugins: {
 | 
			
		||||
            "@": {
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * Because we try to delay loading rules until absolutely
 | 
			
		||||
                 * necessary, a proxy allows us to hook into the lazy-loading
 | 
			
		||||
                 * aspect of the rules map while still keeping all of the
 | 
			
		||||
                 * relevant configuration inside of the config array.
 | 
			
		||||
                 */
 | 
			
		||||
                rules: new Proxy({}, {
 | 
			
		||||
                    get(target, property) {
 | 
			
		||||
                        return Rules.get(property);
 | 
			
		||||
                    },
 | 
			
		||||
 | 
			
		||||
                    has(target, property) {
 | 
			
		||||
                        return Rules.has(property);
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        languageOptions: {
 | 
			
		||||
            sourceType: "module",
 | 
			
		||||
            ecmaVersion: "latest",
 | 
			
		||||
            parser: require("espree"),
 | 
			
		||||
            parserOptions: {}
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // default ignores are listed here
 | 
			
		||||
    {
 | 
			
		||||
        ignores: [
 | 
			
		||||
            "**/node_modules/",
 | 
			
		||||
            ".git/"
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // intentionally empty config to ensure these files are globbed by default
 | 
			
		||||
    {
 | 
			
		||||
        files: ["**/*.js", "**/*.mjs"]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        files: ["**/*.cjs"],
 | 
			
		||||
        languageOptions: {
 | 
			
		||||
            sourceType: "commonjs",
 | 
			
		||||
            ecmaVersion: "latest"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										274
									
								
								node_modules/eslint/lib/config/flat-config-array.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								node_modules/eslint/lib/config/flat-config-array.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,274 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Flat Config Array
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const { ConfigArray, ConfigArraySymbol } = require("@humanwhocodes/config-array");
 | 
			
		||||
const { flatConfigSchema } = require("./flat-config-schema");
 | 
			
		||||
const { RuleValidator } = require("./rule-validator");
 | 
			
		||||
const { defaultConfig } = require("./default-config");
 | 
			
		||||
const jsPlugin = require("@eslint/js");
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const ruleValidator = new RuleValidator();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Splits a plugin identifier in the form a/b/c into two parts: a/b and c.
 | 
			
		||||
 * @param {string} identifier The identifier to parse.
 | 
			
		||||
 * @returns {{objectName: string, pluginName: string}} The parts of the plugin
 | 
			
		||||
 *      name.
 | 
			
		||||
 */
 | 
			
		||||
function splitPluginIdentifier(identifier) {
 | 
			
		||||
    const parts = identifier.split("/");
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        objectName: parts.pop(),
 | 
			
		||||
        pluginName: parts.join("/")
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the name of an object in the config by reading its `meta` key.
 | 
			
		||||
 * @param {Object} object The object to check.
 | 
			
		||||
 * @returns {string?} The name of the object if found or `null` if there
 | 
			
		||||
 *      is no name.
 | 
			
		||||
 */
 | 
			
		||||
function getObjectId(object) {
 | 
			
		||||
 | 
			
		||||
    // first check old-style name
 | 
			
		||||
    let name = object.name;
 | 
			
		||||
 | 
			
		||||
    if (!name) {
 | 
			
		||||
 | 
			
		||||
        if (!object.meta) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        name = object.meta.name;
 | 
			
		||||
 | 
			
		||||
        if (!name) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // now check for old-style version
 | 
			
		||||
    let version = object.version;
 | 
			
		||||
 | 
			
		||||
    if (!version) {
 | 
			
		||||
        version = object.meta && object.meta.version;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // if there's a version then append that
 | 
			
		||||
    if (version) {
 | 
			
		||||
        return `${name}@${version}`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const originalBaseConfig = Symbol("originalBaseConfig");
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Exports
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents an array containing configuration information for ESLint.
 | 
			
		||||
 */
 | 
			
		||||
class FlatConfigArray extends ConfigArray {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new instance.
 | 
			
		||||
     * @param {*[]} configs An array of configuration information.
 | 
			
		||||
     * @param {{basePath: string, shouldIgnore: boolean, baseConfig: FlatConfig}} options The options
 | 
			
		||||
     *      to use for the config array instance.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(configs, {
 | 
			
		||||
        basePath,
 | 
			
		||||
        shouldIgnore = true,
 | 
			
		||||
        baseConfig = defaultConfig
 | 
			
		||||
    } = {}) {
 | 
			
		||||
        super(configs, {
 | 
			
		||||
            basePath,
 | 
			
		||||
            schema: flatConfigSchema
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (baseConfig[Symbol.iterator]) {
 | 
			
		||||
            this.unshift(...baseConfig);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.unshift(baseConfig);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The base config used to build the config array.
 | 
			
		||||
         * @type {Array<FlatConfig>}
 | 
			
		||||
         */
 | 
			
		||||
        this[originalBaseConfig] = baseConfig;
 | 
			
		||||
        Object.defineProperty(this, originalBaseConfig, { writable: false });
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines if `ignores` fields should be honored.
 | 
			
		||||
         * If true, then all `ignores` fields are honored.
 | 
			
		||||
         * if false, then only `ignores` fields in the baseConfig are honored.
 | 
			
		||||
         * @type {boolean}
 | 
			
		||||
         */
 | 
			
		||||
        this.shouldIgnore = shouldIgnore;
 | 
			
		||||
        Object.defineProperty(this, "shouldIgnore", { writable: false });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* eslint-disable class-methods-use-this -- Desired as instance method */
 | 
			
		||||
    /**
 | 
			
		||||
     * Replaces a config with another config to allow us to put strings
 | 
			
		||||
     * in the config array that will be replaced by objects before
 | 
			
		||||
     * normalization.
 | 
			
		||||
     * @param {Object} config The config to preprocess.
 | 
			
		||||
     * @returns {Object} The preprocessed config.
 | 
			
		||||
     */
 | 
			
		||||
    [ConfigArraySymbol.preprocessConfig](config) {
 | 
			
		||||
        if (config === "eslint:recommended") {
 | 
			
		||||
 | 
			
		||||
            // if we are in a Node.js environment warn the user
 | 
			
		||||
            if (typeof process !== "undefined" && process.emitWarning) {
 | 
			
		||||
                process.emitWarning("The 'eslint:recommended' string configuration is deprecated and will be replaced by the @eslint/js package's 'recommended' config.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return jsPlugin.configs.recommended;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (config === "eslint:all") {
 | 
			
		||||
 | 
			
		||||
            // if we are in a Node.js environment warn the user
 | 
			
		||||
            if (typeof process !== "undefined" && process.emitWarning) {
 | 
			
		||||
                process.emitWarning("The 'eslint:all' string configuration is deprecated and will be replaced by the @eslint/js package's 'all' config.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return jsPlugin.configs.all;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * If `shouldIgnore` is false, we remove any ignore patterns specified
 | 
			
		||||
         * in the config so long as it's not a default config and it doesn't
 | 
			
		||||
         * have a `files` entry.
 | 
			
		||||
         */
 | 
			
		||||
        if (
 | 
			
		||||
            !this.shouldIgnore &&
 | 
			
		||||
            !this[originalBaseConfig].includes(config) &&
 | 
			
		||||
            config.ignores &&
 | 
			
		||||
            !config.files
 | 
			
		||||
        ) {
 | 
			
		||||
            /* eslint-disable-next-line no-unused-vars -- need to strip off other keys */
 | 
			
		||||
            const { ignores, ...otherKeys } = config;
 | 
			
		||||
 | 
			
		||||
            return otherKeys;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return config;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Finalizes the config by replacing plugin references with their objects
 | 
			
		||||
     * and validating rule option schemas.
 | 
			
		||||
     * @param {Object} config The config to finalize.
 | 
			
		||||
     * @returns {Object} The finalized config.
 | 
			
		||||
     * @throws {TypeError} If the config is invalid.
 | 
			
		||||
     */
 | 
			
		||||
    [ConfigArraySymbol.finalizeConfig](config) {
 | 
			
		||||
 | 
			
		||||
        const { plugins, languageOptions, processor } = config;
 | 
			
		||||
        let parserName, processorName;
 | 
			
		||||
        let invalidParser = false,
 | 
			
		||||
            invalidProcessor = false;
 | 
			
		||||
 | 
			
		||||
        // Check parser value
 | 
			
		||||
        if (languageOptions && languageOptions.parser) {
 | 
			
		||||
            const { parser } = languageOptions;
 | 
			
		||||
 | 
			
		||||
            if (typeof parser === "object") {
 | 
			
		||||
                parserName = getObjectId(parser);
 | 
			
		||||
 | 
			
		||||
                if (!parserName) {
 | 
			
		||||
                    invalidParser = true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                invalidParser = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check processor value
 | 
			
		||||
        if (processor) {
 | 
			
		||||
            if (typeof processor === "string") {
 | 
			
		||||
                const { pluginName, objectName: localProcessorName } = splitPluginIdentifier(processor);
 | 
			
		||||
 | 
			
		||||
                processorName = processor;
 | 
			
		||||
 | 
			
		||||
                if (!plugins || !plugins[pluginName] || !plugins[pluginName].processors || !plugins[pluginName].processors[localProcessorName]) {
 | 
			
		||||
                    throw new TypeError(`Key "processor": Could not find "${localProcessorName}" in plugin "${pluginName}".`);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                config.processor = plugins[pluginName].processors[localProcessorName];
 | 
			
		||||
            } else if (typeof processor === "object") {
 | 
			
		||||
                processorName = getObjectId(processor);
 | 
			
		||||
 | 
			
		||||
                if (!processorName) {
 | 
			
		||||
                    invalidProcessor = true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                invalidProcessor = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ruleValidator.validate(config);
 | 
			
		||||
 | 
			
		||||
        // apply special logic for serialization into JSON
 | 
			
		||||
        /* eslint-disable object-shorthand -- shorthand would change "this" value */
 | 
			
		||||
        Object.defineProperty(config, "toJSON", {
 | 
			
		||||
            value: function() {
 | 
			
		||||
 | 
			
		||||
                if (invalidParser) {
 | 
			
		||||
                    throw new Error("Could not serialize parser object (missing 'meta' object).");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (invalidProcessor) {
 | 
			
		||||
                    throw new Error("Could not serialize processor object (missing 'meta' object).");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return {
 | 
			
		||||
                    ...this,
 | 
			
		||||
                    plugins: Object.entries(plugins).map(([namespace, plugin]) => {
 | 
			
		||||
 | 
			
		||||
                        const pluginId = getObjectId(plugin);
 | 
			
		||||
 | 
			
		||||
                        if (!pluginId) {
 | 
			
		||||
                            return namespace;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        return `${namespace}:${pluginId}`;
 | 
			
		||||
                    }),
 | 
			
		||||
                    languageOptions: {
 | 
			
		||||
                        ...languageOptions,
 | 
			
		||||
                        parser: parserName
 | 
			
		||||
                    },
 | 
			
		||||
                    processor: processorName
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        /* eslint-enable object-shorthand -- ok to enable now */
 | 
			
		||||
 | 
			
		||||
        return config;
 | 
			
		||||
    }
 | 
			
		||||
    /* eslint-enable class-methods-use-this -- Desired as instance method */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.FlatConfigArray = FlatConfigArray;
 | 
			
		||||
							
								
								
									
										111
									
								
								node_modules/eslint/lib/config/flat-config-helpers.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								node_modules/eslint/lib/config/flat-config-helpers.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Shared functions to work with configs.
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Functions
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parses a ruleId into its plugin and rule parts.
 | 
			
		||||
 * @param {string} ruleId The rule ID to parse.
 | 
			
		||||
 * @returns {{pluginName:string,ruleName:string}} The plugin and rule
 | 
			
		||||
 *      parts of the ruleId;
 | 
			
		||||
 */
 | 
			
		||||
function parseRuleId(ruleId) {
 | 
			
		||||
    let pluginName, ruleName;
 | 
			
		||||
 | 
			
		||||
    // distinguish between core rules and plugin rules
 | 
			
		||||
    if (ruleId.includes("/")) {
 | 
			
		||||
 | 
			
		||||
        // mimic scoped npm packages
 | 
			
		||||
        if (ruleId.startsWith("@")) {
 | 
			
		||||
            pluginName = ruleId.slice(0, ruleId.lastIndexOf("/"));
 | 
			
		||||
        } else {
 | 
			
		||||
            pluginName = ruleId.slice(0, ruleId.indexOf("/"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ruleName = ruleId.slice(pluginName.length + 1);
 | 
			
		||||
    } else {
 | 
			
		||||
        pluginName = "@";
 | 
			
		||||
        ruleName = ruleId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        pluginName,
 | 
			
		||||
        ruleName
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieves a rule instance from a given config based on the ruleId.
 | 
			
		||||
 * @param {string} ruleId The rule ID to look for.
 | 
			
		||||
 * @param {FlatConfig} config The config to search.
 | 
			
		||||
 * @returns {import("../shared/types").Rule|undefined} The rule if found
 | 
			
		||||
 *      or undefined if not.
 | 
			
		||||
 */
 | 
			
		||||
function getRuleFromConfig(ruleId, config) {
 | 
			
		||||
 | 
			
		||||
    const { pluginName, ruleName } = parseRuleId(ruleId);
 | 
			
		||||
 | 
			
		||||
    const plugin = config.plugins && config.plugins[pluginName];
 | 
			
		||||
    let rule = plugin && plugin.rules && plugin.rules[ruleName];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // normalize function rules into objects
 | 
			
		||||
    if (rule && typeof rule === "function") {
 | 
			
		||||
        rule = {
 | 
			
		||||
            create: rule
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return rule;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets a complete options schema for a rule.
 | 
			
		||||
 * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object
 | 
			
		||||
 * @returns {Object} JSON Schema for the rule's options.
 | 
			
		||||
 */
 | 
			
		||||
function getRuleOptionsSchema(rule) {
 | 
			
		||||
 | 
			
		||||
    if (!rule) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const schema = rule.schema || rule.meta && rule.meta.schema;
 | 
			
		||||
 | 
			
		||||
    if (Array.isArray(schema)) {
 | 
			
		||||
        if (schema.length) {
 | 
			
		||||
            return {
 | 
			
		||||
                type: "array",
 | 
			
		||||
                items: schema,
 | 
			
		||||
                minItems: 0,
 | 
			
		||||
                maxItems: schema.length
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        return {
 | 
			
		||||
            type: "array",
 | 
			
		||||
            minItems: 0,
 | 
			
		||||
            maxItems: 0
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Given a full schema, leave it alone
 | 
			
		||||
    return schema || null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Exports
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    parseRuleId,
 | 
			
		||||
    getRuleFromConfig,
 | 
			
		||||
    getRuleOptionsSchema
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										562
									
								
								node_modules/eslint/lib/config/flat-config-schema.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										562
									
								
								node_modules/eslint/lib/config/flat-config-schema.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,562 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Flat config schema
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Note: This can be removed in ESLint v9 because structuredClone is available globally
 | 
			
		||||
 * starting in Node.js v17.
 | 
			
		||||
 */
 | 
			
		||||
const structuredClone = require("@ungap/structured-clone").default;
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Type Definitions
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef ObjectPropertySchema
 | 
			
		||||
 * @property {Function|string} merge The function or name of the function to call
 | 
			
		||||
 *      to merge multiple objects with this property.
 | 
			
		||||
 * @property {Function|string} validate The function or name of the function to call
 | 
			
		||||
 *      to validate the value of this property.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const ruleSeverities = new Map([
 | 
			
		||||
    [0, 0], ["off", 0],
 | 
			
		||||
    [1, 1], ["warn", 1],
 | 
			
		||||
    [2, 2], ["error", 2]
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
const globalVariablesValues = new Set([
 | 
			
		||||
    true, "true", "writable", "writeable",
 | 
			
		||||
    false, "false", "readonly", "readable", null,
 | 
			
		||||
    "off"
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a value is a non-null object.
 | 
			
		||||
 * @param {any} value The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if the value is a non-null object.
 | 
			
		||||
 */
 | 
			
		||||
function isNonNullObject(value) {
 | 
			
		||||
    return typeof value === "object" && value !== null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a value is undefined.
 | 
			
		||||
 * @param {any} value The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if the value is undefined.
 | 
			
		||||
 */
 | 
			
		||||
function isUndefined(value) {
 | 
			
		||||
    return typeof value === "undefined";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Deeply merges two objects.
 | 
			
		||||
 * @param {Object} first The base object.
 | 
			
		||||
 * @param {Object} second The overrides object.
 | 
			
		||||
 * @returns {Object} An object with properties from both first and second.
 | 
			
		||||
 */
 | 
			
		||||
function deepMerge(first = {}, second = {}) {
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * If the second value is an array, just return it. We don't merge
 | 
			
		||||
     * arrays because order matters and we can't know the correct order.
 | 
			
		||||
     */
 | 
			
		||||
    if (Array.isArray(second)) {
 | 
			
		||||
        return second;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * First create a result object where properties from the second object
 | 
			
		||||
     * overwrite properties from the first. This sets up a baseline to use
 | 
			
		||||
     * later rather than needing to inspect and change every property
 | 
			
		||||
     * individually.
 | 
			
		||||
     */
 | 
			
		||||
    const result = {
 | 
			
		||||
        ...first,
 | 
			
		||||
        ...second
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    for (const key of Object.keys(second)) {
 | 
			
		||||
 | 
			
		||||
        // avoid hairy edge case
 | 
			
		||||
        if (key === "__proto__") {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const firstValue = first[key];
 | 
			
		||||
        const secondValue = second[key];
 | 
			
		||||
 | 
			
		||||
        if (isNonNullObject(firstValue)) {
 | 
			
		||||
            result[key] = deepMerge(firstValue, secondValue);
 | 
			
		||||
        } else if (isUndefined(firstValue)) {
 | 
			
		||||
            if (isNonNullObject(secondValue)) {
 | 
			
		||||
                result[key] = deepMerge(
 | 
			
		||||
                    Array.isArray(secondValue) ? [] : {},
 | 
			
		||||
                    secondValue
 | 
			
		||||
                );
 | 
			
		||||
            } else if (!isUndefined(secondValue)) {
 | 
			
		||||
                result[key] = secondValue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Normalizes the rule options config for a given rule by ensuring that
 | 
			
		||||
 * it is an array and that the first item is 0, 1, or 2.
 | 
			
		||||
 * @param {Array|string|number} ruleOptions The rule options config.
 | 
			
		||||
 * @returns {Array} An array of rule options.
 | 
			
		||||
 */
 | 
			
		||||
function normalizeRuleOptions(ruleOptions) {
 | 
			
		||||
 | 
			
		||||
    const finalOptions = Array.isArray(ruleOptions)
 | 
			
		||||
        ? ruleOptions.slice(0)
 | 
			
		||||
        : [ruleOptions];
 | 
			
		||||
 | 
			
		||||
    finalOptions[0] = ruleSeverities.get(finalOptions[0]);
 | 
			
		||||
    return structuredClone(finalOptions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Assertions
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when a rule's options are configured with an invalid type.
 | 
			
		||||
 */
 | 
			
		||||
class InvalidRuleOptionsError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} ruleId Rule name being configured.
 | 
			
		||||
     * @param {any} value The invalid value.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(ruleId, value) {
 | 
			
		||||
        super(`Key "${ruleId}": Expected severity of "off", 0, "warn", 1, "error", or 2.`);
 | 
			
		||||
        this.messageTemplate = "invalid-rule-options";
 | 
			
		||||
        this.messageData = { ruleId, value };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validates that a value is a valid rule options entry.
 | 
			
		||||
 * @param {string} ruleId Rule name being configured.
 | 
			
		||||
 * @param {any} value The value to check.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 * @throws {InvalidRuleOptionsError} If the value isn't a valid rule options.
 | 
			
		||||
 */
 | 
			
		||||
function assertIsRuleOptions(ruleId, value) {
 | 
			
		||||
    if (typeof value !== "string" && typeof value !== "number" && !Array.isArray(value)) {
 | 
			
		||||
        throw new InvalidRuleOptionsError(ruleId, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when a rule's severity is invalid.
 | 
			
		||||
 */
 | 
			
		||||
class InvalidRuleSeverityError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} ruleId Rule name being configured.
 | 
			
		||||
     * @param {any} value The invalid value.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(ruleId, value) {
 | 
			
		||||
        super(`Key "${ruleId}": Expected severity of "off", 0, "warn", 1, "error", or 2.`);
 | 
			
		||||
        this.messageTemplate = "invalid-rule-severity";
 | 
			
		||||
        this.messageData = { ruleId, value };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validates that a value is valid rule severity.
 | 
			
		||||
 * @param {string} ruleId Rule name being configured.
 | 
			
		||||
 * @param {any} value The value to check.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 * @throws {InvalidRuleSeverityError} If the value isn't a valid rule severity.
 | 
			
		||||
 */
 | 
			
		||||
function assertIsRuleSeverity(ruleId, value) {
 | 
			
		||||
    const severity = ruleSeverities.get(value);
 | 
			
		||||
 | 
			
		||||
    if (typeof severity === "undefined") {
 | 
			
		||||
        throw new InvalidRuleSeverityError(ruleId, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validates that a given string is the form pluginName/objectName.
 | 
			
		||||
 * @param {string} value The string to check.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 * @throws {TypeError} If the string isn't in the correct format.
 | 
			
		||||
 */
 | 
			
		||||
function assertIsPluginMemberName(value) {
 | 
			
		||||
    if (!/[@a-z0-9-_$]+(?:\/(?:[a-z0-9-_$]+))+$/iu.test(value)) {
 | 
			
		||||
        throw new TypeError(`Expected string in the form "pluginName/objectName" but found "${value}".`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validates that a value is an object.
 | 
			
		||||
 * @param {any} value The value to check.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 * @throws {TypeError} If the value isn't an object.
 | 
			
		||||
 */
 | 
			
		||||
function assertIsObject(value) {
 | 
			
		||||
    if (!isNonNullObject(value)) {
 | 
			
		||||
        throw new TypeError("Expected an object.");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when there's an eslintrc-style options in a flat config.
 | 
			
		||||
 */
 | 
			
		||||
class IncompatibleKeyError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} key The invalid key.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(key) {
 | 
			
		||||
        super("This appears to be in eslintrc format rather than flat config format.");
 | 
			
		||||
        this.messageTemplate = "eslintrc-incompat";
 | 
			
		||||
        this.messageData = { key };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when there's an eslintrc-style plugins array found.
 | 
			
		||||
 */
 | 
			
		||||
class IncompatiblePluginsError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new instance.
 | 
			
		||||
     * @param {Array<string>} plugins The plugins array.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(plugins) {
 | 
			
		||||
        super("This appears to be in eslintrc format (array of strings) rather than flat config format (object).");
 | 
			
		||||
        this.messageTemplate = "eslintrc-plugins";
 | 
			
		||||
        this.messageData = { plugins };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Low-Level Schemas
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const booleanSchema = {
 | 
			
		||||
    merge: "replace",
 | 
			
		||||
    validate: "boolean"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const deepObjectAssignSchema = {
 | 
			
		||||
    merge(first = {}, second = {}) {
 | 
			
		||||
        return deepMerge(first, second);
 | 
			
		||||
    },
 | 
			
		||||
    validate: "object"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// High-Level Schemas
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const globalsSchema = {
 | 
			
		||||
    merge: "assign",
 | 
			
		||||
    validate(value) {
 | 
			
		||||
 | 
			
		||||
        assertIsObject(value);
 | 
			
		||||
 | 
			
		||||
        for (const key of Object.keys(value)) {
 | 
			
		||||
 | 
			
		||||
            // avoid hairy edge case
 | 
			
		||||
            if (key === "__proto__") {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (key !== key.trim()) {
 | 
			
		||||
                throw new TypeError(`Global "${key}" has leading or trailing whitespace.`);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!globalVariablesValues.has(value[key])) {
 | 
			
		||||
                throw new TypeError(`Key "${key}": Expected "readonly", "writable", or "off".`);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const parserSchema = {
 | 
			
		||||
    merge: "replace",
 | 
			
		||||
    validate(value) {
 | 
			
		||||
 | 
			
		||||
        if (!value || typeof value !== "object" ||
 | 
			
		||||
            (typeof value.parse !== "function" && typeof value.parseForESLint !== "function")
 | 
			
		||||
        ) {
 | 
			
		||||
            throw new TypeError("Expected object with parse() or parseForESLint() method.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const pluginsSchema = {
 | 
			
		||||
    merge(first = {}, second = {}) {
 | 
			
		||||
        const keys = new Set([...Object.keys(first), ...Object.keys(second)]);
 | 
			
		||||
        const result = {};
 | 
			
		||||
 | 
			
		||||
        // manually validate that plugins are not redefined
 | 
			
		||||
        for (const key of keys) {
 | 
			
		||||
 | 
			
		||||
            // avoid hairy edge case
 | 
			
		||||
            if (key === "__proto__") {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (key in first && key in second && first[key] !== second[key]) {
 | 
			
		||||
                throw new TypeError(`Cannot redefine plugin "${key}".`);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            result[key] = second[key] || first[key];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    },
 | 
			
		||||
    validate(value) {
 | 
			
		||||
 | 
			
		||||
        // first check the value to be sure it's an object
 | 
			
		||||
        if (value === null || typeof value !== "object") {
 | 
			
		||||
            throw new TypeError("Expected an object.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // make sure it's not an array, which would mean eslintrc-style is used
 | 
			
		||||
        if (Array.isArray(value)) {
 | 
			
		||||
            throw new IncompatiblePluginsError(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // second check the keys to make sure they are objects
 | 
			
		||||
        for (const key of Object.keys(value)) {
 | 
			
		||||
 | 
			
		||||
            // avoid hairy edge case
 | 
			
		||||
            if (key === "__proto__") {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (value[key] === null || typeof value[key] !== "object") {
 | 
			
		||||
                throw new TypeError(`Key "${key}": Expected an object.`);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const processorSchema = {
 | 
			
		||||
    merge: "replace",
 | 
			
		||||
    validate(value) {
 | 
			
		||||
        if (typeof value === "string") {
 | 
			
		||||
            assertIsPluginMemberName(value);
 | 
			
		||||
        } else if (value && typeof value === "object") {
 | 
			
		||||
            if (typeof value.preprocess !== "function" || typeof value.postprocess !== "function") {
 | 
			
		||||
                throw new TypeError("Object must have a preprocess() and a postprocess() method.");
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new TypeError("Expected an object or a string.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const rulesSchema = {
 | 
			
		||||
    merge(first = {}, second = {}) {
 | 
			
		||||
 | 
			
		||||
        const result = {
 | 
			
		||||
            ...first,
 | 
			
		||||
            ...second
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        for (const ruleId of Object.keys(result)) {
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
 | 
			
		||||
                // avoid hairy edge case
 | 
			
		||||
                if (ruleId === "__proto__") {
 | 
			
		||||
 | 
			
		||||
                    /* eslint-disable-next-line no-proto -- Though deprecated, may still be present */
 | 
			
		||||
                    delete result.__proto__;
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                result[ruleId] = normalizeRuleOptions(result[ruleId]);
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If either rule config is missing, then the correct
 | 
			
		||||
                 * config is already present and we just need to normalize
 | 
			
		||||
                 * the severity.
 | 
			
		||||
                 */
 | 
			
		||||
                if (!(ruleId in first) || !(ruleId in second)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const firstRuleOptions = normalizeRuleOptions(first[ruleId]);
 | 
			
		||||
                const secondRuleOptions = normalizeRuleOptions(second[ruleId]);
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If the second rule config only has a severity (length of 1),
 | 
			
		||||
                 * then use that severity and keep the rest of the options from
 | 
			
		||||
                 * the first rule config.
 | 
			
		||||
                 */
 | 
			
		||||
                if (secondRuleOptions.length === 1) {
 | 
			
		||||
                    result[ruleId] = [secondRuleOptions[0], ...firstRuleOptions.slice(1)];
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * In any other situation, then the second rule config takes
 | 
			
		||||
                 * precedence. That means the value at `result[ruleId]` is
 | 
			
		||||
                 * already correct and no further work is necessary.
 | 
			
		||||
                 */
 | 
			
		||||
            } catch (ex) {
 | 
			
		||||
                throw new Error(`Key "${ruleId}": ${ex.message}`, { cause: ex });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    validate(value) {
 | 
			
		||||
        assertIsObject(value);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * We are not checking the rule schema here because there is no
 | 
			
		||||
         * guarantee that the rule definition is present at this point. Instead
 | 
			
		||||
         * we wait and check the rule schema during the finalization step
 | 
			
		||||
         * of calculating a config.
 | 
			
		||||
         */
 | 
			
		||||
        for (const ruleId of Object.keys(value)) {
 | 
			
		||||
 | 
			
		||||
            // avoid hairy edge case
 | 
			
		||||
            if (ruleId === "__proto__") {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const ruleOptions = value[ruleId];
 | 
			
		||||
 | 
			
		||||
            assertIsRuleOptions(ruleId, ruleOptions);
 | 
			
		||||
 | 
			
		||||
            if (Array.isArray(ruleOptions)) {
 | 
			
		||||
                assertIsRuleSeverity(ruleId, ruleOptions[0]);
 | 
			
		||||
            } else {
 | 
			
		||||
                assertIsRuleSeverity(ruleId, ruleOptions);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const ecmaVersionSchema = {
 | 
			
		||||
    merge: "replace",
 | 
			
		||||
    validate(value) {
 | 
			
		||||
        if (typeof value === "number" || value === "latest") {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new TypeError("Expected a number or \"latest\".");
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {ObjectPropertySchema} */
 | 
			
		||||
const sourceTypeSchema = {
 | 
			
		||||
    merge: "replace",
 | 
			
		||||
    validate(value) {
 | 
			
		||||
        if (typeof value !== "string" || !/^(?:script|module|commonjs)$/u.test(value)) {
 | 
			
		||||
            throw new TypeError("Expected \"script\", \"module\", or \"commonjs\".");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a schema that always throws an error. Useful for warning
 | 
			
		||||
 * about eslintrc-style keys.
 | 
			
		||||
 * @param {string} key The eslintrc key to create a schema for.
 | 
			
		||||
 * @returns {ObjectPropertySchema} The schema.
 | 
			
		||||
 */
 | 
			
		||||
function createEslintrcErrorSchema(key) {
 | 
			
		||||
    return {
 | 
			
		||||
        merge: "replace",
 | 
			
		||||
        validate() {
 | 
			
		||||
            throw new IncompatibleKeyError(key);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const eslintrcKeys = [
 | 
			
		||||
    "env",
 | 
			
		||||
    "extends",
 | 
			
		||||
    "globals",
 | 
			
		||||
    "ignorePatterns",
 | 
			
		||||
    "noInlineConfig",
 | 
			
		||||
    "overrides",
 | 
			
		||||
    "parser",
 | 
			
		||||
    "parserOptions",
 | 
			
		||||
    "reportUnusedDisableDirectives",
 | 
			
		||||
    "root"
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Full schema
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const flatConfigSchema = {
 | 
			
		||||
 | 
			
		||||
    // eslintrc-style keys that should always error
 | 
			
		||||
    ...Object.fromEntries(eslintrcKeys.map(key => [key, createEslintrcErrorSchema(key)])),
 | 
			
		||||
 | 
			
		||||
    // flat config keys
 | 
			
		||||
    settings: deepObjectAssignSchema,
 | 
			
		||||
    linterOptions: {
 | 
			
		||||
        schema: {
 | 
			
		||||
            noInlineConfig: booleanSchema,
 | 
			
		||||
            reportUnusedDisableDirectives: booleanSchema
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    languageOptions: {
 | 
			
		||||
        schema: {
 | 
			
		||||
            ecmaVersion: ecmaVersionSchema,
 | 
			
		||||
            sourceType: sourceTypeSchema,
 | 
			
		||||
            globals: globalsSchema,
 | 
			
		||||
            parser: parserSchema,
 | 
			
		||||
            parserOptions: deepObjectAssignSchema
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    processor: processorSchema,
 | 
			
		||||
    plugins: pluginsSchema,
 | 
			
		||||
    rules: rulesSchema
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Exports
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    flatConfigSchema,
 | 
			
		||||
    assertIsRuleSeverity,
 | 
			
		||||
    assertIsRuleOptions
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										158
									
								
								node_modules/eslint/lib/config/rule-validator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								node_modules/eslint/lib/config/rule-validator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule Validator
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const ajvImport = require("../shared/ajv");
 | 
			
		||||
const ajv = ajvImport();
 | 
			
		||||
const {
 | 
			
		||||
    parseRuleId,
 | 
			
		||||
    getRuleFromConfig,
 | 
			
		||||
    getRuleOptionsSchema
 | 
			
		||||
} = require("./flat-config-helpers");
 | 
			
		||||
const ruleReplacements = require("../../conf/replacements.json");
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Throws a helpful error when a rule cannot be found.
 | 
			
		||||
 * @param {Object} ruleId The rule identifier.
 | 
			
		||||
 * @param {string} ruleId.pluginName The ID of the rule to find.
 | 
			
		||||
 * @param {string} ruleId.ruleName The ID of the rule to find.
 | 
			
		||||
 * @param {Object} config The config to search in.
 | 
			
		||||
 * @throws {TypeError} For missing plugin or rule.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function throwRuleNotFoundError({ pluginName, ruleName }, config) {
 | 
			
		||||
 | 
			
		||||
    const ruleId = pluginName === "@" ? ruleName : `${pluginName}/${ruleName}`;
 | 
			
		||||
 | 
			
		||||
    const errorMessageHeader = `Key "rules": Key "${ruleId}"`;
 | 
			
		||||
    let errorMessage = `${errorMessageHeader}: Could not find plugin "${pluginName}".`;
 | 
			
		||||
 | 
			
		||||
    // if the plugin exists then we need to check if the rule exists
 | 
			
		||||
    if (config.plugins && config.plugins[pluginName]) {
 | 
			
		||||
        const replacementRuleName = ruleReplacements.rules[ruleName];
 | 
			
		||||
 | 
			
		||||
        if (pluginName === "@" && replacementRuleName) {
 | 
			
		||||
 | 
			
		||||
            errorMessage = `${errorMessageHeader}: Rule "${ruleName}" was removed and replaced by "${replacementRuleName}".`;
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            errorMessage = `${errorMessageHeader}: Could not find "${ruleName}" in plugin "${pluginName}".`;
 | 
			
		||||
 | 
			
		||||
            // otherwise, let's see if we can find the rule name elsewhere
 | 
			
		||||
            for (const [otherPluginName, otherPlugin] of Object.entries(config.plugins)) {
 | 
			
		||||
                if (otherPlugin.rules && otherPlugin.rules[ruleName]) {
 | 
			
		||||
                    errorMessage += ` Did you mean "${otherPluginName}/${ruleName}"?`;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // falls through to throw error
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    throw new TypeError(errorMessage);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Exports
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements validation functionality for the rules portion of a config.
 | 
			
		||||
 */
 | 
			
		||||
class RuleValidator {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new instance.
 | 
			
		||||
     */
 | 
			
		||||
    constructor() {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * A collection of compiled validators for rules that have already
 | 
			
		||||
         * been validated.
 | 
			
		||||
         * @type {WeakMap}
 | 
			
		||||
         */
 | 
			
		||||
        this.validators = new WeakMap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Validates all of the rule configurations in a config against each
 | 
			
		||||
     * rule's schema.
 | 
			
		||||
     * @param {Object} config The full config to validate. This object must
 | 
			
		||||
     *      contain both the rules section and the plugins section.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     * @throws {Error} If a rule's configuration does not match its schema.
 | 
			
		||||
     */
 | 
			
		||||
    validate(config) {
 | 
			
		||||
 | 
			
		||||
        if (!config.rules) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (const [ruleId, ruleOptions] of Object.entries(config.rules)) {
 | 
			
		||||
 | 
			
		||||
            // check for edge case
 | 
			
		||||
            if (ruleId === "__proto__") {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * If a rule is disabled, we don't do any validation. This allows
 | 
			
		||||
             * users to safely set any value to 0 or "off" without worrying
 | 
			
		||||
             * that it will cause a validation error.
 | 
			
		||||
             *
 | 
			
		||||
             * Note: ruleOptions is always an array at this point because
 | 
			
		||||
             * this validation occurs after FlatConfigArray has merged and
 | 
			
		||||
             * normalized values.
 | 
			
		||||
             */
 | 
			
		||||
            if (ruleOptions[0] === 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const rule = getRuleFromConfig(ruleId, config);
 | 
			
		||||
 | 
			
		||||
            if (!rule) {
 | 
			
		||||
                throwRuleNotFoundError(parseRuleId(ruleId), config);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Precompile and cache validator the first time
 | 
			
		||||
            if (!this.validators.has(rule)) {
 | 
			
		||||
                const schema = getRuleOptionsSchema(rule);
 | 
			
		||||
 | 
			
		||||
                if (schema) {
 | 
			
		||||
                    this.validators.set(rule, ajv.compile(schema));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const validateRule = this.validators.get(rule);
 | 
			
		||||
 | 
			
		||||
            if (validateRule) {
 | 
			
		||||
 | 
			
		||||
                validateRule(ruleOptions.slice(1));
 | 
			
		||||
 | 
			
		||||
                if (validateRule.errors) {
 | 
			
		||||
                    throw new Error(`Key "rules": Key "${ruleId}": ${
 | 
			
		||||
                        validateRule.errors.map(
 | 
			
		||||
                            error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n`
 | 
			
		||||
                        ).join("")
 | 
			
		||||
                    }`);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.RuleValidator = RuleValidator;
 | 
			
		||||
							
								
								
									
										909
									
								
								node_modules/eslint/lib/eslint/eslint-helpers.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										909
									
								
								node_modules/eslint/lib/eslint/eslint-helpers.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,909 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Helper functions for ESLint class
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const path = require("path");
 | 
			
		||||
const fs = require("fs");
 | 
			
		||||
const fsp = fs.promises;
 | 
			
		||||
const isGlob = require("is-glob");
 | 
			
		||||
const hash = require("../cli-engine/hash");
 | 
			
		||||
const minimatch = require("minimatch");
 | 
			
		||||
const util = require("util");
 | 
			
		||||
const fswalk = require("@nodelib/fs.walk");
 | 
			
		||||
const globParent = require("glob-parent");
 | 
			
		||||
const isPathInside = require("is-path-inside");
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Fixup references
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const doFsWalk = util.promisify(fswalk.walk);
 | 
			
		||||
const Minimatch = minimatch.Minimatch;
 | 
			
		||||
const MINIMATCH_OPTIONS = { dot: true };
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Types
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef {Object} GlobSearch
 | 
			
		||||
 * @property {Array<string>} patterns The normalized patterns to use for a search.
 | 
			
		||||
 * @property {Array<string>} rawPatterns The patterns as entered by the user
 | 
			
		||||
 *      before doing any normalization.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Errors
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when no files match a glob.
 | 
			
		||||
 */
 | 
			
		||||
class NoFilesFoundError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} pattern The glob pattern which was not found.
 | 
			
		||||
     * @param {boolean} globEnabled If `false` then the pattern was a glob pattern, but glob was disabled.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(pattern, globEnabled) {
 | 
			
		||||
        super(`No files matching '${pattern}' were found${!globEnabled ? " (glob was disabled)" : ""}.`);
 | 
			
		||||
        this.messageTemplate = "file-not-found";
 | 
			
		||||
        this.messageData = { pattern, globDisabled: !globEnabled };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when a search fails to match multiple patterns.
 | 
			
		||||
 */
 | 
			
		||||
class UnmatchedSearchPatternsError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {Object} options The options for the error.
 | 
			
		||||
     * @param {string} options.basePath The directory that was searched.
 | 
			
		||||
     * @param {Array<string>} options.unmatchedPatterns The glob patterns
 | 
			
		||||
     *      which were not found.
 | 
			
		||||
     * @param {Array<string>} options.patterns The glob patterns that were
 | 
			
		||||
     *      searched.
 | 
			
		||||
     * @param {Array<string>} options.rawPatterns The raw glob patterns that
 | 
			
		||||
     *      were searched.
 | 
			
		||||
     */
 | 
			
		||||
    constructor({ basePath, unmatchedPatterns, patterns, rawPatterns }) {
 | 
			
		||||
        super(`No files matching '${rawPatterns}' in '${basePath}' were found.`);
 | 
			
		||||
        this.basePath = basePath;
 | 
			
		||||
        this.unmatchedPatterns = unmatchedPatterns;
 | 
			
		||||
        this.patterns = patterns;
 | 
			
		||||
        this.rawPatterns = rawPatterns;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error type when there are files matched by a glob, but all of them have been ignored.
 | 
			
		||||
 */
 | 
			
		||||
class AllFilesIgnoredError extends Error {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} pattern The glob pattern which was not found.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(pattern) {
 | 
			
		||||
        super(`All files matched by '${pattern}' are ignored.`);
 | 
			
		||||
        this.messageTemplate = "all-files-ignored";
 | 
			
		||||
        this.messageData = { pattern };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// General Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given value is a non-empty string or not.
 | 
			
		||||
 * @param {any} x The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `x` is a non-empty string.
 | 
			
		||||
 */
 | 
			
		||||
function isNonEmptyString(x) {
 | 
			
		||||
    return typeof x === "string" && x.trim() !== "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given value is an array of non-empty strings or not.
 | 
			
		||||
 * @param {any} x The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `x` is an array of non-empty strings.
 | 
			
		||||
 */
 | 
			
		||||
function isArrayOfNonEmptyString(x) {
 | 
			
		||||
    return Array.isArray(x) && x.every(isNonEmptyString);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// File-related Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Normalizes slashes in a file pattern to posix-style.
 | 
			
		||||
 * @param {string} pattern The pattern to replace slashes in.
 | 
			
		||||
 * @returns {string} The pattern with slashes normalized.
 | 
			
		||||
 */
 | 
			
		||||
function normalizeToPosix(pattern) {
 | 
			
		||||
    return pattern.replace(/\\/gu, "/");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a string is a glob pattern or not.
 | 
			
		||||
 * @param {string} pattern A glob pattern.
 | 
			
		||||
 * @returns {boolean} `true` if the string is a glob pattern.
 | 
			
		||||
 */
 | 
			
		||||
function isGlobPattern(pattern) {
 | 
			
		||||
    return isGlob(path.sep === "\\" ? normalizeToPosix(pattern) : pattern);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determines if a given glob pattern will return any results.
 | 
			
		||||
 * Used primarily to help with useful error messages.
 | 
			
		||||
 * @param {Object} options The options for the function.
 | 
			
		||||
 * @param {string} options.basePath The directory to search.
 | 
			
		||||
 * @param {string} options.pattern A glob pattern to match.
 | 
			
		||||
 * @returns {Promise<boolean>} True if there is a glob match, false if not.
 | 
			
		||||
 */
 | 
			
		||||
function globMatch({ basePath, pattern }) {
 | 
			
		||||
 | 
			
		||||
    let found = false;
 | 
			
		||||
    const patternToUse = path.isAbsolute(pattern)
 | 
			
		||||
        ? normalizeToPosix(path.relative(basePath, pattern))
 | 
			
		||||
        : pattern;
 | 
			
		||||
 | 
			
		||||
    const matcher = new Minimatch(patternToUse, MINIMATCH_OPTIONS);
 | 
			
		||||
 | 
			
		||||
    const fsWalkSettings = {
 | 
			
		||||
 | 
			
		||||
        deepFilter(entry) {
 | 
			
		||||
            const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
 | 
			
		||||
 | 
			
		||||
            return !found && matcher.match(relativePath, true);
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        entryFilter(entry) {
 | 
			
		||||
            if (found || entry.dirent.isDirectory()) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
 | 
			
		||||
 | 
			
		||||
            if (matcher.match(relativePath)) {
 | 
			
		||||
                found = true;
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
 | 
			
		||||
        // using a stream so we can exit early because we just need one match
 | 
			
		||||
        const globStream = fswalk.walkStream(basePath, fsWalkSettings);
 | 
			
		||||
 | 
			
		||||
        globStream.on("data", () => {
 | 
			
		||||
            globStream.destroy();
 | 
			
		||||
            resolve(true);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // swallow errors as they're not important here
 | 
			
		||||
        globStream.on("error", () => { });
 | 
			
		||||
 | 
			
		||||
        globStream.on("end", () => {
 | 
			
		||||
            resolve(false);
 | 
			
		||||
        });
 | 
			
		||||
        globStream.read();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Searches a directory looking for matching glob patterns. This uses
 | 
			
		||||
 * the config array's logic to determine if a directory or file should
 | 
			
		||||
 * be ignored, so it is consistent with how ignoring works throughout
 | 
			
		||||
 * ESLint.
 | 
			
		||||
 * @param {Object} options The options for this function.
 | 
			
		||||
 * @param {string} options.basePath The directory to search.
 | 
			
		||||
 * @param {Array<string>} options.patterns An array of glob patterns
 | 
			
		||||
 *      to match.
 | 
			
		||||
 * @param {Array<string>} options.rawPatterns An array of glob patterns
 | 
			
		||||
 *      as the user inputted them. Used for errors.
 | 
			
		||||
 * @param {FlatConfigArray} options.configs The config array to use for
 | 
			
		||||
 *      determining what to ignore.
 | 
			
		||||
 * @param {boolean} options.errorOnUnmatchedPattern Determines if an error
 | 
			
		||||
 *      should be thrown when a pattern is unmatched.
 | 
			
		||||
 * @returns {Promise<Array<string>>} An array of matching file paths
 | 
			
		||||
 *      or an empty array if there are no matches.
 | 
			
		||||
 * @throws {UnmatchedSearchPatternsError} If there is a pattern that doesn't
 | 
			
		||||
 *      match any files.
 | 
			
		||||
 */
 | 
			
		||||
async function globSearch({
 | 
			
		||||
    basePath,
 | 
			
		||||
    patterns,
 | 
			
		||||
    rawPatterns,
 | 
			
		||||
    configs,
 | 
			
		||||
    errorOnUnmatchedPattern
 | 
			
		||||
}) {
 | 
			
		||||
 | 
			
		||||
    if (patterns.length === 0) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * In this section we are converting the patterns into Minimatch
 | 
			
		||||
     * instances for performance reasons. Because we are doing the same
 | 
			
		||||
     * matches repeatedly, it's best to compile those patterns once and
 | 
			
		||||
     * reuse them multiple times.
 | 
			
		||||
     *
 | 
			
		||||
     * To do that, we convert any patterns with an absolute path into a
 | 
			
		||||
     * relative path and normalize it to Posix-style slashes. We also keep
 | 
			
		||||
     * track of the relative patterns to map them back to the original
 | 
			
		||||
     * patterns, which we need in order to throw an error if there are any
 | 
			
		||||
     * unmatched patterns.
 | 
			
		||||
     */
 | 
			
		||||
    const relativeToPatterns = new Map();
 | 
			
		||||
    const matchers = patterns.map((pattern, i) => {
 | 
			
		||||
        const patternToUse = path.isAbsolute(pattern)
 | 
			
		||||
            ? normalizeToPosix(path.relative(basePath, pattern))
 | 
			
		||||
            : pattern;
 | 
			
		||||
 | 
			
		||||
        relativeToPatterns.set(patternToUse, patterns[i]);
 | 
			
		||||
 | 
			
		||||
        return new Minimatch(patternToUse, MINIMATCH_OPTIONS);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * We track unmatched patterns because we may want to throw an error when
 | 
			
		||||
     * they occur. To start, this set is initialized with all of the patterns.
 | 
			
		||||
     * Every time a match occurs, the pattern is removed from the set, making
 | 
			
		||||
     * it easy to tell if we have any unmatched patterns left at the end of
 | 
			
		||||
     * search.
 | 
			
		||||
     */
 | 
			
		||||
    const unmatchedPatterns = new Set([...relativeToPatterns.keys()]);
 | 
			
		||||
 | 
			
		||||
    const filePaths = (await doFsWalk(basePath, {
 | 
			
		||||
 | 
			
		||||
        deepFilter(entry) {
 | 
			
		||||
            const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
 | 
			
		||||
            const matchesPattern = matchers.some(matcher => matcher.match(relativePath, true));
 | 
			
		||||
 | 
			
		||||
            return matchesPattern && !configs.isDirectoryIgnored(entry.path);
 | 
			
		||||
        },
 | 
			
		||||
        entryFilter(entry) {
 | 
			
		||||
            const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
 | 
			
		||||
 | 
			
		||||
            // entries may be directories or files so filter out directories
 | 
			
		||||
            if (entry.dirent.isDirectory()) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Optimization: We need to track when patterns are left unmatched
 | 
			
		||||
             * and so we use `unmatchedPatterns` to do that. There is a bit of
 | 
			
		||||
             * complexity here because the same file can be matched by more than
 | 
			
		||||
             * one pattern. So, when we start, we actually need to test every
 | 
			
		||||
             * pattern against every file. Once we know there are no remaining
 | 
			
		||||
             * unmatched patterns, then we can switch to just looking for the
 | 
			
		||||
             * first matching pattern for improved speed.
 | 
			
		||||
             */
 | 
			
		||||
            const matchesPattern = unmatchedPatterns.size > 0
 | 
			
		||||
                ? matchers.reduce((previousValue, matcher) => {
 | 
			
		||||
                    const pathMatches = matcher.match(relativePath);
 | 
			
		||||
 | 
			
		||||
                    /*
 | 
			
		||||
                     * We updated the unmatched patterns set only if the path
 | 
			
		||||
                     * matches and the file isn't ignored. If the file is
 | 
			
		||||
                     * ignored, that means there wasn't a match for the
 | 
			
		||||
                     * pattern so it should not be removed.
 | 
			
		||||
                     *
 | 
			
		||||
                     * Performance note: isFileIgnored() aggressively caches
 | 
			
		||||
                     * results so there is no performance penalty for calling
 | 
			
		||||
                     * it twice with the same argument.
 | 
			
		||||
                     */
 | 
			
		||||
                    if (pathMatches && !configs.isFileIgnored(entry.path)) {
 | 
			
		||||
                        unmatchedPatterns.delete(matcher.pattern);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return pathMatches || previousValue;
 | 
			
		||||
                }, false)
 | 
			
		||||
                : matchers.some(matcher => matcher.match(relativePath));
 | 
			
		||||
 | 
			
		||||
            return matchesPattern && !configs.isFileIgnored(entry.path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    })).map(entry => entry.path);
 | 
			
		||||
 | 
			
		||||
    // now check to see if we have any unmatched patterns
 | 
			
		||||
    if (errorOnUnmatchedPattern && unmatchedPatterns.size > 0) {
 | 
			
		||||
        throw new UnmatchedSearchPatternsError({
 | 
			
		||||
            basePath,
 | 
			
		||||
            unmatchedPatterns: [...unmatchedPatterns].map(
 | 
			
		||||
                pattern => relativeToPatterns.get(pattern)
 | 
			
		||||
            ),
 | 
			
		||||
            patterns,
 | 
			
		||||
            rawPatterns
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return filePaths;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Throws an error for unmatched patterns. The error will only contain information about the first one.
 | 
			
		||||
 * Checks to see if there are any ignored results for a given search.
 | 
			
		||||
 * @param {Object} options The options for this function.
 | 
			
		||||
 * @param {string} options.basePath The directory to search.
 | 
			
		||||
 * @param {Array<string>} options.patterns An array of glob patterns
 | 
			
		||||
 *      that were used in the original search.
 | 
			
		||||
 * @param {Array<string>} options.rawPatterns An array of glob patterns
 | 
			
		||||
 *      as the user inputted them. Used for errors.
 | 
			
		||||
 * @param {Array<string>} options.unmatchedPatterns A non-empty array of glob patterns
 | 
			
		||||
 *      that were unmatched in the original search.
 | 
			
		||||
 * @returns {void} Always throws an error.
 | 
			
		||||
 * @throws {NoFilesFoundError} If the first unmatched pattern
 | 
			
		||||
 *      doesn't match any files even when there are no ignores.
 | 
			
		||||
 * @throws {AllFilesIgnoredError} If the first unmatched pattern
 | 
			
		||||
 *      matches some files when there are no ignores.
 | 
			
		||||
 */
 | 
			
		||||
async function throwErrorForUnmatchedPatterns({
 | 
			
		||||
    basePath,
 | 
			
		||||
    patterns,
 | 
			
		||||
    rawPatterns,
 | 
			
		||||
    unmatchedPatterns
 | 
			
		||||
}) {
 | 
			
		||||
 | 
			
		||||
    const pattern = unmatchedPatterns[0];
 | 
			
		||||
    const rawPattern = rawPatterns[patterns.indexOf(pattern)];
 | 
			
		||||
 | 
			
		||||
    const patternHasMatch = await globMatch({
 | 
			
		||||
        basePath,
 | 
			
		||||
        pattern
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (patternHasMatch) {
 | 
			
		||||
        throw new AllFilesIgnoredError(rawPattern);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // if we get here there are truly no matches
 | 
			
		||||
    throw new NoFilesFoundError(rawPattern, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Performs multiple glob searches in parallel.
 | 
			
		||||
 * @param {Object} options The options for this function.
 | 
			
		||||
 * @param {Map<string,GlobSearch>} options.searches
 | 
			
		||||
 *      An array of glob patterns to match.
 | 
			
		||||
 * @param {FlatConfigArray} options.configs The config array to use for
 | 
			
		||||
 *      determining what to ignore.
 | 
			
		||||
 * @param {boolean} options.errorOnUnmatchedPattern Determines if an
 | 
			
		||||
 *      unmatched glob pattern should throw an error.
 | 
			
		||||
 * @returns {Promise<Array<string>>} An array of matching file paths
 | 
			
		||||
 *      or an empty array if there are no matches.
 | 
			
		||||
 */
 | 
			
		||||
async function globMultiSearch({ searches, configs, errorOnUnmatchedPattern }) {
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * For convenience, we normalized the search map into an array of objects.
 | 
			
		||||
     * Next, we filter out all searches that have no patterns. This happens
 | 
			
		||||
     * primarily for the cwd, which is prepopulated in the searches map as an
 | 
			
		||||
     * optimization. However, if it has no patterns, it means all patterns
 | 
			
		||||
     * occur outside of the cwd and we can safely filter out that search.
 | 
			
		||||
     */
 | 
			
		||||
    const normalizedSearches = [...searches].map(
 | 
			
		||||
        ([basePath, { patterns, rawPatterns }]) => ({ basePath, patterns, rawPatterns })
 | 
			
		||||
    ).filter(({ patterns }) => patterns.length > 0);
 | 
			
		||||
 | 
			
		||||
    const results = await Promise.allSettled(
 | 
			
		||||
        normalizedSearches.map(
 | 
			
		||||
            ({ basePath, patterns, rawPatterns }) => globSearch({
 | 
			
		||||
                basePath,
 | 
			
		||||
                patterns,
 | 
			
		||||
                rawPatterns,
 | 
			
		||||
                configs,
 | 
			
		||||
                errorOnUnmatchedPattern
 | 
			
		||||
            })
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const filePaths = [];
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < results.length; i++) {
 | 
			
		||||
 | 
			
		||||
        const result = results[i];
 | 
			
		||||
        const currentSearch = normalizedSearches[i];
 | 
			
		||||
 | 
			
		||||
        if (result.status === "fulfilled") {
 | 
			
		||||
 | 
			
		||||
            // if the search was successful just add the results
 | 
			
		||||
            if (result.value.length > 0) {
 | 
			
		||||
                filePaths.push(...result.value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if we make it here then there was an error
 | 
			
		||||
        const error = result.reason;
 | 
			
		||||
 | 
			
		||||
        // unexpected errors should be re-thrown
 | 
			
		||||
        if (!error.basePath) {
 | 
			
		||||
            throw error;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (errorOnUnmatchedPattern) {
 | 
			
		||||
 | 
			
		||||
            await throwErrorForUnmatchedPatterns({
 | 
			
		||||
                ...currentSearch,
 | 
			
		||||
                unmatchedPatterns: error.unmatchedPatterns
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return [...new Set(filePaths)];
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finds all files matching the options specified.
 | 
			
		||||
 * @param {Object} args The arguments objects.
 | 
			
		||||
 * @param {Array<string>} args.patterns An array of glob patterns.
 | 
			
		||||
 * @param {boolean} args.globInputPaths true to interpret glob patterns,
 | 
			
		||||
 *      false to not interpret glob patterns.
 | 
			
		||||
 * @param {string} args.cwd The current working directory to find from.
 | 
			
		||||
 * @param {FlatConfigArray} args.configs The configs for the current run.
 | 
			
		||||
 * @param {boolean} args.errorOnUnmatchedPattern Determines if an unmatched pattern
 | 
			
		||||
 *      should throw an error.
 | 
			
		||||
 * @returns {Promise<Array<string>>} The fully resolved file paths.
 | 
			
		||||
 * @throws {AllFilesIgnoredError} If there are no results due to an ignore pattern.
 | 
			
		||||
 * @throws {NoFilesFoundError} If no files matched the given patterns.
 | 
			
		||||
 */
 | 
			
		||||
async function findFiles({
 | 
			
		||||
    patterns,
 | 
			
		||||
    globInputPaths,
 | 
			
		||||
    cwd,
 | 
			
		||||
    configs,
 | 
			
		||||
    errorOnUnmatchedPattern
 | 
			
		||||
}) {
 | 
			
		||||
 | 
			
		||||
    const results = [];
 | 
			
		||||
    const missingPatterns = [];
 | 
			
		||||
    let globbyPatterns = [];
 | 
			
		||||
    let rawPatterns = [];
 | 
			
		||||
    const searches = new Map([[cwd, { patterns: globbyPatterns, rawPatterns: [] }]]);
 | 
			
		||||
 | 
			
		||||
    // check to see if we have explicit files and directories
 | 
			
		||||
    const filePaths = patterns.map(filePath => path.resolve(cwd, filePath));
 | 
			
		||||
    const stats = await Promise.all(
 | 
			
		||||
        filePaths.map(
 | 
			
		||||
            filePath => fsp.stat(filePath).catch(() => { })
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    stats.forEach((stat, index) => {
 | 
			
		||||
 | 
			
		||||
        const filePath = filePaths[index];
 | 
			
		||||
        const pattern = normalizeToPosix(patterns[index]);
 | 
			
		||||
 | 
			
		||||
        if (stat) {
 | 
			
		||||
 | 
			
		||||
            // files are added directly to the list
 | 
			
		||||
            if (stat.isFile()) {
 | 
			
		||||
                results.push({
 | 
			
		||||
                    filePath,
 | 
			
		||||
                    ignored: configs.isFileIgnored(filePath)
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // directories need extensions attached
 | 
			
		||||
            if (stat.isDirectory()) {
 | 
			
		||||
 | 
			
		||||
                // group everything in cwd together and split out others
 | 
			
		||||
                if (isPathInside(filePath, cwd)) {
 | 
			
		||||
                    ({ patterns: globbyPatterns, rawPatterns } = searches.get(cwd));
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (!searches.has(filePath)) {
 | 
			
		||||
                        searches.set(filePath, { patterns: [], rawPatterns: [] });
 | 
			
		||||
                    }
 | 
			
		||||
                    ({ patterns: globbyPatterns, rawPatterns } = searches.get(filePath));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                globbyPatterns.push(`${normalizeToPosix(filePath)}/**`);
 | 
			
		||||
                rawPatterns.push(pattern);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // save patterns for later use based on whether globs are enabled
 | 
			
		||||
        if (globInputPaths && isGlobPattern(pattern)) {
 | 
			
		||||
 | 
			
		||||
            const basePath = path.resolve(cwd, globParent(pattern));
 | 
			
		||||
 | 
			
		||||
            // group in cwd if possible and split out others
 | 
			
		||||
            if (isPathInside(basePath, cwd)) {
 | 
			
		||||
                ({ patterns: globbyPatterns, rawPatterns } = searches.get(cwd));
 | 
			
		||||
            } else {
 | 
			
		||||
                if (!searches.has(basePath)) {
 | 
			
		||||
                    searches.set(basePath, { patterns: [], rawPatterns: [] });
 | 
			
		||||
                }
 | 
			
		||||
                ({ patterns: globbyPatterns, rawPatterns } = searches.get(basePath));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            globbyPatterns.push(filePath);
 | 
			
		||||
            rawPatterns.push(pattern);
 | 
			
		||||
        } else {
 | 
			
		||||
            missingPatterns.push(pattern);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // there were patterns that didn't match anything, tell the user
 | 
			
		||||
    if (errorOnUnmatchedPattern && missingPatterns.length) {
 | 
			
		||||
        throw new NoFilesFoundError(missingPatterns[0], globInputPaths);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // now we are safe to do the search
 | 
			
		||||
    const globbyResults = await globMultiSearch({
 | 
			
		||||
        searches,
 | 
			
		||||
        configs,
 | 
			
		||||
        errorOnUnmatchedPattern
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return [
 | 
			
		||||
        ...results,
 | 
			
		||||
        ...globbyResults.map(filePath => ({
 | 
			
		||||
            filePath: path.resolve(filePath),
 | 
			
		||||
            ignored: false
 | 
			
		||||
        }))
 | 
			
		||||
    ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Results-related Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if the given message is an error message.
 | 
			
		||||
 * @param {LintMessage} message The message to check.
 | 
			
		||||
 * @returns {boolean} Whether or not the message is an error message.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function isErrorMessage(message) {
 | 
			
		||||
    return message.severity === 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns result with warning by ignore settings
 | 
			
		||||
 * @param {string} filePath File path of checked code
 | 
			
		||||
 * @param {string} baseDir Absolute path of base directory
 | 
			
		||||
 * @returns {LintResult} Result with single warning
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function createIgnoreResult(filePath, baseDir) {
 | 
			
		||||
    let message;
 | 
			
		||||
    const isInNodeModules = baseDir && path.dirname(path.relative(baseDir, filePath)).split(path.sep).includes("node_modules");
 | 
			
		||||
 | 
			
		||||
    if (isInNodeModules) {
 | 
			
		||||
        message = "File ignored by default because it is located under the node_modules directory. Use ignore pattern \"!**/node_modules/\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
 | 
			
		||||
    } else {
 | 
			
		||||
        message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        filePath: path.resolve(filePath),
 | 
			
		||||
        messages: [
 | 
			
		||||
            {
 | 
			
		||||
                ruleId: null,
 | 
			
		||||
                fatal: false,
 | 
			
		||||
                severity: 1,
 | 
			
		||||
                message,
 | 
			
		||||
                nodeType: null
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        suppressedMessages: [],
 | 
			
		||||
        errorCount: 0,
 | 
			
		||||
        warningCount: 1,
 | 
			
		||||
        fatalErrorCount: 0,
 | 
			
		||||
        fixableErrorCount: 0,
 | 
			
		||||
        fixableWarningCount: 0
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Options-related Helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given value is a valid fix type or not.
 | 
			
		||||
 * @param {any} x The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `x` is valid fix type.
 | 
			
		||||
 */
 | 
			
		||||
function isFixType(x) {
 | 
			
		||||
    return x === "directive" || x === "problem" || x === "suggestion" || x === "layout";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given value is an array of fix types or not.
 | 
			
		||||
 * @param {any} x The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `x` is an array of fix types.
 | 
			
		||||
 */
 | 
			
		||||
function isFixTypeArray(x) {
 | 
			
		||||
    return Array.isArray(x) && x.every(isFixType);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error for invalid options.
 | 
			
		||||
 */
 | 
			
		||||
class ESLintInvalidOptionsError extends Error {
 | 
			
		||||
    constructor(messages) {
 | 
			
		||||
        super(`Invalid Options:\n- ${messages.join("\n- ")}`);
 | 
			
		||||
        this.code = "ESLINT_INVALID_OPTIONS";
 | 
			
		||||
        Error.captureStackTrace(this, ESLintInvalidOptionsError);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validates and normalizes options for the wrapped CLIEngine instance.
 | 
			
		||||
 * @param {FlatESLintOptions} options The options to process.
 | 
			
		||||
 * @throws {ESLintInvalidOptionsError} If of any of a variety of type errors.
 | 
			
		||||
 * @returns {FlatESLintOptions} The normalized options.
 | 
			
		||||
 */
 | 
			
		||||
function processOptions({
 | 
			
		||||
    allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored.
 | 
			
		||||
    baseConfig = null,
 | 
			
		||||
    cache = false,
 | 
			
		||||
    cacheLocation = ".eslintcache",
 | 
			
		||||
    cacheStrategy = "metadata",
 | 
			
		||||
    cwd = process.cwd(),
 | 
			
		||||
    errorOnUnmatchedPattern = true,
 | 
			
		||||
    fix = false,
 | 
			
		||||
    fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property.
 | 
			
		||||
    globInputPaths = true,
 | 
			
		||||
    ignore = true,
 | 
			
		||||
    ignorePatterns = null,
 | 
			
		||||
    overrideConfig = null,
 | 
			
		||||
    overrideConfigFile = null,
 | 
			
		||||
    plugins = {},
 | 
			
		||||
    reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that.
 | 
			
		||||
    warnIgnored = true,
 | 
			
		||||
    ...unknownOptions
 | 
			
		||||
}) {
 | 
			
		||||
    const errors = [];
 | 
			
		||||
    const unknownOptionKeys = Object.keys(unknownOptions);
 | 
			
		||||
 | 
			
		||||
    if (unknownOptionKeys.length >= 1) {
 | 
			
		||||
        errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`);
 | 
			
		||||
        if (unknownOptionKeys.includes("cacheFile")) {
 | 
			
		||||
            errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("configFile")) {
 | 
			
		||||
            errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("envs")) {
 | 
			
		||||
            errors.push("'envs' has been removed.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("extensions")) {
 | 
			
		||||
            errors.push("'extensions' has been removed.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("resolvePluginsRelativeTo")) {
 | 
			
		||||
            errors.push("'resolvePluginsRelativeTo' has been removed.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("globals")) {
 | 
			
		||||
            errors.push("'globals' has been removed. Please use the 'overrideConfig.languageOptions.globals' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("ignorePath")) {
 | 
			
		||||
            errors.push("'ignorePath' has been removed.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("ignorePattern")) {
 | 
			
		||||
            errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("parser")) {
 | 
			
		||||
            errors.push("'parser' has been removed. Please use the 'overrideConfig.languageOptions.parser' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("parserOptions")) {
 | 
			
		||||
            errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.languageOptions.parserOptions' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("rules")) {
 | 
			
		||||
            errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("rulePaths")) {
 | 
			
		||||
            errors.push("'rulePaths' has been removed. Please define your rules using plugins.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof allowInlineConfig !== "boolean") {
 | 
			
		||||
        errors.push("'allowInlineConfig' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof baseConfig !== "object") {
 | 
			
		||||
        errors.push("'baseConfig' must be an object or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof cache !== "boolean") {
 | 
			
		||||
        errors.push("'cache' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isNonEmptyString(cacheLocation)) {
 | 
			
		||||
        errors.push("'cacheLocation' must be a non-empty string.");
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
        cacheStrategy !== "metadata" &&
 | 
			
		||||
        cacheStrategy !== "content"
 | 
			
		||||
    ) {
 | 
			
		||||
        errors.push("'cacheStrategy' must be any of \"metadata\", \"content\".");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) {
 | 
			
		||||
        errors.push("'cwd' must be an absolute path.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof errorOnUnmatchedPattern !== "boolean") {
 | 
			
		||||
        errors.push("'errorOnUnmatchedPattern' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof fix !== "boolean" && typeof fix !== "function") {
 | 
			
		||||
        errors.push("'fix' must be a boolean or a function.");
 | 
			
		||||
    }
 | 
			
		||||
    if (fixTypes !== null && !isFixTypeArray(fixTypes)) {
 | 
			
		||||
        errors.push("'fixTypes' must be an array of any of \"directive\", \"problem\", \"suggestion\", and \"layout\".");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof globInputPaths !== "boolean") {
 | 
			
		||||
        errors.push("'globInputPaths' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof ignore !== "boolean") {
 | 
			
		||||
        errors.push("'ignore' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isArrayOfNonEmptyString(ignorePatterns) && ignorePatterns !== null) {
 | 
			
		||||
        errors.push("'ignorePatterns' must be an array of non-empty strings or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof overrideConfig !== "object") {
 | 
			
		||||
        errors.push("'overrideConfig' must be an object or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null && overrideConfigFile !== true) {
 | 
			
		||||
        errors.push("'overrideConfigFile' must be a non-empty string, null, or true.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof plugins !== "object") {
 | 
			
		||||
        errors.push("'plugins' must be an object or null.");
 | 
			
		||||
    } else if (plugins !== null && Object.keys(plugins).includes("")) {
 | 
			
		||||
        errors.push("'plugins' must not include an empty string.");
 | 
			
		||||
    }
 | 
			
		||||
    if (Array.isArray(plugins)) {
 | 
			
		||||
        errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead.");
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
        reportUnusedDisableDirectives !== "error" &&
 | 
			
		||||
        reportUnusedDisableDirectives !== "warn" &&
 | 
			
		||||
        reportUnusedDisableDirectives !== "off" &&
 | 
			
		||||
        reportUnusedDisableDirectives !== null
 | 
			
		||||
    ) {
 | 
			
		||||
        errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof warnIgnored !== "boolean") {
 | 
			
		||||
        errors.push("'warnIgnored' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (errors.length > 0) {
 | 
			
		||||
        throw new ESLintInvalidOptionsError(errors);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        allowInlineConfig,
 | 
			
		||||
        baseConfig,
 | 
			
		||||
        cache,
 | 
			
		||||
        cacheLocation,
 | 
			
		||||
        cacheStrategy,
 | 
			
		||||
 | 
			
		||||
        // when overrideConfigFile is true that means don't do config file lookup
 | 
			
		||||
        configFile: overrideConfigFile === true ? false : overrideConfigFile,
 | 
			
		||||
        overrideConfig,
 | 
			
		||||
        cwd: path.normalize(cwd),
 | 
			
		||||
        errorOnUnmatchedPattern,
 | 
			
		||||
        fix,
 | 
			
		||||
        fixTypes,
 | 
			
		||||
        globInputPaths,
 | 
			
		||||
        ignore,
 | 
			
		||||
        ignorePatterns,
 | 
			
		||||
        reportUnusedDisableDirectives,
 | 
			
		||||
        warnIgnored
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Cache-related helpers
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * return the cacheFile to be used by eslint, based on whether the provided parameter is
 | 
			
		||||
 * a directory or looks like a directory (ends in `path.sep`), in which case the file
 | 
			
		||||
 * name will be the `cacheFile/.cache_hashOfCWD`
 | 
			
		||||
 *
 | 
			
		||||
 * if cacheFile points to a file or looks like a file then in will just use that file
 | 
			
		||||
 * @param {string} cacheFile The name of file to be used to store the cache
 | 
			
		||||
 * @param {string} cwd Current working directory
 | 
			
		||||
 * @returns {string} the resolved path to the cache file
 | 
			
		||||
 */
 | 
			
		||||
function getCacheFile(cacheFile, cwd) {
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * make sure the path separators are normalized for the environment/os
 | 
			
		||||
     * keeping the trailing path separator if present
 | 
			
		||||
     */
 | 
			
		||||
    const normalizedCacheFile = path.normalize(cacheFile);
 | 
			
		||||
 | 
			
		||||
    const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile);
 | 
			
		||||
    const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * return the name for the cache file in case the provided parameter is a directory
 | 
			
		||||
     * @returns {string} the resolved path to the cacheFile
 | 
			
		||||
     */
 | 
			
		||||
    function getCacheFileForDirectory() {
 | 
			
		||||
        return path.join(resolvedCacheFile, `.cache_${hash(cwd)}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let fileStats;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        fileStats = fs.lstatSync(resolvedCacheFile);
 | 
			
		||||
    } catch {
 | 
			
		||||
        fileStats = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * in case the file exists we need to verify if the provided path
 | 
			
		||||
     * is a directory or a file. If it is a directory we want to create a file
 | 
			
		||||
     * inside that directory
 | 
			
		||||
     */
 | 
			
		||||
    if (fileStats) {
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * is a directory or is a file, but the original file the user provided
 | 
			
		||||
         * looks like a directory but `path.resolve` removed the `last path.sep`
 | 
			
		||||
         * so we need to still treat this like a directory
 | 
			
		||||
         */
 | 
			
		||||
        if (fileStats.isDirectory() || looksLikeADirectory) {
 | 
			
		||||
            return getCacheFileForDirectory();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // is file so just use that file
 | 
			
		||||
        return resolvedCacheFile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * here we known the file or directory doesn't exist,
 | 
			
		||||
     * so we will try to infer if its a directory if it looks like a directory
 | 
			
		||||
     * for the current operating system.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    // if the last character passed is a path separator we assume is a directory
 | 
			
		||||
    if (looksLikeADirectory) {
 | 
			
		||||
        return getCacheFileForDirectory();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return resolvedCacheFile;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// Exports
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    isGlobPattern,
 | 
			
		||||
    findFiles,
 | 
			
		||||
 | 
			
		||||
    isNonEmptyString,
 | 
			
		||||
    isArrayOfNonEmptyString,
 | 
			
		||||
 | 
			
		||||
    createIgnoreResult,
 | 
			
		||||
    isErrorMessage,
 | 
			
		||||
 | 
			
		||||
    processOptions,
 | 
			
		||||
 | 
			
		||||
    getCacheFile
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										700
									
								
								node_modules/eslint/lib/eslint/eslint.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										700
									
								
								node_modules/eslint/lib/eslint/eslint.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,700 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Main API Class
 | 
			
		||||
 * @author Kai Cataldo
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const path = require("path");
 | 
			
		||||
const fs = require("fs");
 | 
			
		||||
const { promisify } = require("util");
 | 
			
		||||
const { CLIEngine, getCLIEngineInternalSlots } = require("../cli-engine/cli-engine");
 | 
			
		||||
const BuiltinRules = require("../rules");
 | 
			
		||||
const {
 | 
			
		||||
    Legacy: {
 | 
			
		||||
        ConfigOps: {
 | 
			
		||||
            getRuleSeverity
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
} = require("@eslint/eslintrc");
 | 
			
		||||
const { version } = require("../../package.json");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @typedef {import("../cli-engine/cli-engine").LintReport} CLIEngineLintReport */
 | 
			
		||||
/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */
 | 
			
		||||
/** @typedef {import("../shared/types").ConfigData} ConfigData */
 | 
			
		||||
/** @typedef {import("../shared/types").LintMessage} LintMessage */
 | 
			
		||||
/** @typedef {import("../shared/types").SuppressedLintMessage} SuppressedLintMessage */
 | 
			
		||||
/** @typedef {import("../shared/types").Plugin} Plugin */
 | 
			
		||||
/** @typedef {import("../shared/types").Rule} Rule */
 | 
			
		||||
/** @typedef {import("../shared/types").LintResult} LintResult */
 | 
			
		||||
/** @typedef {import("../shared/types").ResultsMeta} ResultsMeta */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The main formatter object.
 | 
			
		||||
 * @typedef LoadedFormatter
 | 
			
		||||
 * @property {(results: LintResult[], resultsMeta: ResultsMeta) => string | Promise<string>} format format function.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The options with which to configure the ESLint instance.
 | 
			
		||||
 * @typedef {Object} ESLintOptions
 | 
			
		||||
 * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments.
 | 
			
		||||
 * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this instance
 | 
			
		||||
 * @property {boolean} [cache] Enable result caching.
 | 
			
		||||
 * @property {string} [cacheLocation] The cache file to use instead of .eslintcache.
 | 
			
		||||
 * @property {"metadata" | "content"} [cacheStrategy] The strategy used to detect changed files.
 | 
			
		||||
 * @property {string} [cwd] The value to use for the current working directory.
 | 
			
		||||
 * @property {boolean} [errorOnUnmatchedPattern] If `false` then `ESLint#lintFiles()` doesn't throw even if no target files found. Defaults to `true`.
 | 
			
		||||
 * @property {string[]} [extensions] An array of file extensions to check.
 | 
			
		||||
 * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean.
 | 
			
		||||
 * @property {string[]} [fixTypes] Array of rule types to apply fixes for.
 | 
			
		||||
 * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
 | 
			
		||||
 * @property {boolean} [ignore] False disables use of .eslintignore.
 | 
			
		||||
 * @property {string} [ignorePath] The ignore file to use instead of .eslintignore.
 | 
			
		||||
 * @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance
 | 
			
		||||
 * @property {string} [overrideConfigFile] The configuration file to use.
 | 
			
		||||
 * @property {Record<string,Plugin>|null} [plugins] Preloaded plugins. This is a map-like object, keys are plugin IDs and each value is implementation.
 | 
			
		||||
 * @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives.
 | 
			
		||||
 * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD.
 | 
			
		||||
 * @property {string[]} [rulePaths] An array of directories to load custom rules from.
 | 
			
		||||
 * @property {boolean} [useEslintrc] False disables looking for .eslintrc.* files.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A rules metadata object.
 | 
			
		||||
 * @typedef {Object} RulesMeta
 | 
			
		||||
 * @property {string} id The plugin ID.
 | 
			
		||||
 * @property {Object} definition The plugin definition.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Private members for the `ESLint` instance.
 | 
			
		||||
 * @typedef {Object} ESLintPrivateMembers
 | 
			
		||||
 * @property {CLIEngine} cliEngine The wrapped CLIEngine instance.
 | 
			
		||||
 * @property {ESLintOptions} options The options used to instantiate the ESLint instance.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const writeFile = promisify(fs.writeFile);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The map with which to store private class members.
 | 
			
		||||
 * @type {WeakMap<ESLint, ESLintPrivateMembers>}
 | 
			
		||||
 */
 | 
			
		||||
const privateMembersMap = new WeakMap();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given value is a non-empty string or not.
 | 
			
		||||
 * @param {any} x The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `x` is a non-empty string.
 | 
			
		||||
 */
 | 
			
		||||
function isNonEmptyString(x) {
 | 
			
		||||
    return typeof x === "string" && x.trim() !== "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given value is an array of non-empty strings or not.
 | 
			
		||||
 * @param {any} x The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `x` is an array of non-empty strings.
 | 
			
		||||
 */
 | 
			
		||||
function isArrayOfNonEmptyString(x) {
 | 
			
		||||
    return Array.isArray(x) && x.every(isNonEmptyString);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given value is a valid fix type or not.
 | 
			
		||||
 * @param {any} x The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `x` is valid fix type.
 | 
			
		||||
 */
 | 
			
		||||
function isFixType(x) {
 | 
			
		||||
    return x === "directive" || x === "problem" || x === "suggestion" || x === "layout";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a given value is an array of fix types or not.
 | 
			
		||||
 * @param {any} x The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `x` is an array of fix types.
 | 
			
		||||
 */
 | 
			
		||||
function isFixTypeArray(x) {
 | 
			
		||||
    return Array.isArray(x) && x.every(isFixType);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The error for invalid options.
 | 
			
		||||
 */
 | 
			
		||||
class ESLintInvalidOptionsError extends Error {
 | 
			
		||||
    constructor(messages) {
 | 
			
		||||
        super(`Invalid Options:\n- ${messages.join("\n- ")}`);
 | 
			
		||||
        this.code = "ESLINT_INVALID_OPTIONS";
 | 
			
		||||
        Error.captureStackTrace(this, ESLintInvalidOptionsError);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validates and normalizes options for the wrapped CLIEngine instance.
 | 
			
		||||
 * @param {ESLintOptions} options The options to process.
 | 
			
		||||
 * @throws {ESLintInvalidOptionsError} If of any of a variety of type errors.
 | 
			
		||||
 * @returns {ESLintOptions} The normalized options.
 | 
			
		||||
 */
 | 
			
		||||
function processOptions({
 | 
			
		||||
    allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored.
 | 
			
		||||
    baseConfig = null,
 | 
			
		||||
    cache = false,
 | 
			
		||||
    cacheLocation = ".eslintcache",
 | 
			
		||||
    cacheStrategy = "metadata",
 | 
			
		||||
    cwd = process.cwd(),
 | 
			
		||||
    errorOnUnmatchedPattern = true,
 | 
			
		||||
    extensions = null, // ← should be null by default because if it's an array then it suppresses RFC20 feature.
 | 
			
		||||
    fix = false,
 | 
			
		||||
    fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property.
 | 
			
		||||
    globInputPaths = true,
 | 
			
		||||
    ignore = true,
 | 
			
		||||
    ignorePath = null, // ← should be null by default because if it's a string then it may throw ENOENT.
 | 
			
		||||
    overrideConfig = null,
 | 
			
		||||
    overrideConfigFile = null,
 | 
			
		||||
    plugins = {},
 | 
			
		||||
    reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that.
 | 
			
		||||
    resolvePluginsRelativeTo = null, // ← should be null by default because if it's a string then it suppresses RFC47 feature.
 | 
			
		||||
    rulePaths = [],
 | 
			
		||||
    useEslintrc = true,
 | 
			
		||||
    ...unknownOptions
 | 
			
		||||
}) {
 | 
			
		||||
    const errors = [];
 | 
			
		||||
    const unknownOptionKeys = Object.keys(unknownOptions);
 | 
			
		||||
 | 
			
		||||
    if (unknownOptionKeys.length >= 1) {
 | 
			
		||||
        errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`);
 | 
			
		||||
        if (unknownOptionKeys.includes("cacheFile")) {
 | 
			
		||||
            errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("configFile")) {
 | 
			
		||||
            errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("envs")) {
 | 
			
		||||
            errors.push("'envs' has been removed. Please use the 'overrideConfig.env' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("globals")) {
 | 
			
		||||
            errors.push("'globals' has been removed. Please use the 'overrideConfig.globals' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("ignorePattern")) {
 | 
			
		||||
            errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("parser")) {
 | 
			
		||||
            errors.push("'parser' has been removed. Please use the 'overrideConfig.parser' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("parserOptions")) {
 | 
			
		||||
            errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
        if (unknownOptionKeys.includes("rules")) {
 | 
			
		||||
            errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof allowInlineConfig !== "boolean") {
 | 
			
		||||
        errors.push("'allowInlineConfig' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof baseConfig !== "object") {
 | 
			
		||||
        errors.push("'baseConfig' must be an object or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof cache !== "boolean") {
 | 
			
		||||
        errors.push("'cache' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isNonEmptyString(cacheLocation)) {
 | 
			
		||||
        errors.push("'cacheLocation' must be a non-empty string.");
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
        cacheStrategy !== "metadata" &&
 | 
			
		||||
        cacheStrategy !== "content"
 | 
			
		||||
    ) {
 | 
			
		||||
        errors.push("'cacheStrategy' must be any of \"metadata\", \"content\".");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) {
 | 
			
		||||
        errors.push("'cwd' must be an absolute path.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof errorOnUnmatchedPattern !== "boolean") {
 | 
			
		||||
        errors.push("'errorOnUnmatchedPattern' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isArrayOfNonEmptyString(extensions) && extensions !== null) {
 | 
			
		||||
        errors.push("'extensions' must be an array of non-empty strings or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof fix !== "boolean" && typeof fix !== "function") {
 | 
			
		||||
        errors.push("'fix' must be a boolean or a function.");
 | 
			
		||||
    }
 | 
			
		||||
    if (fixTypes !== null && !isFixTypeArray(fixTypes)) {
 | 
			
		||||
        errors.push("'fixTypes' must be an array of any of \"directive\", \"problem\", \"suggestion\", and \"layout\".");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof globInputPaths !== "boolean") {
 | 
			
		||||
        errors.push("'globInputPaths' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof ignore !== "boolean") {
 | 
			
		||||
        errors.push("'ignore' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isNonEmptyString(ignorePath) && ignorePath !== null) {
 | 
			
		||||
        errors.push("'ignorePath' must be a non-empty string or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof overrideConfig !== "object") {
 | 
			
		||||
        errors.push("'overrideConfig' must be an object or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null) {
 | 
			
		||||
        errors.push("'overrideConfigFile' must be a non-empty string or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof plugins !== "object") {
 | 
			
		||||
        errors.push("'plugins' must be an object or null.");
 | 
			
		||||
    } else if (plugins !== null && Object.keys(plugins).includes("")) {
 | 
			
		||||
        errors.push("'plugins' must not include an empty string.");
 | 
			
		||||
    }
 | 
			
		||||
    if (Array.isArray(plugins)) {
 | 
			
		||||
        errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead.");
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
        reportUnusedDisableDirectives !== "error" &&
 | 
			
		||||
        reportUnusedDisableDirectives !== "warn" &&
 | 
			
		||||
        reportUnusedDisableDirectives !== "off" &&
 | 
			
		||||
        reportUnusedDisableDirectives !== null
 | 
			
		||||
    ) {
 | 
			
		||||
        errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
        !isNonEmptyString(resolvePluginsRelativeTo) &&
 | 
			
		||||
        resolvePluginsRelativeTo !== null
 | 
			
		||||
    ) {
 | 
			
		||||
        errors.push("'resolvePluginsRelativeTo' must be a non-empty string or null.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!isArrayOfNonEmptyString(rulePaths)) {
 | 
			
		||||
        errors.push("'rulePaths' must be an array of non-empty strings.");
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof useEslintrc !== "boolean") {
 | 
			
		||||
        errors.push("'useEslintrc' must be a boolean.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (errors.length > 0) {
 | 
			
		||||
        throw new ESLintInvalidOptionsError(errors);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        allowInlineConfig,
 | 
			
		||||
        baseConfig,
 | 
			
		||||
        cache,
 | 
			
		||||
        cacheLocation,
 | 
			
		||||
        cacheStrategy,
 | 
			
		||||
        configFile: overrideConfigFile,
 | 
			
		||||
        cwd: path.normalize(cwd),
 | 
			
		||||
        errorOnUnmatchedPattern,
 | 
			
		||||
        extensions,
 | 
			
		||||
        fix,
 | 
			
		||||
        fixTypes,
 | 
			
		||||
        globInputPaths,
 | 
			
		||||
        ignore,
 | 
			
		||||
        ignorePath,
 | 
			
		||||
        reportUnusedDisableDirectives,
 | 
			
		||||
        resolvePluginsRelativeTo,
 | 
			
		||||
        rulePaths,
 | 
			
		||||
        useEslintrc
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a value has one or more properties and that value is not undefined.
 | 
			
		||||
 * @param {any} obj The value to check.
 | 
			
		||||
 * @returns {boolean} `true` if `obj` has one or more properties that that value is not undefined.
 | 
			
		||||
 */
 | 
			
		||||
function hasDefinedProperty(obj) {
 | 
			
		||||
    if (typeof obj === "object" && obj !== null) {
 | 
			
		||||
        for (const key in obj) {
 | 
			
		||||
            if (typeof obj[key] !== "undefined") {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create rulesMeta object.
 | 
			
		||||
 * @param {Map<string,Rule>} rules a map of rules from which to generate the object.
 | 
			
		||||
 * @returns {Object} metadata for all enabled rules.
 | 
			
		||||
 */
 | 
			
		||||
function createRulesMeta(rules) {
 | 
			
		||||
    return Array.from(rules).reduce((retVal, [id, rule]) => {
 | 
			
		||||
        retVal[id] = rule.meta;
 | 
			
		||||
        return retVal;
 | 
			
		||||
    }, {});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @type {WeakMap<ExtractedConfig, DeprecatedRuleInfo[]>} */
 | 
			
		||||
const usedDeprecatedRulesCache = new WeakMap();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create used deprecated rule list.
 | 
			
		||||
 * @param {CLIEngine} cliEngine The CLIEngine instance.
 | 
			
		||||
 * @param {string} maybeFilePath The absolute path to a lint target file or `"<text>"`.
 | 
			
		||||
 * @returns {DeprecatedRuleInfo[]} The used deprecated rule list.
 | 
			
		||||
 */
 | 
			
		||||
function getOrFindUsedDeprecatedRules(cliEngine, maybeFilePath) {
 | 
			
		||||
    const {
 | 
			
		||||
        configArrayFactory,
 | 
			
		||||
        options: { cwd }
 | 
			
		||||
    } = getCLIEngineInternalSlots(cliEngine);
 | 
			
		||||
    const filePath = path.isAbsolute(maybeFilePath)
 | 
			
		||||
        ? maybeFilePath
 | 
			
		||||
        : path.join(cwd, "__placeholder__.js");
 | 
			
		||||
    const configArray = configArrayFactory.getConfigArrayForFile(filePath);
 | 
			
		||||
    const config = configArray.extractConfig(filePath);
 | 
			
		||||
 | 
			
		||||
    // Most files use the same config, so cache it.
 | 
			
		||||
    if (!usedDeprecatedRulesCache.has(config)) {
 | 
			
		||||
        const pluginRules = configArray.pluginRules;
 | 
			
		||||
        const retv = [];
 | 
			
		||||
 | 
			
		||||
        for (const [ruleId, ruleConf] of Object.entries(config.rules)) {
 | 
			
		||||
            if (getRuleSeverity(ruleConf) === 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            const rule = pluginRules.get(ruleId) || BuiltinRules.get(ruleId);
 | 
			
		||||
            const meta = rule && rule.meta;
 | 
			
		||||
 | 
			
		||||
            if (meta && meta.deprecated) {
 | 
			
		||||
                retv.push({ ruleId, replacedBy: meta.replacedBy || [] });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        usedDeprecatedRulesCache.set(config, Object.freeze(retv));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return usedDeprecatedRulesCache.get(config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Processes the linting results generated by a CLIEngine linting report to
 | 
			
		||||
 * match the ESLint class's API.
 | 
			
		||||
 * @param {CLIEngine} cliEngine The CLIEngine instance.
 | 
			
		||||
 * @param {CLIEngineLintReport} report The CLIEngine linting report to process.
 | 
			
		||||
 * @returns {LintResult[]} The processed linting results.
 | 
			
		||||
 */
 | 
			
		||||
function processCLIEngineLintReport(cliEngine, { results }) {
 | 
			
		||||
    const descriptor = {
 | 
			
		||||
        configurable: true,
 | 
			
		||||
        enumerable: true,
 | 
			
		||||
        get() {
 | 
			
		||||
            return getOrFindUsedDeprecatedRules(cliEngine, this.filePath);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    for (const result of results) {
 | 
			
		||||
        Object.defineProperty(result, "usedDeprecatedRules", descriptor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return results;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An Array.prototype.sort() compatible compare function to order results by their file path.
 | 
			
		||||
 * @param {LintResult} a The first lint result.
 | 
			
		||||
 * @param {LintResult} b The second lint result.
 | 
			
		||||
 * @returns {number} An integer representing the order in which the two results should occur.
 | 
			
		||||
 */
 | 
			
		||||
function compareResultsByFilePath(a, b) {
 | 
			
		||||
    if (a.filePath < b.filePath) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (a.filePath > b.filePath) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Main API.
 | 
			
		||||
 */
 | 
			
		||||
class ESLint {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new instance of the main ESLint API.
 | 
			
		||||
     * @param {ESLintOptions} options The options for this instance.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(options = {}) {
 | 
			
		||||
        const processedOptions = processOptions(options);
 | 
			
		||||
        const cliEngine = new CLIEngine(processedOptions, { preloadedPlugins: options.plugins });
 | 
			
		||||
        const {
 | 
			
		||||
            configArrayFactory,
 | 
			
		||||
            lastConfigArrays
 | 
			
		||||
        } = getCLIEngineInternalSlots(cliEngine);
 | 
			
		||||
        let updated = false;
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Address `overrideConfig` to set override config.
 | 
			
		||||
         * Operate the `configArrayFactory` internal slot directly because this
 | 
			
		||||
         * functionality doesn't exist as the public API of CLIEngine.
 | 
			
		||||
         */
 | 
			
		||||
        if (hasDefinedProperty(options.overrideConfig)) {
 | 
			
		||||
            configArrayFactory.setOverrideConfig(options.overrideConfig);
 | 
			
		||||
            updated = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Update caches.
 | 
			
		||||
        if (updated) {
 | 
			
		||||
            configArrayFactory.clearCache();
 | 
			
		||||
            lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Initialize private properties.
 | 
			
		||||
        privateMembersMap.set(this, {
 | 
			
		||||
            cliEngine,
 | 
			
		||||
            options: processedOptions
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The version text.
 | 
			
		||||
     * @type {string}
 | 
			
		||||
     */
 | 
			
		||||
    static get version() {
 | 
			
		||||
        return version;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Outputs fixes from the given results to files.
 | 
			
		||||
     * @param {LintResult[]} results The lint results.
 | 
			
		||||
     * @returns {Promise<void>} Returns a promise that is used to track side effects.
 | 
			
		||||
     */
 | 
			
		||||
    static async outputFixes(results) {
 | 
			
		||||
        if (!Array.isArray(results)) {
 | 
			
		||||
            throw new Error("'results' must be an array");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await Promise.all(
 | 
			
		||||
            results
 | 
			
		||||
                .filter(result => {
 | 
			
		||||
                    if (typeof result !== "object" || result === null) {
 | 
			
		||||
                        throw new Error("'results' must include only objects");
 | 
			
		||||
                    }
 | 
			
		||||
                    return (
 | 
			
		||||
                        typeof result.output === "string" &&
 | 
			
		||||
                        path.isAbsolute(result.filePath)
 | 
			
		||||
                    );
 | 
			
		||||
                })
 | 
			
		||||
                .map(r => writeFile(r.filePath, r.output))
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns results that only contains errors.
 | 
			
		||||
     * @param {LintResult[]} results The results to filter.
 | 
			
		||||
     * @returns {LintResult[]} The filtered results.
 | 
			
		||||
     */
 | 
			
		||||
    static getErrorResults(results) {
 | 
			
		||||
        return CLIEngine.getErrorResults(results);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns meta objects for each rule represented in the lint results.
 | 
			
		||||
     * @param {LintResult[]} results The results to fetch rules meta for.
 | 
			
		||||
     * @returns {Object} A mapping of ruleIds to rule meta objects.
 | 
			
		||||
     */
 | 
			
		||||
    getRulesMetaForResults(results) {
 | 
			
		||||
 | 
			
		||||
        const resultRuleIds = new Set();
 | 
			
		||||
 | 
			
		||||
        // first gather all ruleIds from all results
 | 
			
		||||
 | 
			
		||||
        for (const result of results) {
 | 
			
		||||
            for (const { ruleId } of result.messages) {
 | 
			
		||||
                resultRuleIds.add(ruleId);
 | 
			
		||||
            }
 | 
			
		||||
            for (const { ruleId } of result.suppressedMessages) {
 | 
			
		||||
                resultRuleIds.add(ruleId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // create a map of all rules in the results
 | 
			
		||||
 | 
			
		||||
        const { cliEngine } = privateMembersMap.get(this);
 | 
			
		||||
        const rules = cliEngine.getRules();
 | 
			
		||||
        const resultRules = new Map();
 | 
			
		||||
 | 
			
		||||
        for (const [ruleId, rule] of rules) {
 | 
			
		||||
            if (resultRuleIds.has(ruleId)) {
 | 
			
		||||
                resultRules.set(ruleId, rule);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return createRulesMeta(resultRules);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Executes the current configuration on an array of file and directory names.
 | 
			
		||||
     * @param {string[]} patterns An array of file and directory names.
 | 
			
		||||
     * @returns {Promise<LintResult[]>} The results of linting the file patterns given.
 | 
			
		||||
     */
 | 
			
		||||
    async lintFiles(patterns) {
 | 
			
		||||
        if (!isNonEmptyString(patterns) && !isArrayOfNonEmptyString(patterns)) {
 | 
			
		||||
            throw new Error("'patterns' must be a non-empty string or an array of non-empty strings");
 | 
			
		||||
        }
 | 
			
		||||
        const { cliEngine } = privateMembersMap.get(this);
 | 
			
		||||
 | 
			
		||||
        return processCLIEngineLintReport(
 | 
			
		||||
            cliEngine,
 | 
			
		||||
            cliEngine.executeOnFiles(patterns)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Executes the current configuration on text.
 | 
			
		||||
     * @param {string} code A string of JavaScript code to lint.
 | 
			
		||||
     * @param {Object} [options] The options.
 | 
			
		||||
     * @param {string} [options.filePath] The path to the file of the source code.
 | 
			
		||||
     * @param {boolean} [options.warnIgnored] When set to true, warn if given filePath is an ignored path.
 | 
			
		||||
     * @returns {Promise<LintResult[]>} The results of linting the string of code given.
 | 
			
		||||
     */
 | 
			
		||||
    async lintText(code, options = {}) {
 | 
			
		||||
        if (typeof code !== "string") {
 | 
			
		||||
            throw new Error("'code' must be a string");
 | 
			
		||||
        }
 | 
			
		||||
        if (typeof options !== "object") {
 | 
			
		||||
            throw new Error("'options' must be an object, null, or undefined");
 | 
			
		||||
        }
 | 
			
		||||
        const {
 | 
			
		||||
            filePath,
 | 
			
		||||
            warnIgnored = false,
 | 
			
		||||
            ...unknownOptions
 | 
			
		||||
        } = options || {};
 | 
			
		||||
 | 
			
		||||
        const unknownOptionKeys = Object.keys(unknownOptions);
 | 
			
		||||
 | 
			
		||||
        if (unknownOptionKeys.length > 0) {
 | 
			
		||||
            throw new Error(`'options' must not include the unknown option(s): ${unknownOptionKeys.join(", ")}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (filePath !== void 0 && !isNonEmptyString(filePath)) {
 | 
			
		||||
            throw new Error("'options.filePath' must be a non-empty string or undefined");
 | 
			
		||||
        }
 | 
			
		||||
        if (typeof warnIgnored !== "boolean") {
 | 
			
		||||
            throw new Error("'options.warnIgnored' must be a boolean or undefined");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const { cliEngine } = privateMembersMap.get(this);
 | 
			
		||||
 | 
			
		||||
        return processCLIEngineLintReport(
 | 
			
		||||
            cliEngine,
 | 
			
		||||
            cliEngine.executeOnText(code, filePath, warnIgnored)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the formatter representing the given formatter name.
 | 
			
		||||
     * @param {string} [name] The name of the formatter to load.
 | 
			
		||||
     * The following values are allowed:
 | 
			
		||||
     * - `undefined` ... Load `stylish` builtin formatter.
 | 
			
		||||
     * - A builtin formatter name ... Load the builtin formatter.
 | 
			
		||||
     * - A third-party formatter name:
 | 
			
		||||
     *   - `foo` → `eslint-formatter-foo`
 | 
			
		||||
     *   - `@foo` → `@foo/eslint-formatter`
 | 
			
		||||
     *   - `@foo/bar` → `@foo/eslint-formatter-bar`
 | 
			
		||||
     * - A file path ... Load the file.
 | 
			
		||||
     * @returns {Promise<LoadedFormatter>} A promise resolving to the formatter object.
 | 
			
		||||
     * This promise will be rejected if the given formatter was not found or not
 | 
			
		||||
     * a function.
 | 
			
		||||
     */
 | 
			
		||||
    async loadFormatter(name = "stylish") {
 | 
			
		||||
        if (typeof name !== "string") {
 | 
			
		||||
            throw new Error("'name' must be a string");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const { cliEngine, options } = privateMembersMap.get(this);
 | 
			
		||||
        const formatter = cliEngine.getFormatter(name);
 | 
			
		||||
 | 
			
		||||
        if (typeof formatter !== "function") {
 | 
			
		||||
            throw new Error(`Formatter must be a function, but got a ${typeof formatter}.`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * The main formatter method.
 | 
			
		||||
             * @param {LintResult[]} results The lint results to format.
 | 
			
		||||
             * @param {ResultsMeta} resultsMeta Warning count and max threshold.
 | 
			
		||||
             * @returns {string | Promise<string>} The formatted lint results.
 | 
			
		||||
             */
 | 
			
		||||
            format(results, resultsMeta) {
 | 
			
		||||
                let rulesMeta = null;
 | 
			
		||||
 | 
			
		||||
                results.sort(compareResultsByFilePath);
 | 
			
		||||
 | 
			
		||||
                return formatter(results, {
 | 
			
		||||
                    ...resultsMeta,
 | 
			
		||||
                    get cwd() {
 | 
			
		||||
                        return options.cwd;
 | 
			
		||||
                    },
 | 
			
		||||
                    get rulesMeta() {
 | 
			
		||||
                        if (!rulesMeta) {
 | 
			
		||||
                            rulesMeta = createRulesMeta(cliEngine.getRules());
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        return rulesMeta;
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a configuration object for the given file based on the CLI options.
 | 
			
		||||
     * This is the same logic used by the ESLint CLI executable to determine
 | 
			
		||||
     * configuration for each file it processes.
 | 
			
		||||
     * @param {string} filePath The path of the file to retrieve a config object for.
 | 
			
		||||
     * @returns {Promise<ConfigData>} A configuration object for the file.
 | 
			
		||||
     */
 | 
			
		||||
    async calculateConfigForFile(filePath) {
 | 
			
		||||
        if (!isNonEmptyString(filePath)) {
 | 
			
		||||
            throw new Error("'filePath' must be a non-empty string");
 | 
			
		||||
        }
 | 
			
		||||
        const { cliEngine } = privateMembersMap.get(this);
 | 
			
		||||
 | 
			
		||||
        return cliEngine.getConfigForFile(filePath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if a given path is ignored by ESLint.
 | 
			
		||||
     * @param {string} filePath The path of the file to check.
 | 
			
		||||
     * @returns {Promise<boolean>} Whether or not the given path is ignored.
 | 
			
		||||
     */
 | 
			
		||||
    async isPathIgnored(filePath) {
 | 
			
		||||
        if (!isNonEmptyString(filePath)) {
 | 
			
		||||
            throw new Error("'filePath' must be a non-empty string");
 | 
			
		||||
        }
 | 
			
		||||
        const { cliEngine } = privateMembersMap.get(this);
 | 
			
		||||
 | 
			
		||||
        return cliEngine.isPathIgnored(filePath);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    ESLint,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the private class members of a given ESLint instance for tests.
 | 
			
		||||
     * @param {ESLint} instance The ESLint instance to get.
 | 
			
		||||
     * @returns {ESLintPrivateMembers} The instance's private class members.
 | 
			
		||||
     */
 | 
			
		||||
    getESLintPrivateMembers(instance) {
 | 
			
		||||
        return privateMembersMap.get(instance);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1149
									
								
								node_modules/eslint/lib/eslint/flat-eslint.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1149
									
								
								node_modules/eslint/lib/eslint/flat-eslint.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										9
									
								
								node_modules/eslint/lib/eslint/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/eslint/lib/eslint/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const { ESLint } = require("./eslint");
 | 
			
		||||
const { FlatESLint } = require("./flat-eslint");
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    ESLint,
 | 
			
		||||
    FlatESLint
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										465
									
								
								node_modules/eslint/lib/linter/apply-disable-directives.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										465
									
								
								node_modules/eslint/lib/linter/apply-disable-directives.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,465 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A module that filters reported problems based on `eslint-disable` and `eslint-enable` comments
 | 
			
		||||
 * @author Teddy Katz
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @typedef {import("../shared/types").LintMessage} LintMessage */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Module Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const escapeRegExp = require("escape-string-regexp");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compares the locations of two objects in a source file
 | 
			
		||||
 * @param {{line: number, column: number}} itemA The first object
 | 
			
		||||
 * @param {{line: number, column: number}} itemB The second object
 | 
			
		||||
 * @returns {number} A value less than 1 if itemA appears before itemB in the source file, greater than 1 if
 | 
			
		||||
 * itemA appears after itemB in the source file, or 0 if itemA and itemB have the same location.
 | 
			
		||||
 */
 | 
			
		||||
function compareLocations(itemA, itemB) {
 | 
			
		||||
    return itemA.line - itemB.line || itemA.column - itemB.column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Groups a set of directives into sub-arrays by their parent comment.
 | 
			
		||||
 * @param {Iterable<Directive>} directives Unused directives to be removed.
 | 
			
		||||
 * @returns {Directive[][]} Directives grouped by their parent comment.
 | 
			
		||||
 */
 | 
			
		||||
function groupByParentComment(directives) {
 | 
			
		||||
    const groups = new Map();
 | 
			
		||||
 | 
			
		||||
    for (const directive of directives) {
 | 
			
		||||
        const { unprocessedDirective: { parentComment } } = directive;
 | 
			
		||||
 | 
			
		||||
        if (groups.has(parentComment)) {
 | 
			
		||||
            groups.get(parentComment).push(directive);
 | 
			
		||||
        } else {
 | 
			
		||||
            groups.set(parentComment, [directive]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return [...groups.values()];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates removal details for a set of directives within the same comment.
 | 
			
		||||
 * @param {Directive[]} directives Unused directives to be removed.
 | 
			
		||||
 * @param {Token} commentToken The backing Comment token.
 | 
			
		||||
 * @returns {{ description, fix, unprocessedDirective }[]} Details for later creation of output Problems.
 | 
			
		||||
 */
 | 
			
		||||
function createIndividualDirectivesRemoval(directives, commentToken) {
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * `commentToken.value` starts right after `//` or `/*`.
 | 
			
		||||
     * All calculated offsets will be relative to this index.
 | 
			
		||||
     */
 | 
			
		||||
    const commentValueStart = commentToken.range[0] + "//".length;
 | 
			
		||||
 | 
			
		||||
    // Find where the list of rules starts. `\S+` matches with the directive name (e.g. `eslint-disable-line`)
 | 
			
		||||
    const listStartOffset = /^\s*\S+\s+/u.exec(commentToken.value)[0].length;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Get the list text without any surrounding whitespace. In order to preserve the original
 | 
			
		||||
     * formatting, we don't want to change that whitespace.
 | 
			
		||||
     *
 | 
			
		||||
     *     // eslint-disable-line rule-one , rule-two , rule-three -- comment
 | 
			
		||||
     *                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
     */
 | 
			
		||||
    const listText = commentToken.value
 | 
			
		||||
        .slice(listStartOffset) // remove directive name and all whitespace before the list
 | 
			
		||||
        .split(/\s-{2,}\s/u)[0] // remove `-- comment`, if it exists
 | 
			
		||||
        .trimEnd(); // remove all whitespace after the list
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * We can assume that `listText` contains multiple elements.
 | 
			
		||||
     * Otherwise, this function wouldn't be called - if there is
 | 
			
		||||
     * only one rule in the list, then the whole comment must be removed.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    return directives.map(directive => {
 | 
			
		||||
        const { ruleId } = directive;
 | 
			
		||||
 | 
			
		||||
        const regex = new RegExp(String.raw`(?:^|\s*,\s*)(?<quote>['"]?)${escapeRegExp(ruleId)}\k<quote>(?:\s*,\s*|$)`, "u");
 | 
			
		||||
        const match = regex.exec(listText);
 | 
			
		||||
        const matchedText = match[0];
 | 
			
		||||
        const matchStartOffset = listStartOffset + match.index;
 | 
			
		||||
        const matchEndOffset = matchStartOffset + matchedText.length;
 | 
			
		||||
 | 
			
		||||
        const firstIndexOfComma = matchedText.indexOf(",");
 | 
			
		||||
        const lastIndexOfComma = matchedText.lastIndexOf(",");
 | 
			
		||||
 | 
			
		||||
        let removalStartOffset, removalEndOffset;
 | 
			
		||||
 | 
			
		||||
        if (firstIndexOfComma !== lastIndexOfComma) {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Since there are two commas, this must one of the elements in the middle of the list.
 | 
			
		||||
             * Matched range starts where the previous rule name ends, and ends where the next rule name starts.
 | 
			
		||||
             *
 | 
			
		||||
             *     // eslint-disable-line rule-one , rule-two , rule-three -- comment
 | 
			
		||||
             *                                    ^^^^^^^^^^^^^^
 | 
			
		||||
             *
 | 
			
		||||
             * We want to remove only the content between the two commas, and also one of the commas.
 | 
			
		||||
             *
 | 
			
		||||
             *     // eslint-disable-line rule-one , rule-two , rule-three -- comment
 | 
			
		||||
             *                                     ^^^^^^^^^^^
 | 
			
		||||
             */
 | 
			
		||||
            removalStartOffset = matchStartOffset + firstIndexOfComma;
 | 
			
		||||
            removalEndOffset = matchStartOffset + lastIndexOfComma;
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * This is either the first element or the last element.
 | 
			
		||||
             *
 | 
			
		||||
             * If this is the first element, matched range starts where the first rule name starts
 | 
			
		||||
             * and ends where the second rule name starts. This is exactly the range we want
 | 
			
		||||
             * to remove so that the second rule name will start where the first one was starting
 | 
			
		||||
             * and thus preserve the original formatting.
 | 
			
		||||
             *
 | 
			
		||||
             *     // eslint-disable-line rule-one , rule-two , rule-three -- comment
 | 
			
		||||
             *                            ^^^^^^^^^^^
 | 
			
		||||
             *
 | 
			
		||||
             * Similarly, if this is the last element, we've already matched the range we want to
 | 
			
		||||
             * remove. The previous rule name will end where the last one was ending, relative
 | 
			
		||||
             * to the content on the right side.
 | 
			
		||||
             *
 | 
			
		||||
             *     // eslint-disable-line rule-one , rule-two , rule-three -- comment
 | 
			
		||||
             *                                               ^^^^^^^^^^^^^
 | 
			
		||||
             */
 | 
			
		||||
            removalStartOffset = matchStartOffset;
 | 
			
		||||
            removalEndOffset = matchEndOffset;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            description: `'${ruleId}'`,
 | 
			
		||||
            fix: {
 | 
			
		||||
                range: [
 | 
			
		||||
                    commentValueStart + removalStartOffset,
 | 
			
		||||
                    commentValueStart + removalEndOffset
 | 
			
		||||
                ],
 | 
			
		||||
                text: ""
 | 
			
		||||
            },
 | 
			
		||||
            unprocessedDirective: directive.unprocessedDirective
 | 
			
		||||
        };
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a description of deleting an entire unused disable comment.
 | 
			
		||||
 * @param {Directive[]} directives Unused directives to be removed.
 | 
			
		||||
 * @param {Token} commentToken The backing Comment token.
 | 
			
		||||
 * @returns {{ description, fix, unprocessedDirective }} Details for later creation of an output Problem.
 | 
			
		||||
 */
 | 
			
		||||
function createCommentRemoval(directives, commentToken) {
 | 
			
		||||
    const { range } = commentToken;
 | 
			
		||||
    const ruleIds = directives.filter(directive => directive.ruleId).map(directive => `'${directive.ruleId}'`);
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        description: ruleIds.length <= 2
 | 
			
		||||
            ? ruleIds.join(" or ")
 | 
			
		||||
            : `${ruleIds.slice(0, ruleIds.length - 1).join(", ")}, or ${ruleIds[ruleIds.length - 1]}`,
 | 
			
		||||
        fix: {
 | 
			
		||||
            range,
 | 
			
		||||
            text: " "
 | 
			
		||||
        },
 | 
			
		||||
        unprocessedDirective: directives[0].unprocessedDirective
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parses details from directives to create output Problems.
 | 
			
		||||
 * @param {Iterable<Directive>} allDirectives Unused directives to be removed.
 | 
			
		||||
 * @returns {{ description, fix, unprocessedDirective }[]} Details for later creation of output Problems.
 | 
			
		||||
 */
 | 
			
		||||
function processUnusedDirectives(allDirectives) {
 | 
			
		||||
    const directiveGroups = groupByParentComment(allDirectives);
 | 
			
		||||
 | 
			
		||||
    return directiveGroups.flatMap(
 | 
			
		||||
        directives => {
 | 
			
		||||
            const { parentComment } = directives[0].unprocessedDirective;
 | 
			
		||||
            const remainingRuleIds = new Set(parentComment.ruleIds);
 | 
			
		||||
 | 
			
		||||
            for (const directive of directives) {
 | 
			
		||||
                remainingRuleIds.delete(directive.ruleId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return remainingRuleIds.size
 | 
			
		||||
                ? createIndividualDirectivesRemoval(directives, parentComment.commentToken)
 | 
			
		||||
                : [createCommentRemoval(directives, parentComment.commentToken)];
 | 
			
		||||
        }
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Collect eslint-enable comments that are removing suppressions by eslint-disable comments.
 | 
			
		||||
 * @param {Directive[]} directives The directives to check.
 | 
			
		||||
 * @returns {Set<Directive>} The used eslint-enable comments
 | 
			
		||||
 */
 | 
			
		||||
function collectUsedEnableDirectives(directives) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A Map of `eslint-enable` keyed by ruleIds that may be marked as used.
 | 
			
		||||
     * If `eslint-enable` does not have a ruleId, the key will be `null`.
 | 
			
		||||
     * @type {Map<string|null, Directive>}
 | 
			
		||||
     */
 | 
			
		||||
    const enabledRules = new Map();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A Set of `eslint-enable` marked as used.
 | 
			
		||||
     * It is also the return value of `collectUsedEnableDirectives` function.
 | 
			
		||||
     * @type {Set<Directive>}
 | 
			
		||||
     */
 | 
			
		||||
    const usedEnableDirectives = new Set();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Checks the directives backwards to see if the encountered `eslint-enable` is used by the previous `eslint-disable`,
 | 
			
		||||
     * and if so, stores the `eslint-enable` in `usedEnableDirectives`.
 | 
			
		||||
     */
 | 
			
		||||
    for (let index = directives.length - 1; index >= 0; index--) {
 | 
			
		||||
        const directive = directives[index];
 | 
			
		||||
 | 
			
		||||
        if (directive.type === "disable") {
 | 
			
		||||
            if (enabledRules.size === 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (directive.ruleId === null) {
 | 
			
		||||
 | 
			
		||||
                // If encounter `eslint-disable` without ruleId,
 | 
			
		||||
                // mark all `eslint-enable` currently held in enabledRules as used.
 | 
			
		||||
                // e.g.
 | 
			
		||||
                //    /* eslint-disable */ <- current directive
 | 
			
		||||
                //    /* eslint-enable rule-id1 */ <- used
 | 
			
		||||
                //    /* eslint-enable rule-id2 */ <- used
 | 
			
		||||
                //    /* eslint-enable */ <- used
 | 
			
		||||
                for (const enableDirective of enabledRules.values()) {
 | 
			
		||||
                    usedEnableDirectives.add(enableDirective);
 | 
			
		||||
                }
 | 
			
		||||
                enabledRules.clear();
 | 
			
		||||
            } else {
 | 
			
		||||
                const enableDirective = enabledRules.get(directive.ruleId);
 | 
			
		||||
 | 
			
		||||
                if (enableDirective) {
 | 
			
		||||
 | 
			
		||||
                    // If encounter `eslint-disable` with ruleId, and there is an `eslint-enable` with the same ruleId in enabledRules,
 | 
			
		||||
                    // mark `eslint-enable` with ruleId as used.
 | 
			
		||||
                    // e.g.
 | 
			
		||||
                    //    /* eslint-disable rule-id */ <- current directive
 | 
			
		||||
                    //    /* eslint-enable rule-id */ <- used
 | 
			
		||||
                    usedEnableDirectives.add(enableDirective);
 | 
			
		||||
                } else {
 | 
			
		||||
                    const enabledDirectiveWithoutRuleId = enabledRules.get(null);
 | 
			
		||||
 | 
			
		||||
                    if (enabledDirectiveWithoutRuleId) {
 | 
			
		||||
 | 
			
		||||
                        // If encounter `eslint-disable` with ruleId, and there is no `eslint-enable` with the same ruleId in enabledRules,
 | 
			
		||||
                        // mark `eslint-enable` without ruleId as used.
 | 
			
		||||
                        // e.g.
 | 
			
		||||
                        //    /* eslint-disable rule-id */ <- current directive
 | 
			
		||||
                        //    /* eslint-enable */ <- used
 | 
			
		||||
                        usedEnableDirectives.add(enabledDirectiveWithoutRuleId);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else if (directive.type === "enable") {
 | 
			
		||||
            if (directive.ruleId === null) {
 | 
			
		||||
 | 
			
		||||
                // If encounter `eslint-enable` without ruleId, the `eslint-enable` that follows it are unused.
 | 
			
		||||
                // So clear enabledRules.
 | 
			
		||||
                // e.g.
 | 
			
		||||
                //    /* eslint-enable */ <- current directive
 | 
			
		||||
                //    /* eslint-enable rule-id *// <- unused
 | 
			
		||||
                //    /* eslint-enable */ <- unused
 | 
			
		||||
                enabledRules.clear();
 | 
			
		||||
                enabledRules.set(null, directive);
 | 
			
		||||
            } else {
 | 
			
		||||
                enabledRules.set(directive.ruleId, directive);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return usedEnableDirectives;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is the same as the exported function, except that it
 | 
			
		||||
 * doesn't handle disable-line and disable-next-line directives, and it always reports unused
 | 
			
		||||
 * disable directives.
 | 
			
		||||
 * @param {Object} options options for applying directives. This is the same as the options
 | 
			
		||||
 * for the exported function, except that `reportUnusedDisableDirectives` is not supported
 | 
			
		||||
 * (this function always reports unused disable directives).
 | 
			
		||||
 * @returns {{problems: LintMessage[], unusedDirectives: LintMessage[]}} An object with a list
 | 
			
		||||
 * of problems (including suppressed ones) and unused eslint-disable directives
 | 
			
		||||
 */
 | 
			
		||||
function applyDirectives(options) {
 | 
			
		||||
    const problems = [];
 | 
			
		||||
    const usedDisableDirectives = new Set();
 | 
			
		||||
 | 
			
		||||
    for (const problem of options.problems) {
 | 
			
		||||
        let disableDirectivesForProblem = [];
 | 
			
		||||
        let nextDirectiveIndex = 0;
 | 
			
		||||
 | 
			
		||||
        while (
 | 
			
		||||
            nextDirectiveIndex < options.directives.length &&
 | 
			
		||||
            compareLocations(options.directives[nextDirectiveIndex], problem) <= 0
 | 
			
		||||
        ) {
 | 
			
		||||
            const directive = options.directives[nextDirectiveIndex++];
 | 
			
		||||
 | 
			
		||||
            if (directive.ruleId === null || directive.ruleId === problem.ruleId) {
 | 
			
		||||
                switch (directive.type) {
 | 
			
		||||
                    case "disable":
 | 
			
		||||
                        disableDirectivesForProblem.push(directive);
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    case "enable":
 | 
			
		||||
                        disableDirectivesForProblem = [];
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    // no default
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (disableDirectivesForProblem.length > 0) {
 | 
			
		||||
            const suppressions = disableDirectivesForProblem.map(directive => ({
 | 
			
		||||
                kind: "directive",
 | 
			
		||||
                justification: directive.unprocessedDirective.justification
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            if (problem.suppressions) {
 | 
			
		||||
                problem.suppressions = problem.suppressions.concat(suppressions);
 | 
			
		||||
            } else {
 | 
			
		||||
                problem.suppressions = suppressions;
 | 
			
		||||
                usedDisableDirectives.add(disableDirectivesForProblem[disableDirectivesForProblem.length - 1]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        problems.push(problem);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const unusedDisableDirectivesToReport = options.directives
 | 
			
		||||
        .filter(directive => directive.type === "disable" && !usedDisableDirectives.has(directive));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const unusedEnableDirectivesToReport = new Set(
 | 
			
		||||
        options.directives.filter(directive => directive.unprocessedDirective.type === "enable")
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * If directives has the eslint-enable directive,
 | 
			
		||||
     * check whether the eslint-enable comment is used.
 | 
			
		||||
     */
 | 
			
		||||
    if (unusedEnableDirectivesToReport.size > 0) {
 | 
			
		||||
        for (const directive of collectUsedEnableDirectives(options.directives)) {
 | 
			
		||||
            unusedEnableDirectivesToReport.delete(directive);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const processed = processUnusedDirectives(unusedDisableDirectivesToReport)
 | 
			
		||||
        .concat(processUnusedDirectives(unusedEnableDirectivesToReport));
 | 
			
		||||
 | 
			
		||||
    const unusedDirectives = processed
 | 
			
		||||
        .map(({ description, fix, unprocessedDirective }) => {
 | 
			
		||||
            const { parentComment, type, line, column } = unprocessedDirective;
 | 
			
		||||
 | 
			
		||||
            let message;
 | 
			
		||||
 | 
			
		||||
            if (type === "enable") {
 | 
			
		||||
                message = description
 | 
			
		||||
                    ? `Unused eslint-enable directive (no matching eslint-disable directives were found for ${description}).`
 | 
			
		||||
                    : "Unused eslint-enable directive (no matching eslint-disable directives were found).";
 | 
			
		||||
            } else {
 | 
			
		||||
                message = description
 | 
			
		||||
                    ? `Unused eslint-disable directive (no problems were reported from ${description}).`
 | 
			
		||||
                    : "Unused eslint-disable directive (no problems were reported).";
 | 
			
		||||
            }
 | 
			
		||||
            return {
 | 
			
		||||
                ruleId: null,
 | 
			
		||||
                message,
 | 
			
		||||
                line: type === "disable-next-line" ? parentComment.commentToken.loc.start.line : line,
 | 
			
		||||
                column: type === "disable-next-line" ? parentComment.commentToken.loc.start.column + 1 : column,
 | 
			
		||||
                severity: options.reportUnusedDisableDirectives === "warn" ? 1 : 2,
 | 
			
		||||
                nodeType: null,
 | 
			
		||||
                ...options.disableFixes ? {} : { fix }
 | 
			
		||||
            };
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    return { problems, unusedDirectives };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Given a list of directive comments (i.e. metadata about eslint-disable and eslint-enable comments) and a list
 | 
			
		||||
 * of reported problems, adds the suppression information to the problems.
 | 
			
		||||
 * @param {Object} options Information about directives and problems
 | 
			
		||||
 * @param {{
 | 
			
		||||
 *      type: ("disable"|"enable"|"disable-line"|"disable-next-line"),
 | 
			
		||||
 *      ruleId: (string|null),
 | 
			
		||||
 *      line: number,
 | 
			
		||||
 *      column: number,
 | 
			
		||||
 *      justification: string
 | 
			
		||||
 * }} options.directives Directive comments found in the file, with one-based columns.
 | 
			
		||||
 * Two directive comments can only have the same location if they also have the same type (e.g. a single eslint-disable
 | 
			
		||||
 * comment for two different rules is represented as two directives).
 | 
			
		||||
 * @param {{ruleId: (string|null), line: number, column: number}[]} options.problems
 | 
			
		||||
 * A list of problems reported by rules, sorted by increasing location in the file, with one-based columns.
 | 
			
		||||
 * @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives
 | 
			
		||||
 * @param {boolean} options.disableFixes If true, it doesn't make `fix` properties.
 | 
			
		||||
 * @returns {{ruleId: (string|null), line: number, column: number, suppressions?: {kind: string, justification: string}}[]}
 | 
			
		||||
 * An object with a list of reported problems, the suppressed of which contain the suppression information.
 | 
			
		||||
 */
 | 
			
		||||
module.exports = ({ directives, disableFixes, problems, reportUnusedDisableDirectives = "off" }) => {
 | 
			
		||||
    const blockDirectives = directives
 | 
			
		||||
        .filter(directive => directive.type === "disable" || directive.type === "enable")
 | 
			
		||||
        .map(directive => Object.assign({}, directive, { unprocessedDirective: directive }))
 | 
			
		||||
        .sort(compareLocations);
 | 
			
		||||
 | 
			
		||||
    const lineDirectives = directives.flatMap(directive => {
 | 
			
		||||
        switch (directive.type) {
 | 
			
		||||
            case "disable":
 | 
			
		||||
            case "enable":
 | 
			
		||||
                return [];
 | 
			
		||||
 | 
			
		||||
            case "disable-line":
 | 
			
		||||
                return [
 | 
			
		||||
                    { type: "disable", line: directive.line, column: 1, ruleId: directive.ruleId, unprocessedDirective: directive },
 | 
			
		||||
                    { type: "enable", line: directive.line + 1, column: 0, ruleId: directive.ruleId, unprocessedDirective: directive }
 | 
			
		||||
                ];
 | 
			
		||||
 | 
			
		||||
            case "disable-next-line":
 | 
			
		||||
                return [
 | 
			
		||||
                    { type: "disable", line: directive.line + 1, column: 1, ruleId: directive.ruleId, unprocessedDirective: directive },
 | 
			
		||||
                    { type: "enable", line: directive.line + 2, column: 0, ruleId: directive.ruleId, unprocessedDirective: directive }
 | 
			
		||||
                ];
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                throw new TypeError(`Unrecognized directive type '${directive.type}'`);
 | 
			
		||||
        }
 | 
			
		||||
    }).sort(compareLocations);
 | 
			
		||||
 | 
			
		||||
    const blockDirectivesResult = applyDirectives({
 | 
			
		||||
        problems,
 | 
			
		||||
        directives: blockDirectives,
 | 
			
		||||
        disableFixes,
 | 
			
		||||
        reportUnusedDisableDirectives
 | 
			
		||||
    });
 | 
			
		||||
    const lineDirectivesResult = applyDirectives({
 | 
			
		||||
        problems: blockDirectivesResult.problems,
 | 
			
		||||
        directives: lineDirectives,
 | 
			
		||||
        disableFixes,
 | 
			
		||||
        reportUnusedDisableDirectives
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return reportUnusedDisableDirectives !== "off"
 | 
			
		||||
        ? lineDirectivesResult.problems
 | 
			
		||||
            .concat(blockDirectivesResult.unusedDirectives)
 | 
			
		||||
            .concat(lineDirectivesResult.unusedDirectives)
 | 
			
		||||
            .sort(compareLocations)
 | 
			
		||||
        : lineDirectivesResult.problems;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										852
									
								
								node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										852
									
								
								node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,852 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A class of the code path analyzer.
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const assert = require("assert"),
 | 
			
		||||
    { breakableTypePattern } = require("../../shared/ast-utils"),
 | 
			
		||||
    CodePath = require("./code-path"),
 | 
			
		||||
    CodePathSegment = require("./code-path-segment"),
 | 
			
		||||
    IdGenerator = require("./id-generator"),
 | 
			
		||||
    debug = require("./debug-helpers");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given node is a `case` node (not `default` node).
 | 
			
		||||
 * @param {ASTNode} node A `SwitchCase` node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a `case` node (not `default` node).
 | 
			
		||||
 */
 | 
			
		||||
function isCaseNode(node) {
 | 
			
		||||
    return Boolean(node.test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if a given node appears as the value of a PropertyDefinition node.
 | 
			
		||||
 * @param {ASTNode} node THe node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a PropertyDefinition value,
 | 
			
		||||
 *      false if not.
 | 
			
		||||
 */
 | 
			
		||||
function isPropertyDefinitionValue(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return parent && parent.type === "PropertyDefinition" && parent.value === node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given logical operator is taken into account for the code
 | 
			
		||||
 * path analysis.
 | 
			
		||||
 * @param {string} operator The operator found in the LogicalExpression node
 | 
			
		||||
 * @returns {boolean} `true` if the operator is "&&" or "||" or "??"
 | 
			
		||||
 */
 | 
			
		||||
function isHandledLogicalOperator(operator) {
 | 
			
		||||
    return operator === "&&" || operator === "||" || operator === "??";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given assignment operator is a logical assignment operator.
 | 
			
		||||
 * Logical assignments are taken into account for the code path analysis
 | 
			
		||||
 * because of their short-circuiting semantics.
 | 
			
		||||
 * @param {string} operator The operator found in the AssignmentExpression node
 | 
			
		||||
 * @returns {boolean} `true` if the operator is "&&=" or "||=" or "??="
 | 
			
		||||
 */
 | 
			
		||||
function isLogicalAssignmentOperator(operator) {
 | 
			
		||||
    return operator === "&&=" || operator === "||=" || operator === "??=";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the label if the parent node of a given node is a LabeledStatement.
 | 
			
		||||
 * @param {ASTNode} node A node to get.
 | 
			
		||||
 * @returns {string|null} The label or `null`.
 | 
			
		||||
 */
 | 
			
		||||
function getLabel(node) {
 | 
			
		||||
    if (node.parent.type === "LabeledStatement") {
 | 
			
		||||
        return node.parent.label.name;
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given logical expression node goes different path
 | 
			
		||||
 * between the `true` case and the `false` case.
 | 
			
		||||
 * @param {ASTNode} node A node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a test of a choice statement.
 | 
			
		||||
 */
 | 
			
		||||
function isForkingByTrueOrFalse(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    switch (parent.type) {
 | 
			
		||||
        case "ConditionalExpression":
 | 
			
		||||
        case "IfStatement":
 | 
			
		||||
        case "WhileStatement":
 | 
			
		||||
        case "DoWhileStatement":
 | 
			
		||||
        case "ForStatement":
 | 
			
		||||
            return parent.test === node;
 | 
			
		||||
 | 
			
		||||
        case "LogicalExpression":
 | 
			
		||||
            return isHandledLogicalOperator(parent.operator);
 | 
			
		||||
 | 
			
		||||
        case "AssignmentExpression":
 | 
			
		||||
            return isLogicalAssignmentOperator(parent.operator);
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the boolean value of a given literal node.
 | 
			
		||||
 *
 | 
			
		||||
 * This is used to detect infinity loops (e.g. `while (true) {}`).
 | 
			
		||||
 * Statements preceded by an infinity loop are unreachable if the loop didn't
 | 
			
		||||
 * have any `break` statement.
 | 
			
		||||
 * @param {ASTNode} node A node to get.
 | 
			
		||||
 * @returns {boolean|undefined} a boolean value if the node is a Literal node,
 | 
			
		||||
 *   otherwise `undefined`.
 | 
			
		||||
 */
 | 
			
		||||
function getBooleanValueIfSimpleConstant(node) {
 | 
			
		||||
    if (node.type === "Literal") {
 | 
			
		||||
        return Boolean(node.value);
 | 
			
		||||
    }
 | 
			
		||||
    return void 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks that a given identifier node is a reference or not.
 | 
			
		||||
 *
 | 
			
		||||
 * This is used to detect the first throwable node in a `try` block.
 | 
			
		||||
 * @param {ASTNode} node An Identifier node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a reference.
 | 
			
		||||
 */
 | 
			
		||||
function isIdentifierReference(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    switch (parent.type) {
 | 
			
		||||
        case "LabeledStatement":
 | 
			
		||||
        case "BreakStatement":
 | 
			
		||||
        case "ContinueStatement":
 | 
			
		||||
        case "ArrayPattern":
 | 
			
		||||
        case "RestElement":
 | 
			
		||||
        case "ImportSpecifier":
 | 
			
		||||
        case "ImportDefaultSpecifier":
 | 
			
		||||
        case "ImportNamespaceSpecifier":
 | 
			
		||||
        case "CatchClause":
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        case "FunctionDeclaration":
 | 
			
		||||
        case "FunctionExpression":
 | 
			
		||||
        case "ArrowFunctionExpression":
 | 
			
		||||
        case "ClassDeclaration":
 | 
			
		||||
        case "ClassExpression":
 | 
			
		||||
        case "VariableDeclarator":
 | 
			
		||||
            return parent.id !== node;
 | 
			
		||||
 | 
			
		||||
        case "Property":
 | 
			
		||||
        case "PropertyDefinition":
 | 
			
		||||
        case "MethodDefinition":
 | 
			
		||||
            return (
 | 
			
		||||
                parent.key !== node ||
 | 
			
		||||
                parent.computed ||
 | 
			
		||||
                parent.shorthand
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        case "AssignmentPattern":
 | 
			
		||||
            return parent.key !== node;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updates the current segment with the head segment.
 | 
			
		||||
 * This is similar to local branches and tracking branches of git.
 | 
			
		||||
 *
 | 
			
		||||
 * To separate the current and the head is in order to not make useless segments.
 | 
			
		||||
 *
 | 
			
		||||
 * In this process, both "onCodePathSegmentStart" and "onCodePathSegmentEnd"
 | 
			
		||||
 * events are fired.
 | 
			
		||||
 * @param {CodePathAnalyzer} analyzer The instance.
 | 
			
		||||
 * @param {ASTNode} node The current AST node.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function forwardCurrentToHead(analyzer, node) {
 | 
			
		||||
    const codePath = analyzer.codePath;
 | 
			
		||||
    const state = CodePath.getState(codePath);
 | 
			
		||||
    const currentSegments = state.currentSegments;
 | 
			
		||||
    const headSegments = state.headSegments;
 | 
			
		||||
    const end = Math.max(currentSegments.length, headSegments.length);
 | 
			
		||||
    let i, currentSegment, headSegment;
 | 
			
		||||
 | 
			
		||||
    // Fires leaving events.
 | 
			
		||||
    for (i = 0; i < end; ++i) {
 | 
			
		||||
        currentSegment = currentSegments[i];
 | 
			
		||||
        headSegment = headSegments[i];
 | 
			
		||||
 | 
			
		||||
        if (currentSegment !== headSegment && currentSegment) {
 | 
			
		||||
 | 
			
		||||
            const eventName = currentSegment.reachable
 | 
			
		||||
                ? "onCodePathSegmentEnd"
 | 
			
		||||
                : "onUnreachableCodePathSegmentEnd";
 | 
			
		||||
 | 
			
		||||
            debug.dump(`${eventName} ${currentSegment.id}`);
 | 
			
		||||
 | 
			
		||||
            analyzer.emitter.emit(
 | 
			
		||||
                eventName,
 | 
			
		||||
                currentSegment,
 | 
			
		||||
                node
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update state.
 | 
			
		||||
    state.currentSegments = headSegments;
 | 
			
		||||
 | 
			
		||||
    // Fires entering events.
 | 
			
		||||
    for (i = 0; i < end; ++i) {
 | 
			
		||||
        currentSegment = currentSegments[i];
 | 
			
		||||
        headSegment = headSegments[i];
 | 
			
		||||
 | 
			
		||||
        if (currentSegment !== headSegment && headSegment) {
 | 
			
		||||
 | 
			
		||||
            const eventName = headSegment.reachable
 | 
			
		||||
                ? "onCodePathSegmentStart"
 | 
			
		||||
                : "onUnreachableCodePathSegmentStart";
 | 
			
		||||
 | 
			
		||||
            debug.dump(`${eventName} ${headSegment.id}`);
 | 
			
		||||
 | 
			
		||||
            CodePathSegment.markUsed(headSegment);
 | 
			
		||||
            analyzer.emitter.emit(
 | 
			
		||||
                eventName,
 | 
			
		||||
                headSegment,
 | 
			
		||||
                node
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updates the current segment with empty.
 | 
			
		||||
 * This is called at the last of functions or the program.
 | 
			
		||||
 * @param {CodePathAnalyzer} analyzer The instance.
 | 
			
		||||
 * @param {ASTNode} node The current AST node.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function leaveFromCurrentSegment(analyzer, node) {
 | 
			
		||||
    const state = CodePath.getState(analyzer.codePath);
 | 
			
		||||
    const currentSegments = state.currentSegments;
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < currentSegments.length; ++i) {
 | 
			
		||||
        const currentSegment = currentSegments[i];
 | 
			
		||||
        const eventName = currentSegment.reachable
 | 
			
		||||
            ? "onCodePathSegmentEnd"
 | 
			
		||||
            : "onUnreachableCodePathSegmentEnd";
 | 
			
		||||
 | 
			
		||||
        debug.dump(`${eventName} ${currentSegment.id}`);
 | 
			
		||||
 | 
			
		||||
        analyzer.emitter.emit(
 | 
			
		||||
            eventName,
 | 
			
		||||
            currentSegment,
 | 
			
		||||
            node
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state.currentSegments = [];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updates the code path due to the position of a given node in the parent node
 | 
			
		||||
 * thereof.
 | 
			
		||||
 *
 | 
			
		||||
 * For example, if the node is `parent.consequent`, this creates a fork from the
 | 
			
		||||
 * current path.
 | 
			
		||||
 * @param {CodePathAnalyzer} analyzer The instance.
 | 
			
		||||
 * @param {ASTNode} node The current AST node.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function preprocess(analyzer, node) {
 | 
			
		||||
    const codePath = analyzer.codePath;
 | 
			
		||||
    const state = CodePath.getState(codePath);
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    switch (parent.type) {
 | 
			
		||||
 | 
			
		||||
        // The `arguments.length == 0` case is in `postprocess` function.
 | 
			
		||||
        case "CallExpression":
 | 
			
		||||
            if (parent.optional === true && parent.arguments.length >= 1 && parent.arguments[0] === node) {
 | 
			
		||||
                state.makeOptionalRight();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case "MemberExpression":
 | 
			
		||||
            if (parent.optional === true && parent.property === node) {
 | 
			
		||||
                state.makeOptionalRight();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "LogicalExpression":
 | 
			
		||||
            if (
 | 
			
		||||
                parent.right === node &&
 | 
			
		||||
                isHandledLogicalOperator(parent.operator)
 | 
			
		||||
            ) {
 | 
			
		||||
                state.makeLogicalRight();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "AssignmentExpression":
 | 
			
		||||
            if (
 | 
			
		||||
                parent.right === node &&
 | 
			
		||||
                isLogicalAssignmentOperator(parent.operator)
 | 
			
		||||
            ) {
 | 
			
		||||
                state.makeLogicalRight();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "ConditionalExpression":
 | 
			
		||||
        case "IfStatement":
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Fork if this node is at `consequent`/`alternate`.
 | 
			
		||||
             * `popForkContext()` exists at `IfStatement:exit` and
 | 
			
		||||
             * `ConditionalExpression:exit`.
 | 
			
		||||
             */
 | 
			
		||||
            if (parent.consequent === node) {
 | 
			
		||||
                state.makeIfConsequent();
 | 
			
		||||
            } else if (parent.alternate === node) {
 | 
			
		||||
                state.makeIfAlternate();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "SwitchCase":
 | 
			
		||||
            if (parent.consequent[0] === node) {
 | 
			
		||||
                state.makeSwitchCaseBody(false, !parent.test);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "TryStatement":
 | 
			
		||||
            if (parent.handler === node) {
 | 
			
		||||
                state.makeCatchBlock();
 | 
			
		||||
            } else if (parent.finalizer === node) {
 | 
			
		||||
                state.makeFinallyBlock();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "WhileStatement":
 | 
			
		||||
            if (parent.test === node) {
 | 
			
		||||
                state.makeWhileTest(getBooleanValueIfSimpleConstant(node));
 | 
			
		||||
            } else {
 | 
			
		||||
                assert(parent.body === node);
 | 
			
		||||
                state.makeWhileBody();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "DoWhileStatement":
 | 
			
		||||
            if (parent.body === node) {
 | 
			
		||||
                state.makeDoWhileBody();
 | 
			
		||||
            } else {
 | 
			
		||||
                assert(parent.test === node);
 | 
			
		||||
                state.makeDoWhileTest(getBooleanValueIfSimpleConstant(node));
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "ForStatement":
 | 
			
		||||
            if (parent.test === node) {
 | 
			
		||||
                state.makeForTest(getBooleanValueIfSimpleConstant(node));
 | 
			
		||||
            } else if (parent.update === node) {
 | 
			
		||||
                state.makeForUpdate();
 | 
			
		||||
            } else if (parent.body === node) {
 | 
			
		||||
                state.makeForBody();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "ForInStatement":
 | 
			
		||||
        case "ForOfStatement":
 | 
			
		||||
            if (parent.left === node) {
 | 
			
		||||
                state.makeForInOfLeft();
 | 
			
		||||
            } else if (parent.right === node) {
 | 
			
		||||
                state.makeForInOfRight();
 | 
			
		||||
            } else {
 | 
			
		||||
                assert(parent.body === node);
 | 
			
		||||
                state.makeForInOfBody();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "AssignmentPattern":
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Fork if this node is at `right`.
 | 
			
		||||
             * `left` is executed always, so it uses the current path.
 | 
			
		||||
             * `popForkContext()` exists at `AssignmentPattern:exit`.
 | 
			
		||||
             */
 | 
			
		||||
            if (parent.right === node) {
 | 
			
		||||
                state.pushForkContext();
 | 
			
		||||
                state.forkBypassPath();
 | 
			
		||||
                state.forkPath();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updates the code path due to the type of a given node in entering.
 | 
			
		||||
 * @param {CodePathAnalyzer} analyzer The instance.
 | 
			
		||||
 * @param {ASTNode} node The current AST node.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function processCodePathToEnter(analyzer, node) {
 | 
			
		||||
    let codePath = analyzer.codePath;
 | 
			
		||||
    let state = codePath && CodePath.getState(codePath);
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new code path and trigger the onCodePathStart event
 | 
			
		||||
     * based on the currently selected node.
 | 
			
		||||
     * @param {string} origin The reason the code path was started.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    function startCodePath(origin) {
 | 
			
		||||
        if (codePath) {
 | 
			
		||||
 | 
			
		||||
            // Emits onCodePathSegmentStart events if updated.
 | 
			
		||||
            forwardCurrentToHead(analyzer, node);
 | 
			
		||||
            debug.dumpState(node, state, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create the code path of this scope.
 | 
			
		||||
        codePath = analyzer.codePath = new CodePath({
 | 
			
		||||
            id: analyzer.idGenerator.next(),
 | 
			
		||||
            origin,
 | 
			
		||||
            upper: codePath,
 | 
			
		||||
            onLooped: analyzer.onLooped
 | 
			
		||||
        });
 | 
			
		||||
        state = CodePath.getState(codePath);
 | 
			
		||||
 | 
			
		||||
        // Emits onCodePathStart events.
 | 
			
		||||
        debug.dump(`onCodePathStart ${codePath.id}`);
 | 
			
		||||
        analyzer.emitter.emit("onCodePathStart", codePath, node);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Special case: The right side of class field initializer is considered
 | 
			
		||||
     * to be its own function, so we need to start a new code path in this
 | 
			
		||||
     * case.
 | 
			
		||||
     */
 | 
			
		||||
    if (isPropertyDefinitionValue(node)) {
 | 
			
		||||
        startCodePath("class-field-initializer");
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Intentional fall through because `node` needs to also be
 | 
			
		||||
         * processed by the code below. For example, if we have:
 | 
			
		||||
         *
 | 
			
		||||
         * class Foo {
 | 
			
		||||
         *     a = () => {}
 | 
			
		||||
         * }
 | 
			
		||||
         *
 | 
			
		||||
         * In this case, we also need start a second code path.
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (node.type) {
 | 
			
		||||
        case "Program":
 | 
			
		||||
            startCodePath("program");
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "FunctionDeclaration":
 | 
			
		||||
        case "FunctionExpression":
 | 
			
		||||
        case "ArrowFunctionExpression":
 | 
			
		||||
            startCodePath("function");
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "StaticBlock":
 | 
			
		||||
            startCodePath("class-static-block");
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "ChainExpression":
 | 
			
		||||
            state.pushChainContext();
 | 
			
		||||
            break;
 | 
			
		||||
        case "CallExpression":
 | 
			
		||||
            if (node.optional === true) {
 | 
			
		||||
                state.makeOptionalNode();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case "MemberExpression":
 | 
			
		||||
            if (node.optional === true) {
 | 
			
		||||
                state.makeOptionalNode();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "LogicalExpression":
 | 
			
		||||
            if (isHandledLogicalOperator(node.operator)) {
 | 
			
		||||
                state.pushChoiceContext(
 | 
			
		||||
                    node.operator,
 | 
			
		||||
                    isForkingByTrueOrFalse(node)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "AssignmentExpression":
 | 
			
		||||
            if (isLogicalAssignmentOperator(node.operator)) {
 | 
			
		||||
                state.pushChoiceContext(
 | 
			
		||||
                    node.operator.slice(0, -1), // removes `=` from the end
 | 
			
		||||
                    isForkingByTrueOrFalse(node)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "ConditionalExpression":
 | 
			
		||||
        case "IfStatement":
 | 
			
		||||
            state.pushChoiceContext("test", false);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "SwitchStatement":
 | 
			
		||||
            state.pushSwitchContext(
 | 
			
		||||
                node.cases.some(isCaseNode),
 | 
			
		||||
                getLabel(node)
 | 
			
		||||
            );
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "TryStatement":
 | 
			
		||||
            state.pushTryContext(Boolean(node.finalizer));
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "SwitchCase":
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Fork if this node is after the 2st node in `cases`.
 | 
			
		||||
             * It's similar to `else` blocks.
 | 
			
		||||
             * The next `test` node is processed in this path.
 | 
			
		||||
             */
 | 
			
		||||
            if (parent.discriminant !== node && parent.cases[0] !== node) {
 | 
			
		||||
                state.forkPath();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "WhileStatement":
 | 
			
		||||
        case "DoWhileStatement":
 | 
			
		||||
        case "ForStatement":
 | 
			
		||||
        case "ForInStatement":
 | 
			
		||||
        case "ForOfStatement":
 | 
			
		||||
            state.pushLoopContext(node.type, getLabel(node));
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "LabeledStatement":
 | 
			
		||||
            if (!breakableTypePattern.test(node.body.type)) {
 | 
			
		||||
                state.pushBreakContext(false, node.label.name);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Emits onCodePathSegmentStart events if updated.
 | 
			
		||||
    forwardCurrentToHead(analyzer, node);
 | 
			
		||||
    debug.dumpState(node, state, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updates the code path due to the type of a given node in leaving.
 | 
			
		||||
 * @param {CodePathAnalyzer} analyzer The instance.
 | 
			
		||||
 * @param {ASTNode} node The current AST node.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function processCodePathToExit(analyzer, node) {
 | 
			
		||||
 | 
			
		||||
    const codePath = analyzer.codePath;
 | 
			
		||||
    const state = CodePath.getState(codePath);
 | 
			
		||||
    let dontForward = false;
 | 
			
		||||
 | 
			
		||||
    switch (node.type) {
 | 
			
		||||
        case "ChainExpression":
 | 
			
		||||
            state.popChainContext();
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "IfStatement":
 | 
			
		||||
        case "ConditionalExpression":
 | 
			
		||||
            state.popChoiceContext();
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "LogicalExpression":
 | 
			
		||||
            if (isHandledLogicalOperator(node.operator)) {
 | 
			
		||||
                state.popChoiceContext();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "AssignmentExpression":
 | 
			
		||||
            if (isLogicalAssignmentOperator(node.operator)) {
 | 
			
		||||
                state.popChoiceContext();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "SwitchStatement":
 | 
			
		||||
            state.popSwitchContext();
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "SwitchCase":
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * This is the same as the process at the 1st `consequent` node in
 | 
			
		||||
             * `preprocess` function.
 | 
			
		||||
             * Must do if this `consequent` is empty.
 | 
			
		||||
             */
 | 
			
		||||
            if (node.consequent.length === 0) {
 | 
			
		||||
                state.makeSwitchCaseBody(true, !node.test);
 | 
			
		||||
            }
 | 
			
		||||
            if (state.forkContext.reachable) {
 | 
			
		||||
                dontForward = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "TryStatement":
 | 
			
		||||
            state.popTryContext();
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "BreakStatement":
 | 
			
		||||
            forwardCurrentToHead(analyzer, node);
 | 
			
		||||
            state.makeBreak(node.label && node.label.name);
 | 
			
		||||
            dontForward = true;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "ContinueStatement":
 | 
			
		||||
            forwardCurrentToHead(analyzer, node);
 | 
			
		||||
            state.makeContinue(node.label && node.label.name);
 | 
			
		||||
            dontForward = true;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "ReturnStatement":
 | 
			
		||||
            forwardCurrentToHead(analyzer, node);
 | 
			
		||||
            state.makeReturn();
 | 
			
		||||
            dontForward = true;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "ThrowStatement":
 | 
			
		||||
            forwardCurrentToHead(analyzer, node);
 | 
			
		||||
            state.makeThrow();
 | 
			
		||||
            dontForward = true;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "Identifier":
 | 
			
		||||
            if (isIdentifierReference(node)) {
 | 
			
		||||
                state.makeFirstThrowablePathInTryBlock();
 | 
			
		||||
                dontForward = true;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "CallExpression":
 | 
			
		||||
        case "ImportExpression":
 | 
			
		||||
        case "MemberExpression":
 | 
			
		||||
        case "NewExpression":
 | 
			
		||||
        case "YieldExpression":
 | 
			
		||||
            state.makeFirstThrowablePathInTryBlock();
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "WhileStatement":
 | 
			
		||||
        case "DoWhileStatement":
 | 
			
		||||
        case "ForStatement":
 | 
			
		||||
        case "ForInStatement":
 | 
			
		||||
        case "ForOfStatement":
 | 
			
		||||
            state.popLoopContext();
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "AssignmentPattern":
 | 
			
		||||
            state.popForkContext();
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case "LabeledStatement":
 | 
			
		||||
            if (!breakableTypePattern.test(node.body.type)) {
 | 
			
		||||
                state.popBreakContext();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Emits onCodePathSegmentStart events if updated.
 | 
			
		||||
    if (!dontForward) {
 | 
			
		||||
        forwardCurrentToHead(analyzer, node);
 | 
			
		||||
    }
 | 
			
		||||
    debug.dumpState(node, state, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updates the code path to finalize the current code path.
 | 
			
		||||
 * @param {CodePathAnalyzer} analyzer The instance.
 | 
			
		||||
 * @param {ASTNode} node The current AST node.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function postprocess(analyzer, node) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Ends the code path for the current node.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    function endCodePath() {
 | 
			
		||||
        let codePath = analyzer.codePath;
 | 
			
		||||
 | 
			
		||||
        // Mark the current path as the final node.
 | 
			
		||||
        CodePath.getState(codePath).makeFinal();
 | 
			
		||||
 | 
			
		||||
        // Emits onCodePathSegmentEnd event of the current segments.
 | 
			
		||||
        leaveFromCurrentSegment(analyzer, node);
 | 
			
		||||
 | 
			
		||||
        // Emits onCodePathEnd event of this code path.
 | 
			
		||||
        debug.dump(`onCodePathEnd ${codePath.id}`);
 | 
			
		||||
        analyzer.emitter.emit("onCodePathEnd", codePath, node);
 | 
			
		||||
        debug.dumpDot(codePath);
 | 
			
		||||
 | 
			
		||||
        codePath = analyzer.codePath = analyzer.codePath.upper;
 | 
			
		||||
        if (codePath) {
 | 
			
		||||
            debug.dumpState(node, CodePath.getState(codePath), true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (node.type) {
 | 
			
		||||
        case "Program":
 | 
			
		||||
        case "FunctionDeclaration":
 | 
			
		||||
        case "FunctionExpression":
 | 
			
		||||
        case "ArrowFunctionExpression":
 | 
			
		||||
        case "StaticBlock": {
 | 
			
		||||
            endCodePath();
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // The `arguments.length >= 1` case is in `preprocess` function.
 | 
			
		||||
        case "CallExpression":
 | 
			
		||||
            if (node.optional === true && node.arguments.length === 0) {
 | 
			
		||||
                CodePath.getState(analyzer.codePath).makeOptionalRight();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Special case: The right side of class field initializer is considered
 | 
			
		||||
     * to be its own function, so we need to end a code path in this
 | 
			
		||||
     * case.
 | 
			
		||||
     *
 | 
			
		||||
     * We need to check after the other checks in order to close the
 | 
			
		||||
     * code paths in the correct order for code like this:
 | 
			
		||||
     *
 | 
			
		||||
     *
 | 
			
		||||
     * class Foo {
 | 
			
		||||
     *     a = () => {}
 | 
			
		||||
     * }
 | 
			
		||||
     *
 | 
			
		||||
     * In this case, The ArrowFunctionExpression code path is closed first
 | 
			
		||||
     * and then we need to close the code path for the PropertyDefinition
 | 
			
		||||
     * value.
 | 
			
		||||
     */
 | 
			
		||||
    if (isPropertyDefinitionValue(node)) {
 | 
			
		||||
        endCodePath();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The class to analyze code paths.
 | 
			
		||||
 * This class implements the EventGenerator interface.
 | 
			
		||||
 */
 | 
			
		||||
class CodePathAnalyzer {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {EventGenerator} eventGenerator An event generator to wrap.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(eventGenerator) {
 | 
			
		||||
        this.original = eventGenerator;
 | 
			
		||||
        this.emitter = eventGenerator.emitter;
 | 
			
		||||
        this.codePath = null;
 | 
			
		||||
        this.idGenerator = new IdGenerator("s");
 | 
			
		||||
        this.currentNode = null;
 | 
			
		||||
        this.onLooped = this.onLooped.bind(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Does the process to enter a given AST node.
 | 
			
		||||
     * This updates state of analysis and calls `enterNode` of the wrapped.
 | 
			
		||||
     * @param {ASTNode} node A node which is entering.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    enterNode(node) {
 | 
			
		||||
        this.currentNode = node;
 | 
			
		||||
 | 
			
		||||
        // Updates the code path due to node's position in its parent node.
 | 
			
		||||
        if (node.parent) {
 | 
			
		||||
            preprocess(this, node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Updates the code path.
 | 
			
		||||
         * And emits onCodePathStart/onCodePathSegmentStart events.
 | 
			
		||||
         */
 | 
			
		||||
        processCodePathToEnter(this, node);
 | 
			
		||||
 | 
			
		||||
        // Emits node events.
 | 
			
		||||
        this.original.enterNode(node);
 | 
			
		||||
 | 
			
		||||
        this.currentNode = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Does the process to leave a given AST node.
 | 
			
		||||
     * This updates state of analysis and calls `leaveNode` of the wrapped.
 | 
			
		||||
     * @param {ASTNode} node A node which is leaving.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    leaveNode(node) {
 | 
			
		||||
        this.currentNode = node;
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Updates the code path.
 | 
			
		||||
         * And emits onCodePathStart/onCodePathSegmentStart events.
 | 
			
		||||
         */
 | 
			
		||||
        processCodePathToExit(this, node);
 | 
			
		||||
 | 
			
		||||
        // Emits node events.
 | 
			
		||||
        this.original.leaveNode(node);
 | 
			
		||||
 | 
			
		||||
        // Emits the last onCodePathStart/onCodePathSegmentStart events.
 | 
			
		||||
        postprocess(this, node);
 | 
			
		||||
 | 
			
		||||
        this.currentNode = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is called on a code path looped.
 | 
			
		||||
     * Then this raises a looped event.
 | 
			
		||||
     * @param {CodePathSegment} fromSegment A segment of prev.
 | 
			
		||||
     * @param {CodePathSegment} toSegment A segment of next.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    onLooped(fromSegment, toSegment) {
 | 
			
		||||
        if (fromSegment.reachable && toSegment.reachable) {
 | 
			
		||||
            debug.dump(`onCodePathSegmentLoop ${fromSegment.id} -> ${toSegment.id}`);
 | 
			
		||||
            this.emitter.emit(
 | 
			
		||||
                "onCodePathSegmentLoop",
 | 
			
		||||
                fromSegment,
 | 
			
		||||
                toSegment,
 | 
			
		||||
                this.currentNode
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = CodePathAnalyzer;
 | 
			
		||||
							
								
								
									
										263
									
								
								node_modules/eslint/lib/linter/code-path-analysis/code-path-segment.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								node_modules/eslint/lib/linter/code-path-analysis/code-path-segment.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,263 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview The CodePathSegment class.
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const debug = require("./debug-helpers");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given segment is reachable.
 | 
			
		||||
 * @param {CodePathSegment} segment A segment to check.
 | 
			
		||||
 * @returns {boolean} `true` if the segment is reachable.
 | 
			
		||||
 */
 | 
			
		||||
function isReachable(segment) {
 | 
			
		||||
    return segment.reachable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A code path segment.
 | 
			
		||||
 *
 | 
			
		||||
 * Each segment is arranged in a series of linked lists (implemented by arrays)
 | 
			
		||||
 * that keep track of the previous and next segments in a code path. In this way,
 | 
			
		||||
 * you can navigate between all segments in any code path so long as you have a
 | 
			
		||||
 * reference to any segment in that code path.
 | 
			
		||||
 *
 | 
			
		||||
 * When first created, the segment is in a detached state, meaning that it knows the
 | 
			
		||||
 * segments that came before it but those segments don't know that this new segment
 | 
			
		||||
 * follows it. Only when `CodePathSegment#markUsed()` is called on a segment does it
 | 
			
		||||
 * officially become part of the code path by updating the previous segments to know
 | 
			
		||||
 * that this new segment follows.
 | 
			
		||||
 */
 | 
			
		||||
class CodePathSegment {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new instance.
 | 
			
		||||
     * @param {string} id An identifier.
 | 
			
		||||
     * @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
 | 
			
		||||
     *   This array includes unreachable segments.
 | 
			
		||||
     * @param {boolean} reachable A flag which shows this is reachable.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(id, allPrevSegments, reachable) {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The identifier of this code path.
 | 
			
		||||
         * Rules use it to store additional information of each rule.
 | 
			
		||||
         * @type {string}
 | 
			
		||||
         */
 | 
			
		||||
        this.id = id;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An array of the next reachable segments.
 | 
			
		||||
         * @type {CodePathSegment[]}
 | 
			
		||||
         */
 | 
			
		||||
        this.nextSegments = [];
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An array of the previous reachable segments.
 | 
			
		||||
         * @type {CodePathSegment[]}
 | 
			
		||||
         */
 | 
			
		||||
        this.prevSegments = allPrevSegments.filter(isReachable);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An array of all next segments including reachable and unreachable.
 | 
			
		||||
         * @type {CodePathSegment[]}
 | 
			
		||||
         */
 | 
			
		||||
        this.allNextSegments = [];
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An array of all previous segments including reachable and unreachable.
 | 
			
		||||
         * @type {CodePathSegment[]}
 | 
			
		||||
         */
 | 
			
		||||
        this.allPrevSegments = allPrevSegments;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * A flag which shows this is reachable.
 | 
			
		||||
         * @type {boolean}
 | 
			
		||||
         */
 | 
			
		||||
        this.reachable = reachable;
 | 
			
		||||
 | 
			
		||||
        // Internal data.
 | 
			
		||||
        Object.defineProperty(this, "internal", {
 | 
			
		||||
            value: {
 | 
			
		||||
 | 
			
		||||
                // determines if the segment has been attached to the code path
 | 
			
		||||
                used: false,
 | 
			
		||||
 | 
			
		||||
                // array of previous segments coming from the end of a loop
 | 
			
		||||
                loopedPrevSegments: []
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        /* c8 ignore start */
 | 
			
		||||
        if (debug.enabled) {
 | 
			
		||||
            this.internal.nodes = [];
 | 
			
		||||
        }/* c8 ignore stop */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks a given previous segment is coming from the end of a loop.
 | 
			
		||||
     * @param {CodePathSegment} segment A previous segment to check.
 | 
			
		||||
     * @returns {boolean} `true` if the segment is coming from the end of a loop.
 | 
			
		||||
     */
 | 
			
		||||
    isLoopedPrevSegment(segment) {
 | 
			
		||||
        return this.internal.loopedPrevSegments.includes(segment);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates the root segment.
 | 
			
		||||
     * @param {string} id An identifier.
 | 
			
		||||
     * @returns {CodePathSegment} The created segment.
 | 
			
		||||
     */
 | 
			
		||||
    static newRoot(id) {
 | 
			
		||||
        return new CodePathSegment(id, [], true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new segment and appends it after the given segments.
 | 
			
		||||
     * @param {string} id An identifier.
 | 
			
		||||
     * @param {CodePathSegment[]} allPrevSegments An array of the previous segments
 | 
			
		||||
     *      to append to.
 | 
			
		||||
     * @returns {CodePathSegment} The created segment.
 | 
			
		||||
     */
 | 
			
		||||
    static newNext(id, allPrevSegments) {
 | 
			
		||||
        return new CodePathSegment(
 | 
			
		||||
            id,
 | 
			
		||||
            CodePathSegment.flattenUnusedSegments(allPrevSegments),
 | 
			
		||||
            allPrevSegments.some(isReachable)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an unreachable segment and appends it after the given segments.
 | 
			
		||||
     * @param {string} id An identifier.
 | 
			
		||||
     * @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
 | 
			
		||||
     * @returns {CodePathSegment} The created segment.
 | 
			
		||||
     */
 | 
			
		||||
    static newUnreachable(id, allPrevSegments) {
 | 
			
		||||
        const segment = new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), false);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * In `if (a) return a; foo();` case, the unreachable segment preceded by
 | 
			
		||||
         * the return statement is not used but must not be removed.
 | 
			
		||||
         */
 | 
			
		||||
        CodePathSegment.markUsed(segment);
 | 
			
		||||
 | 
			
		||||
        return segment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a segment that follows given segments.
 | 
			
		||||
     * This factory method does not connect with `allPrevSegments`.
 | 
			
		||||
     * But this inherits `reachable` flag.
 | 
			
		||||
     * @param {string} id An identifier.
 | 
			
		||||
     * @param {CodePathSegment[]} allPrevSegments An array of the previous segments.
 | 
			
		||||
     * @returns {CodePathSegment} The created segment.
 | 
			
		||||
     */
 | 
			
		||||
    static newDisconnected(id, allPrevSegments) {
 | 
			
		||||
        return new CodePathSegment(id, [], allPrevSegments.some(isReachable));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Marks a given segment as used.
 | 
			
		||||
     *
 | 
			
		||||
     * And this function registers the segment into the previous segments as a next.
 | 
			
		||||
     * @param {CodePathSegment} segment A segment to mark.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    static markUsed(segment) {
 | 
			
		||||
        if (segment.internal.used) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        segment.internal.used = true;
 | 
			
		||||
 | 
			
		||||
        let i;
 | 
			
		||||
 | 
			
		||||
        if (segment.reachable) {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * If the segment is reachable, then it's officially part of the
 | 
			
		||||
             * code path. This loops through all previous segments to update
 | 
			
		||||
             * their list of next segments. Because the segment is reachable,
 | 
			
		||||
             * it's added to both `nextSegments` and `allNextSegments`.
 | 
			
		||||
             */
 | 
			
		||||
            for (i = 0; i < segment.allPrevSegments.length; ++i) {
 | 
			
		||||
                const prevSegment = segment.allPrevSegments[i];
 | 
			
		||||
 | 
			
		||||
                prevSegment.allNextSegments.push(segment);
 | 
			
		||||
                prevSegment.nextSegments.push(segment);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * If the segment is not reachable, then it's not officially part of the
 | 
			
		||||
             * code path. This loops through all previous segments to update
 | 
			
		||||
             * their list of next segments. Because the segment is not reachable,
 | 
			
		||||
             * it's added only to `allNextSegments`.
 | 
			
		||||
             */
 | 
			
		||||
            for (i = 0; i < segment.allPrevSegments.length; ++i) {
 | 
			
		||||
                segment.allPrevSegments[i].allNextSegments.push(segment);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Marks a previous segment as looped.
 | 
			
		||||
     * @param {CodePathSegment} segment A segment.
 | 
			
		||||
     * @param {CodePathSegment} prevSegment A previous segment to mark.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    static markPrevSegmentAsLooped(segment, prevSegment) {
 | 
			
		||||
        segment.internal.loopedPrevSegments.push(prevSegment);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new array based on an array of segments. If any segment in the
 | 
			
		||||
     * array is unused, then it is replaced by all of its previous segments.
 | 
			
		||||
     * All used segments are returned as-is without replacement.
 | 
			
		||||
     * @param {CodePathSegment[]} segments The array of segments to flatten.
 | 
			
		||||
     * @returns {CodePathSegment[]} The flattened array.
 | 
			
		||||
     */
 | 
			
		||||
    static flattenUnusedSegments(segments) {
 | 
			
		||||
        const done = new Set();
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < segments.length; ++i) {
 | 
			
		||||
            const segment = segments[i];
 | 
			
		||||
 | 
			
		||||
            // Ignores duplicated.
 | 
			
		||||
            if (done.has(segment)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Use previous segments if unused.
 | 
			
		||||
            if (!segment.internal.used) {
 | 
			
		||||
                for (let j = 0; j < segment.allPrevSegments.length; ++j) {
 | 
			
		||||
                    const prevSegment = segment.allPrevSegments[j];
 | 
			
		||||
 | 
			
		||||
                    if (!done.has(prevSegment)) {
 | 
			
		||||
                        done.add(prevSegment);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                done.add(segment);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [...done];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = CodePathSegment;
 | 
			
		||||
							
								
								
									
										2348
									
								
								node_modules/eslint/lib/linter/code-path-analysis/code-path-state.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2348
									
								
								node_modules/eslint/lib/linter/code-path-analysis/code-path-state.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										342
									
								
								node_modules/eslint/lib/linter/code-path-analysis/code-path.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								node_modules/eslint/lib/linter/code-path-analysis/code-path.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,342 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A class of the code path.
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const CodePathState = require("./code-path-state");
 | 
			
		||||
const IdGenerator = require("./id-generator");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A code path.
 | 
			
		||||
 */
 | 
			
		||||
class CodePath {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new instance.
 | 
			
		||||
     * @param {Object} options Options for the function (see below).
 | 
			
		||||
     * @param {string} options.id An identifier.
 | 
			
		||||
     * @param {string} options.origin The type of code path origin.
 | 
			
		||||
     * @param {CodePath|null} options.upper The code path of the upper function scope.
 | 
			
		||||
     * @param {Function} options.onLooped A callback function to notify looping.
 | 
			
		||||
     */
 | 
			
		||||
    constructor({ id, origin, upper, onLooped }) {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The identifier of this code path.
 | 
			
		||||
         * Rules use it to store additional information of each rule.
 | 
			
		||||
         * @type {string}
 | 
			
		||||
         */
 | 
			
		||||
        this.id = id;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The reason that this code path was started. May be "program",
 | 
			
		||||
         * "function", "class-field-initializer", or "class-static-block".
 | 
			
		||||
         * @type {string}
 | 
			
		||||
         */
 | 
			
		||||
        this.origin = origin;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The code path of the upper function scope.
 | 
			
		||||
         * @type {CodePath|null}
 | 
			
		||||
         */
 | 
			
		||||
        this.upper = upper;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The code paths of nested function scopes.
 | 
			
		||||
         * @type {CodePath[]}
 | 
			
		||||
         */
 | 
			
		||||
        this.childCodePaths = [];
 | 
			
		||||
 | 
			
		||||
        // Initializes internal state.
 | 
			
		||||
        Object.defineProperty(
 | 
			
		||||
            this,
 | 
			
		||||
            "internal",
 | 
			
		||||
            { value: new CodePathState(new IdGenerator(`${id}_`), onLooped) }
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // Adds this into `childCodePaths` of `upper`.
 | 
			
		||||
        if (upper) {
 | 
			
		||||
            upper.childCodePaths.push(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the state of a given code path.
 | 
			
		||||
     * @param {CodePath} codePath A code path to get.
 | 
			
		||||
     * @returns {CodePathState} The state of the code path.
 | 
			
		||||
     */
 | 
			
		||||
    static getState(codePath) {
 | 
			
		||||
        return codePath.internal;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The initial code path segment. This is the segment that is at the head
 | 
			
		||||
     * of the code path.
 | 
			
		||||
     * This is a passthrough to the underlying `CodePathState`.
 | 
			
		||||
     * @type {CodePathSegment}
 | 
			
		||||
     */
 | 
			
		||||
    get initialSegment() {
 | 
			
		||||
        return this.internal.initialSegment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Final code path segments. These are the terminal (tail) segments in the
 | 
			
		||||
     * code path, which is the combination of `returnedSegments` and `thrownSegments`.
 | 
			
		||||
     * All segments in this array are reachable.
 | 
			
		||||
     * This is a passthrough to the underlying `CodePathState`.
 | 
			
		||||
     * @type {CodePathSegment[]}
 | 
			
		||||
     */
 | 
			
		||||
    get finalSegments() {
 | 
			
		||||
        return this.internal.finalSegments;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Final code path segments that represent normal completion of the code path.
 | 
			
		||||
     * For functions, this means both explicit `return` statements and implicit returns,
 | 
			
		||||
     * such as the last reachable segment in a function that does not have an
 | 
			
		||||
     * explicit `return` as this implicitly returns `undefined`. For scripts,
 | 
			
		||||
     * modules, class field initializers, and class static blocks, this means
 | 
			
		||||
     * all lines of code have been executed.
 | 
			
		||||
     * These segments are also present in `finalSegments`.
 | 
			
		||||
     * This is a passthrough to the underlying `CodePathState`.
 | 
			
		||||
     * @type {CodePathSegment[]}
 | 
			
		||||
     */
 | 
			
		||||
    get returnedSegments() {
 | 
			
		||||
        return this.internal.returnedForkContext;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Final code path segments that represent `throw` statements.
 | 
			
		||||
     * This is a passthrough to the underlying `CodePathState`.
 | 
			
		||||
     * These segments are also present in `finalSegments`.
 | 
			
		||||
     * @type {CodePathSegment[]}
 | 
			
		||||
     */
 | 
			
		||||
    get thrownSegments() {
 | 
			
		||||
        return this.internal.thrownForkContext;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Tracks the traversal of the code path through each segment. This array
 | 
			
		||||
     * starts empty and segments are added or removed as the code path is
 | 
			
		||||
     * traversed. This array always ends up empty at the end of a code path
 | 
			
		||||
     * traversal. The `CodePathState` uses this to track its progress through
 | 
			
		||||
     * the code path.
 | 
			
		||||
     * This is a passthrough to the underlying `CodePathState`.
 | 
			
		||||
     * @type {CodePathSegment[]}
 | 
			
		||||
     * @deprecated
 | 
			
		||||
     */
 | 
			
		||||
    get currentSegments() {
 | 
			
		||||
        return this.internal.currentSegments;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Traverses all segments in this code path.
 | 
			
		||||
     *
 | 
			
		||||
     *     codePath.traverseSegments((segment, controller) => {
 | 
			
		||||
     *         // do something.
 | 
			
		||||
     *     });
 | 
			
		||||
     *
 | 
			
		||||
     * This method enumerates segments in order from the head.
 | 
			
		||||
     *
 | 
			
		||||
     * The `controller` argument has two methods:
 | 
			
		||||
     *
 | 
			
		||||
     * - `skip()` - skips the following segments in this branch
 | 
			
		||||
     * - `break()` - skips all following segments in the traversal
 | 
			
		||||
     *
 | 
			
		||||
     * A note on the parameters: the `options` argument is optional. This means
 | 
			
		||||
     * the first argument might be an options object or the callback function.
 | 
			
		||||
     * @param {Object} [optionsOrCallback] Optional first and last segments to traverse.
 | 
			
		||||
     * @param {CodePathSegment} [optionsOrCallback.first] The first segment to traverse.
 | 
			
		||||
     * @param {CodePathSegment} [optionsOrCallback.last] The last segment to traverse.
 | 
			
		||||
     * @param {Function} callback A callback function.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    traverseSegments(optionsOrCallback, callback) {
 | 
			
		||||
 | 
			
		||||
        // normalize the arguments into a callback and options
 | 
			
		||||
        let resolvedOptions;
 | 
			
		||||
        let resolvedCallback;
 | 
			
		||||
 | 
			
		||||
        if (typeof optionsOrCallback === "function") {
 | 
			
		||||
            resolvedCallback = optionsOrCallback;
 | 
			
		||||
            resolvedOptions = {};
 | 
			
		||||
        } else {
 | 
			
		||||
            resolvedOptions = optionsOrCallback || {};
 | 
			
		||||
            resolvedCallback = callback;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // determine where to start traversing from based on the options
 | 
			
		||||
        const startSegment = resolvedOptions.first || this.internal.initialSegment;
 | 
			
		||||
        const lastSegment = resolvedOptions.last;
 | 
			
		||||
 | 
			
		||||
        // set up initial location information
 | 
			
		||||
        let record = null;
 | 
			
		||||
        let index = 0;
 | 
			
		||||
        let end = 0;
 | 
			
		||||
        let segment = null;
 | 
			
		||||
 | 
			
		||||
        // segments that have already been visited during traversal
 | 
			
		||||
        const visited = new Set();
 | 
			
		||||
 | 
			
		||||
        // tracks the traversal steps
 | 
			
		||||
        const stack = [[startSegment, 0]];
 | 
			
		||||
 | 
			
		||||
        // tracks the last skipped segment during traversal
 | 
			
		||||
        let skippedSegment = null;
 | 
			
		||||
 | 
			
		||||
        // indicates if we exited early from the traversal
 | 
			
		||||
        let broken = false;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Maintains traversal state.
 | 
			
		||||
         */
 | 
			
		||||
        const controller = {
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Skip the following segments in this branch.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            skip() {
 | 
			
		||||
                if (stack.length <= 1) {
 | 
			
		||||
                    broken = true;
 | 
			
		||||
                } else {
 | 
			
		||||
                    skippedSegment = stack[stack.length - 2][0];
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Stop traversal completely - do not traverse to any
 | 
			
		||||
             * other segments.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            break() {
 | 
			
		||||
                broken = true;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if a given previous segment has been visited.
 | 
			
		||||
         * @param {CodePathSegment} prevSegment A previous segment to check.
 | 
			
		||||
         * @returns {boolean} `true` if the segment has been visited.
 | 
			
		||||
         */
 | 
			
		||||
        function isVisited(prevSegment) {
 | 
			
		||||
            return (
 | 
			
		||||
                visited.has(prevSegment) ||
 | 
			
		||||
                segment.isLoopedPrevSegment(prevSegment)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // the traversal
 | 
			
		||||
        while (stack.length > 0) {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * This isn't a pure stack. We use the top record all the time
 | 
			
		||||
             * but don't always pop it off. The record is popped only if
 | 
			
		||||
             * one of the following is true:
 | 
			
		||||
             *
 | 
			
		||||
             * 1) We have already visited the segment.
 | 
			
		||||
             * 2) We have not visited *all* of the previous segments.
 | 
			
		||||
             * 3) We have traversed past the available next segments.
 | 
			
		||||
             *
 | 
			
		||||
             * Otherwise, we just read the value and sometimes modify the
 | 
			
		||||
             * record as we traverse.
 | 
			
		||||
             */
 | 
			
		||||
            record = stack[stack.length - 1];
 | 
			
		||||
            segment = record[0];
 | 
			
		||||
            index = record[1];
 | 
			
		||||
 | 
			
		||||
            if (index === 0) {
 | 
			
		||||
 | 
			
		||||
                // Skip if this segment has been visited already.
 | 
			
		||||
                if (visited.has(segment)) {
 | 
			
		||||
                    stack.pop();
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Skip if all previous segments have not been visited.
 | 
			
		||||
                if (segment !== startSegment &&
 | 
			
		||||
                    segment.prevSegments.length > 0 &&
 | 
			
		||||
                    !segment.prevSegments.every(isVisited)
 | 
			
		||||
                ) {
 | 
			
		||||
                    stack.pop();
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Reset the skipping flag if all branches have been skipped.
 | 
			
		||||
                if (skippedSegment && segment.prevSegments.includes(skippedSegment)) {
 | 
			
		||||
                    skippedSegment = null;
 | 
			
		||||
                }
 | 
			
		||||
                visited.add(segment);
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If the most recent segment hasn't been skipped, then we call
 | 
			
		||||
                 * the callback, passing in the segment and the controller.
 | 
			
		||||
                 */
 | 
			
		||||
                if (!skippedSegment) {
 | 
			
		||||
                    resolvedCallback.call(this, segment, controller);
 | 
			
		||||
 | 
			
		||||
                    // exit if we're at the last segment
 | 
			
		||||
                    if (segment === lastSegment) {
 | 
			
		||||
                        controller.skip();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /*
 | 
			
		||||
                     * If the previous statement was executed, or if the callback
 | 
			
		||||
                     * called a method on the controller, we might need to exit the
 | 
			
		||||
                     * loop, so check for that and break accordingly.
 | 
			
		||||
                     */
 | 
			
		||||
                    if (broken) {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Update the stack.
 | 
			
		||||
            end = segment.nextSegments.length - 1;
 | 
			
		||||
            if (index < end) {
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If we haven't yet visited all of the next segments, update
 | 
			
		||||
                 * the current top record on the stack to the next index to visit
 | 
			
		||||
                 * and then push a record for the current segment on top.
 | 
			
		||||
                 *
 | 
			
		||||
                 * Setting the current top record's index lets us know how many
 | 
			
		||||
                 * times we've been here and ensures that the segment won't be
 | 
			
		||||
                 * reprocessed (because we only process segments with an index
 | 
			
		||||
                 * of 0).
 | 
			
		||||
                 */
 | 
			
		||||
                record[1] += 1;
 | 
			
		||||
                stack.push([segment.nextSegments[index], 0]);
 | 
			
		||||
            } else if (index === end) {
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If we are at the last next segment, then reset the top record
 | 
			
		||||
                 * in the stack to next segment and set its index to 0 so it will
 | 
			
		||||
                 * be processed next.
 | 
			
		||||
                 */
 | 
			
		||||
                record[0] = segment.nextSegments[index];
 | 
			
		||||
                record[1] = 0;
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If index > end, that means we have no more segments that need
 | 
			
		||||
                 * processing. So, we pop that record off of the stack in order to
 | 
			
		||||
                 * continue traversing at the next level up.
 | 
			
		||||
                 */
 | 
			
		||||
                stack.pop();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = CodePath;
 | 
			
		||||
							
								
								
									
										203
									
								
								node_modules/eslint/lib/linter/code-path-analysis/debug-helpers.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								node_modules/eslint/lib/linter/code-path-analysis/debug-helpers.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,203 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Helpers to debug for code path analysis.
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const debug = require("debug")("eslint:code-path");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets id of a given segment.
 | 
			
		||||
 * @param {CodePathSegment} segment A segment to get.
 | 
			
		||||
 * @returns {string} Id of the segment.
 | 
			
		||||
 */
 | 
			
		||||
/* c8 ignore next */
 | 
			
		||||
function getId(segment) { // eslint-disable-line jsdoc/require-jsdoc -- Ignoring
 | 
			
		||||
    return segment.id + (segment.reachable ? "" : "!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get string for the given node and operation.
 | 
			
		||||
 * @param {ASTNode} node The node to convert.
 | 
			
		||||
 * @param {"enter" | "exit" | undefined} label The operation label.
 | 
			
		||||
 * @returns {string} The string representation.
 | 
			
		||||
 */
 | 
			
		||||
function nodeToString(node, label) {
 | 
			
		||||
    const suffix = label ? `:${label}` : "";
 | 
			
		||||
 | 
			
		||||
    switch (node.type) {
 | 
			
		||||
        case "Identifier": return `${node.type}${suffix} (${node.name})`;
 | 
			
		||||
        case "Literal": return `${node.type}${suffix} (${node.value})`;
 | 
			
		||||
        default: return `${node.type}${suffix}`;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A flag that debug dumping is enabled or not.
 | 
			
		||||
     * @type {boolean}
 | 
			
		||||
     */
 | 
			
		||||
    enabled: debug.enabled,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Dumps given objects.
 | 
			
		||||
     * @param {...any} args objects to dump.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    dump: debug,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Dumps the current analyzing state.
 | 
			
		||||
     * @param {ASTNode} node A node to dump.
 | 
			
		||||
     * @param {CodePathState} state A state to dump.
 | 
			
		||||
     * @param {boolean} leaving A flag whether or not it's leaving
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    dumpState: !debug.enabled ? debug : /* c8 ignore next */ function(node, state, leaving) {
 | 
			
		||||
        for (let i = 0; i < state.currentSegments.length; ++i) {
 | 
			
		||||
            const segInternal = state.currentSegments[i].internal;
 | 
			
		||||
 | 
			
		||||
            if (leaving) {
 | 
			
		||||
                const last = segInternal.nodes.length - 1;
 | 
			
		||||
 | 
			
		||||
                if (last >= 0 && segInternal.nodes[last] === nodeToString(node, "enter")) {
 | 
			
		||||
                    segInternal.nodes[last] = nodeToString(node, void 0);
 | 
			
		||||
                } else {
 | 
			
		||||
                    segInternal.nodes.push(nodeToString(node, "exit"));
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                segInternal.nodes.push(nodeToString(node, "enter"));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        debug([
 | 
			
		||||
            `${state.currentSegments.map(getId).join(",")})`,
 | 
			
		||||
            `${node.type}${leaving ? ":exit" : ""}`
 | 
			
		||||
        ].join(" "));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Dumps a DOT code of a given code path.
 | 
			
		||||
     * The DOT code can be visualized with Graphvis.
 | 
			
		||||
     * @param {CodePath} codePath A code path to dump.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     * @see http://www.graphviz.org
 | 
			
		||||
     * @see http://www.webgraphviz.com
 | 
			
		||||
     */
 | 
			
		||||
    dumpDot: !debug.enabled ? debug : /* c8 ignore next */ function(codePath) {
 | 
			
		||||
        let text =
 | 
			
		||||
            "\n" +
 | 
			
		||||
            "digraph {\n" +
 | 
			
		||||
            "node[shape=box,style=\"rounded,filled\",fillcolor=white];\n" +
 | 
			
		||||
            "initial[label=\"\",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];\n";
 | 
			
		||||
 | 
			
		||||
        if (codePath.returnedSegments.length > 0) {
 | 
			
		||||
            text += "final[label=\"\",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n";
 | 
			
		||||
        }
 | 
			
		||||
        if (codePath.thrownSegments.length > 0) {
 | 
			
		||||
            text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize=true];\n";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const traceMap = Object.create(null);
 | 
			
		||||
        const arrows = this.makeDotArrows(codePath, traceMap);
 | 
			
		||||
 | 
			
		||||
        for (const id in traceMap) { // eslint-disable-line guard-for-in -- Want ability to traverse prototype
 | 
			
		||||
            const segment = traceMap[id];
 | 
			
		||||
 | 
			
		||||
            text += `${id}[`;
 | 
			
		||||
 | 
			
		||||
            if (segment.reachable) {
 | 
			
		||||
                text += "label=\"";
 | 
			
		||||
            } else {
 | 
			
		||||
                text += "style=\"rounded,dashed,filled\",fillcolor=\"#FF9800\",label=\"<<unreachable>>\\n";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (segment.internal.nodes.length > 0) {
 | 
			
		||||
                text += segment.internal.nodes.join("\\n");
 | 
			
		||||
            } else {
 | 
			
		||||
                text += "????";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            text += "\"];\n";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        text += `${arrows}\n`;
 | 
			
		||||
        text += "}";
 | 
			
		||||
        debug("DOT", text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes a DOT code of a given code path.
 | 
			
		||||
     * The DOT code can be visualized with Graphvis.
 | 
			
		||||
     * @param {CodePath} codePath A code path to make DOT.
 | 
			
		||||
     * @param {Object} traceMap Optional. A map to check whether or not segments had been done.
 | 
			
		||||
     * @returns {string} A DOT code of the code path.
 | 
			
		||||
     */
 | 
			
		||||
    makeDotArrows(codePath, traceMap) {
 | 
			
		||||
        const stack = [[codePath.initialSegment, 0]];
 | 
			
		||||
        const done = traceMap || Object.create(null);
 | 
			
		||||
        let lastId = codePath.initialSegment.id;
 | 
			
		||||
        let text = `initial->${codePath.initialSegment.id}`;
 | 
			
		||||
 | 
			
		||||
        while (stack.length > 0) {
 | 
			
		||||
            const item = stack.pop();
 | 
			
		||||
            const segment = item[0];
 | 
			
		||||
            const index = item[1];
 | 
			
		||||
 | 
			
		||||
            if (done[segment.id] && index === 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            done[segment.id] = segment;
 | 
			
		||||
 | 
			
		||||
            const nextSegment = segment.allNextSegments[index];
 | 
			
		||||
 | 
			
		||||
            if (!nextSegment) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (lastId === segment.id) {
 | 
			
		||||
                text += `->${nextSegment.id}`;
 | 
			
		||||
            } else {
 | 
			
		||||
                text += `;\n${segment.id}->${nextSegment.id}`;
 | 
			
		||||
            }
 | 
			
		||||
            lastId = nextSegment.id;
 | 
			
		||||
 | 
			
		||||
            stack.unshift([segment, 1 + index]);
 | 
			
		||||
            stack.push([nextSegment, 0]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        codePath.returnedSegments.forEach(finalSegment => {
 | 
			
		||||
            if (lastId === finalSegment.id) {
 | 
			
		||||
                text += "->final";
 | 
			
		||||
            } else {
 | 
			
		||||
                text += `;\n${finalSegment.id}->final`;
 | 
			
		||||
            }
 | 
			
		||||
            lastId = null;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        codePath.thrownSegments.forEach(finalSegment => {
 | 
			
		||||
            if (lastId === finalSegment.id) {
 | 
			
		||||
                text += "->thrown";
 | 
			
		||||
            } else {
 | 
			
		||||
                text += `;\n${finalSegment.id}->thrown`;
 | 
			
		||||
            }
 | 
			
		||||
            lastId = null;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return `${text};`;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										349
									
								
								node_modules/eslint/lib/linter/code-path-analysis/fork-context.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										349
									
								
								node_modules/eslint/lib/linter/code-path-analysis/fork-context.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,349 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A class to operate forking.
 | 
			
		||||
 *
 | 
			
		||||
 * This is state of forking.
 | 
			
		||||
 * This has a fork list and manages it.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const assert = require("assert"),
 | 
			
		||||
    CodePathSegment = require("./code-path-segment");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determines whether or not a given segment is reachable.
 | 
			
		||||
 * @param {CodePathSegment} segment The segment to check.
 | 
			
		||||
 * @returns {boolean} `true` if the segment is reachable.
 | 
			
		||||
 */
 | 
			
		||||
function isReachable(segment) {
 | 
			
		||||
    return segment.reachable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a new segment for each fork in the given context and appends it
 | 
			
		||||
 * to the end of the specified range of segments. Ultimately, this ends up calling
 | 
			
		||||
 * `new CodePathSegment()` for each of the forks using the `create` argument
 | 
			
		||||
 * as a wrapper around special behavior.
 | 
			
		||||
 *
 | 
			
		||||
 * The `startIndex` and `endIndex` arguments specify a range of segments in
 | 
			
		||||
 * `context` that should become `allPrevSegments` for the newly created
 | 
			
		||||
 * `CodePathSegment` objects.
 | 
			
		||||
 *
 | 
			
		||||
 * When `context.segmentsList` is `[[a, b], [c, d], [e, f]]`, `begin` is `0`, and
 | 
			
		||||
 * `end` is `-1`, this creates two new segments, `[g, h]`. This `g` is appended to
 | 
			
		||||
 * the end of the path from `a`, `c`, and `e`. This `h` is appended to the end of
 | 
			
		||||
 * `b`, `d`, and `f`.
 | 
			
		||||
 * @param {ForkContext} context An instance from which the previous segments
 | 
			
		||||
 *      will be obtained.
 | 
			
		||||
 * @param {number} startIndex The index of the first segment in the context
 | 
			
		||||
 *      that should be specified as previous segments for the newly created segments.
 | 
			
		||||
 * @param {number} endIndex The index of the last segment in the context
 | 
			
		||||
 *      that should be specified as previous segments for the newly created segments.
 | 
			
		||||
 * @param {Function} create A function that creates new `CodePathSegment`
 | 
			
		||||
 *      instances in a particular way. See the `CodePathSegment.new*` methods.
 | 
			
		||||
 * @returns {Array<CodePathSegment>} An array of the newly-created segments.
 | 
			
		||||
 */
 | 
			
		||||
function createSegments(context, startIndex, endIndex, create) {
 | 
			
		||||
 | 
			
		||||
    /** @type {Array<Array<CodePathSegment>>} */
 | 
			
		||||
    const list = context.segmentsList;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Both `startIndex` and `endIndex` work the same way: if the number is zero
 | 
			
		||||
     * or more, then the number is used as-is. If the number is negative,
 | 
			
		||||
     * then that number is added to the length of the segments list to
 | 
			
		||||
     * determine the index to use. That means -1 for either argument
 | 
			
		||||
     * is the last element, -2 is the second to last, and so on.
 | 
			
		||||
     *
 | 
			
		||||
     * So if `startIndex` is 0, `endIndex` is -1, and `list.length` is 3, the
 | 
			
		||||
     * effective `startIndex` is 0 and the effective `endIndex` is 2, so this function
 | 
			
		||||
     * will include items at indices 0, 1, and 2.
 | 
			
		||||
     *
 | 
			
		||||
     * Therefore, if `startIndex` is -1 and `endIndex` is -1, that means we'll only
 | 
			
		||||
     * be using the last segment in `list`.
 | 
			
		||||
     */
 | 
			
		||||
    const normalizedBegin = startIndex >= 0 ? startIndex : list.length + startIndex;
 | 
			
		||||
    const normalizedEnd = endIndex >= 0 ? endIndex : list.length + endIndex;
 | 
			
		||||
 | 
			
		||||
    /** @type {Array<CodePathSegment>} */
 | 
			
		||||
    const segments = [];
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < context.count; ++i) {
 | 
			
		||||
 | 
			
		||||
        // this is passed into `new CodePathSegment` to add to code path.
 | 
			
		||||
        const allPrevSegments = [];
 | 
			
		||||
 | 
			
		||||
        for (let j = normalizedBegin; j <= normalizedEnd; ++j) {
 | 
			
		||||
            allPrevSegments.push(list[j][i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // note: `create` is just a wrapper that augments `new CodePathSegment`.
 | 
			
		||||
        segments.push(create(context.idGenerator.next(), allPrevSegments));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return segments;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Inside of a `finally` block we end up with two parallel paths. If the code path
 | 
			
		||||
 * exits by a control statement (such as `break` or `continue`) from the `finally`
 | 
			
		||||
 * block, then we need to merge the remaining parallel paths back into one.
 | 
			
		||||
 * @param {ForkContext} context The fork context to work on.
 | 
			
		||||
 * @param {Array<CodePathSegment>} segments Segments to merge.
 | 
			
		||||
 * @returns {Array<CodePathSegment>} The merged segments.
 | 
			
		||||
 */
 | 
			
		||||
function mergeExtraSegments(context, segments) {
 | 
			
		||||
    let currentSegments = segments;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * We need to ensure that the array returned from this function contains no more
 | 
			
		||||
     * than the number of segments that the context allows. `context.count` indicates
 | 
			
		||||
     * how many items should be in the returned array to ensure that the new segment
 | 
			
		||||
     * entries will line up with the already existing segment entries.
 | 
			
		||||
     */
 | 
			
		||||
    while (currentSegments.length > context.count) {
 | 
			
		||||
        const merged = [];
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Because `context.count` is a factor of 2 inside of a `finally` block,
 | 
			
		||||
         * we can divide the segment count by 2 to merge the paths together.
 | 
			
		||||
         * This loops through each segment in the list and creates a new `CodePathSegment`
 | 
			
		||||
         * that has the segment and the segment two slots away as previous segments.
 | 
			
		||||
         *
 | 
			
		||||
         * If `currentSegments` is [a,b,c,d], this will create new segments e and f, such
 | 
			
		||||
         * that:
 | 
			
		||||
         *
 | 
			
		||||
         * When `i` is 0:
 | 
			
		||||
         * a->e
 | 
			
		||||
         * c->e
 | 
			
		||||
         *
 | 
			
		||||
         * When `i` is 1:
 | 
			
		||||
         * b->f
 | 
			
		||||
         * d->f
 | 
			
		||||
         */
 | 
			
		||||
        for (let i = 0, length = Math.floor(currentSegments.length / 2); i < length; ++i) {
 | 
			
		||||
            merged.push(CodePathSegment.newNext(
 | 
			
		||||
                context.idGenerator.next(),
 | 
			
		||||
                [currentSegments[i], currentSegments[i + length]]
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Go through the loop condition one more time to see if we have the
 | 
			
		||||
         * number of segments for the context. If not, we'll keep merging paths
 | 
			
		||||
         * of the merged segments until we get there.
 | 
			
		||||
         */
 | 
			
		||||
        currentSegments = merged;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return currentSegments;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Manages the forking of code paths.
 | 
			
		||||
 */
 | 
			
		||||
class ForkContext {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new instance.
 | 
			
		||||
     * @param {IdGenerator} idGenerator An identifier generator for segments.
 | 
			
		||||
     * @param {ForkContext|null} upper The preceding fork context.
 | 
			
		||||
     * @param {number} count The number of parallel segments in each element
 | 
			
		||||
     *      of `segmentsList`.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(idGenerator, upper, count) {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The ID generator that will generate segment IDs for any new
 | 
			
		||||
         * segments that are created.
 | 
			
		||||
         * @type {IdGenerator}
 | 
			
		||||
         */
 | 
			
		||||
        this.idGenerator = idGenerator;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The preceding fork context.
 | 
			
		||||
         * @type {ForkContext|null}
 | 
			
		||||
         */
 | 
			
		||||
        this.upper = upper;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The number of elements in each element of `segmentsList`. In most
 | 
			
		||||
         * cases, this is 1 but can be 2 when there is a `finally` present,
 | 
			
		||||
         * which forks the code path outside of normal flow. In the case of nested
 | 
			
		||||
         * `finally` blocks, this can be a multiple of 2.
 | 
			
		||||
         * @type {number}
 | 
			
		||||
         */
 | 
			
		||||
        this.count = count;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The segments within this context. Each element in this array has
 | 
			
		||||
         * `count` elements that represent one step in each fork. For example,
 | 
			
		||||
         * when `segmentsList` is `[[a, b], [c, d], [e, f]]`, there is one path
 | 
			
		||||
         * a->c->e and one path b->d->f, and `count` is 2 because each element
 | 
			
		||||
         * is an array with two elements.
 | 
			
		||||
         * @type {Array<Array<CodePathSegment>>}
 | 
			
		||||
         */
 | 
			
		||||
        this.segmentsList = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The segments that begin this fork context.
 | 
			
		||||
     * @type {Array<CodePathSegment>}
 | 
			
		||||
     */
 | 
			
		||||
    get head() {
 | 
			
		||||
        const list = this.segmentsList;
 | 
			
		||||
 | 
			
		||||
        return list.length === 0 ? [] : list[list.length - 1];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Indicates if the context contains no segments.
 | 
			
		||||
     * @type {boolean}
 | 
			
		||||
     */
 | 
			
		||||
    get empty() {
 | 
			
		||||
        return this.segmentsList.length === 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Indicates if there are any segments that are reachable.
 | 
			
		||||
     * @type {boolean}
 | 
			
		||||
     */
 | 
			
		||||
    get reachable() {
 | 
			
		||||
        const segments = this.head;
 | 
			
		||||
 | 
			
		||||
        return segments.length > 0 && segments.some(isReachable);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new segments in this context and appends them to the end of the
 | 
			
		||||
     * already existing `CodePathSegment`s specified by `startIndex` and
 | 
			
		||||
     * `endIndex`.
 | 
			
		||||
     * @param {number} startIndex The index of the first segment in the context
 | 
			
		||||
     *      that should be specified as previous segments for the newly created segments.
 | 
			
		||||
     * @param {number} endIndex The index of the last segment in the context
 | 
			
		||||
     *      that should be specified as previous segments for the newly created segments.
 | 
			
		||||
     * @returns {Array<CodePathSegment>} An array of the newly created segments.
 | 
			
		||||
     */
 | 
			
		||||
    makeNext(startIndex, endIndex) {
 | 
			
		||||
        return createSegments(this, startIndex, endIndex, CodePathSegment.newNext);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new unreachable segments in this context and appends them to the end of the
 | 
			
		||||
     * already existing `CodePathSegment`s specified by `startIndex` and
 | 
			
		||||
     * `endIndex`.
 | 
			
		||||
     * @param {number} startIndex The index of the first segment in the context
 | 
			
		||||
     *      that should be specified as previous segments for the newly created segments.
 | 
			
		||||
     * @param {number} endIndex The index of the last segment in the context
 | 
			
		||||
     *      that should be specified as previous segments for the newly created segments.
 | 
			
		||||
     * @returns {Array<CodePathSegment>} An array of the newly created segments.
 | 
			
		||||
     */
 | 
			
		||||
    makeUnreachable(startIndex, endIndex) {
 | 
			
		||||
        return createSegments(this, startIndex, endIndex, CodePathSegment.newUnreachable);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new segments in this context and does not append them to the end
 | 
			
		||||
     *  of the already existing `CodePathSegment`s specified by `startIndex` and
 | 
			
		||||
     * `endIndex`. The `startIndex` and `endIndex` are only used to determine if
 | 
			
		||||
     * the new segments should be reachable. If any of the segments in this range
 | 
			
		||||
     * are reachable then the new segments are also reachable; otherwise, the new
 | 
			
		||||
     * segments are unreachable.
 | 
			
		||||
     * @param {number} startIndex The index of the first segment in the context
 | 
			
		||||
     *      that should be considered for reachability.
 | 
			
		||||
     * @param {number} endIndex The index of the last segment in the context
 | 
			
		||||
     *      that should be considered for reachability.
 | 
			
		||||
     * @returns {Array<CodePathSegment>} An array of the newly created segments.
 | 
			
		||||
     */
 | 
			
		||||
    makeDisconnected(startIndex, endIndex) {
 | 
			
		||||
        return createSegments(this, startIndex, endIndex, CodePathSegment.newDisconnected);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds segments to the head of this context.
 | 
			
		||||
     * @param {Array<CodePathSegment>} segments The segments to add.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    add(segments) {
 | 
			
		||||
        assert(segments.length >= this.count, `${segments.length} >= ${this.count}`);
 | 
			
		||||
        this.segmentsList.push(mergeExtraSegments(this, segments));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Replaces the head segments with the given segments.
 | 
			
		||||
     * The current head segments are removed.
 | 
			
		||||
     * @param {Array<CodePathSegment>} replacementHeadSegments The new head segments.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    replaceHead(replacementHeadSegments) {
 | 
			
		||||
        assert(
 | 
			
		||||
            replacementHeadSegments.length >= this.count,
 | 
			
		||||
            `${replacementHeadSegments.length} >= ${this.count}`
 | 
			
		||||
        );
 | 
			
		||||
        this.segmentsList.splice(-1, 1, mergeExtraSegments(this, replacementHeadSegments));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds all segments of a given fork context into this context.
 | 
			
		||||
     * @param {ForkContext} otherForkContext The fork context to add from.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    addAll(otherForkContext) {
 | 
			
		||||
        assert(otherForkContext.count === this.count);
 | 
			
		||||
        this.segmentsList.push(...otherForkContext.segmentsList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Clears all segments in this context.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    clear() {
 | 
			
		||||
        this.segmentsList = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new root context, meaning that there are no parent
 | 
			
		||||
     * fork contexts.
 | 
			
		||||
     * @param {IdGenerator} idGenerator An identifier generator for segments.
 | 
			
		||||
     * @returns {ForkContext} New fork context.
 | 
			
		||||
     */
 | 
			
		||||
    static newRoot(idGenerator) {
 | 
			
		||||
        const context = new ForkContext(idGenerator, null, 1);
 | 
			
		||||
 | 
			
		||||
        context.add([CodePathSegment.newRoot(idGenerator.next())]);
 | 
			
		||||
 | 
			
		||||
        return context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an empty fork context preceded by a given context.
 | 
			
		||||
     * @param {ForkContext} parentContext The parent fork context.
 | 
			
		||||
     * @param {boolean} shouldForkLeavingPath Indicates that we are inside of
 | 
			
		||||
     *      a `finally` block and should therefore fork the path that leaves
 | 
			
		||||
     *      `finally`.
 | 
			
		||||
     * @returns {ForkContext} New fork context.
 | 
			
		||||
     */
 | 
			
		||||
    static newEmpty(parentContext, shouldForkLeavingPath) {
 | 
			
		||||
        return new ForkContext(
 | 
			
		||||
            parentContext.idGenerator,
 | 
			
		||||
            parentContext,
 | 
			
		||||
            (shouldForkLeavingPath ? 2 : 1) * parentContext.count
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = ForkContext;
 | 
			
		||||
							
								
								
									
										45
									
								
								node_modules/eslint/lib/linter/code-path-analysis/id-generator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								node_modules/eslint/lib/linter/code-path-analysis/id-generator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A class of identifiers generator for code path segments.
 | 
			
		||||
 *
 | 
			
		||||
 * Each rule uses the identifier of code path segments to store additional
 | 
			
		||||
 * information of the code path.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A generator for unique ids.
 | 
			
		||||
 */
 | 
			
		||||
class IdGenerator {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {string} prefix Optional. A prefix of generated ids.
 | 
			
		||||
     */
 | 
			
		||||
    constructor(prefix) {
 | 
			
		||||
        this.prefix = String(prefix);
 | 
			
		||||
        this.n = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generates id.
 | 
			
		||||
     * @returns {string} A generated id.
 | 
			
		||||
     */
 | 
			
		||||
    next() {
 | 
			
		||||
        this.n = 1 + this.n | 0;
 | 
			
		||||
 | 
			
		||||
        /* c8 ignore start */
 | 
			
		||||
        if (this.n < 0) {
 | 
			
		||||
            this.n = 1;
 | 
			
		||||
        }/* c8 ignore stop */
 | 
			
		||||
 | 
			
		||||
        return this.prefix + this.n;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = IdGenerator;
 | 
			
		||||
							
								
								
									
										151
									
								
								node_modules/eslint/lib/linter/config-comment-parser.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								node_modules/eslint/lib/linter/config-comment-parser.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Config Comment Parser
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* eslint class-methods-use-this: off -- Methods desired on instance */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const levn = require("levn"),
 | 
			
		||||
    {
 | 
			
		||||
        Legacy: {
 | 
			
		||||
            ConfigOps
 | 
			
		||||
        }
 | 
			
		||||
    } = require("@eslint/eslintrc/universal");
 | 
			
		||||
 | 
			
		||||
const debug = require("debug")("eslint:config-comment-parser");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @typedef {import("../shared/types").LintMessage} LintMessage */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Object to parse ESLint configuration comments inside JavaScript files.
 | 
			
		||||
 * @name ConfigCommentParser
 | 
			
		||||
 */
 | 
			
		||||
module.exports = class ConfigCommentParser {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses a list of "name:string_value" or/and "name" options divided by comma or
 | 
			
		||||
     * whitespace. Used for "global" and "exported" comments.
 | 
			
		||||
     * @param {string} string The string to parse.
 | 
			
		||||
     * @param {Comment} comment The comment node which has the string.
 | 
			
		||||
     * @returns {Object} Result map object of names and string values, or null values if no value was provided
 | 
			
		||||
     */
 | 
			
		||||
    parseStringConfig(string, comment) {
 | 
			
		||||
        debug("Parsing String config");
 | 
			
		||||
 | 
			
		||||
        const items = {};
 | 
			
		||||
 | 
			
		||||
        // Collapse whitespace around `:` and `,` to make parsing easier
 | 
			
		||||
        const trimmedString = string.replace(/\s*([:,])\s*/gu, "$1");
 | 
			
		||||
 | 
			
		||||
        trimmedString.split(/\s|,+/u).forEach(name => {
 | 
			
		||||
            if (!name) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // value defaults to null (if not provided), e.g: "foo" => ["foo", null]
 | 
			
		||||
            const [key, value = null] = name.split(":");
 | 
			
		||||
 | 
			
		||||
            items[key] = { value, comment };
 | 
			
		||||
        });
 | 
			
		||||
        return items;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses a JSON-like config.
 | 
			
		||||
     * @param {string} string The string to parse.
 | 
			
		||||
     * @param {Object} location Start line and column of comments for potential error message.
 | 
			
		||||
     * @returns {({success: true, config: Object}|{success: false, error: LintMessage})} Result map object
 | 
			
		||||
     */
 | 
			
		||||
    parseJsonConfig(string, location) {
 | 
			
		||||
        debug("Parsing JSON config");
 | 
			
		||||
 | 
			
		||||
        let items = {};
 | 
			
		||||
 | 
			
		||||
        // Parses a JSON-like comment by the same way as parsing CLI option.
 | 
			
		||||
        try {
 | 
			
		||||
            items = levn.parse("Object", string) || {};
 | 
			
		||||
 | 
			
		||||
            // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`.
 | 
			
		||||
            // Also, commaless notations have invalid severity:
 | 
			
		||||
            //     "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"}
 | 
			
		||||
            // Should ignore that case as well.
 | 
			
		||||
            if (ConfigOps.isEverySeverityValid(items)) {
 | 
			
		||||
                return {
 | 
			
		||||
                    success: true,
 | 
			
		||||
                    config: items
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
        } catch {
 | 
			
		||||
 | 
			
		||||
            debug("Levn parsing failed; falling back to manual parsing.");
 | 
			
		||||
 | 
			
		||||
            // ignore to parse the string by a fallback.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Optionator cannot parse commaless notations.
 | 
			
		||||
         * But we are supporting that. So this is a fallback for that.
 | 
			
		||||
         */
 | 
			
		||||
        items = {};
 | 
			
		||||
        const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            items = JSON.parse(`{${normalizedString}}`);
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            debug("Manual parsing failed.");
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                success: false,
 | 
			
		||||
                error: {
 | 
			
		||||
                    ruleId: null,
 | 
			
		||||
                    fatal: true,
 | 
			
		||||
                    severity: 2,
 | 
			
		||||
                    message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`,
 | 
			
		||||
                    line: location.start.line,
 | 
			
		||||
                    column: location.start.column + 1,
 | 
			
		||||
                    nodeType: null
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            success: true,
 | 
			
		||||
            config: items
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses a config of values separated by comma.
 | 
			
		||||
     * @param {string} string The string to parse.
 | 
			
		||||
     * @returns {Object} Result map of values and true values
 | 
			
		||||
     */
 | 
			
		||||
    parseListConfig(string) {
 | 
			
		||||
        debug("Parsing list config");
 | 
			
		||||
 | 
			
		||||
        const items = {};
 | 
			
		||||
 | 
			
		||||
        string.split(",").forEach(name => {
 | 
			
		||||
            const trimmedName = name.trim().replace(/^(?<quote>['"]?)(?<ruleId>.*)\k<quote>$/us, "$<ruleId>");
 | 
			
		||||
 | 
			
		||||
            if (trimmedName) {
 | 
			
		||||
                items[trimmedName] = true;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return items;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										13
									
								
								node_modules/eslint/lib/linter/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								node_modules/eslint/lib/linter/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const { Linter } = require("./linter");
 | 
			
		||||
const interpolate = require("./interpolate");
 | 
			
		||||
const SourceCodeFixer = require("./source-code-fixer");
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    Linter,
 | 
			
		||||
 | 
			
		||||
    // For testers.
 | 
			
		||||
    SourceCodeFixer,
 | 
			
		||||
    interpolate
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										28
									
								
								node_modules/eslint/lib/linter/interpolate.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								node_modules/eslint/lib/linter/interpolate.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Interpolate keys from an object into a string with {{ }} markers.
 | 
			
		||||
 * @author Jed Fox
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module.exports = (text, data) => {
 | 
			
		||||
    if (!data) {
 | 
			
		||||
        return text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Substitution content for any {{ }} markers.
 | 
			
		||||
    return text.replace(/\{\{([^{}]+?)\}\}/gu, (fullMatch, termWithWhitespace) => {
 | 
			
		||||
        const term = termWithWhitespace.trim();
 | 
			
		||||
 | 
			
		||||
        if (term in data) {
 | 
			
		||||
            return data[term];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Preserve old behavior: If parameter name not provided, don't replace it.
 | 
			
		||||
        return fullMatch;
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										2134
									
								
								node_modules/eslint/lib/linter/linter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2134
									
								
								node_modules/eslint/lib/linter/linter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										354
									
								
								node_modules/eslint/lib/linter/node-event-generator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										354
									
								
								node_modules/eslint/lib/linter/node-event-generator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,354 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview The event generator for AST nodes.
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const esquery = require("esquery");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An object describing an AST selector
 | 
			
		||||
 * @typedef {Object} ASTSelector
 | 
			
		||||
 * @property {string} rawSelector The string that was parsed into this selector
 | 
			
		||||
 * @property {boolean} isExit `true` if this should be emitted when exiting the node rather than when entering
 | 
			
		||||
 * @property {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector
 | 
			
		||||
 * @property {string[]|null} listenerTypes A list of node types that could possibly cause the selector to match,
 | 
			
		||||
 * or `null` if all node types could cause a match
 | 
			
		||||
 * @property {number} attributeCount The total number of classes, pseudo-classes, and attribute queries in this selector
 | 
			
		||||
 * @property {number} identifierCount The total number of identifier queries in this selector
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Computes the union of one or more arrays
 | 
			
		||||
 * @param {...any[]} arrays One or more arrays to union
 | 
			
		||||
 * @returns {any[]} The union of the input arrays
 | 
			
		||||
 */
 | 
			
		||||
function union(...arrays) {
 | 
			
		||||
    return [...new Set(arrays.flat())];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Computes the intersection of one or more arrays
 | 
			
		||||
 * @param {...any[]} arrays One or more arrays to intersect
 | 
			
		||||
 * @returns {any[]} The intersection of the input arrays
 | 
			
		||||
 */
 | 
			
		||||
function intersection(...arrays) {
 | 
			
		||||
    if (arrays.length === 0) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result = [...new Set(arrays[0])];
 | 
			
		||||
 | 
			
		||||
    for (const array of arrays.slice(1)) {
 | 
			
		||||
        result = result.filter(x => array.includes(x));
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets the possible types of a selector
 | 
			
		||||
 * @param {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector
 | 
			
		||||
 * @returns {string[]|null} The node types that could possibly trigger this selector, or `null` if all node types could trigger it
 | 
			
		||||
 */
 | 
			
		||||
function getPossibleTypes(parsedSelector) {
 | 
			
		||||
    switch (parsedSelector.type) {
 | 
			
		||||
        case "identifier":
 | 
			
		||||
            return [parsedSelector.value];
 | 
			
		||||
 | 
			
		||||
        case "matches": {
 | 
			
		||||
            const typesForComponents = parsedSelector.selectors.map(getPossibleTypes);
 | 
			
		||||
 | 
			
		||||
            if (typesForComponents.every(Boolean)) {
 | 
			
		||||
                return union(...typesForComponents);
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case "compound": {
 | 
			
		||||
            const typesForComponents = parsedSelector.selectors.map(getPossibleTypes).filter(typesForComponent => typesForComponent);
 | 
			
		||||
 | 
			
		||||
            // If all of the components could match any type, then the compound could also match any type.
 | 
			
		||||
            if (!typesForComponents.length) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * If at least one of the components could only match a particular type, the compound could only match
 | 
			
		||||
             * the intersection of those types.
 | 
			
		||||
             */
 | 
			
		||||
            return intersection(...typesForComponents);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case "child":
 | 
			
		||||
        case "descendant":
 | 
			
		||||
        case "sibling":
 | 
			
		||||
        case "adjacent":
 | 
			
		||||
            return getPossibleTypes(parsedSelector.right);
 | 
			
		||||
 | 
			
		||||
        case "class":
 | 
			
		||||
            if (parsedSelector.name === "function") {
 | 
			
		||||
                return ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Counts the number of class, pseudo-class, and attribute queries in this selector
 | 
			
		||||
 * @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior
 | 
			
		||||
 * @returns {number} The number of class, pseudo-class, and attribute queries in this selector
 | 
			
		||||
 */
 | 
			
		||||
function countClassAttributes(parsedSelector) {
 | 
			
		||||
    switch (parsedSelector.type) {
 | 
			
		||||
        case "child":
 | 
			
		||||
        case "descendant":
 | 
			
		||||
        case "sibling":
 | 
			
		||||
        case "adjacent":
 | 
			
		||||
            return countClassAttributes(parsedSelector.left) + countClassAttributes(parsedSelector.right);
 | 
			
		||||
 | 
			
		||||
        case "compound":
 | 
			
		||||
        case "not":
 | 
			
		||||
        case "matches":
 | 
			
		||||
            return parsedSelector.selectors.reduce((sum, childSelector) => sum + countClassAttributes(childSelector), 0);
 | 
			
		||||
 | 
			
		||||
        case "attribute":
 | 
			
		||||
        case "field":
 | 
			
		||||
        case "nth-child":
 | 
			
		||||
        case "nth-last-child":
 | 
			
		||||
            return 1;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Counts the number of identifier queries in this selector
 | 
			
		||||
 * @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior
 | 
			
		||||
 * @returns {number} The number of identifier queries
 | 
			
		||||
 */
 | 
			
		||||
function countIdentifiers(parsedSelector) {
 | 
			
		||||
    switch (parsedSelector.type) {
 | 
			
		||||
        case "child":
 | 
			
		||||
        case "descendant":
 | 
			
		||||
        case "sibling":
 | 
			
		||||
        case "adjacent":
 | 
			
		||||
            return countIdentifiers(parsedSelector.left) + countIdentifiers(parsedSelector.right);
 | 
			
		||||
 | 
			
		||||
        case "compound":
 | 
			
		||||
        case "not":
 | 
			
		||||
        case "matches":
 | 
			
		||||
            return parsedSelector.selectors.reduce((sum, childSelector) => sum + countIdentifiers(childSelector), 0);
 | 
			
		||||
 | 
			
		||||
        case "identifier":
 | 
			
		||||
            return 1;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compares the specificity of two selector objects, with CSS-like rules.
 | 
			
		||||
 * @param {ASTSelector} selectorA An AST selector descriptor
 | 
			
		||||
 * @param {ASTSelector} selectorB Another AST selector descriptor
 | 
			
		||||
 * @returns {number}
 | 
			
		||||
 * a value less than 0 if selectorA is less specific than selectorB
 | 
			
		||||
 * a value greater than 0 if selectorA is more specific than selectorB
 | 
			
		||||
 * a value less than 0 if selectorA and selectorB have the same specificity, and selectorA <= selectorB alphabetically
 | 
			
		||||
 * a value greater than 0 if selectorA and selectorB have the same specificity, and selectorA > selectorB alphabetically
 | 
			
		||||
 */
 | 
			
		||||
function compareSpecificity(selectorA, selectorB) {
 | 
			
		||||
    return selectorA.attributeCount - selectorB.attributeCount ||
 | 
			
		||||
        selectorA.identifierCount - selectorB.identifierCount ||
 | 
			
		||||
        (selectorA.rawSelector <= selectorB.rawSelector ? -1 : 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parses a raw selector string, and throws a useful error if parsing fails.
 | 
			
		||||
 * @param {string} rawSelector A raw AST selector
 | 
			
		||||
 * @returns {Object} An object (from esquery) describing the matching behavior of this selector
 | 
			
		||||
 * @throws {Error} An error if the selector is invalid
 | 
			
		||||
 */
 | 
			
		||||
function tryParseSelector(rawSelector) {
 | 
			
		||||
    try {
 | 
			
		||||
        return esquery.parse(rawSelector.replace(/:exit$/u, ""));
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
        if (err.location && err.location.start && typeof err.location.start.offset === "number") {
 | 
			
		||||
            throw new SyntaxError(`Syntax error in selector "${rawSelector}" at position ${err.location.start.offset}: ${err.message}`);
 | 
			
		||||
        }
 | 
			
		||||
        throw err;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const selectorCache = new Map();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parses a raw selector string, and returns the parsed selector along with specificity and type information.
 | 
			
		||||
 * @param {string} rawSelector A raw AST selector
 | 
			
		||||
 * @returns {ASTSelector} A selector descriptor
 | 
			
		||||
 */
 | 
			
		||||
function parseSelector(rawSelector) {
 | 
			
		||||
    if (selectorCache.has(rawSelector)) {
 | 
			
		||||
        return selectorCache.get(rawSelector);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const parsedSelector = tryParseSelector(rawSelector);
 | 
			
		||||
 | 
			
		||||
    const result = {
 | 
			
		||||
        rawSelector,
 | 
			
		||||
        isExit: rawSelector.endsWith(":exit"),
 | 
			
		||||
        parsedSelector,
 | 
			
		||||
        listenerTypes: getPossibleTypes(parsedSelector),
 | 
			
		||||
        attributeCount: countClassAttributes(parsedSelector),
 | 
			
		||||
        identifierCount: countIdentifiers(parsedSelector)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    selectorCache.set(rawSelector, result);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The event generator for AST nodes.
 | 
			
		||||
 * This implements below interface.
 | 
			
		||||
 *
 | 
			
		||||
 * ```ts
 | 
			
		||||
 * interface EventGenerator {
 | 
			
		||||
 *     emitter: SafeEmitter;
 | 
			
		||||
 *     enterNode(node: ASTNode): void;
 | 
			
		||||
 *     leaveNode(node: ASTNode): void;
 | 
			
		||||
 * }
 | 
			
		||||
 * ```
 | 
			
		||||
 */
 | 
			
		||||
class NodeEventGenerator {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {SafeEmitter} emitter
 | 
			
		||||
     * An SafeEmitter which is the destination of events. This emitter must already
 | 
			
		||||
     * have registered listeners for all of the events that it needs to listen for.
 | 
			
		||||
     * (See lib/linter/safe-emitter.js for more details on `SafeEmitter`.)
 | 
			
		||||
     * @param {ESQueryOptions} esqueryOptions `esquery` options for traversing custom nodes.
 | 
			
		||||
     * @returns {NodeEventGenerator} new instance
 | 
			
		||||
     */
 | 
			
		||||
    constructor(emitter, esqueryOptions) {
 | 
			
		||||
        this.emitter = emitter;
 | 
			
		||||
        this.esqueryOptions = esqueryOptions;
 | 
			
		||||
        this.currentAncestry = [];
 | 
			
		||||
        this.enterSelectorsByNodeType = new Map();
 | 
			
		||||
        this.exitSelectorsByNodeType = new Map();
 | 
			
		||||
        this.anyTypeEnterSelectors = [];
 | 
			
		||||
        this.anyTypeExitSelectors = [];
 | 
			
		||||
 | 
			
		||||
        emitter.eventNames().forEach(rawSelector => {
 | 
			
		||||
            const selector = parseSelector(rawSelector);
 | 
			
		||||
 | 
			
		||||
            if (selector.listenerTypes) {
 | 
			
		||||
                const typeMap = selector.isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType;
 | 
			
		||||
 | 
			
		||||
                selector.listenerTypes.forEach(nodeType => {
 | 
			
		||||
                    if (!typeMap.has(nodeType)) {
 | 
			
		||||
                        typeMap.set(nodeType, []);
 | 
			
		||||
                    }
 | 
			
		||||
                    typeMap.get(nodeType).push(selector);
 | 
			
		||||
                });
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            const selectors = selector.isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors;
 | 
			
		||||
 | 
			
		||||
            selectors.push(selector);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.anyTypeEnterSelectors.sort(compareSpecificity);
 | 
			
		||||
        this.anyTypeExitSelectors.sort(compareSpecificity);
 | 
			
		||||
        this.enterSelectorsByNodeType.forEach(selectorList => selectorList.sort(compareSpecificity));
 | 
			
		||||
        this.exitSelectorsByNodeType.forEach(selectorList => selectorList.sort(compareSpecificity));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks a selector against a node, and emits it if it matches
 | 
			
		||||
     * @param {ASTNode} node The node to check
 | 
			
		||||
     * @param {ASTSelector} selector An AST selector descriptor
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    applySelector(node, selector) {
 | 
			
		||||
        if (esquery.matches(node, selector.parsedSelector, this.currentAncestry, this.esqueryOptions)) {
 | 
			
		||||
            this.emitter.emit(selector.rawSelector, node);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Applies all appropriate selectors to a node, in specificity order
 | 
			
		||||
     * @param {ASTNode} node The node to check
 | 
			
		||||
     * @param {boolean} isExit `false` if the node is currently being entered, `true` if it's currently being exited
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    applySelectors(node, isExit) {
 | 
			
		||||
        const selectorsByNodeType = (isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType).get(node.type) || [];
 | 
			
		||||
        const anyTypeSelectors = isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors;
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * selectorsByNodeType and anyTypeSelectors were already sorted by specificity in the constructor.
 | 
			
		||||
         * Iterate through each of them, applying selectors in the right order.
 | 
			
		||||
         */
 | 
			
		||||
        let selectorsByTypeIndex = 0;
 | 
			
		||||
        let anyTypeSelectorsIndex = 0;
 | 
			
		||||
 | 
			
		||||
        while (selectorsByTypeIndex < selectorsByNodeType.length || anyTypeSelectorsIndex < anyTypeSelectors.length) {
 | 
			
		||||
            if (
 | 
			
		||||
                selectorsByTypeIndex >= selectorsByNodeType.length ||
 | 
			
		||||
                anyTypeSelectorsIndex < anyTypeSelectors.length &&
 | 
			
		||||
                compareSpecificity(anyTypeSelectors[anyTypeSelectorsIndex], selectorsByNodeType[selectorsByTypeIndex]) < 0
 | 
			
		||||
            ) {
 | 
			
		||||
                this.applySelector(node, anyTypeSelectors[anyTypeSelectorsIndex++]);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.applySelector(node, selectorsByNodeType[selectorsByTypeIndex++]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Emits an event of entering AST node.
 | 
			
		||||
     * @param {ASTNode} node A node which was entered.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    enterNode(node) {
 | 
			
		||||
        if (node.parent) {
 | 
			
		||||
            this.currentAncestry.unshift(node.parent);
 | 
			
		||||
        }
 | 
			
		||||
        this.applySelectors(node, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Emits an event of leaving AST node.
 | 
			
		||||
     * @param {ASTNode} node A node which was left.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    leaveNode(node) {
 | 
			
		||||
        this.applySelectors(node, true);
 | 
			
		||||
        this.currentAncestry.shift();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = NodeEventGenerator;
 | 
			
		||||
							
								
								
									
										369
									
								
								node_modules/eslint/lib/linter/report-translator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								node_modules/eslint/lib/linter/report-translator.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,369 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A helper that translates context.report() calls from the rule API into generic problem objects
 | 
			
		||||
 * @author Teddy Katz
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const assert = require("assert");
 | 
			
		||||
const ruleFixer = require("./rule-fixer");
 | 
			
		||||
const interpolate = require("./interpolate");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @typedef {import("../shared/types").LintMessage} LintMessage */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An error message description
 | 
			
		||||
 * @typedef {Object} MessageDescriptor
 | 
			
		||||
 * @property {ASTNode} [node] The reported node
 | 
			
		||||
 * @property {Location} loc The location of the problem.
 | 
			
		||||
 * @property {string} message The problem message.
 | 
			
		||||
 * @property {Object} [data] Optional data to use to fill in placeholders in the
 | 
			
		||||
 *      message.
 | 
			
		||||
 * @property {Function} [fix] The function to call that creates a fix command.
 | 
			
		||||
 * @property {Array<{desc?: string, messageId?: string, fix: Function}>} suggest Suggestion descriptions and functions to create a the associated fixes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Module Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Translates a multi-argument context.report() call into a single object argument call
 | 
			
		||||
 * @param {...*} args A list of arguments passed to `context.report`
 | 
			
		||||
 * @returns {MessageDescriptor} A normalized object containing report information
 | 
			
		||||
 */
 | 
			
		||||
function normalizeMultiArgReportCall(...args) {
 | 
			
		||||
 | 
			
		||||
    // If there is one argument, it is considered to be a new-style call already.
 | 
			
		||||
    if (args.length === 1) {
 | 
			
		||||
 | 
			
		||||
        // Shallow clone the object to avoid surprises if reusing the descriptor
 | 
			
		||||
        return Object.assign({}, args[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If the second argument is a string, the arguments are interpreted as [node, message, data, fix].
 | 
			
		||||
    if (typeof args[1] === "string") {
 | 
			
		||||
        return {
 | 
			
		||||
            node: args[0],
 | 
			
		||||
            message: args[1],
 | 
			
		||||
            data: args[2],
 | 
			
		||||
            fix: args[3]
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Otherwise, the arguments are interpreted as [node, loc, message, data, fix].
 | 
			
		||||
    return {
 | 
			
		||||
        node: args[0],
 | 
			
		||||
        loc: args[1],
 | 
			
		||||
        message: args[2],
 | 
			
		||||
        data: args[3],
 | 
			
		||||
        fix: args[4]
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Asserts that either a loc or a node was provided, and the node is valid if it was provided.
 | 
			
		||||
 * @param {MessageDescriptor} descriptor A descriptor to validate
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 * @throws AssertionError if neither a node nor a loc was provided, or if the node is not an object
 | 
			
		||||
 */
 | 
			
		||||
function assertValidNodeInfo(descriptor) {
 | 
			
		||||
    if (descriptor.node) {
 | 
			
		||||
        assert(typeof descriptor.node === "object", "Node must be an object");
 | 
			
		||||
    } else {
 | 
			
		||||
        assert(descriptor.loc, "Node must be provided when reporting error if location is not provided");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Normalizes a MessageDescriptor to always have a `loc` with `start` and `end` properties
 | 
			
		||||
 * @param {MessageDescriptor} descriptor A descriptor for the report from a rule.
 | 
			
		||||
 * @returns {{start: Location, end: (Location|null)}} An updated location that infers the `start` and `end` properties
 | 
			
		||||
 * from the `node` of the original descriptor, or infers the `start` from the `loc` of the original descriptor.
 | 
			
		||||
 */
 | 
			
		||||
function normalizeReportLoc(descriptor) {
 | 
			
		||||
    if (descriptor.loc) {
 | 
			
		||||
        if (descriptor.loc.start) {
 | 
			
		||||
            return descriptor.loc;
 | 
			
		||||
        }
 | 
			
		||||
        return { start: descriptor.loc, end: null };
 | 
			
		||||
    }
 | 
			
		||||
    return descriptor.node.loc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Clones the given fix object.
 | 
			
		||||
 * @param {Fix|null} fix The fix to clone.
 | 
			
		||||
 * @returns {Fix|null} Deep cloned fix object or `null` if `null` or `undefined` was passed in.
 | 
			
		||||
 */
 | 
			
		||||
function cloneFix(fix) {
 | 
			
		||||
    if (!fix) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        range: [fix.range[0], fix.range[1]],
 | 
			
		||||
        text: fix.text
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check that a fix has a valid range.
 | 
			
		||||
 * @param {Fix|null} fix The fix to validate.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function assertValidFix(fix) {
 | 
			
		||||
    if (fix) {
 | 
			
		||||
        assert(fix.range && typeof fix.range[0] === "number" && typeof fix.range[1] === "number", `Fix has invalid range: ${JSON.stringify(fix, null, 2)}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compares items in a fixes array by range.
 | 
			
		||||
 * @param {Fix} a The first message.
 | 
			
		||||
 * @param {Fix} b The second message.
 | 
			
		||||
 * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function compareFixesByRange(a, b) {
 | 
			
		||||
    return a.range[0] - b.range[0] || a.range[1] - b.range[1];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Merges the given fixes array into one.
 | 
			
		||||
 * @param {Fix[]} fixes The fixes to merge.
 | 
			
		||||
 * @param {SourceCode} sourceCode The source code object to get the text between fixes.
 | 
			
		||||
 * @returns {{text: string, range: number[]}} The merged fixes
 | 
			
		||||
 */
 | 
			
		||||
function mergeFixes(fixes, sourceCode) {
 | 
			
		||||
    for (const fix of fixes) {
 | 
			
		||||
        assertValidFix(fix);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (fixes.length === 0) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    if (fixes.length === 1) {
 | 
			
		||||
        return cloneFix(fixes[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fixes.sort(compareFixesByRange);
 | 
			
		||||
 | 
			
		||||
    const originalText = sourceCode.text;
 | 
			
		||||
    const start = fixes[0].range[0];
 | 
			
		||||
    const end = fixes[fixes.length - 1].range[1];
 | 
			
		||||
    let text = "";
 | 
			
		||||
    let lastPos = Number.MIN_SAFE_INTEGER;
 | 
			
		||||
 | 
			
		||||
    for (const fix of fixes) {
 | 
			
		||||
        assert(fix.range[0] >= lastPos, "Fix objects must not be overlapped in a report.");
 | 
			
		||||
 | 
			
		||||
        if (fix.range[0] >= 0) {
 | 
			
		||||
            text += originalText.slice(Math.max(0, start, lastPos), fix.range[0]);
 | 
			
		||||
        }
 | 
			
		||||
        text += fix.text;
 | 
			
		||||
        lastPos = fix.range[1];
 | 
			
		||||
    }
 | 
			
		||||
    text += originalText.slice(Math.max(0, start, lastPos), end);
 | 
			
		||||
 | 
			
		||||
    return { range: [start, end], text };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets one fix object from the given descriptor.
 | 
			
		||||
 * If the descriptor retrieves multiple fixes, this merges those to one.
 | 
			
		||||
 * @param {MessageDescriptor} descriptor The report descriptor.
 | 
			
		||||
 * @param {SourceCode} sourceCode The source code object to get text between fixes.
 | 
			
		||||
 * @returns {({text: string, range: number[]}|null)} The fix for the descriptor
 | 
			
		||||
 */
 | 
			
		||||
function normalizeFixes(descriptor, sourceCode) {
 | 
			
		||||
    if (typeof descriptor.fix !== "function") {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // @type {null | Fix | Fix[] | IterableIterator<Fix>}
 | 
			
		||||
    const fix = descriptor.fix(ruleFixer);
 | 
			
		||||
 | 
			
		||||
    // Merge to one.
 | 
			
		||||
    if (fix && Symbol.iterator in fix) {
 | 
			
		||||
        return mergeFixes(Array.from(fix), sourceCode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assertValidFix(fix);
 | 
			
		||||
    return cloneFix(fix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets an array of suggestion objects from the given descriptor.
 | 
			
		||||
 * @param {MessageDescriptor} descriptor The report descriptor.
 | 
			
		||||
 * @param {SourceCode} sourceCode The source code object to get text between fixes.
 | 
			
		||||
 * @param {Object} messages Object of meta messages for the rule.
 | 
			
		||||
 * @returns {Array<SuggestionResult>} The suggestions for the descriptor
 | 
			
		||||
 */
 | 
			
		||||
function mapSuggestions(descriptor, sourceCode, messages) {
 | 
			
		||||
    if (!descriptor.suggest || !Array.isArray(descriptor.suggest)) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return descriptor.suggest
 | 
			
		||||
        .map(suggestInfo => {
 | 
			
		||||
            const computedDesc = suggestInfo.desc || messages[suggestInfo.messageId];
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                ...suggestInfo,
 | 
			
		||||
                desc: interpolate(computedDesc, suggestInfo.data),
 | 
			
		||||
                fix: normalizeFixes(suggestInfo, sourceCode)
 | 
			
		||||
            };
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        // Remove suggestions that didn't provide a fix
 | 
			
		||||
        .filter(({ fix }) => fix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates information about the report from a descriptor
 | 
			
		||||
 * @param {Object} options Information about the problem
 | 
			
		||||
 * @param {string} options.ruleId Rule ID
 | 
			
		||||
 * @param {(0|1|2)} options.severity Rule severity
 | 
			
		||||
 * @param {(ASTNode|null)} options.node Node
 | 
			
		||||
 * @param {string} options.message Error message
 | 
			
		||||
 * @param {string} [options.messageId] The error message ID.
 | 
			
		||||
 * @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location
 | 
			
		||||
 * @param {{text: string, range: (number[]|null)}} options.fix The fix object
 | 
			
		||||
 * @param {Array<{text: string, range: (number[]|null)}>} options.suggestions The array of suggestions objects
 | 
			
		||||
 * @returns {LintMessage} Information about the report
 | 
			
		||||
 */
 | 
			
		||||
function createProblem(options) {
 | 
			
		||||
    const problem = {
 | 
			
		||||
        ruleId: options.ruleId,
 | 
			
		||||
        severity: options.severity,
 | 
			
		||||
        message: options.message,
 | 
			
		||||
        line: options.loc.start.line,
 | 
			
		||||
        column: options.loc.start.column + 1,
 | 
			
		||||
        nodeType: options.node && options.node.type || null
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * If this isn’t in the conditional, some of the tests fail
 | 
			
		||||
     * because `messageId` is present in the problem object
 | 
			
		||||
     */
 | 
			
		||||
    if (options.messageId) {
 | 
			
		||||
        problem.messageId = options.messageId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (options.loc.end) {
 | 
			
		||||
        problem.endLine = options.loc.end.line;
 | 
			
		||||
        problem.endColumn = options.loc.end.column + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (options.fix) {
 | 
			
		||||
        problem.fix = options.fix;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (options.suggestions && options.suggestions.length > 0) {
 | 
			
		||||
        problem.suggestions = options.suggestions;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return problem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Validates that suggestions are properly defined. Throws if an error is detected.
 | 
			
		||||
 * @param {Array<{ desc?: string, messageId?: string }>} suggest The incoming suggest data.
 | 
			
		||||
 * @param {Object} messages Object of meta messages for the rule.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function validateSuggestions(suggest, messages) {
 | 
			
		||||
    if (suggest && Array.isArray(suggest)) {
 | 
			
		||||
        suggest.forEach(suggestion => {
 | 
			
		||||
            if (suggestion.messageId) {
 | 
			
		||||
                const { messageId } = suggestion;
 | 
			
		||||
 | 
			
		||||
                if (!messages) {
 | 
			
		||||
                    throw new TypeError(`context.report() called with a suggest option with a messageId '${messageId}', but no messages were present in the rule metadata.`);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!messages[messageId]) {
 | 
			
		||||
                    throw new TypeError(`context.report() called with a suggest option with a messageId '${messageId}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (suggestion.desc) {
 | 
			
		||||
                    throw new TypeError("context.report() called with a suggest option that defines both a 'messageId' and an 'desc'. Please only pass one.");
 | 
			
		||||
                }
 | 
			
		||||
            } else if (!suggestion.desc) {
 | 
			
		||||
                throw new TypeError("context.report() called with a suggest option that doesn't have either a `desc` or `messageId`");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (typeof suggestion.fix !== "function") {
 | 
			
		||||
                throw new TypeError(`context.report() called with a suggest option without a fix function. See: ${suggestion}`);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a function that converts the arguments of a `context.report` call from a rule into a reported
 | 
			
		||||
 * problem for the Node.js API.
 | 
			
		||||
 * @param {{ruleId: string, severity: number, sourceCode: SourceCode, messageIds: Object, disableFixes: boolean}} metadata Metadata for the reported problem
 | 
			
		||||
 * @param {SourceCode} sourceCode The `SourceCode` instance for the text being linted
 | 
			
		||||
 * @returns {function(...args): LintMessage} Function that returns information about the report
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module.exports = function createReportTranslator(metadata) {
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * `createReportTranslator` gets called once per enabled rule per file. It needs to be very performant.
 | 
			
		||||
     * The report translator itself (i.e. the function that `createReportTranslator` returns) gets
 | 
			
		||||
     * called every time a rule reports a problem, which happens much less frequently (usually, the vast
 | 
			
		||||
     * majority of rules don't report any problems for a given file).
 | 
			
		||||
     */
 | 
			
		||||
    return (...args) => {
 | 
			
		||||
        const descriptor = normalizeMultiArgReportCall(...args);
 | 
			
		||||
        const messages = metadata.messageIds;
 | 
			
		||||
 | 
			
		||||
        assertValidNodeInfo(descriptor);
 | 
			
		||||
 | 
			
		||||
        let computedMessage;
 | 
			
		||||
 | 
			
		||||
        if (descriptor.messageId) {
 | 
			
		||||
            if (!messages) {
 | 
			
		||||
                throw new TypeError("context.report() called with a messageId, but no messages were present in the rule metadata.");
 | 
			
		||||
            }
 | 
			
		||||
            const id = descriptor.messageId;
 | 
			
		||||
 | 
			
		||||
            if (descriptor.message) {
 | 
			
		||||
                throw new TypeError("context.report() called with a message and a messageId. Please only pass one.");
 | 
			
		||||
            }
 | 
			
		||||
            if (!messages || !Object.prototype.hasOwnProperty.call(messages, id)) {
 | 
			
		||||
                throw new TypeError(`context.report() called with a messageId of '${id}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`);
 | 
			
		||||
            }
 | 
			
		||||
            computedMessage = messages[id];
 | 
			
		||||
        } else if (descriptor.message) {
 | 
			
		||||
            computedMessage = descriptor.message;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new TypeError("Missing `message` property in report() call; add a message that describes the linting problem.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        validateSuggestions(descriptor.suggest, messages);
 | 
			
		||||
 | 
			
		||||
        return createProblem({
 | 
			
		||||
            ruleId: metadata.ruleId,
 | 
			
		||||
            severity: metadata.severity,
 | 
			
		||||
            node: descriptor.node,
 | 
			
		||||
            message: interpolate(computedMessage, descriptor.data),
 | 
			
		||||
            messageId: descriptor.messageId,
 | 
			
		||||
            loc: normalizeReportLoc(descriptor),
 | 
			
		||||
            fix: metadata.disableFixes ? null : normalizeFixes(descriptor, metadata.sourceCode),
 | 
			
		||||
            suggestions: metadata.disableFixes ? [] : mapSuggestions(descriptor, metadata.sourceCode, messages)
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										140
									
								
								node_modules/eslint/lib/linter/rule-fixer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								node_modules/eslint/lib/linter/rule-fixer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview An object that creates fix commands for rules.
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
// none!
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a fix command that inserts text at the specified index in the source text.
 | 
			
		||||
 * @param {int} index The 0-based index at which to insert the new text.
 | 
			
		||||
 * @param {string} text The text to insert.
 | 
			
		||||
 * @returns {Object} The fix command.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function insertTextAt(index, text) {
 | 
			
		||||
    return {
 | 
			
		||||
        range: [index, index],
 | 
			
		||||
        text
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates code fixing commands for rules.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const ruleFixer = Object.freeze({
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a fix command that inserts text after the given node or token.
 | 
			
		||||
     * The fix is not applied until applyFixes() is called.
 | 
			
		||||
     * @param {ASTNode|Token} nodeOrToken The node or token to insert after.
 | 
			
		||||
     * @param {string} text The text to insert.
 | 
			
		||||
     * @returns {Object} The fix command.
 | 
			
		||||
     */
 | 
			
		||||
    insertTextAfter(nodeOrToken, text) {
 | 
			
		||||
        return this.insertTextAfterRange(nodeOrToken.range, text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a fix command that inserts text after the specified range in the source text.
 | 
			
		||||
     * The fix is not applied until applyFixes() is called.
 | 
			
		||||
     * @param {int[]} range The range to replace, first item is start of range, second
 | 
			
		||||
     *      is end of range.
 | 
			
		||||
     * @param {string} text The text to insert.
 | 
			
		||||
     * @returns {Object} The fix command.
 | 
			
		||||
     */
 | 
			
		||||
    insertTextAfterRange(range, text) {
 | 
			
		||||
        return insertTextAt(range[1], text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a fix command that inserts text before the given node or token.
 | 
			
		||||
     * The fix is not applied until applyFixes() is called.
 | 
			
		||||
     * @param {ASTNode|Token} nodeOrToken The node or token to insert before.
 | 
			
		||||
     * @param {string} text The text to insert.
 | 
			
		||||
     * @returns {Object} The fix command.
 | 
			
		||||
     */
 | 
			
		||||
    insertTextBefore(nodeOrToken, text) {
 | 
			
		||||
        return this.insertTextBeforeRange(nodeOrToken.range, text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a fix command that inserts text before the specified range in the source text.
 | 
			
		||||
     * The fix is not applied until applyFixes() is called.
 | 
			
		||||
     * @param {int[]} range The range to replace, first item is start of range, second
 | 
			
		||||
     *      is end of range.
 | 
			
		||||
     * @param {string} text The text to insert.
 | 
			
		||||
     * @returns {Object} The fix command.
 | 
			
		||||
     */
 | 
			
		||||
    insertTextBeforeRange(range, text) {
 | 
			
		||||
        return insertTextAt(range[0], text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a fix command that replaces text at the node or token.
 | 
			
		||||
     * The fix is not applied until applyFixes() is called.
 | 
			
		||||
     * @param {ASTNode|Token} nodeOrToken The node or token to remove.
 | 
			
		||||
     * @param {string} text The text to insert.
 | 
			
		||||
     * @returns {Object} The fix command.
 | 
			
		||||
     */
 | 
			
		||||
    replaceText(nodeOrToken, text) {
 | 
			
		||||
        return this.replaceTextRange(nodeOrToken.range, text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a fix command that replaces text at the specified range in the source text.
 | 
			
		||||
     * The fix is not applied until applyFixes() is called.
 | 
			
		||||
     * @param {int[]} range The range to replace, first item is start of range, second
 | 
			
		||||
     *      is end of range.
 | 
			
		||||
     * @param {string} text The text to insert.
 | 
			
		||||
     * @returns {Object} The fix command.
 | 
			
		||||
     */
 | 
			
		||||
    replaceTextRange(range, text) {
 | 
			
		||||
        return {
 | 
			
		||||
            range,
 | 
			
		||||
            text
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a fix command that removes the node or token from the source.
 | 
			
		||||
     * The fix is not applied until applyFixes() is called.
 | 
			
		||||
     * @param {ASTNode|Token} nodeOrToken The node or token to remove.
 | 
			
		||||
     * @returns {Object} The fix command.
 | 
			
		||||
     */
 | 
			
		||||
    remove(nodeOrToken) {
 | 
			
		||||
        return this.removeRange(nodeOrToken.range);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a fix command that removes the specified range of text from the source.
 | 
			
		||||
     * The fix is not applied until applyFixes() is called.
 | 
			
		||||
     * @param {int[]} range The range to remove, first item is start of range, second
 | 
			
		||||
     *      is end of range.
 | 
			
		||||
     * @returns {Object} The fix command.
 | 
			
		||||
     */
 | 
			
		||||
    removeRange(range) {
 | 
			
		||||
        return {
 | 
			
		||||
            range,
 | 
			
		||||
            text: ""
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = ruleFixer;
 | 
			
		||||
							
								
								
									
										80
									
								
								node_modules/eslint/lib/linter/rules.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								node_modules/eslint/lib/linter/rules.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Defines a storage for rules.
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 * @author aladdin-add
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const builtInRules = require("../rules");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Normalizes a rule module to the new-style API
 | 
			
		||||
 * @param {(Function|{create: Function})} rule A rule object, which can either be a function
 | 
			
		||||
 * ("old-style") or an object with a `create` method ("new-style")
 | 
			
		||||
 * @returns {{create: Function}} A new-style rule.
 | 
			
		||||
 */
 | 
			
		||||
function normalizeRule(rule) {
 | 
			
		||||
    return typeof rule === "function" ? Object.assign({ create: rule }, rule) : rule;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A storage for rules.
 | 
			
		||||
 */
 | 
			
		||||
class Rules {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._rules = Object.create(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Registers a rule module for rule id in storage.
 | 
			
		||||
     * @param {string} ruleId Rule id (file name).
 | 
			
		||||
     * @param {Function} ruleModule Rule handler.
 | 
			
		||||
     * @returns {void}
 | 
			
		||||
     */
 | 
			
		||||
    define(ruleId, ruleModule) {
 | 
			
		||||
        this._rules[ruleId] = normalizeRule(ruleModule);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Access rule handler by id (file name).
 | 
			
		||||
     * @param {string} ruleId Rule id (file name).
 | 
			
		||||
     * @returns {{create: Function, schema: JsonSchema[]}}
 | 
			
		||||
     * A rule. This is normalized to always have the new-style shape with a `create` method.
 | 
			
		||||
     */
 | 
			
		||||
    get(ruleId) {
 | 
			
		||||
        if (typeof this._rules[ruleId] === "string") {
 | 
			
		||||
            this.define(ruleId, require(this._rules[ruleId]));
 | 
			
		||||
        }
 | 
			
		||||
        if (this._rules[ruleId]) {
 | 
			
		||||
            return this._rules[ruleId];
 | 
			
		||||
        }
 | 
			
		||||
        if (builtInRules.has(ruleId)) {
 | 
			
		||||
            return builtInRules.get(ruleId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *[Symbol.iterator]() {
 | 
			
		||||
        yield* builtInRules;
 | 
			
		||||
 | 
			
		||||
        for (const ruleId of Object.keys(this._rules)) {
 | 
			
		||||
            yield [ruleId, this.get(ruleId)];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = Rules;
 | 
			
		||||
							
								
								
									
										52
									
								
								node_modules/eslint/lib/linter/safe-emitter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								node_modules/eslint/lib/linter/safe-emitter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A variant of EventEmitter which does not give listeners information about each other
 | 
			
		||||
 * @author Teddy Katz
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An event emitter
 | 
			
		||||
 * @typedef {Object} SafeEmitter
 | 
			
		||||
 * @property {(eventName: string, listenerFunc: Function) => void} on Adds a listener for a given event name
 | 
			
		||||
 * @property {(eventName: string, arg1?: any, arg2?: any, arg3?: any) => void} emit Emits an event with a given name.
 | 
			
		||||
 * This calls all the listeners that were listening for that name, with `arg1`, `arg2`, and `arg3` as arguments.
 | 
			
		||||
 * @property {function(): string[]} eventNames Gets the list of event names that have registered listeners.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates an object which can listen for and emit events.
 | 
			
		||||
 * This is similar to the EventEmitter API in Node's standard library, but it has a few differences.
 | 
			
		||||
 * The goal is to allow multiple modules to attach arbitrary listeners to the same emitter, without
 | 
			
		||||
 * letting the modules know about each other at all.
 | 
			
		||||
 * 1. It has no special keys like `error` and `newListener`, which would allow modules to detect when
 | 
			
		||||
 * another module throws an error or registers a listener.
 | 
			
		||||
 * 2. It calls listener functions without any `this` value. (`EventEmitter` calls listeners with a
 | 
			
		||||
 * `this` value of the emitter instance, which would give listeners access to other listeners.)
 | 
			
		||||
 * @returns {SafeEmitter} An emitter
 | 
			
		||||
 */
 | 
			
		||||
module.exports = () => {
 | 
			
		||||
    const listeners = Object.create(null);
 | 
			
		||||
 | 
			
		||||
    return Object.freeze({
 | 
			
		||||
        on(eventName, listener) {
 | 
			
		||||
            if (eventName in listeners) {
 | 
			
		||||
                listeners[eventName].push(listener);
 | 
			
		||||
            } else {
 | 
			
		||||
                listeners[eventName] = [listener];
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        emit(eventName, ...args) {
 | 
			
		||||
            if (eventName in listeners) {
 | 
			
		||||
                listeners[eventName].forEach(listener => listener(...args));
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        eventNames() {
 | 
			
		||||
            return Object.keys(listeners);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										152
									
								
								node_modules/eslint/lib/linter/source-code-fixer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								node_modules/eslint/lib/linter/source-code-fixer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview An object that caches and applies source code fixes.
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const debug = require("debug")("eslint:source-code-fixer");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const BOM = "\uFEFF";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compares items in a messages array by range.
 | 
			
		||||
 * @param {Message} a The first message.
 | 
			
		||||
 * @param {Message} b The second message.
 | 
			
		||||
 * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function compareMessagesByFixRange(a, b) {
 | 
			
		||||
    return a.fix.range[0] - b.fix.range[0] || a.fix.range[1] - b.fix.range[1];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compares items in a messages array by line and column.
 | 
			
		||||
 * @param {Message} a The first message.
 | 
			
		||||
 * @param {Message} b The second message.
 | 
			
		||||
 * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function compareMessagesByLocation(a, b) {
 | 
			
		||||
    return a.line - b.line || a.column - b.column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utility for apply fixes to source code.
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
function SourceCodeFixer() {
 | 
			
		||||
    Object.freeze(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Applies the fixes specified by the messages to the given text. Tries to be
 | 
			
		||||
 * smart about the fixes and won't apply fixes over the same area in the text.
 | 
			
		||||
 * @param {string} sourceText The text to apply the changes to.
 | 
			
		||||
 * @param {Message[]} messages The array of messages reported by ESLint.
 | 
			
		||||
 * @param {boolean|Function} [shouldFix=true] Determines whether each message should be fixed
 | 
			
		||||
 * @returns {Object} An object containing the fixed text and any unfixed messages.
 | 
			
		||||
 */
 | 
			
		||||
SourceCodeFixer.applyFixes = function(sourceText, messages, shouldFix) {
 | 
			
		||||
    debug("Applying fixes");
 | 
			
		||||
 | 
			
		||||
    if (shouldFix === false) {
 | 
			
		||||
        debug("shouldFix parameter was false, not attempting fixes");
 | 
			
		||||
        return {
 | 
			
		||||
            fixed: false,
 | 
			
		||||
            messages,
 | 
			
		||||
            output: sourceText
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // clone the array
 | 
			
		||||
    const remainingMessages = [],
 | 
			
		||||
        fixes = [],
 | 
			
		||||
        bom = sourceText.startsWith(BOM) ? BOM : "",
 | 
			
		||||
        text = bom ? sourceText.slice(1) : sourceText;
 | 
			
		||||
    let lastPos = Number.NEGATIVE_INFINITY,
 | 
			
		||||
        output = bom;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Try to use the 'fix' from a problem.
 | 
			
		||||
     * @param {Message} problem The message object to apply fixes from
 | 
			
		||||
     * @returns {boolean} Whether fix was successfully applied
 | 
			
		||||
     */
 | 
			
		||||
    function attemptFix(problem) {
 | 
			
		||||
        const fix = problem.fix;
 | 
			
		||||
        const start = fix.range[0];
 | 
			
		||||
        const end = fix.range[1];
 | 
			
		||||
 | 
			
		||||
        // Remain it as a problem if it's overlapped or it's a negative range
 | 
			
		||||
        if (lastPos >= start || start > end) {
 | 
			
		||||
            remainingMessages.push(problem);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Remove BOM.
 | 
			
		||||
        if ((start < 0 && end >= 0) || (start === 0 && fix.text.startsWith(BOM))) {
 | 
			
		||||
            output = "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Make output to this fix.
 | 
			
		||||
        output += text.slice(Math.max(0, lastPos), Math.max(0, start));
 | 
			
		||||
        output += fix.text;
 | 
			
		||||
        lastPos = end;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    messages.forEach(problem => {
 | 
			
		||||
        if (Object.prototype.hasOwnProperty.call(problem, "fix")) {
 | 
			
		||||
            fixes.push(problem);
 | 
			
		||||
        } else {
 | 
			
		||||
            remainingMessages.push(problem);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (fixes.length) {
 | 
			
		||||
        debug("Found fixes to apply");
 | 
			
		||||
        let fixesWereApplied = false;
 | 
			
		||||
 | 
			
		||||
        for (const problem of fixes.sort(compareMessagesByFixRange)) {
 | 
			
		||||
            if (typeof shouldFix !== "function" || shouldFix(problem)) {
 | 
			
		||||
                attemptFix(problem);
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * The only time attemptFix will fail is if a previous fix was
 | 
			
		||||
                 * applied which conflicts with it.  So we can mark this as true.
 | 
			
		||||
                 */
 | 
			
		||||
                fixesWereApplied = true;
 | 
			
		||||
            } else {
 | 
			
		||||
                remainingMessages.push(problem);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        output += text.slice(Math.max(0, lastPos));
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            fixed: fixesWereApplied,
 | 
			
		||||
            messages: remainingMessages.sort(compareMessagesByLocation),
 | 
			
		||||
            output
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    debug("No fixes to apply");
 | 
			
		||||
    return {
 | 
			
		||||
        fixed: false,
 | 
			
		||||
        messages,
 | 
			
		||||
        output: bom + text
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = SourceCodeFixer;
 | 
			
		||||
							
								
								
									
										161
									
								
								node_modules/eslint/lib/linter/timing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								node_modules/eslint/lib/linter/timing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Tracks performance of individual rules.
 | 
			
		||||
 * @author Brandon Mills
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/* c8 ignore next */
 | 
			
		||||
/**
 | 
			
		||||
 * Align the string to left
 | 
			
		||||
 * @param {string} str string to evaluate
 | 
			
		||||
 * @param {int} len length of the string
 | 
			
		||||
 * @param {string} ch delimiter character
 | 
			
		||||
 * @returns {string} modified string
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function alignLeft(str, len, ch) {
 | 
			
		||||
    return str + new Array(len - str.length + 1).join(ch || " ");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* c8 ignore next */
 | 
			
		||||
/**
 | 
			
		||||
 * Align the string to right
 | 
			
		||||
 * @param {string} str string to evaluate
 | 
			
		||||
 * @param {int} len length of the string
 | 
			
		||||
 * @param {string} ch delimiter character
 | 
			
		||||
 * @returns {string} modified string
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function alignRight(str, len, ch) {
 | 
			
		||||
    return new Array(len - str.length + 1).join(ch || " ") + str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Module definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const enabled = !!process.env.TIMING;
 | 
			
		||||
 | 
			
		||||
const HEADERS = ["Rule", "Time (ms)", "Relative"];
 | 
			
		||||
const ALIGN = [alignLeft, alignRight, alignRight];
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Decide how many rules to show in the output list.
 | 
			
		||||
 * @returns {number} the number of rules to show
 | 
			
		||||
 */
 | 
			
		||||
function getListSize() {
 | 
			
		||||
    const MINIMUM_SIZE = 10;
 | 
			
		||||
 | 
			
		||||
    if (typeof process.env.TIMING !== "string") {
 | 
			
		||||
        return MINIMUM_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (process.env.TIMING.toLowerCase() === "all") {
 | 
			
		||||
        return Number.POSITIVE_INFINITY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const TIMING_ENV_VAR_AS_INTEGER = Number.parseInt(process.env.TIMING, 10);
 | 
			
		||||
 | 
			
		||||
    return TIMING_ENV_VAR_AS_INTEGER > 10 ? TIMING_ENV_VAR_AS_INTEGER : MINIMUM_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* c8 ignore next */
 | 
			
		||||
/**
 | 
			
		||||
 * display the data
 | 
			
		||||
 * @param {Object} data Data object to be displayed
 | 
			
		||||
 * @returns {void} prints modified string with console.log
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
function display(data) {
 | 
			
		||||
    let total = 0;
 | 
			
		||||
    const rows = Object.keys(data)
 | 
			
		||||
        .map(key => {
 | 
			
		||||
            const time = data[key];
 | 
			
		||||
 | 
			
		||||
            total += time;
 | 
			
		||||
            return [key, time];
 | 
			
		||||
        })
 | 
			
		||||
        .sort((a, b) => b[1] - a[1])
 | 
			
		||||
        .slice(0, getListSize());
 | 
			
		||||
 | 
			
		||||
    rows.forEach(row => {
 | 
			
		||||
        row.push(`${(row[1] * 100 / total).toFixed(1)}%`);
 | 
			
		||||
        row[1] = row[1].toFixed(3);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    rows.unshift(HEADERS);
 | 
			
		||||
 | 
			
		||||
    const widths = [];
 | 
			
		||||
 | 
			
		||||
    rows.forEach(row => {
 | 
			
		||||
        const len = row.length;
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < len; i++) {
 | 
			
		||||
            const n = row[i].length;
 | 
			
		||||
 | 
			
		||||
            if (!widths[i] || n > widths[i]) {
 | 
			
		||||
                widths[i] = n;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const table = rows.map(row => (
 | 
			
		||||
        row
 | 
			
		||||
            .map((cell, index) => ALIGN[index](cell, widths[index]))
 | 
			
		||||
            .join(" | ")
 | 
			
		||||
    ));
 | 
			
		||||
 | 
			
		||||
    table.splice(1, 0, widths.map((width, index) => {
 | 
			
		||||
        const extraAlignment = index !== 0 && index !== widths.length - 1 ? 2 : 1;
 | 
			
		||||
 | 
			
		||||
        return ALIGN[index](":", width + extraAlignment, "-");
 | 
			
		||||
    }).join("|"));
 | 
			
		||||
 | 
			
		||||
    console.log(table.join("\n")); // eslint-disable-line no-console -- Debugging function
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* c8 ignore next */
 | 
			
		||||
module.exports = (function() {
 | 
			
		||||
 | 
			
		||||
    const data = Object.create(null);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Time the run
 | 
			
		||||
     * @param {any} key key from the data object
 | 
			
		||||
     * @param {Function} fn function to be called
 | 
			
		||||
     * @returns {Function} function to be executed
 | 
			
		||||
     * @private
 | 
			
		||||
     */
 | 
			
		||||
    function time(key, fn) {
 | 
			
		||||
        if (typeof data[key] === "undefined") {
 | 
			
		||||
            data[key] = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return function(...args) {
 | 
			
		||||
            let t = process.hrtime();
 | 
			
		||||
            const result = fn(...args);
 | 
			
		||||
 | 
			
		||||
            t = process.hrtime(t);
 | 
			
		||||
            data[key] += t[0] * 1e3 + t[1] / 1e6;
 | 
			
		||||
            return result;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (enabled) {
 | 
			
		||||
        process.on("exit", () => {
 | 
			
		||||
            display(data);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        time,
 | 
			
		||||
        enabled,
 | 
			
		||||
        getListSize
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}());
 | 
			
		||||
							
								
								
									
										390
									
								
								node_modules/eslint/lib/options.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										390
									
								
								node_modules/eslint/lib/options.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,390 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Options configuration for optionator.
 | 
			
		||||
 * @author George Zahariev
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const optionator = require("optionator");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The options object parsed by Optionator.
 | 
			
		||||
 * @typedef {Object} ParsedCLIOptions
 | 
			
		||||
 * @property {boolean} cache Only check changed files
 | 
			
		||||
 * @property {string} cacheFile Path to the cache file. Deprecated: use --cache-location
 | 
			
		||||
 * @property {string} [cacheLocation] Path to the cache file or directory
 | 
			
		||||
 * @property {"metadata" | "content"} cacheStrategy Strategy to use for detecting changed files in the cache
 | 
			
		||||
 * @property {boolean} [color] Force enabling/disabling of color
 | 
			
		||||
 * @property {string} [config] Use this configuration, overriding .eslintrc.* config options if present
 | 
			
		||||
 * @property {boolean} debug Output debugging information
 | 
			
		||||
 * @property {string[]} [env] Specify environments
 | 
			
		||||
 * @property {boolean} envInfo Output execution environment information
 | 
			
		||||
 * @property {boolean} errorOnUnmatchedPattern Prevent errors when pattern is unmatched
 | 
			
		||||
 * @property {boolean} eslintrc Disable use of configuration from .eslintrc.*
 | 
			
		||||
 * @property {string[]} [ext] Specify JavaScript file extensions
 | 
			
		||||
 * @property {boolean} fix Automatically fix problems
 | 
			
		||||
 * @property {boolean} fixDryRun Automatically fix problems without saving the changes to the file system
 | 
			
		||||
 * @property {("directive" | "problem" | "suggestion" | "layout")[]} [fixType] Specify the types of fixes to apply (directive, problem, suggestion, layout)
 | 
			
		||||
 * @property {string} format Use a specific output format
 | 
			
		||||
 * @property {string[]} [global] Define global variables
 | 
			
		||||
 * @property {boolean} [help] Show help
 | 
			
		||||
 * @property {boolean} ignore Disable use of ignore files and patterns
 | 
			
		||||
 * @property {string} [ignorePath] Specify path of ignore file
 | 
			
		||||
 * @property {string[]} [ignorePattern] Pattern of files to ignore (in addition to those in .eslintignore)
 | 
			
		||||
 * @property {boolean} init Run config initialization wizard
 | 
			
		||||
 * @property {boolean} inlineConfig Prevent comments from changing config or rules
 | 
			
		||||
 * @property {number} maxWarnings Number of warnings to trigger nonzero exit code
 | 
			
		||||
 * @property {string} [outputFile] Specify file to write report to
 | 
			
		||||
 * @property {string} [parser] Specify the parser to be used
 | 
			
		||||
 * @property {Object} [parserOptions] Specify parser options
 | 
			
		||||
 * @property {string[]} [plugin] Specify plugins
 | 
			
		||||
 * @property {string} [printConfig] Print the configuration for the given file
 | 
			
		||||
 * @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable and eslint-enable directives
 | 
			
		||||
 * @property {string} [resolvePluginsRelativeTo] A folder where plugins should be resolved from, CWD by default
 | 
			
		||||
 * @property {Object} [rule] Specify rules
 | 
			
		||||
 * @property {string[]} [rulesdir] Load additional rules from this directory. Deprecated: Use rules from plugins
 | 
			
		||||
 * @property {boolean} stdin Lint code provided on <STDIN>
 | 
			
		||||
 * @property {string} [stdinFilename] Specify filename to process STDIN as
 | 
			
		||||
 * @property {boolean} quiet Report errors only
 | 
			
		||||
 * @property {boolean} [version] Output the version number
 | 
			
		||||
 * @property {boolean} warnIgnored Show warnings when the file list includes ignored files
 | 
			
		||||
 * @property {string[]} _ Positional filenames or patterns
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Initialization and Public Interface
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
// exports "parse(args)", "generateHelp()", and "generateHelpForOption(optionName)"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates the CLI options for ESLint.
 | 
			
		||||
 * @param {boolean} usingFlatConfig Indicates if flat config is being used.
 | 
			
		||||
 * @returns {Object} The optionator instance.
 | 
			
		||||
 */
 | 
			
		||||
module.exports = function(usingFlatConfig) {
 | 
			
		||||
 | 
			
		||||
    let lookupFlag;
 | 
			
		||||
 | 
			
		||||
    if (usingFlatConfig) {
 | 
			
		||||
        lookupFlag = {
 | 
			
		||||
            option: "config-lookup",
 | 
			
		||||
            type: "Boolean",
 | 
			
		||||
            default: "true",
 | 
			
		||||
            description: "Disable look up for eslint.config.js"
 | 
			
		||||
        };
 | 
			
		||||
    } else {
 | 
			
		||||
        lookupFlag = {
 | 
			
		||||
            option: "eslintrc",
 | 
			
		||||
            type: "Boolean",
 | 
			
		||||
            default: "true",
 | 
			
		||||
            description: "Disable use of configuration from .eslintrc.*"
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let envFlag;
 | 
			
		||||
 | 
			
		||||
    if (!usingFlatConfig) {
 | 
			
		||||
        envFlag = {
 | 
			
		||||
            option: "env",
 | 
			
		||||
            type: "[String]",
 | 
			
		||||
            description: "Specify environments"
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let extFlag;
 | 
			
		||||
 | 
			
		||||
    if (!usingFlatConfig) {
 | 
			
		||||
        extFlag = {
 | 
			
		||||
            option: "ext",
 | 
			
		||||
            type: "[String]",
 | 
			
		||||
            description: "Specify JavaScript file extensions"
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let resolvePluginsFlag;
 | 
			
		||||
 | 
			
		||||
    if (!usingFlatConfig) {
 | 
			
		||||
        resolvePluginsFlag = {
 | 
			
		||||
            option: "resolve-plugins-relative-to",
 | 
			
		||||
            type: "path::String",
 | 
			
		||||
            description: "A folder where plugins should be resolved from, CWD by default"
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let rulesDirFlag;
 | 
			
		||||
 | 
			
		||||
    if (!usingFlatConfig) {
 | 
			
		||||
        rulesDirFlag = {
 | 
			
		||||
            option: "rulesdir",
 | 
			
		||||
            type: "[path::String]",
 | 
			
		||||
            description: "Load additional rules from this directory. Deprecated: Use rules from plugins"
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let ignorePathFlag;
 | 
			
		||||
 | 
			
		||||
    if (!usingFlatConfig) {
 | 
			
		||||
        ignorePathFlag = {
 | 
			
		||||
            option: "ignore-path",
 | 
			
		||||
            type: "path::String",
 | 
			
		||||
            description: "Specify path of ignore file"
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let warnIgnoredFlag;
 | 
			
		||||
 | 
			
		||||
    if (usingFlatConfig) {
 | 
			
		||||
        warnIgnoredFlag = {
 | 
			
		||||
            option: "warn-ignored",
 | 
			
		||||
            type: "Boolean",
 | 
			
		||||
            default: "true",
 | 
			
		||||
            description: "Suppress warnings when the file list includes ignored files"
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return optionator({
 | 
			
		||||
        prepend: "eslint [options] file.js [file.js] [dir]",
 | 
			
		||||
        defaults: {
 | 
			
		||||
            concatRepeatedArrays: true,
 | 
			
		||||
            mergeRepeatedObjects: true
 | 
			
		||||
        },
 | 
			
		||||
        options: [
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Basic configuration"
 | 
			
		||||
            },
 | 
			
		||||
            lookupFlag,
 | 
			
		||||
            {
 | 
			
		||||
                option: "config",
 | 
			
		||||
                alias: "c",
 | 
			
		||||
                type: "path::String",
 | 
			
		||||
                description: usingFlatConfig
 | 
			
		||||
                    ? "Use this configuration instead of eslint.config.js"
 | 
			
		||||
                    : "Use this configuration, overriding .eslintrc.* config options if present"
 | 
			
		||||
            },
 | 
			
		||||
            envFlag,
 | 
			
		||||
            extFlag,
 | 
			
		||||
            {
 | 
			
		||||
                option: "global",
 | 
			
		||||
                type: "[String]",
 | 
			
		||||
                description: "Define global variables"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "parser",
 | 
			
		||||
                type: "String",
 | 
			
		||||
                description: "Specify the parser to be used"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "parser-options",
 | 
			
		||||
                type: "Object",
 | 
			
		||||
                description: "Specify parser options"
 | 
			
		||||
            },
 | 
			
		||||
            resolvePluginsFlag,
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Specify Rules and Plugins"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "plugin",
 | 
			
		||||
                type: "[String]",
 | 
			
		||||
                description: "Specify plugins"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "rule",
 | 
			
		||||
                type: "Object",
 | 
			
		||||
                description: "Specify rules"
 | 
			
		||||
            },
 | 
			
		||||
            rulesDirFlag,
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Fix Problems"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "fix",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: false,
 | 
			
		||||
                description: "Automatically fix problems"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "fix-dry-run",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: false,
 | 
			
		||||
                description: "Automatically fix problems without saving the changes to the file system"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "fix-type",
 | 
			
		||||
                type: "Array",
 | 
			
		||||
                description: "Specify the types of fixes to apply (directive, problem, suggestion, layout)"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Ignore Files"
 | 
			
		||||
            },
 | 
			
		||||
            ignorePathFlag,
 | 
			
		||||
            {
 | 
			
		||||
                option: "ignore",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "true",
 | 
			
		||||
                description: "Disable use of ignore files and patterns"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "ignore-pattern",
 | 
			
		||||
                type: "[String]",
 | 
			
		||||
                description: "Pattern of files to ignore (in addition to those in .eslintignore)",
 | 
			
		||||
                concatRepeatedArrays: [true, {
 | 
			
		||||
                    oneValuePerFlag: true
 | 
			
		||||
                }]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Use stdin"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "stdin",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "false",
 | 
			
		||||
                description: "Lint code provided on <STDIN>"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "stdin-filename",
 | 
			
		||||
                type: "String",
 | 
			
		||||
                description: "Specify filename to process STDIN as"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Handle Warnings"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "quiet",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "false",
 | 
			
		||||
                description: "Report errors only"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "max-warnings",
 | 
			
		||||
                type: "Int",
 | 
			
		||||
                default: "-1",
 | 
			
		||||
                description: "Number of warnings to trigger nonzero exit code"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Output"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "output-file",
 | 
			
		||||
                alias: "o",
 | 
			
		||||
                type: "path::String",
 | 
			
		||||
                description: "Specify file to write report to"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "format",
 | 
			
		||||
                alias: "f",
 | 
			
		||||
                type: "String",
 | 
			
		||||
                default: "stylish",
 | 
			
		||||
                description: "Use a specific output format"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "color",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                alias: "no-color",
 | 
			
		||||
                description: "Force enabling/disabling of color"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Inline configuration comments"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "inline-config",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "true",
 | 
			
		||||
                description: "Prevent comments from changing config or rules"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "report-unused-disable-directives",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: void 0,
 | 
			
		||||
                description: "Adds reported errors for unused eslint-disable and eslint-enable directives"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Caching"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "cache",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "false",
 | 
			
		||||
                description: "Only check changed files"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "cache-file",
 | 
			
		||||
                type: "path::String",
 | 
			
		||||
                default: ".eslintcache",
 | 
			
		||||
                description: "Path to the cache file. Deprecated: use --cache-location"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "cache-location",
 | 
			
		||||
                type: "path::String",
 | 
			
		||||
                description: "Path to the cache file or directory"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "cache-strategy",
 | 
			
		||||
                dependsOn: ["cache"],
 | 
			
		||||
                type: "String",
 | 
			
		||||
                default: "metadata",
 | 
			
		||||
                enum: ["metadata", "content"],
 | 
			
		||||
                description: "Strategy to use for detecting changed files in the cache"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                heading: "Miscellaneous"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "init",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "false",
 | 
			
		||||
                description: "Run config initialization wizard"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "env-info",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "false",
 | 
			
		||||
                description: "Output execution environment information"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "error-on-unmatched-pattern",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "true",
 | 
			
		||||
                description: "Prevent errors when pattern is unmatched"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "exit-on-fatal-error",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: "false",
 | 
			
		||||
                description: "Exit with exit code 2 in case of fatal error"
 | 
			
		||||
            },
 | 
			
		||||
            warnIgnoredFlag,
 | 
			
		||||
            {
 | 
			
		||||
                option: "debug",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                default: false,
 | 
			
		||||
                description: "Output debugging information"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "help",
 | 
			
		||||
                alias: "h",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                description: "Show help"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "version",
 | 
			
		||||
                alias: "v",
 | 
			
		||||
                type: "Boolean",
 | 
			
		||||
                description: "Output the version number"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                option: "print-config",
 | 
			
		||||
                type: "path::String",
 | 
			
		||||
                description: "Print the configuration for the given file"
 | 
			
		||||
            }
 | 
			
		||||
        ].filter(value => !!value)
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1122
									
								
								node_modules/eslint/lib/rule-tester/flat-rule-tester.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1122
									
								
								node_modules/eslint/lib/rule-tester/flat-rule-tester.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5
									
								
								node_modules/eslint/lib/rule-tester/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								node_modules/eslint/lib/rule-tester/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    RuleTester: require("./rule-tester")
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1206
									
								
								node_modules/eslint/lib/rule-tester/rule-tester.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1206
									
								
								node_modules/eslint/lib/rule-tester/rule-tester.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										346
									
								
								node_modules/eslint/lib/rules/accessor-pairs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								node_modules/eslint/lib/rules/accessor-pairs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,346 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce getter and setter pairs in objects and classes.
 | 
			
		||||
 * @author Gyandeep Singh
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Property name if it can be computed statically, otherwise the list of the tokens of the key node.
 | 
			
		||||
 * @typedef {string|Token[]} Key
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Accessor nodes with the same key.
 | 
			
		||||
 * @typedef {Object} AccessorData
 | 
			
		||||
 * @property {Key} key Accessor's key
 | 
			
		||||
 * @property {ASTNode[]} getters List of getter nodes.
 | 
			
		||||
 * @property {ASTNode[]} setters List of setter nodes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not the given lists represent the equal tokens in the same order.
 | 
			
		||||
 * Tokens are compared by their properties, not by instance.
 | 
			
		||||
 * @param {Token[]} left First list of tokens.
 | 
			
		||||
 * @param {Token[]} right Second list of tokens.
 | 
			
		||||
 * @returns {boolean} `true` if the lists have same tokens.
 | 
			
		||||
 */
 | 
			
		||||
function areEqualTokenLists(left, right) {
 | 
			
		||||
    if (left.length !== right.length) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < left.length; i++) {
 | 
			
		||||
        const leftToken = left[i],
 | 
			
		||||
            rightToken = right[i];
 | 
			
		||||
 | 
			
		||||
        if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not the given keys are equal.
 | 
			
		||||
 * @param {Key} left First key.
 | 
			
		||||
 * @param {Key} right Second key.
 | 
			
		||||
 * @returns {boolean} `true` if the keys are equal.
 | 
			
		||||
 */
 | 
			
		||||
function areEqualKeys(left, right) {
 | 
			
		||||
    if (typeof left === "string" && typeof right === "string") {
 | 
			
		||||
 | 
			
		||||
        // Statically computed names.
 | 
			
		||||
        return left === right;
 | 
			
		||||
    }
 | 
			
		||||
    if (Array.isArray(left) && Array.isArray(right)) {
 | 
			
		||||
 | 
			
		||||
        // Token lists.
 | 
			
		||||
        return areEqualTokenLists(left, right);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given node is of an accessor kind ('get' or 'set').
 | 
			
		||||
 * @param {ASTNode} node A node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is of an accessor kind.
 | 
			
		||||
 */
 | 
			
		||||
function isAccessorKind(node) {
 | 
			
		||||
    return node.kind === "get" || node.kind === "set";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given node is an argument of a specified method call.
 | 
			
		||||
 * @param {ASTNode} node A node to check.
 | 
			
		||||
 * @param {number} index An expected index of the node in arguments.
 | 
			
		||||
 * @param {string} object An expected name of the object of the method.
 | 
			
		||||
 * @param {string} property An expected name of the method.
 | 
			
		||||
 * @returns {boolean} `true` if the node is an argument of the specified method call.
 | 
			
		||||
 */
 | 
			
		||||
function isArgumentOfMethodCall(node, index, object, property) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        parent.type === "CallExpression" &&
 | 
			
		||||
        astUtils.isSpecificMemberAccess(parent.callee, object, property) &&
 | 
			
		||||
        parent.arguments[index] === node
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given node is a property descriptor.
 | 
			
		||||
 * @param {ASTNode} node A node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a property descriptor.
 | 
			
		||||
 */
 | 
			
		||||
function isPropertyDescriptor(node) {
 | 
			
		||||
 | 
			
		||||
    // Object.defineProperty(obj, "foo", {set: ...})
 | 
			
		||||
    if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") ||
 | 
			
		||||
        isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty")
 | 
			
		||||
    ) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Object.defineProperties(obj, {foo: {set: ...}})
 | 
			
		||||
     * Object.create(proto, {foo: {set: ...}})
 | 
			
		||||
     */
 | 
			
		||||
    const grandparent = node.parent.parent;
 | 
			
		||||
 | 
			
		||||
    return grandparent.type === "ObjectExpression" && (
 | 
			
		||||
        isArgumentOfMethodCall(grandparent, 1, "Object", "create") ||
 | 
			
		||||
        isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties")
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce getter and setter pairs in objects and classes",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/accessor-pairs"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [{
 | 
			
		||||
            type: "object",
 | 
			
		||||
            properties: {
 | 
			
		||||
                getWithoutSet: {
 | 
			
		||||
                    type: "boolean",
 | 
			
		||||
                    default: false
 | 
			
		||||
                },
 | 
			
		||||
                setWithoutGet: {
 | 
			
		||||
                    type: "boolean",
 | 
			
		||||
                    default: true
 | 
			
		||||
                },
 | 
			
		||||
                enforceForClassMembers: {
 | 
			
		||||
                    type: "boolean",
 | 
			
		||||
                    default: true
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            additionalProperties: false
 | 
			
		||||
        }],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingGetterInPropertyDescriptor: "Getter is not present in property descriptor.",
 | 
			
		||||
            missingSetterInPropertyDescriptor: "Setter is not present in property descriptor.",
 | 
			
		||||
            missingGetterInObjectLiteral: "Getter is not present for {{ name }}.",
 | 
			
		||||
            missingSetterInObjectLiteral: "Setter is not present for {{ name }}.",
 | 
			
		||||
            missingGetterInClass: "Getter is not present for class {{ name }}.",
 | 
			
		||||
            missingSetterInClass: "Setter is not present for class {{ name }}."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const config = context.options[0] || {};
 | 
			
		||||
        const checkGetWithoutSet = config.getWithoutSet === true;
 | 
			
		||||
        const checkSetWithoutGet = config.setWithoutGet !== false;
 | 
			
		||||
        const enforceForClassMembers = config.enforceForClassMembers !== false;
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports the given node.
 | 
			
		||||
         * @param {ASTNode} node The node to report.
 | 
			
		||||
         * @param {string} messageKind "missingGetter" or "missingSetter".
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function report(node, messageKind) {
 | 
			
		||||
            if (node.type === "Property") {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    messageId: `${messageKind}InObjectLiteral`,
 | 
			
		||||
                    loc: astUtils.getFunctionHeadLoc(node.value, sourceCode),
 | 
			
		||||
                    data: { name: astUtils.getFunctionNameWithKind(node.value) }
 | 
			
		||||
                });
 | 
			
		||||
            } else if (node.type === "MethodDefinition") {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    messageId: `${messageKind}InClass`,
 | 
			
		||||
                    loc: astUtils.getFunctionHeadLoc(node.value, sourceCode),
 | 
			
		||||
                    data: { name: astUtils.getFunctionNameWithKind(node.value) }
 | 
			
		||||
                });
 | 
			
		||||
            } else {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    messageId: `${messageKind}InPropertyDescriptor`
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports each of the nodes in the given list using the same messageId.
 | 
			
		||||
         * @param {ASTNode[]} nodes Nodes to report.
 | 
			
		||||
         * @param {string} messageKind "missingGetter" or "missingSetter".
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function reportList(nodes, messageKind) {
 | 
			
		||||
            for (const node of nodes) {
 | 
			
		||||
                report(node, messageKind);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks accessor pairs in the given list of nodes.
 | 
			
		||||
         * @param {ASTNode[]} nodes The list to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function checkList(nodes) {
 | 
			
		||||
            const accessors = [];
 | 
			
		||||
            let found = false;
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < nodes.length; i++) {
 | 
			
		||||
                const node = nodes[i];
 | 
			
		||||
 | 
			
		||||
                if (isAccessorKind(node)) {
 | 
			
		||||
 | 
			
		||||
                    // Creates a new `AccessorData` object for the given getter or setter node.
 | 
			
		||||
                    const name = astUtils.getStaticPropertyName(node);
 | 
			
		||||
                    const key = (name !== null) ? name : sourceCode.getTokens(node.key);
 | 
			
		||||
 | 
			
		||||
                    // Merges the given `AccessorData` object into the given accessors list.
 | 
			
		||||
                    for (let j = 0; j < accessors.length; j++) {
 | 
			
		||||
                        const accessor = accessors[j];
 | 
			
		||||
 | 
			
		||||
                        if (areEqualKeys(accessor.key, key)) {
 | 
			
		||||
                            accessor.getters.push(...node.kind === "get" ? [node] : []);
 | 
			
		||||
                            accessor.setters.push(...node.kind === "set" ? [node] : []);
 | 
			
		||||
                            found = true;
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!found) {
 | 
			
		||||
                        accessors.push({
 | 
			
		||||
                            key,
 | 
			
		||||
                            getters: node.kind === "get" ? [node] : [],
 | 
			
		||||
                            setters: node.kind === "set" ? [node] : []
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    found = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (const { getters, setters } of accessors) {
 | 
			
		||||
                if (checkSetWithoutGet && setters.length && !getters.length) {
 | 
			
		||||
                    reportList(setters, "missingGetter");
 | 
			
		||||
                }
 | 
			
		||||
                if (checkGetWithoutSet && getters.length && !setters.length) {
 | 
			
		||||
                    reportList(getters, "missingSetter");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks accessor pairs in an object literal.
 | 
			
		||||
         * @param {ASTNode} node `ObjectExpression` node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function checkObjectLiteral(node) {
 | 
			
		||||
            checkList(node.properties.filter(p => p.type === "Property"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks accessor pairs in a property descriptor.
 | 
			
		||||
         * @param {ASTNode} node Property descriptor `ObjectExpression` node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function checkPropertyDescriptor(node) {
 | 
			
		||||
            const namesToCheck = new Set(node.properties
 | 
			
		||||
                .filter(p => p.type === "Property" && p.kind === "init" && !p.computed)
 | 
			
		||||
                .map(({ key }) => key.name));
 | 
			
		||||
 | 
			
		||||
            const hasGetter = namesToCheck.has("get");
 | 
			
		||||
            const hasSetter = namesToCheck.has("set");
 | 
			
		||||
 | 
			
		||||
            if (checkSetWithoutGet && hasSetter && !hasGetter) {
 | 
			
		||||
                report(node, "missingGetter");
 | 
			
		||||
            }
 | 
			
		||||
            if (checkGetWithoutSet && hasGetter && !hasSetter) {
 | 
			
		||||
                report(node, "missingSetter");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks the given object expression as an object literal and as a possible property descriptor.
 | 
			
		||||
         * @param {ASTNode} node `ObjectExpression` node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function checkObjectExpression(node) {
 | 
			
		||||
            checkObjectLiteral(node);
 | 
			
		||||
            if (isPropertyDescriptor(node)) {
 | 
			
		||||
                checkPropertyDescriptor(node);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks the given class body.
 | 
			
		||||
         * @param {ASTNode} node `ClassBody` node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function checkClassBody(node) {
 | 
			
		||||
            const methodDefinitions = node.body.filter(m => m.type === "MethodDefinition");
 | 
			
		||||
 | 
			
		||||
            checkList(methodDefinitions.filter(m => m.static));
 | 
			
		||||
            checkList(methodDefinitions.filter(m => !m.static));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const listeners = {};
 | 
			
		||||
 | 
			
		||||
        if (checkSetWithoutGet || checkGetWithoutSet) {
 | 
			
		||||
            listeners.ObjectExpression = checkObjectExpression;
 | 
			
		||||
            if (enforceForClassMembers) {
 | 
			
		||||
                listeners.ClassBody = checkClassBody;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return listeners;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										261
									
								
								node_modules/eslint/lib/rules/array-bracket-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								node_modules/eslint/lib/rules/array-bracket-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,261 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce linebreaks after open and before close array brackets
 | 
			
		||||
 * @author Jan Peer Stöcklmair <https://github.com/JPeer264>
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce linebreaks after opening and before closing array brackets",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/array-bracket-newline"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                oneOf: [
 | 
			
		||||
                    {
 | 
			
		||||
                        enum: ["always", "never", "consistent"]
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: "object",
 | 
			
		||||
                        properties: {
 | 
			
		||||
                            multiline: {
 | 
			
		||||
                                type: "boolean"
 | 
			
		||||
                            },
 | 
			
		||||
                            minItems: {
 | 
			
		||||
                                type: ["integer", "null"],
 | 
			
		||||
                                minimum: 0
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        additionalProperties: false
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedOpeningLinebreak: "There should be no linebreak after '['.",
 | 
			
		||||
            unexpectedClosingLinebreak: "There should be no linebreak before ']'.",
 | 
			
		||||
            missingOpeningLinebreak: "A linebreak is required after '['.",
 | 
			
		||||
            missingClosingLinebreak: "A linebreak is required before ']'."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Normalizes a given option value.
 | 
			
		||||
         * @param {string|Object|undefined} option An option value to parse.
 | 
			
		||||
         * @returns {{multiline: boolean, minItems: number}} Normalized option object.
 | 
			
		||||
         */
 | 
			
		||||
        function normalizeOptionValue(option) {
 | 
			
		||||
            let consistent = false;
 | 
			
		||||
            let multiline = false;
 | 
			
		||||
            let minItems = 0;
 | 
			
		||||
 | 
			
		||||
            if (option) {
 | 
			
		||||
                if (option === "consistent") {
 | 
			
		||||
                    consistent = true;
 | 
			
		||||
                    minItems = Number.POSITIVE_INFINITY;
 | 
			
		||||
                } else if (option === "always" || option.minItems === 0) {
 | 
			
		||||
                    minItems = 0;
 | 
			
		||||
                } else if (option === "never") {
 | 
			
		||||
                    minItems = Number.POSITIVE_INFINITY;
 | 
			
		||||
                } else {
 | 
			
		||||
                    multiline = Boolean(option.multiline);
 | 
			
		||||
                    minItems = option.minItems || Number.POSITIVE_INFINITY;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                consistent = false;
 | 
			
		||||
                multiline = true;
 | 
			
		||||
                minItems = Number.POSITIVE_INFINITY;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return { consistent, multiline, minItems };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Normalizes a given option value.
 | 
			
		||||
         * @param {string|Object|undefined} options An option value to parse.
 | 
			
		||||
         * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object.
 | 
			
		||||
         */
 | 
			
		||||
        function normalizeOptions(options) {
 | 
			
		||||
            const value = normalizeOptionValue(options);
 | 
			
		||||
 | 
			
		||||
            return { ArrayExpression: value, ArrayPattern: value };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there shouldn't be a linebreak after the first token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportNoBeginningLinebreak(node, token) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: token.loc,
 | 
			
		||||
                messageId: "unexpectedOpeningLinebreak",
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    const nextToken = sourceCode.getTokenAfter(token, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
                    if (astUtils.isCommentToken(nextToken)) {
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return fixer.removeRange([token.range[1], nextToken.range[0]]);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there shouldn't be a linebreak before the last token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportNoEndingLinebreak(node, token) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: token.loc,
 | 
			
		||||
                messageId: "unexpectedClosingLinebreak",
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    const previousToken = sourceCode.getTokenBefore(token, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
                    if (astUtils.isCommentToken(previousToken)) {
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return fixer.removeRange([previousToken.range[1], token.range[0]]);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there should be a linebreak after the first token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportRequiredBeginningLinebreak(node, token) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: token.loc,
 | 
			
		||||
                messageId: "missingOpeningLinebreak",
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.insertTextAfter(token, "\n");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there should be a linebreak before the last token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportRequiredEndingLinebreak(node, token) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: token.loc,
 | 
			
		||||
                messageId: "missingClosingLinebreak",
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.insertTextBefore(token, "\n");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports a given node if it violated this rule.
 | 
			
		||||
         * @param {ASTNode} node A node to check. This is an ArrayExpression node or an ArrayPattern node.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function check(node) {
 | 
			
		||||
            const elements = node.elements;
 | 
			
		||||
            const normalizedOptions = normalizeOptions(context.options[0]);
 | 
			
		||||
            const options = normalizedOptions[node.type];
 | 
			
		||||
            const openBracket = sourceCode.getFirstToken(node);
 | 
			
		||||
            const closeBracket = sourceCode.getLastToken(node);
 | 
			
		||||
            const firstIncComment = sourceCode.getTokenAfter(openBracket, { includeComments: true });
 | 
			
		||||
            const lastIncComment = sourceCode.getTokenBefore(closeBracket, { includeComments: true });
 | 
			
		||||
            const first = sourceCode.getTokenAfter(openBracket);
 | 
			
		||||
            const last = sourceCode.getTokenBefore(closeBracket);
 | 
			
		||||
 | 
			
		||||
            const needsLinebreaks = (
 | 
			
		||||
                elements.length >= options.minItems ||
 | 
			
		||||
                (
 | 
			
		||||
                    options.multiline &&
 | 
			
		||||
                    elements.length > 0 &&
 | 
			
		||||
                    firstIncComment.loc.start.line !== lastIncComment.loc.end.line
 | 
			
		||||
                ) ||
 | 
			
		||||
                (
 | 
			
		||||
                    elements.length === 0 &&
 | 
			
		||||
                    firstIncComment.type === "Block" &&
 | 
			
		||||
                    firstIncComment.loc.start.line !== lastIncComment.loc.end.line &&
 | 
			
		||||
                    firstIncComment === lastIncComment
 | 
			
		||||
                ) ||
 | 
			
		||||
                (
 | 
			
		||||
                    options.consistent &&
 | 
			
		||||
                    openBracket.loc.end.line !== first.loc.start.line
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Use tokens or comments to check multiline or not.
 | 
			
		||||
             * But use only tokens to check whether linebreaks are needed.
 | 
			
		||||
             * This allows:
 | 
			
		||||
             *     var arr = [ // eslint-disable-line foo
 | 
			
		||||
             *         'a'
 | 
			
		||||
             *     ]
 | 
			
		||||
             */
 | 
			
		||||
 | 
			
		||||
            if (needsLinebreaks) {
 | 
			
		||||
                if (astUtils.isTokenOnSameLine(openBracket, first)) {
 | 
			
		||||
                    reportRequiredBeginningLinebreak(node, openBracket);
 | 
			
		||||
                }
 | 
			
		||||
                if (astUtils.isTokenOnSameLine(last, closeBracket)) {
 | 
			
		||||
                    reportRequiredEndingLinebreak(node, closeBracket);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (!astUtils.isTokenOnSameLine(openBracket, first)) {
 | 
			
		||||
                    reportNoBeginningLinebreak(node, openBracket);
 | 
			
		||||
                }
 | 
			
		||||
                if (!astUtils.isTokenOnSameLine(last, closeBracket)) {
 | 
			
		||||
                    reportNoEndingLinebreak(node, closeBracket);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            ArrayPattern: check,
 | 
			
		||||
            ArrayExpression: check
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										244
									
								
								node_modules/eslint/lib/rules/array-bracket-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								node_modules/eslint/lib/rules/array-bracket-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,244 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Disallows or enforces spaces inside of array brackets.
 | 
			
		||||
 * @author Jamund Ferguson
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent spacing inside array brackets",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/array-bracket-spacing"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["always", "never"]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    singleValue: {
 | 
			
		||||
                        type: "boolean"
 | 
			
		||||
                    },
 | 
			
		||||
                    objectsInArrays: {
 | 
			
		||||
                        type: "boolean"
 | 
			
		||||
                    },
 | 
			
		||||
                    arraysInArrays: {
 | 
			
		||||
                        type: "boolean"
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.",
 | 
			
		||||
            unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.",
 | 
			
		||||
            missingSpaceAfter: "A space is required after '{{tokenValue}}'.",
 | 
			
		||||
            missingSpaceBefore: "A space is required before '{{tokenValue}}'."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const spaced = context.options[0] === "always",
 | 
			
		||||
            sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether an option is set, relative to the spacing option.
 | 
			
		||||
         * If spaced is "always", then check whether option is set to false.
 | 
			
		||||
         * If spaced is "never", then check whether option is set to true.
 | 
			
		||||
         * @param {Object} option The option to exclude.
 | 
			
		||||
         * @returns {boolean} Whether or not the property is excluded.
 | 
			
		||||
         */
 | 
			
		||||
        function isOptionSet(option) {
 | 
			
		||||
            return context.options[1] ? context.options[1][option] === !spaced : false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const options = {
 | 
			
		||||
            spaced,
 | 
			
		||||
            singleElementException: isOptionSet("singleValue"),
 | 
			
		||||
            objectsInArraysException: isOptionSet("objectsInArrays"),
 | 
			
		||||
            arraysInArraysException: isOptionSet("arraysInArrays")
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there shouldn't be a space after the first token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportNoBeginningSpace(node, token) {
 | 
			
		||||
            const nextToken = sourceCode.getTokenAfter(token);
 | 
			
		||||
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: { start: token.loc.end, end: nextToken.loc.start },
 | 
			
		||||
                messageId: "unexpectedSpaceAfter",
 | 
			
		||||
                data: {
 | 
			
		||||
                    tokenValue: token.value
 | 
			
		||||
                },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.removeRange([token.range[1], nextToken.range[0]]);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there shouldn't be a space before the last token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportNoEndingSpace(node, token) {
 | 
			
		||||
            const previousToken = sourceCode.getTokenBefore(token);
 | 
			
		||||
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: { start: previousToken.loc.end, end: token.loc.start },
 | 
			
		||||
                messageId: "unexpectedSpaceBefore",
 | 
			
		||||
                data: {
 | 
			
		||||
                    tokenValue: token.value
 | 
			
		||||
                },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.removeRange([previousToken.range[1], token.range[0]]);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there should be a space after the first token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportRequiredBeginningSpace(node, token) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: token.loc,
 | 
			
		||||
                messageId: "missingSpaceAfter",
 | 
			
		||||
                data: {
 | 
			
		||||
                    tokenValue: token.value
 | 
			
		||||
                },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.insertTextAfter(token, " ");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there should be a space before the last token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportRequiredEndingSpace(node, token) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: token.loc,
 | 
			
		||||
                messageId: "missingSpaceBefore",
 | 
			
		||||
                data: {
 | 
			
		||||
                    tokenValue: token.value
 | 
			
		||||
                },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.insertTextBefore(token, " ");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines if a node is an object type
 | 
			
		||||
         * @param {ASTNode} node The node to check.
 | 
			
		||||
         * @returns {boolean} Whether or not the node is an object type.
 | 
			
		||||
         */
 | 
			
		||||
        function isObjectType(node) {
 | 
			
		||||
            return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines if a node is an array type
 | 
			
		||||
         * @param {ASTNode} node The node to check.
 | 
			
		||||
         * @returns {boolean} Whether or not the node is an array type.
 | 
			
		||||
         */
 | 
			
		||||
        function isArrayType(node) {
 | 
			
		||||
            return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Validates the spacing around array brackets
 | 
			
		||||
         * @param {ASTNode} node The node we're checking for spacing
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function validateArraySpacing(node) {
 | 
			
		||||
            if (options.spaced && node.elements.length === 0) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const first = sourceCode.getFirstToken(node),
 | 
			
		||||
                second = sourceCode.getFirstToken(node, 1),
 | 
			
		||||
                last = node.typeAnnotation
 | 
			
		||||
                    ? sourceCode.getTokenBefore(node.typeAnnotation)
 | 
			
		||||
                    : sourceCode.getLastToken(node),
 | 
			
		||||
                penultimate = sourceCode.getTokenBefore(last),
 | 
			
		||||
                firstElement = node.elements[0],
 | 
			
		||||
                lastElement = node.elements[node.elements.length - 1];
 | 
			
		||||
 | 
			
		||||
            const openingBracketMustBeSpaced =
 | 
			
		||||
                options.objectsInArraysException && isObjectType(firstElement) ||
 | 
			
		||||
                options.arraysInArraysException && isArrayType(firstElement) ||
 | 
			
		||||
                options.singleElementException && node.elements.length === 1
 | 
			
		||||
                    ? !options.spaced : options.spaced;
 | 
			
		||||
 | 
			
		||||
            const closingBracketMustBeSpaced =
 | 
			
		||||
                options.objectsInArraysException && isObjectType(lastElement) ||
 | 
			
		||||
                options.arraysInArraysException && isArrayType(lastElement) ||
 | 
			
		||||
                options.singleElementException && node.elements.length === 1
 | 
			
		||||
                    ? !options.spaced : options.spaced;
 | 
			
		||||
 | 
			
		||||
            if (astUtils.isTokenOnSameLine(first, second)) {
 | 
			
		||||
                if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) {
 | 
			
		||||
                    reportRequiredBeginningSpace(node, first);
 | 
			
		||||
                }
 | 
			
		||||
                if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) {
 | 
			
		||||
                    reportNoBeginningSpace(node, first);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (first !== penultimate && astUtils.isTokenOnSameLine(penultimate, last)) {
 | 
			
		||||
                if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) {
 | 
			
		||||
                    reportRequiredEndingSpace(node, last);
 | 
			
		||||
                }
 | 
			
		||||
                if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) {
 | 
			
		||||
                    reportNoEndingSpace(node, last);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            ArrayPattern: validateArraySpacing,
 | 
			
		||||
            ArrayExpression: validateArraySpacing
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										446
									
								
								node_modules/eslint/lib/rules/array-callback-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										446
									
								
								node_modules/eslint/lib/rules/array-callback-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,446 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce return statements in callbacks of array's methods
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
 | 
			
		||||
const TARGET_METHODS = /^(?:every|filter|find(?:Last)?(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort|toSorted)$/u;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks a given node is a member access which has the specified name's
 | 
			
		||||
 * property.
 | 
			
		||||
 * @param {ASTNode} node A node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a member access which has
 | 
			
		||||
 *      the specified name's property. The node may be a `(Chain|Member)Expression` node.
 | 
			
		||||
 */
 | 
			
		||||
function isTargetMethod(node) {
 | 
			
		||||
    return astUtils.isSpecificMemberAccess(node, null, TARGET_METHODS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks all segments in a set and returns true if any are reachable.
 | 
			
		||||
 * @param {Set<CodePathSegment>} segments The segments to check.
 | 
			
		||||
 * @returns {boolean} True if any segment is reachable; false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
function isAnySegmentReachable(segments) {
 | 
			
		||||
 | 
			
		||||
    for (const segment of segments) {
 | 
			
		||||
        if (segment.reachable) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a human-legible description of an array method
 | 
			
		||||
 * @param {string} arrayMethodName A method name to fully qualify
 | 
			
		||||
 * @returns {string} the method name prefixed with `Array.` if it is a class method,
 | 
			
		||||
 *      or else `Array.prototype.` if it is an instance method.
 | 
			
		||||
 */
 | 
			
		||||
function fullMethodName(arrayMethodName) {
 | 
			
		||||
    if (["from", "of", "isArray"].includes(arrayMethodName)) {
 | 
			
		||||
        return "Array.".concat(arrayMethodName);
 | 
			
		||||
    }
 | 
			
		||||
    return "Array.prototype.".concat(arrayMethodName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given node is a function expression which is the
 | 
			
		||||
 * callback of an array method, returning the method name.
 | 
			
		||||
 * @param {ASTNode} node A node to check. This is one of
 | 
			
		||||
 *      FunctionExpression or ArrowFunctionExpression.
 | 
			
		||||
 * @returns {string} The method name if the node is a callback method,
 | 
			
		||||
 *      null otherwise.
 | 
			
		||||
 */
 | 
			
		||||
function getArrayMethodName(node) {
 | 
			
		||||
    let currentNode = node;
 | 
			
		||||
 | 
			
		||||
    while (currentNode) {
 | 
			
		||||
        const parent = currentNode.parent;
 | 
			
		||||
 | 
			
		||||
        switch (parent.type) {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Looks up the destination. e.g.,
 | 
			
		||||
             * foo.every(nativeFoo || function foo() { ... });
 | 
			
		||||
             */
 | 
			
		||||
            case "LogicalExpression":
 | 
			
		||||
            case "ConditionalExpression":
 | 
			
		||||
            case "ChainExpression":
 | 
			
		||||
                currentNode = parent;
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * If the upper function is IIFE, checks the destination of the return value.
 | 
			
		||||
             * e.g.
 | 
			
		||||
             *   foo.every((function() {
 | 
			
		||||
             *     // setup...
 | 
			
		||||
             *     return function callback() { ... };
 | 
			
		||||
             *   })());
 | 
			
		||||
             */
 | 
			
		||||
            case "ReturnStatement": {
 | 
			
		||||
                const func = astUtils.getUpperFunction(parent);
 | 
			
		||||
 | 
			
		||||
                if (func === null || !astUtils.isCallee(func)) {
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
                currentNode = func.parent;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * e.g.
 | 
			
		||||
             *   Array.from([], function() {});
 | 
			
		||||
             *   list.every(function() {});
 | 
			
		||||
             */
 | 
			
		||||
            case "CallExpression":
 | 
			
		||||
                if (astUtils.isArrayFromMethod(parent.callee)) {
 | 
			
		||||
                    if (
 | 
			
		||||
                        parent.arguments.length >= 2 &&
 | 
			
		||||
                        parent.arguments[1] === currentNode
 | 
			
		||||
                    ) {
 | 
			
		||||
                        return "from";
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (isTargetMethod(parent.callee)) {
 | 
			
		||||
                    if (
 | 
			
		||||
                        parent.arguments.length >= 1 &&
 | 
			
		||||
                        parent.arguments[0] === currentNode
 | 
			
		||||
                    ) {
 | 
			
		||||
                        return astUtils.getStaticPropertyName(parent.callee);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            // Otherwise this node is not target.
 | 
			
		||||
            default:
 | 
			
		||||
                return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* c8 ignore next */
 | 
			
		||||
    return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if the given node is a void expression.
 | 
			
		||||
 * @param {ASTNode} node The node to check.
 | 
			
		||||
 * @returns {boolean} - `true` if the node is a void expression
 | 
			
		||||
 */
 | 
			
		||||
function isExpressionVoid(node) {
 | 
			
		||||
    return node.type === "UnaryExpression" && node.operator === "void";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fixes the linting error by prepending "void " to the given node
 | 
			
		||||
 * @param {Object} sourceCode context given by context.sourceCode
 | 
			
		||||
 * @param {ASTNode} node The node to fix.
 | 
			
		||||
 * @param {Object} fixer The fixer object provided by ESLint.
 | 
			
		||||
 * @returns {Array<Object>} - An array of fix objects to apply to the node.
 | 
			
		||||
 */
 | 
			
		||||
function voidPrependFixer(sourceCode, node, fixer) {
 | 
			
		||||
 | 
			
		||||
    const requiresParens =
 | 
			
		||||
 | 
			
		||||
        // prepending `void ` will fail if the node has a lower precedence than void
 | 
			
		||||
        astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression", operator: "void" }) &&
 | 
			
		||||
 | 
			
		||||
        // check if there are parentheses around the node to avoid redundant parentheses
 | 
			
		||||
        !astUtils.isParenthesised(sourceCode, node);
 | 
			
		||||
 | 
			
		||||
    // avoid parentheses issues
 | 
			
		||||
    const returnOrArrowToken = sourceCode.getTokenBefore(
 | 
			
		||||
        node,
 | 
			
		||||
        node.parent.type === "ArrowFunctionExpression"
 | 
			
		||||
            ? astUtils.isArrowToken
 | 
			
		||||
 | 
			
		||||
            // isReturnToken
 | 
			
		||||
            : token => token.type === "Keyword" && token.value === "return"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const firstToken = sourceCode.getTokenAfter(returnOrArrowToken);
 | 
			
		||||
 | 
			
		||||
    const prependSpace =
 | 
			
		||||
 | 
			
		||||
        // is return token, as => allows void to be adjacent
 | 
			
		||||
        returnOrArrowToken.value === "return" &&
 | 
			
		||||
 | 
			
		||||
        // If two tokens (return and "(") are adjacent
 | 
			
		||||
        returnOrArrowToken.range[1] === firstToken.range[0];
 | 
			
		||||
 | 
			
		||||
    return [
 | 
			
		||||
        fixer.insertTextBefore(firstToken, `${prependSpace ? " " : ""}void ${requiresParens ? "(" : ""}`),
 | 
			
		||||
        fixer.insertTextAfter(node, requiresParens ? ")" : "")
 | 
			
		||||
    ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fixes the linting error by `wrapping {}` around the given node's body.
 | 
			
		||||
 * @param {Object} sourceCode context given by context.sourceCode
 | 
			
		||||
 * @param {ASTNode} node The node to fix.
 | 
			
		||||
 * @param {Object} fixer The fixer object provided by ESLint.
 | 
			
		||||
 * @returns {Array<Object>} - An array of fix objects to apply to the node.
 | 
			
		||||
 */
 | 
			
		||||
function curlyWrapFixer(sourceCode, node, fixer) {
 | 
			
		||||
    const arrowToken = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);
 | 
			
		||||
    const firstToken = sourceCode.getTokenAfter(arrowToken);
 | 
			
		||||
    const lastToken = sourceCode.getLastToken(node);
 | 
			
		||||
 | 
			
		||||
    return [
 | 
			
		||||
        fixer.insertTextBefore(firstToken, "{"),
 | 
			
		||||
        fixer.insertTextAfter(lastToken, "}")
 | 
			
		||||
    ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "problem",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce `return` statements in callbacks of array methods",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/array-callback-return"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        // eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- false positive
 | 
			
		||||
        hasSuggestions: true,
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    allowImplicit: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    },
 | 
			
		||||
                    checkForEach: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    },
 | 
			
		||||
                    allowVoid: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            expectedAtEnd: "{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.",
 | 
			
		||||
            expectedInside: "{{arrayMethodName}}() expects a return value from {{name}}.",
 | 
			
		||||
            expectedReturnValue: "{{arrayMethodName}}() expects a return value from {{name}}.",
 | 
			
		||||
            expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}.",
 | 
			
		||||
            wrapBraces: "Wrap the expression in `{}`.",
 | 
			
		||||
            prependVoid: "Prepend `void` to the expression."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const options = context.options[0] || { allowImplicit: false, checkForEach: false, allowVoid: false };
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        let funcInfo = {
 | 
			
		||||
            arrayMethodName: null,
 | 
			
		||||
            upper: null,
 | 
			
		||||
            codePath: null,
 | 
			
		||||
            hasReturn: false,
 | 
			
		||||
            shouldCheck: false,
 | 
			
		||||
            node: null
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether or not the last code path segment is reachable.
 | 
			
		||||
         * Then reports this function if the segment is reachable.
 | 
			
		||||
         *
 | 
			
		||||
         * If the last code path segment is reachable, there are paths which are not
 | 
			
		||||
         * returned or thrown.
 | 
			
		||||
         * @param {ASTNode} node A node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkLastSegment(node) {
 | 
			
		||||
 | 
			
		||||
            if (!funcInfo.shouldCheck) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const messageAndSuggestions = { messageId: "", suggest: [] };
 | 
			
		||||
 | 
			
		||||
            if (funcInfo.arrayMethodName === "forEach") {
 | 
			
		||||
                if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) {
 | 
			
		||||
 | 
			
		||||
                    if (options.allowVoid) {
 | 
			
		||||
                        if (isExpressionVoid(node.body)) {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        messageAndSuggestions.messageId = "expectedNoReturnValue";
 | 
			
		||||
                        messageAndSuggestions.suggest = [
 | 
			
		||||
                            {
 | 
			
		||||
                                messageId: "wrapBraces",
 | 
			
		||||
                                fix(fixer) {
 | 
			
		||||
                                    return curlyWrapFixer(sourceCode, node, fixer);
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            {
 | 
			
		||||
                                messageId: "prependVoid",
 | 
			
		||||
                                fix(fixer) {
 | 
			
		||||
                                    return voidPrependFixer(sourceCode, node.body, fixer);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        ];
 | 
			
		||||
                    } else {
 | 
			
		||||
                        messageAndSuggestions.messageId = "expectedNoReturnValue";
 | 
			
		||||
                        messageAndSuggestions.suggest = [{
 | 
			
		||||
                            messageId: "wrapBraces",
 | 
			
		||||
                            fix(fixer) {
 | 
			
		||||
                                return curlyWrapFixer(sourceCode, node, fixer);
 | 
			
		||||
                            }
 | 
			
		||||
                        }];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (node.body.type === "BlockStatement" && isAnySegmentReachable(funcInfo.currentSegments)) {
 | 
			
		||||
                    messageAndSuggestions.messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (messageAndSuggestions.messageId) {
 | 
			
		||||
                const name = astUtils.getFunctionNameWithKind(node);
 | 
			
		||||
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc: astUtils.getFunctionHeadLoc(node, sourceCode),
 | 
			
		||||
                    messageId: messageAndSuggestions.messageId,
 | 
			
		||||
                    data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) },
 | 
			
		||||
                    suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            // Stacks this function's information.
 | 
			
		||||
            onCodePathStart(codePath, node) {
 | 
			
		||||
 | 
			
		||||
                let methodName = null;
 | 
			
		||||
 | 
			
		||||
                if (TARGET_NODE_TYPE.test(node.type)) {
 | 
			
		||||
                    methodName = getArrayMethodName(node);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                funcInfo = {
 | 
			
		||||
                    arrayMethodName: methodName,
 | 
			
		||||
                    upper: funcInfo,
 | 
			
		||||
                    codePath,
 | 
			
		||||
                    hasReturn: false,
 | 
			
		||||
                    shouldCheck:
 | 
			
		||||
                        methodName &&
 | 
			
		||||
                        !node.async &&
 | 
			
		||||
                        !node.generator,
 | 
			
		||||
                    node,
 | 
			
		||||
                    currentSegments: new Set()
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Pops this function's information.
 | 
			
		||||
            onCodePathEnd() {
 | 
			
		||||
                funcInfo = funcInfo.upper;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onUnreachableCodePathSegmentStart(segment) {
 | 
			
		||||
                funcInfo.currentSegments.add(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onUnreachableCodePathSegmentEnd(segment) {
 | 
			
		||||
                funcInfo.currentSegments.delete(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onCodePathSegmentStart(segment) {
 | 
			
		||||
                funcInfo.currentSegments.add(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onCodePathSegmentEnd(segment) {
 | 
			
		||||
                funcInfo.currentSegments.delete(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // Checks the return statement is valid.
 | 
			
		||||
            ReturnStatement(node) {
 | 
			
		||||
 | 
			
		||||
                if (!funcInfo.shouldCheck) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                funcInfo.hasReturn = true;
 | 
			
		||||
 | 
			
		||||
                const messageAndSuggestions = { messageId: "", suggest: [] };
 | 
			
		||||
 | 
			
		||||
                if (funcInfo.arrayMethodName === "forEach") {
 | 
			
		||||
 | 
			
		||||
                    // if checkForEach: true, returning a value at any path inside a forEach is not allowed
 | 
			
		||||
                    if (options.checkForEach && node.argument) {
 | 
			
		||||
 | 
			
		||||
                        if (options.allowVoid) {
 | 
			
		||||
                            if (isExpressionVoid(node.argument)) {
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            messageAndSuggestions.messageId = "expectedNoReturnValue";
 | 
			
		||||
                            messageAndSuggestions.suggest = [{
 | 
			
		||||
                                messageId: "prependVoid",
 | 
			
		||||
                                fix(fixer) {
 | 
			
		||||
                                    return voidPrependFixer(sourceCode, node.argument, fixer);
 | 
			
		||||
                                }
 | 
			
		||||
                            }];
 | 
			
		||||
                        } else {
 | 
			
		||||
                            messageAndSuggestions.messageId = "expectedNoReturnValue";
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
 | 
			
		||||
                    // if allowImplicit: false, should also check node.argument
 | 
			
		||||
                    if (!options.allowImplicit && !node.argument) {
 | 
			
		||||
                        messageAndSuggestions.messageId = "expectedReturnValue";
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (messageAndSuggestions.messageId) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        messageId: messageAndSuggestions.messageId,
 | 
			
		||||
                        data: {
 | 
			
		||||
                            name: astUtils.getFunctionNameWithKind(funcInfo.node),
 | 
			
		||||
                            arrayMethodName: fullMethodName(funcInfo.arrayMethodName)
 | 
			
		||||
                        },
 | 
			
		||||
                        suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Reports a given function if the last path is reachable.
 | 
			
		||||
            "FunctionExpression:exit": checkLastSegment,
 | 
			
		||||
            "ArrowFunctionExpression:exit": checkLastSegment
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										311
									
								
								node_modules/eslint/lib/rules/array-element-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								node_modules/eslint/lib/rules/array-element-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,311 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce line breaks after each array element
 | 
			
		||||
 * @author Jan Peer Stöcklmair <https://github.com/JPeer264>
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce line breaks after each array element",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/array-element-newline"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            definitions: {
 | 
			
		||||
                basicConfig: {
 | 
			
		||||
                    oneOf: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["always", "never", "consistent"]
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: "object",
 | 
			
		||||
                            properties: {
 | 
			
		||||
                                multiline: {
 | 
			
		||||
                                    type: "boolean"
 | 
			
		||||
                                },
 | 
			
		||||
                                minItems: {
 | 
			
		||||
                                    type: ["integer", "null"],
 | 
			
		||||
                                    minimum: 0
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            additionalProperties: false
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            type: "array",
 | 
			
		||||
            items: [
 | 
			
		||||
                {
 | 
			
		||||
                    oneOf: [
 | 
			
		||||
                        {
 | 
			
		||||
                            $ref: "#/definitions/basicConfig"
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: "object",
 | 
			
		||||
                            properties: {
 | 
			
		||||
                                ArrayExpression: {
 | 
			
		||||
                                    $ref: "#/definitions/basicConfig"
 | 
			
		||||
                                },
 | 
			
		||||
                                ArrayPattern: {
 | 
			
		||||
                                    $ref: "#/definitions/basicConfig"
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            additionalProperties: false,
 | 
			
		||||
                            minProperties: 1
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedLineBreak: "There should be no linebreak here.",
 | 
			
		||||
            missingLineBreak: "There should be a linebreak after this element."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Normalizes a given option value.
 | 
			
		||||
         * @param {string|Object|undefined} providedOption An option value to parse.
 | 
			
		||||
         * @returns {{multiline: boolean, minItems: number}} Normalized option object.
 | 
			
		||||
         */
 | 
			
		||||
        function normalizeOptionValue(providedOption) {
 | 
			
		||||
            let consistent = false;
 | 
			
		||||
            let multiline = false;
 | 
			
		||||
            let minItems;
 | 
			
		||||
 | 
			
		||||
            const option = providedOption || "always";
 | 
			
		||||
 | 
			
		||||
            if (!option || option === "always" || option.minItems === 0) {
 | 
			
		||||
                minItems = 0;
 | 
			
		||||
            } else if (option === "never") {
 | 
			
		||||
                minItems = Number.POSITIVE_INFINITY;
 | 
			
		||||
            } else if (option === "consistent") {
 | 
			
		||||
                consistent = true;
 | 
			
		||||
                minItems = Number.POSITIVE_INFINITY;
 | 
			
		||||
            } else {
 | 
			
		||||
                multiline = Boolean(option.multiline);
 | 
			
		||||
                minItems = option.minItems || Number.POSITIVE_INFINITY;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return { consistent, multiline, minItems };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Normalizes a given option value.
 | 
			
		||||
         * @param {string|Object|undefined} options An option value to parse.
 | 
			
		||||
         * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object.
 | 
			
		||||
         */
 | 
			
		||||
        function normalizeOptions(options) {
 | 
			
		||||
            if (options && (options.ArrayExpression || options.ArrayPattern)) {
 | 
			
		||||
                let expressionOptions, patternOptions;
 | 
			
		||||
 | 
			
		||||
                if (options.ArrayExpression) {
 | 
			
		||||
                    expressionOptions = normalizeOptionValue(options.ArrayExpression);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (options.ArrayPattern) {
 | 
			
		||||
                    patternOptions = normalizeOptionValue(options.ArrayPattern);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return { ArrayExpression: expressionOptions, ArrayPattern: patternOptions };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const value = normalizeOptionValue(options);
 | 
			
		||||
 | 
			
		||||
            return { ArrayExpression: value, ArrayPattern: value };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there shouldn't be a line break after the first token
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportNoLineBreak(token) {
 | 
			
		||||
            const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
            context.report({
 | 
			
		||||
                loc: {
 | 
			
		||||
                    start: tokenBefore.loc.end,
 | 
			
		||||
                    end: token.loc.start
 | 
			
		||||
                },
 | 
			
		||||
                messageId: "unexpectedLineBreak",
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    if (astUtils.isCommentToken(tokenBefore)) {
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (!astUtils.isTokenOnSameLine(tokenBefore, token)) {
 | 
			
		||||
                        return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ");
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /*
 | 
			
		||||
                     * This will check if the comma is on the same line as the next element
 | 
			
		||||
                     * Following array:
 | 
			
		||||
                     * [
 | 
			
		||||
                     *     1
 | 
			
		||||
                     *     , 2
 | 
			
		||||
                     *     , 3
 | 
			
		||||
                     * ]
 | 
			
		||||
                     *
 | 
			
		||||
                     * will be fixed to:
 | 
			
		||||
                     * [
 | 
			
		||||
                     *     1, 2, 3
 | 
			
		||||
                     * ]
 | 
			
		||||
                     */
 | 
			
		||||
                    const twoTokensBefore = sourceCode.getTokenBefore(tokenBefore, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
                    if (astUtils.isCommentToken(twoTokensBefore)) {
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return fixer.replaceTextRange([twoTokensBefore.range[1], tokenBefore.range[0]], "");
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there should be a line break after the first token
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportRequiredLineBreak(token) {
 | 
			
		||||
            const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
            context.report({
 | 
			
		||||
                loc: {
 | 
			
		||||
                    start: tokenBefore.loc.end,
 | 
			
		||||
                    end: token.loc.start
 | 
			
		||||
                },
 | 
			
		||||
                messageId: "missingLineBreak",
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports a given node if it violated this rule.
 | 
			
		||||
         * @param {ASTNode} node A node to check. This is an ObjectExpression node or an ObjectPattern node.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function check(node) {
 | 
			
		||||
            const elements = node.elements;
 | 
			
		||||
            const normalizedOptions = normalizeOptions(context.options[0]);
 | 
			
		||||
            const options = normalizedOptions[node.type];
 | 
			
		||||
 | 
			
		||||
            if (!options) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let elementBreak = false;
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * MULTILINE: true
 | 
			
		||||
             * loop through every element and check
 | 
			
		||||
             * if at least one element has linebreaks inside
 | 
			
		||||
             * this ensures that following is not valid (due to elements are on the same line):
 | 
			
		||||
             *
 | 
			
		||||
             * [
 | 
			
		||||
             *      1,
 | 
			
		||||
             *      2,
 | 
			
		||||
             *      3
 | 
			
		||||
             * ]
 | 
			
		||||
             */
 | 
			
		||||
            if (options.multiline) {
 | 
			
		||||
                elementBreak = elements
 | 
			
		||||
                    .filter(element => element !== null)
 | 
			
		||||
                    .some(element => element.loc.start.line !== element.loc.end.line);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let linebreaksCount = 0;
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < node.elements.length; i++) {
 | 
			
		||||
                const element = node.elements[i];
 | 
			
		||||
 | 
			
		||||
                const previousElement = elements[i - 1];
 | 
			
		||||
 | 
			
		||||
                if (i === 0 || element === null || previousElement === null) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken);
 | 
			
		||||
                const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken);
 | 
			
		||||
                const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken);
 | 
			
		||||
 | 
			
		||||
                if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
 | 
			
		||||
                    linebreaksCount++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const needsLinebreaks = (
 | 
			
		||||
                elements.length >= options.minItems ||
 | 
			
		||||
                (
 | 
			
		||||
                    options.multiline &&
 | 
			
		||||
                    elementBreak
 | 
			
		||||
                ) ||
 | 
			
		||||
                (
 | 
			
		||||
                    options.consistent &&
 | 
			
		||||
                    linebreaksCount > 0 &&
 | 
			
		||||
                    linebreaksCount < node.elements.length
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            elements.forEach((element, i) => {
 | 
			
		||||
                const previousElement = elements[i - 1];
 | 
			
		||||
 | 
			
		||||
                if (i === 0 || element === null || previousElement === null) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken);
 | 
			
		||||
                const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken);
 | 
			
		||||
                const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken);
 | 
			
		||||
 | 
			
		||||
                if (needsLinebreaks) {
 | 
			
		||||
                    if (astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
 | 
			
		||||
                        reportRequiredLineBreak(firstTokenOfCurrentElement);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) {
 | 
			
		||||
                        reportNoLineBreak(firstTokenOfCurrentElement);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            ArrayPattern: check,
 | 
			
		||||
            ArrayExpression: check
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										296
									
								
								node_modules/eslint/lib/rules/arrow-body-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								node_modules/eslint/lib/rules/arrow-body-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,296 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to require braces in arrow function body.
 | 
			
		||||
 * @author Alberto Rodríguez
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require braces around arrow function bodies",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/arrow-body-style"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            anyOf: [
 | 
			
		||||
                {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["always", "never"]
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    minItems: 0,
 | 
			
		||||
                    maxItems: 1
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["as-needed"]
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: "object",
 | 
			
		||||
                            properties: {
 | 
			
		||||
                                requireReturnForObjectLiteral: { type: "boolean" }
 | 
			
		||||
                            },
 | 
			
		||||
                            additionalProperties: false
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    minItems: 0,
 | 
			
		||||
                    maxItems: 2
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedOtherBlock: "Unexpected block statement surrounding arrow body.",
 | 
			
		||||
            unexpectedEmptyBlock: "Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.",
 | 
			
		||||
            unexpectedObjectBlock: "Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.",
 | 
			
		||||
            unexpectedSingleBlock: "Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.",
 | 
			
		||||
            expectedBlock: "Expected block statement surrounding arrow body."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const options = context.options;
 | 
			
		||||
        const always = options[0] === "always";
 | 
			
		||||
        const asNeeded = !options[0] || options[0] === "as-needed";
 | 
			
		||||
        const never = options[0] === "never";
 | 
			
		||||
        const requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral;
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
        let funcInfo = null;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether the given node has ASI problem or not.
 | 
			
		||||
         * @param {Token} token The token to check.
 | 
			
		||||
         * @returns {boolean} `true` if it changes semantics if `;` or `}` followed by the token are removed.
 | 
			
		||||
         */
 | 
			
		||||
        function hasASIProblem(token) {
 | 
			
		||||
            return token && token.type === "Punctuator" && /^[([/`+-]/u.test(token.value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Gets the closing parenthesis by the given node.
 | 
			
		||||
         * @param {ASTNode} node first node after an opening parenthesis.
 | 
			
		||||
         * @returns {Token} The found closing parenthesis token.
 | 
			
		||||
         */
 | 
			
		||||
        function findClosingParen(node) {
 | 
			
		||||
            let nodeToCheck = node;
 | 
			
		||||
 | 
			
		||||
            while (!astUtils.isParenthesised(sourceCode, nodeToCheck)) {
 | 
			
		||||
                nodeToCheck = nodeToCheck.parent;
 | 
			
		||||
            }
 | 
			
		||||
            return sourceCode.getTokenAfter(nodeToCheck);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check whether the node is inside of a for loop's init
 | 
			
		||||
         * @param {ASTNode} node node is inside for loop
 | 
			
		||||
         * @returns {boolean} `true` if the node is inside of a for loop, else `false`
 | 
			
		||||
         */
 | 
			
		||||
        function isInsideForLoopInitializer(node) {
 | 
			
		||||
            if (node && node.parent) {
 | 
			
		||||
                if (node.parent.type === "ForStatement" && node.parent.init === node) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                return isInsideForLoopInitializer(node.parent);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether a arrow function body needs braces
 | 
			
		||||
         * @param {ASTNode} node The arrow function node.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function validate(node) {
 | 
			
		||||
            const arrowBody = node.body;
 | 
			
		||||
 | 
			
		||||
            if (arrowBody.type === "BlockStatement") {
 | 
			
		||||
                const blockBody = arrowBody.body;
 | 
			
		||||
 | 
			
		||||
                if (blockBody.length !== 1 && !never) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" &&
 | 
			
		||||
                    blockBody[0].argument && blockBody[0].argument.type === "ObjectExpression") {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (never || asNeeded && blockBody[0].type === "ReturnStatement") {
 | 
			
		||||
                    let messageId;
 | 
			
		||||
 | 
			
		||||
                    if (blockBody.length === 0) {
 | 
			
		||||
                        messageId = "unexpectedEmptyBlock";
 | 
			
		||||
                    } else if (blockBody.length > 1) {
 | 
			
		||||
                        messageId = "unexpectedOtherBlock";
 | 
			
		||||
                    } else if (blockBody[0].argument === null) {
 | 
			
		||||
                        messageId = "unexpectedSingleBlock";
 | 
			
		||||
                    } else if (astUtils.isOpeningBraceToken(sourceCode.getFirstToken(blockBody[0], { skip: 1 }))) {
 | 
			
		||||
                        messageId = "unexpectedObjectBlock";
 | 
			
		||||
                    } else {
 | 
			
		||||
                        messageId = "unexpectedSingleBlock";
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        loc: arrowBody.loc,
 | 
			
		||||
                        messageId,
 | 
			
		||||
                        fix(fixer) {
 | 
			
		||||
                            const fixes = [];
 | 
			
		||||
 | 
			
		||||
                            if (blockBody.length !== 1 ||
 | 
			
		||||
                                blockBody[0].type !== "ReturnStatement" ||
 | 
			
		||||
                                !blockBody[0].argument ||
 | 
			
		||||
                                hasASIProblem(sourceCode.getTokenAfter(arrowBody))
 | 
			
		||||
                            ) {
 | 
			
		||||
                                return fixes;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            const openingBrace = sourceCode.getFirstToken(arrowBody);
 | 
			
		||||
                            const closingBrace = sourceCode.getLastToken(arrowBody);
 | 
			
		||||
                            const firstValueToken = sourceCode.getFirstToken(blockBody[0], 1);
 | 
			
		||||
                            const lastValueToken = sourceCode.getLastToken(blockBody[0]);
 | 
			
		||||
                            const commentsExist =
 | 
			
		||||
                                sourceCode.commentsExistBetween(openingBrace, firstValueToken) ||
 | 
			
		||||
                                sourceCode.commentsExistBetween(lastValueToken, closingBrace);
 | 
			
		||||
 | 
			
		||||
                            /*
 | 
			
		||||
                             * Remove tokens around the return value.
 | 
			
		||||
                             * If comments don't exist, remove extra spaces as well.
 | 
			
		||||
                             */
 | 
			
		||||
                            if (commentsExist) {
 | 
			
		||||
                                fixes.push(
 | 
			
		||||
                                    fixer.remove(openingBrace),
 | 
			
		||||
                                    fixer.remove(closingBrace),
 | 
			
		||||
                                    fixer.remove(sourceCode.getTokenAfter(openingBrace)) // return keyword
 | 
			
		||||
                                );
 | 
			
		||||
                            } else {
 | 
			
		||||
                                fixes.push(
 | 
			
		||||
                                    fixer.removeRange([openingBrace.range[0], firstValueToken.range[0]]),
 | 
			
		||||
                                    fixer.removeRange([lastValueToken.range[1], closingBrace.range[1]])
 | 
			
		||||
                                );
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            /*
 | 
			
		||||
                             * If the first token of the return value is `{` or the return value is a sequence expression,
 | 
			
		||||
                             * enclose the return value by parentheses to avoid syntax error.
 | 
			
		||||
                             */
 | 
			
		||||
                            if (astUtils.isOpeningBraceToken(firstValueToken) || blockBody[0].argument.type === "SequenceExpression" || (funcInfo.hasInOperator && isInsideForLoopInitializer(node))) {
 | 
			
		||||
                                if (!astUtils.isParenthesised(sourceCode, blockBody[0].argument)) {
 | 
			
		||||
                                    fixes.push(
 | 
			
		||||
                                        fixer.insertTextBefore(firstValueToken, "("),
 | 
			
		||||
                                        fixer.insertTextAfter(lastValueToken, ")")
 | 
			
		||||
                                    );
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            /*
 | 
			
		||||
                             * If the last token of the return statement is semicolon, remove it.
 | 
			
		||||
                             * Non-block arrow body is an expression, not a statement.
 | 
			
		||||
                             */
 | 
			
		||||
                            if (astUtils.isSemicolonToken(lastValueToken)) {
 | 
			
		||||
                                fixes.push(fixer.remove(lastValueToken));
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            return fixes;
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        loc: arrowBody.loc,
 | 
			
		||||
                        messageId: "expectedBlock",
 | 
			
		||||
                        fix(fixer) {
 | 
			
		||||
                            const fixes = [];
 | 
			
		||||
                            const arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken);
 | 
			
		||||
                            const [firstTokenAfterArrow, secondTokenAfterArrow] = sourceCode.getTokensAfter(arrowToken, { count: 2 });
 | 
			
		||||
                            const lastToken = sourceCode.getLastToken(node);
 | 
			
		||||
 | 
			
		||||
                            let parenthesisedObjectLiteral = null;
 | 
			
		||||
 | 
			
		||||
                            if (
 | 
			
		||||
                                astUtils.isOpeningParenToken(firstTokenAfterArrow) &&
 | 
			
		||||
                                astUtils.isOpeningBraceToken(secondTokenAfterArrow)
 | 
			
		||||
                            ) {
 | 
			
		||||
                                const braceNode = sourceCode.getNodeByRangeIndex(secondTokenAfterArrow.range[0]);
 | 
			
		||||
 | 
			
		||||
                                if (braceNode.type === "ObjectExpression") {
 | 
			
		||||
                                    parenthesisedObjectLiteral = braceNode;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // If the value is object literal, remove parentheses which were forced by syntax.
 | 
			
		||||
                            if (parenthesisedObjectLiteral) {
 | 
			
		||||
                                const openingParenToken = firstTokenAfterArrow;
 | 
			
		||||
                                const openingBraceToken = secondTokenAfterArrow;
 | 
			
		||||
 | 
			
		||||
                                if (astUtils.isTokenOnSameLine(openingParenToken, openingBraceToken)) {
 | 
			
		||||
                                    fixes.push(fixer.replaceText(openingParenToken, "{return "));
 | 
			
		||||
                                } else {
 | 
			
		||||
 | 
			
		||||
                                    // Avoid ASI
 | 
			
		||||
                                    fixes.push(
 | 
			
		||||
                                        fixer.replaceText(openingParenToken, "{"),
 | 
			
		||||
                                        fixer.insertTextBefore(openingBraceToken, "return ")
 | 
			
		||||
                                    );
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                // Closing paren for the object doesn't have to be lastToken, e.g.: () => ({}).foo()
 | 
			
		||||
                                fixes.push(fixer.remove(findClosingParen(parenthesisedObjectLiteral)));
 | 
			
		||||
                                fixes.push(fixer.insertTextAfter(lastToken, "}"));
 | 
			
		||||
 | 
			
		||||
                            } else {
 | 
			
		||||
                                fixes.push(fixer.insertTextBefore(firstTokenAfterArrow, "{return "));
 | 
			
		||||
                                fixes.push(fixer.insertTextAfter(lastToken, "}"));
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            return fixes;
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            "BinaryExpression[operator='in']"() {
 | 
			
		||||
                let info = funcInfo;
 | 
			
		||||
 | 
			
		||||
                while (info) {
 | 
			
		||||
                    info.hasInOperator = true;
 | 
			
		||||
                    info = info.upper;
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            ArrowFunctionExpression() {
 | 
			
		||||
                funcInfo = {
 | 
			
		||||
                    upper: funcInfo,
 | 
			
		||||
                    hasInOperator: false
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
            "ArrowFunctionExpression:exit"(node) {
 | 
			
		||||
                validate(node);
 | 
			
		||||
                funcInfo = funcInfo.upper;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										186
									
								
								node_modules/eslint/lib/rules/arrow-parens.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								node_modules/eslint/lib/rules/arrow-parens.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,186 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to require parens in arrow function arguments.
 | 
			
		||||
 * @author Jxck
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determines if the given arrow function has block body.
 | 
			
		||||
 * @param {ASTNode} node `ArrowFunctionExpression` node.
 | 
			
		||||
 * @returns {boolean} `true` if the function has block body.
 | 
			
		||||
 */
 | 
			
		||||
function hasBlockBody(node) {
 | 
			
		||||
    return node.body.type === "BlockStatement";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require parentheses around arrow function arguments",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/arrow-parens"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["always", "as-needed"]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    requireForBlockBody: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedParens: "Unexpected parentheses around single function argument.",
 | 
			
		||||
            expectedParens: "Expected parentheses around arrow function argument.",
 | 
			
		||||
 | 
			
		||||
            unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.",
 | 
			
		||||
            expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const asNeeded = context.options[0] === "as-needed";
 | 
			
		||||
        const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true;
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Finds opening paren of parameters for the given arrow function, if it exists.
 | 
			
		||||
         * It is assumed that the given arrow function has exactly one parameter.
 | 
			
		||||
         * @param {ASTNode} node `ArrowFunctionExpression` node.
 | 
			
		||||
         * @returns {Token|null} the opening paren, or `null` if the given arrow function doesn't have parens of parameters.
 | 
			
		||||
         */
 | 
			
		||||
        function findOpeningParenOfParams(node) {
 | 
			
		||||
            const tokenBeforeParams = sourceCode.getTokenBefore(node.params[0]);
 | 
			
		||||
 | 
			
		||||
            if (
 | 
			
		||||
                tokenBeforeParams &&
 | 
			
		||||
                astUtils.isOpeningParenToken(tokenBeforeParams) &&
 | 
			
		||||
                node.range[0] <= tokenBeforeParams.range[0]
 | 
			
		||||
            ) {
 | 
			
		||||
                return tokenBeforeParams;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Finds closing paren of parameters for the given arrow function.
 | 
			
		||||
         * It is assumed that the given arrow function has parens of parameters and that it has exactly one parameter.
 | 
			
		||||
         * @param {ASTNode} node `ArrowFunctionExpression` node.
 | 
			
		||||
         * @returns {Token} the closing paren of parameters.
 | 
			
		||||
         */
 | 
			
		||||
        function getClosingParenOfParams(node) {
 | 
			
		||||
            return sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the given arrow function has comments inside parens of parameters.
 | 
			
		||||
         * It is assumed that the given arrow function has parens of parameters.
 | 
			
		||||
         * @param {ASTNode} node `ArrowFunctionExpression` node.
 | 
			
		||||
         * @param {Token} openingParen Opening paren of parameters.
 | 
			
		||||
         * @returns {boolean} `true` if the function has at least one comment inside of parens of parameters.
 | 
			
		||||
         */
 | 
			
		||||
        function hasCommentsInParensOfParams(node, openingParen) {
 | 
			
		||||
            return sourceCode.commentsExistBetween(openingParen, getClosingParenOfParams(node));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the given arrow function has unexpected tokens before opening paren of parameters,
 | 
			
		||||
         * in which case it will be assumed that the existing parens of parameters are necessary.
 | 
			
		||||
         * Only tokens within the range of the arrow function (tokens that are part of the arrow function) are taken into account.
 | 
			
		||||
         * Example: <T>(a) => b
 | 
			
		||||
         * @param {ASTNode} node `ArrowFunctionExpression` node.
 | 
			
		||||
         * @param {Token} openingParen Opening paren of parameters.
 | 
			
		||||
         * @returns {boolean} `true` if the function has at least one unexpected token.
 | 
			
		||||
         */
 | 
			
		||||
        function hasUnexpectedTokensBeforeOpeningParen(node, openingParen) {
 | 
			
		||||
            const expectedCount = node.async ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
            return sourceCode.getFirstToken(node, { skip: expectedCount }) !== openingParen;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            "ArrowFunctionExpression[params.length=1]"(node) {
 | 
			
		||||
                const shouldHaveParens = !asNeeded || requireForBlockBody && hasBlockBody(node);
 | 
			
		||||
                const openingParen = findOpeningParenOfParams(node);
 | 
			
		||||
                const hasParens = openingParen !== null;
 | 
			
		||||
                const [param] = node.params;
 | 
			
		||||
 | 
			
		||||
                if (shouldHaveParens && !hasParens) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        messageId: requireForBlockBody ? "expectedParensBlock" : "expectedParens",
 | 
			
		||||
                        loc: param.loc,
 | 
			
		||||
                        *fix(fixer) {
 | 
			
		||||
                            yield fixer.insertTextBefore(param, "(");
 | 
			
		||||
                            yield fixer.insertTextAfter(param, ")");
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (
 | 
			
		||||
                    !shouldHaveParens &&
 | 
			
		||||
                    hasParens &&
 | 
			
		||||
                    param.type === "Identifier" &&
 | 
			
		||||
                    !param.typeAnnotation &&
 | 
			
		||||
                    !node.returnType &&
 | 
			
		||||
                    !hasCommentsInParensOfParams(node, openingParen) &&
 | 
			
		||||
                    !hasUnexpectedTokensBeforeOpeningParen(node, openingParen)
 | 
			
		||||
                ) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        messageId: requireForBlockBody ? "unexpectedParensInline" : "unexpectedParens",
 | 
			
		||||
                        loc: param.loc,
 | 
			
		||||
                        *fix(fixer) {
 | 
			
		||||
                            const tokenBeforeOpeningParen = sourceCode.getTokenBefore(openingParen);
 | 
			
		||||
                            const closingParen = getClosingParenOfParams(node);
 | 
			
		||||
 | 
			
		||||
                            if (
 | 
			
		||||
                                tokenBeforeOpeningParen &&
 | 
			
		||||
                                tokenBeforeOpeningParen.range[1] === openingParen.range[0] &&
 | 
			
		||||
                                !astUtils.canTokensBeAdjacent(tokenBeforeOpeningParen, sourceCode.getFirstToken(param))
 | 
			
		||||
                            ) {
 | 
			
		||||
                                yield fixer.insertTextBefore(openingParen, " ");
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // remove parens, whitespace inside parens, and possible trailing comma
 | 
			
		||||
                            yield fixer.removeRange([openingParen.range[0], param.range[0]]);
 | 
			
		||||
                            yield fixer.removeRange([param.range[1], closingParen.range[1]]);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										164
									
								
								node_modules/eslint/lib/rules/arrow-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								node_modules/eslint/lib/rules/arrow-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to define spacing before/after arrow function's arrow.
 | 
			
		||||
 * @author Jxck
 | 
			
		||||
 * @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 spacing before and after the arrow in arrow functions",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/arrow-spacing"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    before: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: true
 | 
			
		||||
                    },
 | 
			
		||||
                    after: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: true
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            expectedBefore: "Missing space before =>.",
 | 
			
		||||
            unexpectedBefore: "Unexpected space before =>.",
 | 
			
		||||
 | 
			
		||||
            expectedAfter: "Missing space after =>.",
 | 
			
		||||
            unexpectedAfter: "Unexpected space after =>."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        // merge rules with default
 | 
			
		||||
        const rule = Object.assign({}, context.options[0]);
 | 
			
		||||
 | 
			
		||||
        rule.before = rule.before !== false;
 | 
			
		||||
        rule.after = rule.after !== false;
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Get tokens of arrow(`=>`) and before/after arrow.
 | 
			
		||||
         * @param {ASTNode} node The arrow function node.
 | 
			
		||||
         * @returns {Object} Tokens of arrow and before/after arrow.
 | 
			
		||||
         */
 | 
			
		||||
        function getTokens(node) {
 | 
			
		||||
            const arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                before: sourceCode.getTokenBefore(arrow),
 | 
			
		||||
                arrow,
 | 
			
		||||
                after: sourceCode.getTokenAfter(arrow)
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Count spaces before/after arrow(`=>`) token.
 | 
			
		||||
         * @param {Object} tokens Tokens before/after arrow.
 | 
			
		||||
         * @returns {Object} count of space before/after arrow.
 | 
			
		||||
         */
 | 
			
		||||
        function countSpaces(tokens) {
 | 
			
		||||
            const before = tokens.arrow.range[0] - tokens.before.range[1];
 | 
			
		||||
            const after = tokens.after.range[0] - tokens.arrow.range[1];
 | 
			
		||||
 | 
			
		||||
            return { before, after };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether space(s) before after arrow(`=>`) is satisfy rule.
 | 
			
		||||
         * if before/after value is `true`, there should be space(s).
 | 
			
		||||
         * if before/after value is `false`, there should be no space.
 | 
			
		||||
         * @param {ASTNode} node The arrow function node.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function spaces(node) {
 | 
			
		||||
            const tokens = getTokens(node);
 | 
			
		||||
            const countSpace = countSpaces(tokens);
 | 
			
		||||
 | 
			
		||||
            if (rule.before) {
 | 
			
		||||
 | 
			
		||||
                // should be space(s) before arrow
 | 
			
		||||
                if (countSpace.before === 0) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node: tokens.before,
 | 
			
		||||
                        messageId: "expectedBefore",
 | 
			
		||||
                        fix(fixer) {
 | 
			
		||||
                            return fixer.insertTextBefore(tokens.arrow, " ");
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                // should be no space before arrow
 | 
			
		||||
                if (countSpace.before > 0) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node: tokens.before,
 | 
			
		||||
                        messageId: "unexpectedBefore",
 | 
			
		||||
                        fix(fixer) {
 | 
			
		||||
                            return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (rule.after) {
 | 
			
		||||
 | 
			
		||||
                // should be space(s) after arrow
 | 
			
		||||
                if (countSpace.after === 0) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node: tokens.after,
 | 
			
		||||
                        messageId: "expectedAfter",
 | 
			
		||||
                        fix(fixer) {
 | 
			
		||||
                            return fixer.insertTextAfter(tokens.arrow, " ");
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                // should be no space after arrow
 | 
			
		||||
                if (countSpace.after > 0) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node: tokens.after,
 | 
			
		||||
                        messageId: "unexpectedAfter",
 | 
			
		||||
                        fix(fixer) {
 | 
			
		||||
                            return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            ArrowFunctionExpression: spaces
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										135
									
								
								node_modules/eslint/lib/rules/block-scoped-var.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								node_modules/eslint/lib/rules/block-scoped-var.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to check for "block scoped" variables by binding context
 | 
			
		||||
 * @author Matt DuVall <http://www.mattduvall.com>
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce the use of variables within the scope they are defined",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/block-scoped-var"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            outOfScope: "'{{name}}' declared on line {{definitionLine}} column {{definitionColumn}} is used outside of binding context."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        let stack = [];
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Makes a block scope.
 | 
			
		||||
         * @param {ASTNode} node A node of a scope.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function enterScope(node) {
 | 
			
		||||
            stack.push(node.range);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Pops the last block scope.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function exitScope() {
 | 
			
		||||
            stack.pop();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports a given reference.
 | 
			
		||||
         * @param {eslint-scope.Reference} reference A reference to report.
 | 
			
		||||
         * @param {eslint-scope.Definition} definition A definition for which to report reference.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function report(reference, definition) {
 | 
			
		||||
            const identifier = reference.identifier;
 | 
			
		||||
            const definitionPosition = definition.name.loc.start;
 | 
			
		||||
 | 
			
		||||
            context.report({
 | 
			
		||||
                node: identifier,
 | 
			
		||||
                messageId: "outOfScope",
 | 
			
		||||
                data: {
 | 
			
		||||
                    name: identifier.name,
 | 
			
		||||
                    definitionLine: definitionPosition.line,
 | 
			
		||||
                    definitionColumn: definitionPosition.column + 1
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Finds and reports references which are outside of valid scopes.
 | 
			
		||||
         * @param {ASTNode} node A node to get variables.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkForVariables(node) {
 | 
			
		||||
            if (node.kind !== "var") {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Defines a predicate to check whether or not a given reference is outside of valid scope.
 | 
			
		||||
            const scopeRange = stack[stack.length - 1];
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Check if a reference is out of scope
 | 
			
		||||
             * @param {ASTNode} reference node to examine
 | 
			
		||||
             * @returns {boolean} True is its outside the scope
 | 
			
		||||
             * @private
 | 
			
		||||
             */
 | 
			
		||||
            function isOutsideOfScope(reference) {
 | 
			
		||||
                const idRange = reference.identifier.range;
 | 
			
		||||
 | 
			
		||||
                return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Gets declared variables, and checks its references.
 | 
			
		||||
            const variables = sourceCode.getDeclaredVariables(node);
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < variables.length; ++i) {
 | 
			
		||||
 | 
			
		||||
                // Reports.
 | 
			
		||||
                variables[i]
 | 
			
		||||
                    .references
 | 
			
		||||
                    .filter(isOutsideOfScope)
 | 
			
		||||
                    .forEach(ref => report(ref, variables[i].defs.find(def => def.parent === node)));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            Program(node) {
 | 
			
		||||
                stack = [node.range];
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Manages scopes.
 | 
			
		||||
            BlockStatement: enterScope,
 | 
			
		||||
            "BlockStatement:exit": exitScope,
 | 
			
		||||
            ForStatement: enterScope,
 | 
			
		||||
            "ForStatement:exit": exitScope,
 | 
			
		||||
            ForInStatement: enterScope,
 | 
			
		||||
            "ForInStatement:exit": exitScope,
 | 
			
		||||
            ForOfStatement: enterScope,
 | 
			
		||||
            "ForOfStatement:exit": exitScope,
 | 
			
		||||
            SwitchStatement: enterScope,
 | 
			
		||||
            "SwitchStatement:exit": exitScope,
 | 
			
		||||
            CatchClause: enterScope,
 | 
			
		||||
            "CatchClause:exit": exitScope,
 | 
			
		||||
            StaticBlock: enterScope,
 | 
			
		||||
            "StaticBlock:exit": exitScope,
 | 
			
		||||
 | 
			
		||||
            // Finds and reports references which are outside of valid scope.
 | 
			
		||||
            VariableDeclaration: checkForVariables
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										174
									
								
								node_modules/eslint/lib/rules/block-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								node_modules/eslint/lib/rules/block-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,174 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A rule to disallow or enforce spaces inside of single line blocks.
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const util = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Disallow or enforce spaces inside of blocks after opening block and before closing block",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/block-spacing"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            { enum: ["always", "never"] }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missing: "Requires a space {{location}} '{{token}}'.",
 | 
			
		||||
            extra: "Unexpected space(s) {{location}} '{{token}}'."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const always = (context.options[0] !== "never"),
 | 
			
		||||
            messageId = always ? "missing" : "extra",
 | 
			
		||||
            sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Gets the open brace token from a given node.
 | 
			
		||||
         * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to get.
 | 
			
		||||
         * @returns {Token} The token of the open brace.
 | 
			
		||||
         */
 | 
			
		||||
        function getOpenBrace(node) {
 | 
			
		||||
            if (node.type === "SwitchStatement") {
 | 
			
		||||
                if (node.cases.length > 0) {
 | 
			
		||||
                    return sourceCode.getTokenBefore(node.cases[0]);
 | 
			
		||||
                }
 | 
			
		||||
                return sourceCode.getLastToken(node, 1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (node.type === "StaticBlock") {
 | 
			
		||||
                return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // "BlockStatement"
 | 
			
		||||
            return sourceCode.getFirstToken(node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether or not:
 | 
			
		||||
         *   - given tokens are on same line.
 | 
			
		||||
         *   - there is/isn't a space between given tokens.
 | 
			
		||||
         * @param {Token} left A token to check.
 | 
			
		||||
         * @param {Token} right The token which is next to `left`.
 | 
			
		||||
         * @returns {boolean}
 | 
			
		||||
         *    When the option is `"always"`, `true` if there are one or more spaces between given tokens.
 | 
			
		||||
         *    When the option is `"never"`, `true` if there are not any spaces between given tokens.
 | 
			
		||||
         *    If given tokens are not on same line, it's always `true`.
 | 
			
		||||
         */
 | 
			
		||||
        function isValid(left, right) {
 | 
			
		||||
            return (
 | 
			
		||||
                !util.isTokenOnSameLine(left, right) ||
 | 
			
		||||
                sourceCode.isSpaceBetweenTokens(left, right) === always
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks and reports invalid spacing style inside braces.
 | 
			
		||||
         * @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkSpacingInsideBraces(node) {
 | 
			
		||||
 | 
			
		||||
            // Gets braces and the first/last token of content.
 | 
			
		||||
            const openBrace = getOpenBrace(node);
 | 
			
		||||
            const closeBrace = sourceCode.getLastToken(node);
 | 
			
		||||
            const firstToken = sourceCode.getTokenAfter(openBrace, { includeComments: true });
 | 
			
		||||
            const lastToken = sourceCode.getTokenBefore(closeBrace, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
            // Skip if the node is invalid or empty.
 | 
			
		||||
            if (openBrace.type !== "Punctuator" ||
 | 
			
		||||
                openBrace.value !== "{" ||
 | 
			
		||||
                closeBrace.type !== "Punctuator" ||
 | 
			
		||||
                closeBrace.value !== "}" ||
 | 
			
		||||
                firstToken === closeBrace
 | 
			
		||||
            ) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Skip line comments for option never
 | 
			
		||||
            if (!always && firstToken.type === "Line") {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Check.
 | 
			
		||||
            if (!isValid(openBrace, firstToken)) {
 | 
			
		||||
                let loc = openBrace.loc;
 | 
			
		||||
 | 
			
		||||
                if (messageId === "extra") {
 | 
			
		||||
                    loc = {
 | 
			
		||||
                        start: openBrace.loc.end,
 | 
			
		||||
                        end: firstToken.loc.start
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc,
 | 
			
		||||
                    messageId,
 | 
			
		||||
                    data: {
 | 
			
		||||
                        location: "after",
 | 
			
		||||
                        token: openBrace.value
 | 
			
		||||
                    },
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
                        if (always) {
 | 
			
		||||
                            return fixer.insertTextBefore(firstToken, " ");
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        return fixer.removeRange([openBrace.range[1], firstToken.range[0]]);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            if (!isValid(lastToken, closeBrace)) {
 | 
			
		||||
                let loc = closeBrace.loc;
 | 
			
		||||
 | 
			
		||||
                if (messageId === "extra") {
 | 
			
		||||
                    loc = {
 | 
			
		||||
                        start: lastToken.loc.end,
 | 
			
		||||
                        end: closeBrace.loc.start
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc,
 | 
			
		||||
                    messageId,
 | 
			
		||||
                    data: {
 | 
			
		||||
                        location: "before",
 | 
			
		||||
                        token: closeBrace.value
 | 
			
		||||
                    },
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
                        if (always) {
 | 
			
		||||
                            return fixer.insertTextAfter(lastToken, " ");
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            BlockStatement: checkSpacingInsideBraces,
 | 
			
		||||
            StaticBlock: checkSpacingInsideBraces,
 | 
			
		||||
            SwitchStatement: checkSpacingInsideBraces
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										197
									
								
								node_modules/eslint/lib/rules/brace-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								node_modules/eslint/lib/rules/brace-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to flag block statements that do not use the one true brace style
 | 
			
		||||
 * @author Ian Christian Myers
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent brace style for blocks",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/brace-style"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["1tbs", "stroustrup", "allman"]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    allowSingleLine: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            nextLineOpen: "Opening curly brace does not appear on the same line as controlling statement.",
 | 
			
		||||
            sameLineOpen: "Opening curly brace appears on the same line as controlling statement.",
 | 
			
		||||
            blockSameLine: "Statement inside of curly braces should be on next line.",
 | 
			
		||||
            nextLineClose: "Closing curly brace does not appear on the same line as the subsequent block.",
 | 
			
		||||
            singleLineClose: "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.",
 | 
			
		||||
            sameLineClose: "Closing curly brace appears on the same line as the subsequent block."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const style = context.options[0] || "1tbs",
 | 
			
		||||
            params = context.options[1] || {},
 | 
			
		||||
            sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Fixes a place where a newline unexpectedly appears
 | 
			
		||||
         * @param {Token} firstToken The token before the unexpected newline
 | 
			
		||||
         * @param {Token} secondToken The token after the unexpected newline
 | 
			
		||||
         * @returns {Function} A fixer function to remove the newlines between the tokens
 | 
			
		||||
         */
 | 
			
		||||
        function removeNewlineBetween(firstToken, secondToken) {
 | 
			
		||||
            const textRange = [firstToken.range[1], secondToken.range[0]];
 | 
			
		||||
            const textBetween = sourceCode.text.slice(textRange[0], textRange[1]);
 | 
			
		||||
 | 
			
		||||
            // Don't do a fix if there is a comment between the tokens
 | 
			
		||||
            if (textBetween.trim()) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            return fixer => fixer.replaceTextRange(textRange, " ");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Validates a pair of curly brackets based on the user's config
 | 
			
		||||
         * @param {Token} openingCurly The opening curly bracket
 | 
			
		||||
         * @param {Token} closingCurly The closing curly bracket
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function validateCurlyPair(openingCurly, closingCurly) {
 | 
			
		||||
            const tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly);
 | 
			
		||||
            const tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly);
 | 
			
		||||
            const tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly);
 | 
			
		||||
            const singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly);
 | 
			
		||||
 | 
			
		||||
            if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: openingCurly,
 | 
			
		||||
                    messageId: "nextLineOpen",
 | 
			
		||||
                    fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly)
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: openingCurly,
 | 
			
		||||
                    messageId: "sameLineOpen",
 | 
			
		||||
                    fix: fixer => fixer.insertTextBefore(openingCurly, "\n")
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: openingCurly,
 | 
			
		||||
                    messageId: "blockSameLine",
 | 
			
		||||
                    fix: fixer => fixer.insertTextAfter(openingCurly, "\n")
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: closingCurly,
 | 
			
		||||
                    messageId: "singleLineClose",
 | 
			
		||||
                    fix: fixer => fixer.insertTextBefore(closingCurly, "\n")
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Validates the location of a token that appears before a keyword (e.g. a newline before `else`)
 | 
			
		||||
         * @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`).
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function validateCurlyBeforeKeyword(curlyToken) {
 | 
			
		||||
            const keywordToken = sourceCode.getTokenAfter(curlyToken);
 | 
			
		||||
 | 
			
		||||
            if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: curlyToken,
 | 
			
		||||
                    messageId: "nextLineClose",
 | 
			
		||||
                    fix: removeNewlineBetween(curlyToken, keywordToken)
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: curlyToken,
 | 
			
		||||
                    messageId: "sameLineClose",
 | 
			
		||||
                    fix: fixer => fixer.insertTextAfter(curlyToken, "\n")
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public API
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            BlockStatement(node) {
 | 
			
		||||
                if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
 | 
			
		||||
                    validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            StaticBlock(node) {
 | 
			
		||||
                validateCurlyPair(
 | 
			
		||||
                    sourceCode.getFirstToken(node, { skip: 1 }), // skip the `static` token
 | 
			
		||||
                    sourceCode.getLastToken(node)
 | 
			
		||||
                );
 | 
			
		||||
            },
 | 
			
		||||
            ClassBody(node) {
 | 
			
		||||
                validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
 | 
			
		||||
            },
 | 
			
		||||
            SwitchStatement(node) {
 | 
			
		||||
                const closingCurly = sourceCode.getLastToken(node);
 | 
			
		||||
                const openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly);
 | 
			
		||||
 | 
			
		||||
                validateCurlyPair(openingCurly, closingCurly);
 | 
			
		||||
            },
 | 
			
		||||
            IfStatement(node) {
 | 
			
		||||
                if (node.consequent.type === "BlockStatement" && node.alternate) {
 | 
			
		||||
 | 
			
		||||
                    // Handle the keyword after the `if` block (before `else`)
 | 
			
		||||
                    validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent));
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            TryStatement(node) {
 | 
			
		||||
 | 
			
		||||
                // Handle the keyword after the `try` block (before `catch` or `finally`)
 | 
			
		||||
                validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block));
 | 
			
		||||
 | 
			
		||||
                if (node.handler && node.finalizer) {
 | 
			
		||||
 | 
			
		||||
                    // Handle the keyword after the `catch` block (before `finally`)
 | 
			
		||||
                    validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										187
									
								
								node_modules/eslint/lib/rules/callback-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								node_modules/eslint/lib/rules/callback-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,187 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Enforce return after a callback.
 | 
			
		||||
 * @author Jamund Ferguson
 | 
			
		||||
 * @deprecated in ESLint v7.0.0
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require `return` statements after callbacks",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/callback-return"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [{
 | 
			
		||||
            type: "array",
 | 
			
		||||
            items: { type: "string" }
 | 
			
		||||
        }],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingReturn: "Expected return with your callback function."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const callbacks = context.options[0] || ["callback", "cb", "next"],
 | 
			
		||||
            sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Find the closest parent matching a list of types.
 | 
			
		||||
         * @param {ASTNode} node The node whose parents we are searching
 | 
			
		||||
         * @param {Array} types The node types to match
 | 
			
		||||
         * @returns {ASTNode} The matched node or undefined.
 | 
			
		||||
         */
 | 
			
		||||
        function findClosestParentOfType(node, types) {
 | 
			
		||||
            if (!node.parent) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            if (!types.includes(node.parent.type)) {
 | 
			
		||||
                return findClosestParentOfType(node.parent, types);
 | 
			
		||||
            }
 | 
			
		||||
            return node.parent;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check to see if a node contains only identifiers
 | 
			
		||||
         * @param {ASTNode} node The node to check
 | 
			
		||||
         * @returns {boolean} Whether or not the node contains only identifiers
 | 
			
		||||
         */
 | 
			
		||||
        function containsOnlyIdentifiers(node) {
 | 
			
		||||
            if (node.type === "Identifier") {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (node.type === "MemberExpression") {
 | 
			
		||||
                if (node.object.type === "Identifier") {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                if (node.object.type === "MemberExpression") {
 | 
			
		||||
                    return containsOnlyIdentifiers(node.object);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check to see if a CallExpression is in our callback list.
 | 
			
		||||
         * @param {ASTNode} node The node to check against our callback names list.
 | 
			
		||||
         * @returns {boolean} Whether or not this function matches our callback name.
 | 
			
		||||
         */
 | 
			
		||||
        function isCallback(node) {
 | 
			
		||||
            return containsOnlyIdentifiers(node.callee) && callbacks.includes(sourceCode.getText(node.callee));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether or not the callback is part of a callback expression.
 | 
			
		||||
         * @param {ASTNode} node The callback node
 | 
			
		||||
         * @param {ASTNode} parentNode The expression node
 | 
			
		||||
         * @returns {boolean} Whether or not this is part of a callback expression
 | 
			
		||||
         */
 | 
			
		||||
        function isCallbackExpression(node, parentNode) {
 | 
			
		||||
 | 
			
		||||
            // ensure the parent node exists and is an expression
 | 
			
		||||
            if (!parentNode || parentNode.type !== "ExpressionStatement") {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // cb()
 | 
			
		||||
            if (parentNode.expression === node) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // special case for cb && cb() and similar
 | 
			
		||||
            if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") {
 | 
			
		||||
                if (parentNode.expression.right === node) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            CallExpression(node) {
 | 
			
		||||
 | 
			
		||||
                // if we're not a callback we can return
 | 
			
		||||
                if (!isCallback(node)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // find the closest block, return or loop
 | 
			
		||||
                const closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {};
 | 
			
		||||
 | 
			
		||||
                // if our parent is a return we know we're ok
 | 
			
		||||
                if (closestBlock.type === "ReturnStatement") {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // arrow functions don't always have blocks and implicitly return
 | 
			
		||||
                if (closestBlock.type === "ArrowFunctionExpression") {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // block statements are part of functions and most if statements
 | 
			
		||||
                if (closestBlock.type === "BlockStatement") {
 | 
			
		||||
 | 
			
		||||
                    // find the last item in the block
 | 
			
		||||
                    const lastItem = closestBlock.body[closestBlock.body.length - 1];
 | 
			
		||||
 | 
			
		||||
                    // if the callback is the last thing in a block that might be ok
 | 
			
		||||
                    if (isCallbackExpression(node, lastItem)) {
 | 
			
		||||
 | 
			
		||||
                        const parentType = closestBlock.parent.type;
 | 
			
		||||
 | 
			
		||||
                        // but only if the block is part of a function
 | 
			
		||||
                        if (parentType === "FunctionExpression" ||
 | 
			
		||||
                            parentType === "FunctionDeclaration" ||
 | 
			
		||||
                            parentType === "ArrowFunctionExpression"
 | 
			
		||||
                        ) {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // ending a block with a return is also ok
 | 
			
		||||
                    if (lastItem.type === "ReturnStatement") {
 | 
			
		||||
 | 
			
		||||
                        // but only if the callback is immediately before
 | 
			
		||||
                        if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // as long as you're the child of a function at this point you should be asked to return
 | 
			
		||||
                if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) {
 | 
			
		||||
                    context.report({ node, messageId: "missingReturn" });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										399
									
								
								node_modules/eslint/lib/rules/camelcase.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										399
									
								
								node_modules/eslint/lib/rules/camelcase.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,399 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to flag non-camelcased identifiers
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce camelcase naming convention",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/camelcase"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    ignoreDestructuring: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    },
 | 
			
		||||
                    ignoreImports: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    },
 | 
			
		||||
                    ignoreGlobals: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    },
 | 
			
		||||
                    properties: {
 | 
			
		||||
                        enum: ["always", "never"]
 | 
			
		||||
                    },
 | 
			
		||||
                    allow: {
 | 
			
		||||
                        type: "array",
 | 
			
		||||
                        items: [
 | 
			
		||||
                            {
 | 
			
		||||
                                type: "string"
 | 
			
		||||
                            }
 | 
			
		||||
                        ],
 | 
			
		||||
                        minItems: 0,
 | 
			
		||||
                        uniqueItems: true
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            notCamelCase: "Identifier '{{name}}' is not in camel case.",
 | 
			
		||||
            notCamelCasePrivate: "#{{name}} is not in camel case."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const options = context.options[0] || {};
 | 
			
		||||
        const properties = options.properties === "never" ? "never" : "always";
 | 
			
		||||
        const ignoreDestructuring = options.ignoreDestructuring;
 | 
			
		||||
        const ignoreImports = options.ignoreImports;
 | 
			
		||||
        const ignoreGlobals = options.ignoreGlobals;
 | 
			
		||||
        const allow = options.allow || [];
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        // contains reported nodes to avoid reporting twice on destructuring with shorthand notation
 | 
			
		||||
        const reported = new Set();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if a string contains an underscore and isn't all upper-case
 | 
			
		||||
         * @param {string} name The string to check.
 | 
			
		||||
         * @returns {boolean} if the string is underscored
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isUnderscored(name) {
 | 
			
		||||
            const nameBody = name.replace(/^_+|_+$/gu, "");
 | 
			
		||||
 | 
			
		||||
            // if there's an underscore, it might be A_CONSTANT, which is okay
 | 
			
		||||
            return nameBody.includes("_") && nameBody !== nameBody.toUpperCase();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if a string match the ignore list
 | 
			
		||||
         * @param {string} name The string to check.
 | 
			
		||||
         * @returns {boolean} if the string is ignored
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isAllowed(name) {
 | 
			
		||||
            return allow.some(
 | 
			
		||||
                entry => name === entry || name.match(new RegExp(entry, "u"))
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if a given name is good or not.
 | 
			
		||||
         * @param {string} name The name to check.
 | 
			
		||||
         * @returns {boolean} `true` if the name is good.
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isGoodName(name) {
 | 
			
		||||
            return !isUnderscored(name) || isAllowed(name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if a given identifier reference or member expression is an assignment
 | 
			
		||||
         * target.
 | 
			
		||||
         * @param {ASTNode} node The node to check.
 | 
			
		||||
         * @returns {boolean} `true` if the node is an assignment target.
 | 
			
		||||
         */
 | 
			
		||||
        function isAssignmentTarget(node) {
 | 
			
		||||
            const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
            switch (parent.type) {
 | 
			
		||||
                case "AssignmentExpression":
 | 
			
		||||
                case "AssignmentPattern":
 | 
			
		||||
                    return parent.left === node;
 | 
			
		||||
 | 
			
		||||
                case "Property":
 | 
			
		||||
                    return (
 | 
			
		||||
                        parent.parent.type === "ObjectPattern" &&
 | 
			
		||||
                        parent.value === node
 | 
			
		||||
                    );
 | 
			
		||||
                case "ArrayPattern":
 | 
			
		||||
                case "RestElement":
 | 
			
		||||
                    return true;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if a given binding identifier uses the original name as-is.
 | 
			
		||||
         * - If it's in object destructuring or object expression, the original name is its property name.
 | 
			
		||||
         * - If it's in import declaration, the original name is its exported name.
 | 
			
		||||
         * @param {ASTNode} node The `Identifier` node to check.
 | 
			
		||||
         * @returns {boolean} `true` if the identifier uses the original name as-is.
 | 
			
		||||
         */
 | 
			
		||||
        function equalsToOriginalName(node) {
 | 
			
		||||
            const localName = node.name;
 | 
			
		||||
            const valueNode = node.parent.type === "AssignmentPattern"
 | 
			
		||||
                ? node.parent
 | 
			
		||||
                : node;
 | 
			
		||||
            const parent = valueNode.parent;
 | 
			
		||||
 | 
			
		||||
            switch (parent.type) {
 | 
			
		||||
                case "Property":
 | 
			
		||||
                    return (
 | 
			
		||||
                        (parent.parent.type === "ObjectPattern" || parent.parent.type === "ObjectExpression") &&
 | 
			
		||||
                        parent.value === valueNode &&
 | 
			
		||||
                        !parent.computed &&
 | 
			
		||||
                        parent.key.type === "Identifier" &&
 | 
			
		||||
                        parent.key.name === localName
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                case "ImportSpecifier":
 | 
			
		||||
                    return (
 | 
			
		||||
                        parent.local === node &&
 | 
			
		||||
                        astUtils.getModuleExportName(parent.imported) === localName
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports an AST node as a rule violation.
 | 
			
		||||
         * @param {ASTNode} node The node to report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function report(node) {
 | 
			
		||||
            if (reported.has(node.range[0])) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            reported.add(node.range[0]);
 | 
			
		||||
 | 
			
		||||
            // Report it.
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                messageId: node.type === "PrivateIdentifier"
 | 
			
		||||
                    ? "notCamelCasePrivate"
 | 
			
		||||
                    : "notCamelCase",
 | 
			
		||||
                data: { name: node.name }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports an identifier reference or a binding identifier.
 | 
			
		||||
         * @param {ASTNode} node The `Identifier` node to report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportReferenceId(node) {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * For backward compatibility, if it's in callings then ignore it.
 | 
			
		||||
             * Not sure why it is.
 | 
			
		||||
             */
 | 
			
		||||
            if (
 | 
			
		||||
                node.parent.type === "CallExpression" ||
 | 
			
		||||
                node.parent.type === "NewExpression"
 | 
			
		||||
            ) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * For backward compatibility, if it's a default value of
 | 
			
		||||
             * destructuring/parameters then ignore it.
 | 
			
		||||
             * Not sure why it is.
 | 
			
		||||
             */
 | 
			
		||||
            if (
 | 
			
		||||
                node.parent.type === "AssignmentPattern" &&
 | 
			
		||||
                node.parent.right === node
 | 
			
		||||
            ) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * The `ignoreDestructuring` flag skips the identifiers that uses
 | 
			
		||||
             * the property name as-is.
 | 
			
		||||
             */
 | 
			
		||||
            if (ignoreDestructuring && equalsToOriginalName(node)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            report(node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            // Report camelcase of global variable references ------------------
 | 
			
		||||
            Program(node) {
 | 
			
		||||
                const scope = sourceCode.getScope(node);
 | 
			
		||||
 | 
			
		||||
                if (!ignoreGlobals) {
 | 
			
		||||
 | 
			
		||||
                    // Defined globals in config files or directive comments.
 | 
			
		||||
                    for (const variable of scope.variables) {
 | 
			
		||||
                        if (
 | 
			
		||||
                            variable.identifiers.length > 0 ||
 | 
			
		||||
                            isGoodName(variable.name)
 | 
			
		||||
                        ) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                        for (const reference of variable.references) {
 | 
			
		||||
 | 
			
		||||
                            /*
 | 
			
		||||
                             * For backward compatibility, this rule reports read-only
 | 
			
		||||
                             * references as well.
 | 
			
		||||
                             */
 | 
			
		||||
                            reportReferenceId(reference.identifier);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Undefined globals.
 | 
			
		||||
                for (const reference of scope.through) {
 | 
			
		||||
                    const id = reference.identifier;
 | 
			
		||||
 | 
			
		||||
                    if (isGoodName(id.name)) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /*
 | 
			
		||||
                     * For backward compatibility, this rule reports read-only
 | 
			
		||||
                     * references as well.
 | 
			
		||||
                     */
 | 
			
		||||
                    reportReferenceId(id);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Report camelcase of declared variables --------------------------
 | 
			
		||||
            [[
 | 
			
		||||
                "VariableDeclaration",
 | 
			
		||||
                "FunctionDeclaration",
 | 
			
		||||
                "FunctionExpression",
 | 
			
		||||
                "ArrowFunctionExpression",
 | 
			
		||||
                "ClassDeclaration",
 | 
			
		||||
                "ClassExpression",
 | 
			
		||||
                "CatchClause"
 | 
			
		||||
            ]](node) {
 | 
			
		||||
                for (const variable of sourceCode.getDeclaredVariables(node)) {
 | 
			
		||||
                    if (isGoodName(variable.name)) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    const id = variable.identifiers[0];
 | 
			
		||||
 | 
			
		||||
                    // Report declaration.
 | 
			
		||||
                    if (!(ignoreDestructuring && equalsToOriginalName(id))) {
 | 
			
		||||
                        report(id);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /*
 | 
			
		||||
                     * For backward compatibility, report references as well.
 | 
			
		||||
                     * It looks unnecessary because declarations are reported.
 | 
			
		||||
                     */
 | 
			
		||||
                    for (const reference of variable.references) {
 | 
			
		||||
                        if (reference.init) {
 | 
			
		||||
                            continue; // Skip the write references of initializers.
 | 
			
		||||
                        }
 | 
			
		||||
                        reportReferenceId(reference.identifier);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Report camelcase in properties ----------------------------------
 | 
			
		||||
            [[
 | 
			
		||||
                "ObjectExpression > Property[computed!=true] > Identifier.key",
 | 
			
		||||
                "MethodDefinition[computed!=true] > Identifier.key",
 | 
			
		||||
                "PropertyDefinition[computed!=true] > Identifier.key",
 | 
			
		||||
                "MethodDefinition > PrivateIdentifier.key",
 | 
			
		||||
                "PropertyDefinition > PrivateIdentifier.key"
 | 
			
		||||
            ]](node) {
 | 
			
		||||
                if (properties === "never" || isGoodName(node.name)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                report(node);
 | 
			
		||||
            },
 | 
			
		||||
            "MemberExpression[computed!=true] > Identifier.property"(node) {
 | 
			
		||||
                if (
 | 
			
		||||
                    properties === "never" ||
 | 
			
		||||
                    !isAssignmentTarget(node.parent) || // ← ignore read-only references.
 | 
			
		||||
                    isGoodName(node.name)
 | 
			
		||||
                ) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                report(node);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Report camelcase in import --------------------------------------
 | 
			
		||||
            ImportDeclaration(node) {
 | 
			
		||||
                for (const variable of sourceCode.getDeclaredVariables(node)) {
 | 
			
		||||
                    if (isGoodName(variable.name)) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    const id = variable.identifiers[0];
 | 
			
		||||
 | 
			
		||||
                    // Report declaration.
 | 
			
		||||
                    if (!(ignoreImports && equalsToOriginalName(id))) {
 | 
			
		||||
                        report(id);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /*
 | 
			
		||||
                     * For backward compatibility, report references as well.
 | 
			
		||||
                     * It looks unnecessary because declarations are reported.
 | 
			
		||||
                     */
 | 
			
		||||
                    for (const reference of variable.references) {
 | 
			
		||||
                        reportReferenceId(reference.identifier);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Report camelcase in re-export -----------------------------------
 | 
			
		||||
            [[
 | 
			
		||||
                "ExportAllDeclaration > Identifier.exported",
 | 
			
		||||
                "ExportSpecifier > Identifier.exported"
 | 
			
		||||
            ]](node) {
 | 
			
		||||
                if (isGoodName(node.name)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                report(node);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Report camelcase in labels --------------------------------------
 | 
			
		||||
            [[
 | 
			
		||||
                "LabeledStatement > Identifier.label",
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * For backward compatibility, report references as well.
 | 
			
		||||
                 * It looks unnecessary because declarations are reported.
 | 
			
		||||
                 */
 | 
			
		||||
                "BreakStatement > Identifier.label",
 | 
			
		||||
                "ContinueStatement > Identifier.label"
 | 
			
		||||
            ]](node) {
 | 
			
		||||
                if (isGoodName(node.name)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                report(node);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										300
									
								
								node_modules/eslint/lib/rules/capitalized-comments.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								node_modules/eslint/lib/rules/capitalized-comments.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,300 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview enforce or disallow capitalization of the first letter of a comment
 | 
			
		||||
 * @author Kevin Partington
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const LETTER_PATTERN = require("./utils/patterns/letters");
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN,
 | 
			
		||||
    WHITESPACE = /\s/gu,
 | 
			
		||||
    MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/u; // TODO: Combine w/ max-len pattern?
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Base schema body for defining the basic capitalization rule, ignorePattern,
 | 
			
		||||
 * and ignoreInlineComments values.
 | 
			
		||||
 * This can be used in a few different ways in the actual schema.
 | 
			
		||||
 */
 | 
			
		||||
const SCHEMA_BODY = {
 | 
			
		||||
    type: "object",
 | 
			
		||||
    properties: {
 | 
			
		||||
        ignorePattern: {
 | 
			
		||||
            type: "string"
 | 
			
		||||
        },
 | 
			
		||||
        ignoreInlineComments: {
 | 
			
		||||
            type: "boolean"
 | 
			
		||||
        },
 | 
			
		||||
        ignoreConsecutiveComments: {
 | 
			
		||||
            type: "boolean"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    additionalProperties: false
 | 
			
		||||
};
 | 
			
		||||
const DEFAULTS = {
 | 
			
		||||
    ignorePattern: "",
 | 
			
		||||
    ignoreInlineComments: false,
 | 
			
		||||
    ignoreConsecutiveComments: false
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get normalized options for either block or line comments from the given
 | 
			
		||||
 * user-provided options.
 | 
			
		||||
 * - If the user-provided options is just a string, returns a normalized
 | 
			
		||||
 *   set of options using default values for all other options.
 | 
			
		||||
 * - If the user-provided options is an object, then a normalized option
 | 
			
		||||
 *   set is returned. Options specified in overrides will take priority
 | 
			
		||||
 *   over options specified in the main options object, which will in
 | 
			
		||||
 *   turn take priority over the rule's defaults.
 | 
			
		||||
 * @param {Object|string} rawOptions The user-provided options.
 | 
			
		||||
 * @param {string} which Either "line" or "block".
 | 
			
		||||
 * @returns {Object} The normalized options.
 | 
			
		||||
 */
 | 
			
		||||
function getNormalizedOptions(rawOptions, which) {
 | 
			
		||||
    return Object.assign({}, DEFAULTS, rawOptions[which] || rawOptions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get normalized options for block and line comments.
 | 
			
		||||
 * @param {Object|string} rawOptions The user-provided options.
 | 
			
		||||
 * @returns {Object} An object with "Line" and "Block" keys and corresponding
 | 
			
		||||
 * normalized options objects.
 | 
			
		||||
 */
 | 
			
		||||
function getAllNormalizedOptions(rawOptions = {}) {
 | 
			
		||||
    return {
 | 
			
		||||
        Line: getNormalizedOptions(rawOptions, "line"),
 | 
			
		||||
        Block: getNormalizedOptions(rawOptions, "block")
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a regular expression for each ignorePattern defined in the rule
 | 
			
		||||
 * options.
 | 
			
		||||
 *
 | 
			
		||||
 * This is done in order to avoid invoking the RegExp constructor repeatedly.
 | 
			
		||||
 * @param {Object} normalizedOptions The normalized rule options.
 | 
			
		||||
 * @returns {void}
 | 
			
		||||
 */
 | 
			
		||||
function createRegExpForIgnorePatterns(normalizedOptions) {
 | 
			
		||||
    Object.keys(normalizedOptions).forEach(key => {
 | 
			
		||||
        const ignorePatternStr = normalizedOptions[key].ignorePattern;
 | 
			
		||||
 | 
			
		||||
        if (ignorePatternStr) {
 | 
			
		||||
            const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`, "u");
 | 
			
		||||
 | 
			
		||||
            normalizedOptions[key].ignorePatternRegExp = regExp;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce or disallow capitalization of the first letter of a comment",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/capitalized-comments"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            { enum: ["always", "never"] },
 | 
			
		||||
            {
 | 
			
		||||
                oneOf: [
 | 
			
		||||
                    SCHEMA_BODY,
 | 
			
		||||
                    {
 | 
			
		||||
                        type: "object",
 | 
			
		||||
                        properties: {
 | 
			
		||||
                            line: SCHEMA_BODY,
 | 
			
		||||
                            block: SCHEMA_BODY
 | 
			
		||||
                        },
 | 
			
		||||
                        additionalProperties: false
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedLowercaseComment: "Comments should not begin with a lowercase character.",
 | 
			
		||||
            unexpectedUppercaseComment: "Comments should not begin with an uppercase character."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const capitalize = context.options[0] || "always",
 | 
			
		||||
            normalizedOptions = getAllNormalizedOptions(context.options[1]),
 | 
			
		||||
            sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        createRegExpForIgnorePatterns(normalizedOptions);
 | 
			
		||||
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether a comment is an inline comment.
 | 
			
		||||
         *
 | 
			
		||||
         * For the purpose of this rule, a comment is inline if:
 | 
			
		||||
         * 1. The comment is preceded by a token on the same line; and
 | 
			
		||||
         * 2. The command is followed by a token on the same line.
 | 
			
		||||
         *
 | 
			
		||||
         * Note that the comment itself need not be single-line!
 | 
			
		||||
         *
 | 
			
		||||
         * Also, it follows from this definition that only block comments can
 | 
			
		||||
         * be considered as possibly inline. This is because line comments
 | 
			
		||||
         * would consume any following tokens on the same line as the comment.
 | 
			
		||||
         * @param {ASTNode} comment The comment node to check.
 | 
			
		||||
         * @returns {boolean} True if the comment is an inline comment, false
 | 
			
		||||
         * otherwise.
 | 
			
		||||
         */
 | 
			
		||||
        function isInlineComment(comment) {
 | 
			
		||||
            const previousToken = sourceCode.getTokenBefore(comment, { includeComments: true }),
 | 
			
		||||
                nextToken = sourceCode.getTokenAfter(comment, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
            return Boolean(
 | 
			
		||||
                previousToken &&
 | 
			
		||||
                nextToken &&
 | 
			
		||||
                comment.loc.start.line === previousToken.loc.end.line &&
 | 
			
		||||
                comment.loc.end.line === nextToken.loc.start.line
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determine if a comment follows another comment.
 | 
			
		||||
         * @param {ASTNode} comment The comment to check.
 | 
			
		||||
         * @returns {boolean} True if the comment follows a valid comment.
 | 
			
		||||
         */
 | 
			
		||||
        function isConsecutiveComment(comment) {
 | 
			
		||||
            const previousTokenOrComment = sourceCode.getTokenBefore(comment, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
            return Boolean(
 | 
			
		||||
                previousTokenOrComment &&
 | 
			
		||||
                ["Block", "Line"].includes(previousTokenOrComment.type)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check a comment to determine if it is valid for this rule.
 | 
			
		||||
         * @param {ASTNode} comment The comment node to process.
 | 
			
		||||
         * @param {Object} options The options for checking this comment.
 | 
			
		||||
         * @returns {boolean} True if the comment is valid, false otherwise.
 | 
			
		||||
         */
 | 
			
		||||
        function isCommentValid(comment, options) {
 | 
			
		||||
 | 
			
		||||
            // 1. Check for default ignore pattern.
 | 
			
		||||
            if (DEFAULT_IGNORE_PATTERN.test(comment.value)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 2. Check for custom ignore pattern.
 | 
			
		||||
            const commentWithoutAsterisks = comment.value
 | 
			
		||||
                .replace(/\*/gu, "");
 | 
			
		||||
 | 
			
		||||
            if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 3. Check for inline comments.
 | 
			
		||||
            if (options.ignoreInlineComments && isInlineComment(comment)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 4. Is this a consecutive comment (and are we tolerating those)?
 | 
			
		||||
            if (options.ignoreConsecutiveComments && isConsecutiveComment(comment)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 5. Does the comment start with a possible URL?
 | 
			
		||||
            if (MAYBE_URL.test(commentWithoutAsterisks)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 6. Is the initial word character a letter?
 | 
			
		||||
            const commentWordCharsOnly = commentWithoutAsterisks
 | 
			
		||||
                .replace(WHITESPACE, "");
 | 
			
		||||
 | 
			
		||||
            if (commentWordCharsOnly.length === 0) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const firstWordChar = commentWordCharsOnly[0];
 | 
			
		||||
 | 
			
		||||
            if (!LETTER_PATTERN.test(firstWordChar)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 7. Check the case of the initial word character.
 | 
			
		||||
            const isUppercase = firstWordChar !== firstWordChar.toLocaleLowerCase(),
 | 
			
		||||
                isLowercase = firstWordChar !== firstWordChar.toLocaleUpperCase();
 | 
			
		||||
 | 
			
		||||
            if (capitalize === "always" && isLowercase) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            if (capitalize === "never" && isUppercase) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Process a comment to determine if it needs to be reported.
 | 
			
		||||
         * @param {ASTNode} comment The comment node to process.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function processComment(comment) {
 | 
			
		||||
            const options = normalizedOptions[comment.type],
 | 
			
		||||
                commentValid = isCommentValid(comment, options);
 | 
			
		||||
 | 
			
		||||
            if (!commentValid) {
 | 
			
		||||
                const messageId = capitalize === "always"
 | 
			
		||||
                    ? "unexpectedLowercaseComment"
 | 
			
		||||
                    : "unexpectedUppercaseComment";
 | 
			
		||||
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: null, // Intentionally using loc instead
 | 
			
		||||
                    loc: comment.loc,
 | 
			
		||||
                    messageId,
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
                        const match = comment.value.match(LETTER_PATTERN);
 | 
			
		||||
 | 
			
		||||
                        return fixer.replaceTextRange(
 | 
			
		||||
 | 
			
		||||
                            // Offset match.index by 2 to account for the first 2 characters that start the comment (// or /*)
 | 
			
		||||
                            [comment.range[0] + match.index + 2, comment.range[0] + match.index + 3],
 | 
			
		||||
                            capitalize === "always" ? match[0].toLocaleUpperCase() : match[0].toLocaleLowerCase()
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            Program() {
 | 
			
		||||
                const comments = sourceCode.getAllComments();
 | 
			
		||||
 | 
			
		||||
                comments.filter(token => token.type !== "Shebang").forEach(processComment);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										187
									
								
								node_modules/eslint/lib/rules/class-methods-use-this.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								node_modules/eslint/lib/rules/class-methods-use-this.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,187 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce that all class methods use 'this'.
 | 
			
		||||
 * @author Patrick Williams
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce that class methods utilize `this`",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/class-methods-use-this"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [{
 | 
			
		||||
            type: "object",
 | 
			
		||||
            properties: {
 | 
			
		||||
                exceptMethods: {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: {
 | 
			
		||||
                        type: "string"
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                enforceForClassFields: {
 | 
			
		||||
                    type: "boolean",
 | 
			
		||||
                    default: true
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            additionalProperties: false
 | 
			
		||||
        }],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingThis: "Expected 'this' to be used by class {{name}}."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const config = Object.assign({}, context.options[0]);
 | 
			
		||||
        const enforceForClassFields = config.enforceForClassFields !== false;
 | 
			
		||||
        const exceptMethods = new Set(config.exceptMethods || []);
 | 
			
		||||
 | 
			
		||||
        const stack = [];
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Push `this` used flag initialized with `false` onto the stack.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function pushContext() {
 | 
			
		||||
            stack.push(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Pop `this` used flag from the stack.
 | 
			
		||||
         * @returns {boolean | undefined} `this` used flag
 | 
			
		||||
         */
 | 
			
		||||
        function popContext() {
 | 
			
		||||
            return stack.pop();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Initializes the current context to false and pushes it onto the stack.
 | 
			
		||||
         * These booleans represent whether 'this' has been used in the context.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function enterFunction() {
 | 
			
		||||
            pushContext();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check if the node is an instance method
 | 
			
		||||
         * @param {ASTNode} node node to check
 | 
			
		||||
         * @returns {boolean} True if its an instance method
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isInstanceMethod(node) {
 | 
			
		||||
            switch (node.type) {
 | 
			
		||||
                case "MethodDefinition":
 | 
			
		||||
                    return !node.static && node.kind !== "constructor";
 | 
			
		||||
                case "PropertyDefinition":
 | 
			
		||||
                    return !node.static && enforceForClassFields;
 | 
			
		||||
                default:
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check if the node is an instance method not excluded by config
 | 
			
		||||
         * @param {ASTNode} node node to check
 | 
			
		||||
         * @returns {boolean} True if it is an instance method, and not excluded by config
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isIncludedInstanceMethod(node) {
 | 
			
		||||
            if (isInstanceMethod(node)) {
 | 
			
		||||
                if (node.computed) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const hashIfNeeded = node.key.type === "PrivateIdentifier" ? "#" : "";
 | 
			
		||||
                const name = node.key.type === "Literal"
 | 
			
		||||
                    ? astUtils.getStaticStringValue(node.key)
 | 
			
		||||
                    : (node.key.name || "");
 | 
			
		||||
 | 
			
		||||
                return !exceptMethods.has(hashIfNeeded + name);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if we are leaving a function that is a method, and reports if 'this' has not been used.
 | 
			
		||||
         * Static methods and the constructor are exempt.
 | 
			
		||||
         * Then pops the context off the stack.
 | 
			
		||||
         * @param {ASTNode} node A function node that was entered.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function exitFunction(node) {
 | 
			
		||||
            const methodUsesThis = popContext();
 | 
			
		||||
 | 
			
		||||
            if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc: astUtils.getFunctionHeadLoc(node, context.sourceCode),
 | 
			
		||||
                    messageId: "missingThis",
 | 
			
		||||
                    data: {
 | 
			
		||||
                        name: astUtils.getFunctionNameWithKind(node)
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Mark the current context as having used 'this'.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function markThisUsed() {
 | 
			
		||||
            if (stack.length) {
 | 
			
		||||
                stack[stack.length - 1] = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            FunctionDeclaration: enterFunction,
 | 
			
		||||
            "FunctionDeclaration:exit": exitFunction,
 | 
			
		||||
            FunctionExpression: enterFunction,
 | 
			
		||||
            "FunctionExpression:exit": exitFunction,
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Class field value are implicit functions.
 | 
			
		||||
             */
 | 
			
		||||
            "PropertyDefinition > *.key:exit": pushContext,
 | 
			
		||||
            "PropertyDefinition:exit": popContext,
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Class static blocks are implicit functions. They aren't required to use `this`,
 | 
			
		||||
             * but we have to push context so that it captures any use of `this` in the static block
 | 
			
		||||
             * separately from enclosing contexts, because static blocks have their own `this` and it
 | 
			
		||||
             * shouldn't count as used `this` in enclosing contexts.
 | 
			
		||||
             */
 | 
			
		||||
            StaticBlock: pushContext,
 | 
			
		||||
            "StaticBlock:exit": popContext,
 | 
			
		||||
 | 
			
		||||
            ThisExpression: markThisUsed,
 | 
			
		||||
            Super: markThisUsed,
 | 
			
		||||
            ...(
 | 
			
		||||
                enforceForClassFields && {
 | 
			
		||||
                    "PropertyDefinition > ArrowFunctionExpression.value": enterFunction,
 | 
			
		||||
                    "PropertyDefinition > ArrowFunctionExpression.value:exit": exitFunction
 | 
			
		||||
                }
 | 
			
		||||
            )
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										373
									
								
								node_modules/eslint/lib/rules/comma-dangle.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										373
									
								
								node_modules/eslint/lib/rules/comma-dangle.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,373 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to forbid or enforce dangling commas.
 | 
			
		||||
 * @author Ian Christian Myers
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const DEFAULT_OPTIONS = Object.freeze({
 | 
			
		||||
    arrays: "never",
 | 
			
		||||
    objects: "never",
 | 
			
		||||
    imports: "never",
 | 
			
		||||
    exports: "never",
 | 
			
		||||
    functions: "never"
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a trailing comma is allowed in a given node.
 | 
			
		||||
 * If the `lastItem` is `RestElement` or `RestProperty`, it disallows trailing commas.
 | 
			
		||||
 * @param {ASTNode} lastItem The node of the last element in the given node.
 | 
			
		||||
 * @returns {boolean} `true` if a trailing comma is allowed.
 | 
			
		||||
 */
 | 
			
		||||
function isTrailingCommaAllowed(lastItem) {
 | 
			
		||||
    return !(
 | 
			
		||||
        lastItem.type === "RestElement" ||
 | 
			
		||||
        lastItem.type === "RestProperty" ||
 | 
			
		||||
        lastItem.type === "ExperimentalRestProperty"
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Normalize option value.
 | 
			
		||||
 * @param {string|Object|undefined} optionValue The 1st option value to normalize.
 | 
			
		||||
 * @param {number} ecmaVersion The normalized ECMAScript version.
 | 
			
		||||
 * @returns {Object} The normalized option value.
 | 
			
		||||
 */
 | 
			
		||||
function normalizeOptions(optionValue, ecmaVersion) {
 | 
			
		||||
    if (typeof optionValue === "string") {
 | 
			
		||||
        return {
 | 
			
		||||
            arrays: optionValue,
 | 
			
		||||
            objects: optionValue,
 | 
			
		||||
            imports: optionValue,
 | 
			
		||||
            exports: optionValue,
 | 
			
		||||
            functions: ecmaVersion < 2017 ? "ignore" : optionValue
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof optionValue === "object" && optionValue !== null) {
 | 
			
		||||
        return {
 | 
			
		||||
            arrays: optionValue.arrays || DEFAULT_OPTIONS.arrays,
 | 
			
		||||
            objects: optionValue.objects || DEFAULT_OPTIONS.objects,
 | 
			
		||||
            imports: optionValue.imports || DEFAULT_OPTIONS.imports,
 | 
			
		||||
            exports: optionValue.exports || DEFAULT_OPTIONS.exports,
 | 
			
		||||
            functions: optionValue.functions || DEFAULT_OPTIONS.functions
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return DEFAULT_OPTIONS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require or disallow trailing commas",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/comma-dangle"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            definitions: {
 | 
			
		||||
                value: {
 | 
			
		||||
                    enum: [
 | 
			
		||||
                        "always-multiline",
 | 
			
		||||
                        "always",
 | 
			
		||||
                        "never",
 | 
			
		||||
                        "only-multiline"
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                valueWithIgnore: {
 | 
			
		||||
                    enum: [
 | 
			
		||||
                        "always-multiline",
 | 
			
		||||
                        "always",
 | 
			
		||||
                        "ignore",
 | 
			
		||||
                        "never",
 | 
			
		||||
                        "only-multiline"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            type: "array",
 | 
			
		||||
            items: [
 | 
			
		||||
                {
 | 
			
		||||
                    oneOf: [
 | 
			
		||||
                        {
 | 
			
		||||
                            $ref: "#/definitions/value"
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: "object",
 | 
			
		||||
                            properties: {
 | 
			
		||||
                                arrays: { $ref: "#/definitions/valueWithIgnore" },
 | 
			
		||||
                                objects: { $ref: "#/definitions/valueWithIgnore" },
 | 
			
		||||
                                imports: { $ref: "#/definitions/valueWithIgnore" },
 | 
			
		||||
                                exports: { $ref: "#/definitions/valueWithIgnore" },
 | 
			
		||||
                                functions: { $ref: "#/definitions/valueWithIgnore" }
 | 
			
		||||
                            },
 | 
			
		||||
                            additionalProperties: false
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            additionalItems: false
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpected: "Unexpected trailing comma.",
 | 
			
		||||
            missing: "Missing trailing comma."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const options = normalizeOptions(context.options[0], context.languageOptions.ecmaVersion);
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Gets the last item of the given node.
 | 
			
		||||
         * @param {ASTNode} node The node to get.
 | 
			
		||||
         * @returns {ASTNode|null} The last node or null.
 | 
			
		||||
         */
 | 
			
		||||
        function getLastItem(node) {
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Returns the last element of an array
 | 
			
		||||
             * @param {any[]} array The input array
 | 
			
		||||
             * @returns {any} The last element
 | 
			
		||||
             */
 | 
			
		||||
            function last(array) {
 | 
			
		||||
                return array[array.length - 1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            switch (node.type) {
 | 
			
		||||
                case "ObjectExpression":
 | 
			
		||||
                case "ObjectPattern":
 | 
			
		||||
                    return last(node.properties);
 | 
			
		||||
                case "ArrayExpression":
 | 
			
		||||
                case "ArrayPattern":
 | 
			
		||||
                    return last(node.elements);
 | 
			
		||||
                case "ImportDeclaration":
 | 
			
		||||
                case "ExportNamedDeclaration":
 | 
			
		||||
                    return last(node.specifiers);
 | 
			
		||||
                case "FunctionDeclaration":
 | 
			
		||||
                case "FunctionExpression":
 | 
			
		||||
                case "ArrowFunctionExpression":
 | 
			
		||||
                    return last(node.params);
 | 
			
		||||
                case "CallExpression":
 | 
			
		||||
                case "NewExpression":
 | 
			
		||||
                    return last(node.arguments);
 | 
			
		||||
                default:
 | 
			
		||||
                    return null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Gets the trailing comma token of the given node.
 | 
			
		||||
         * If the trailing comma does not exist, this returns the token which is
 | 
			
		||||
         * the insertion point of the trailing comma token.
 | 
			
		||||
         * @param {ASTNode} node The node to get.
 | 
			
		||||
         * @param {ASTNode} lastItem The last item of the node.
 | 
			
		||||
         * @returns {Token} The trailing comma token or the insertion point.
 | 
			
		||||
         */
 | 
			
		||||
        function getTrailingToken(node, lastItem) {
 | 
			
		||||
            switch (node.type) {
 | 
			
		||||
                case "ObjectExpression":
 | 
			
		||||
                case "ArrayExpression":
 | 
			
		||||
                case "CallExpression":
 | 
			
		||||
                case "NewExpression":
 | 
			
		||||
                    return sourceCode.getLastToken(node, 1);
 | 
			
		||||
                default: {
 | 
			
		||||
                    const nextToken = sourceCode.getTokenAfter(lastItem);
 | 
			
		||||
 | 
			
		||||
                    if (astUtils.isCommaToken(nextToken)) {
 | 
			
		||||
                        return nextToken;
 | 
			
		||||
                    }
 | 
			
		||||
                    return sourceCode.getLastToken(lastItem);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether or not a given node is multiline.
 | 
			
		||||
         * This rule handles a given node as multiline when the closing parenthesis
 | 
			
		||||
         * and the last element are not on the same line.
 | 
			
		||||
         * @param {ASTNode} node A node to check.
 | 
			
		||||
         * @returns {boolean} `true` if the node is multiline.
 | 
			
		||||
         */
 | 
			
		||||
        function isMultiline(node) {
 | 
			
		||||
            const lastItem = getLastItem(node);
 | 
			
		||||
 | 
			
		||||
            if (!lastItem) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const penultimateToken = getTrailingToken(node, lastItem);
 | 
			
		||||
            const lastToken = sourceCode.getTokenAfter(penultimateToken);
 | 
			
		||||
 | 
			
		||||
            return lastToken.loc.end.line !== penultimateToken.loc.end.line;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports a trailing comma if it exists.
 | 
			
		||||
         * @param {ASTNode} node A node to check. Its type is one of
 | 
			
		||||
         *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
 | 
			
		||||
         *   ImportDeclaration, and ExportNamedDeclaration.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function forbidTrailingComma(node) {
 | 
			
		||||
            const lastItem = getLastItem(node);
 | 
			
		||||
 | 
			
		||||
            if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const trailingToken = getTrailingToken(node, lastItem);
 | 
			
		||||
 | 
			
		||||
            if (astUtils.isCommaToken(trailingToken)) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: lastItem,
 | 
			
		||||
                    loc: trailingToken.loc,
 | 
			
		||||
                    messageId: "unexpected",
 | 
			
		||||
                    *fix(fixer) {
 | 
			
		||||
                        yield fixer.remove(trailingToken);
 | 
			
		||||
 | 
			
		||||
                        /*
 | 
			
		||||
                         * Extend the range of the fix to include surrounding tokens to ensure
 | 
			
		||||
                         * that the element after which the comma is removed stays _last_.
 | 
			
		||||
                         * This intentionally makes conflicts in fix ranges with rules that may be
 | 
			
		||||
                         * adding or removing elements in the same autofix pass.
 | 
			
		||||
                         * https://github.com/eslint/eslint/issues/15660
 | 
			
		||||
                         */
 | 
			
		||||
                        yield fixer.insertTextBefore(sourceCode.getTokenBefore(trailingToken), "");
 | 
			
		||||
                        yield fixer.insertTextAfter(sourceCode.getTokenAfter(trailingToken), "");
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports the last element of a given node if it does not have a trailing
 | 
			
		||||
         * comma.
 | 
			
		||||
         *
 | 
			
		||||
         * If a given node is `ArrayPattern` which has `RestElement`, the trailing
 | 
			
		||||
         * comma is disallowed, so report if it exists.
 | 
			
		||||
         * @param {ASTNode} node A node to check. Its type is one of
 | 
			
		||||
         *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
 | 
			
		||||
         *   ImportDeclaration, and ExportNamedDeclaration.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function forceTrailingComma(node) {
 | 
			
		||||
            const lastItem = getLastItem(node);
 | 
			
		||||
 | 
			
		||||
            if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (!isTrailingCommaAllowed(lastItem)) {
 | 
			
		||||
                forbidTrailingComma(node);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const trailingToken = getTrailingToken(node, lastItem);
 | 
			
		||||
 | 
			
		||||
            if (trailingToken.value !== ",") {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: lastItem,
 | 
			
		||||
                    loc: {
 | 
			
		||||
                        start: trailingToken.loc.end,
 | 
			
		||||
                        end: astUtils.getNextLocation(sourceCode, trailingToken.loc.end)
 | 
			
		||||
                    },
 | 
			
		||||
                    messageId: "missing",
 | 
			
		||||
                    *fix(fixer) {
 | 
			
		||||
                        yield fixer.insertTextAfter(trailingToken, ",");
 | 
			
		||||
 | 
			
		||||
                        /*
 | 
			
		||||
                         * Extend the range of the fix to include surrounding tokens to ensure
 | 
			
		||||
                         * that the element after which the comma is inserted stays _last_.
 | 
			
		||||
                         * This intentionally makes conflicts in fix ranges with rules that may be
 | 
			
		||||
                         * adding or removing elements in the same autofix pass.
 | 
			
		||||
                         * https://github.com/eslint/eslint/issues/15660
 | 
			
		||||
                         */
 | 
			
		||||
                        yield fixer.insertTextBefore(trailingToken, "");
 | 
			
		||||
                        yield fixer.insertTextAfter(sourceCode.getTokenAfter(trailingToken), "");
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * If a given node is multiline, reports the last element of a given node
 | 
			
		||||
         * when it does not have a trailing comma.
 | 
			
		||||
         * Otherwise, reports a trailing comma if it exists.
 | 
			
		||||
         * @param {ASTNode} node A node to check. Its type is one of
 | 
			
		||||
         *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
 | 
			
		||||
         *   ImportDeclaration, and ExportNamedDeclaration.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function forceTrailingCommaIfMultiline(node) {
 | 
			
		||||
            if (isMultiline(node)) {
 | 
			
		||||
                forceTrailingComma(node);
 | 
			
		||||
            } else {
 | 
			
		||||
                forbidTrailingComma(node);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Only if a given node is not multiline, reports the last element of a given node
 | 
			
		||||
         * when it does not have a trailing comma.
 | 
			
		||||
         * Otherwise, reports a trailing comma if it exists.
 | 
			
		||||
         * @param {ASTNode} node A node to check. Its type is one of
 | 
			
		||||
         *   ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
 | 
			
		||||
         *   ImportDeclaration, and ExportNamedDeclaration.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function allowTrailingCommaIfMultiline(node) {
 | 
			
		||||
            if (!isMultiline(node)) {
 | 
			
		||||
                forbidTrailingComma(node);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const predicate = {
 | 
			
		||||
            always: forceTrailingComma,
 | 
			
		||||
            "always-multiline": forceTrailingCommaIfMultiline,
 | 
			
		||||
            "only-multiline": allowTrailingCommaIfMultiline,
 | 
			
		||||
            never: forbidTrailingComma,
 | 
			
		||||
            ignore() {}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            ObjectExpression: predicate[options.objects],
 | 
			
		||||
            ObjectPattern: predicate[options.objects],
 | 
			
		||||
 | 
			
		||||
            ArrayExpression: predicate[options.arrays],
 | 
			
		||||
            ArrayPattern: predicate[options.arrays],
 | 
			
		||||
 | 
			
		||||
            ImportDeclaration: predicate[options.imports],
 | 
			
		||||
 | 
			
		||||
            ExportNamedDeclaration: predicate[options.exports],
 | 
			
		||||
 | 
			
		||||
            FunctionDeclaration: predicate[options.functions],
 | 
			
		||||
            FunctionExpression: predicate[options.functions],
 | 
			
		||||
            ArrowFunctionExpression: predicate[options.functions],
 | 
			
		||||
            CallExpression: predicate[options.functions],
 | 
			
		||||
            NewExpression: predicate[options.functions]
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										192
									
								
								node_modules/eslint/lib/rules/comma-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								node_modules/eslint/lib/rules/comma-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Comma spacing - validates spacing before and after comma
 | 
			
		||||
 * @author Vignesh Anand aka vegetableman.
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent spacing before and after commas",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/comma-spacing"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    before: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    },
 | 
			
		||||
                    after: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: true
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missing: "A space is required {{loc}} ','.",
 | 
			
		||||
            unexpected: "There should be no space {{loc}} ','."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
        const tokensAndComments = sourceCode.tokensAndComments;
 | 
			
		||||
 | 
			
		||||
        const options = {
 | 
			
		||||
            before: context.options[0] ? context.options[0].before : false,
 | 
			
		||||
            after: context.options[0] ? context.options[0].after : true
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        // list of comma tokens to ignore for the check of leading whitespace
 | 
			
		||||
        const commaTokensToIgnore = [];
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports a spacing error with an appropriate message.
 | 
			
		||||
         * @param {ASTNode} node The binary expression node to report.
 | 
			
		||||
         * @param {string} loc Is the error "before" or "after" the comma?
 | 
			
		||||
         * @param {ASTNode} otherNode The node at the left or right of `node`
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function report(node, loc, otherNode) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    if (options[loc]) {
 | 
			
		||||
                        if (loc === "before") {
 | 
			
		||||
                            return fixer.insertTextBefore(node, " ");
 | 
			
		||||
                        }
 | 
			
		||||
                        return fixer.insertTextAfter(node, " ");
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    let start, end;
 | 
			
		||||
                    const newText = "";
 | 
			
		||||
 | 
			
		||||
                    if (loc === "before") {
 | 
			
		||||
                        start = otherNode.range[1];
 | 
			
		||||
                        end = node.range[0];
 | 
			
		||||
                    } else {
 | 
			
		||||
                        start = node.range[1];
 | 
			
		||||
                        end = otherNode.range[0];
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return fixer.replaceTextRange([start, end], newText);
 | 
			
		||||
 | 
			
		||||
                },
 | 
			
		||||
                messageId: options[loc] ? "missing" : "unexpected",
 | 
			
		||||
                data: {
 | 
			
		||||
                    loc
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list.
 | 
			
		||||
         * @param {ASTNode} node An ArrayExpression or ArrayPattern node.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function addNullElementsToIgnoreList(node) {
 | 
			
		||||
            let previousToken = sourceCode.getFirstToken(node);
 | 
			
		||||
 | 
			
		||||
            node.elements.forEach(element => {
 | 
			
		||||
                let token;
 | 
			
		||||
 | 
			
		||||
                if (element === null) {
 | 
			
		||||
                    token = sourceCode.getTokenAfter(previousToken);
 | 
			
		||||
 | 
			
		||||
                    if (astUtils.isCommaToken(token)) {
 | 
			
		||||
                        commaTokensToIgnore.push(token);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    token = sourceCode.getTokenAfter(element);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                previousToken = token;
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            "Program:exit"() {
 | 
			
		||||
                tokensAndComments.forEach((token, i) => {
 | 
			
		||||
 | 
			
		||||
                    if (!astUtils.isCommaToken(token)) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    const previousToken = tokensAndComments[i - 1];
 | 
			
		||||
                    const nextToken = tokensAndComments[i + 1];
 | 
			
		||||
 | 
			
		||||
                    if (
 | 
			
		||||
                        previousToken &&
 | 
			
		||||
                        !astUtils.isCommaToken(previousToken) && // ignore spacing between two commas
 | 
			
		||||
 | 
			
		||||
                        /*
 | 
			
		||||
                         * `commaTokensToIgnore` are ending commas of `null` elements (array holes/elisions).
 | 
			
		||||
                         * In addition to spacing between two commas, this can also ignore:
 | 
			
		||||
                         *
 | 
			
		||||
                         *   - Spacing after `[` (controlled by array-bracket-spacing)
 | 
			
		||||
                         *       Example: [ , ]
 | 
			
		||||
                         *                 ^
 | 
			
		||||
                         *   - Spacing after a comment (for backwards compatibility, this was possibly unintentional)
 | 
			
		||||
                         *       Example: [a, /* * / ,]
 | 
			
		||||
                         *                          ^
 | 
			
		||||
                         */
 | 
			
		||||
                        !commaTokensToIgnore.includes(token) &&
 | 
			
		||||
 | 
			
		||||
                        astUtils.isTokenOnSameLine(previousToken, token) &&
 | 
			
		||||
                        options.before !== sourceCode.isSpaceBetweenTokens(previousToken, token)
 | 
			
		||||
                    ) {
 | 
			
		||||
                        report(token, "before", previousToken);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (
 | 
			
		||||
                        nextToken &&
 | 
			
		||||
                        !astUtils.isCommaToken(nextToken) && // ignore spacing between two commas
 | 
			
		||||
                        !astUtils.isClosingParenToken(nextToken) && // controlled by space-in-parens
 | 
			
		||||
                        !astUtils.isClosingBracketToken(nextToken) && // controlled by array-bracket-spacing
 | 
			
		||||
                        !astUtils.isClosingBraceToken(nextToken) && // controlled by object-curly-spacing
 | 
			
		||||
                        !(!options.after && nextToken.type === "Line") && // special case, allow space before line comment
 | 
			
		||||
                        astUtils.isTokenOnSameLine(token, nextToken) &&
 | 
			
		||||
                        options.after !== sourceCode.isSpaceBetweenTokens(token, nextToken)
 | 
			
		||||
                    ) {
 | 
			
		||||
                        report(token, "after", nextToken);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            },
 | 
			
		||||
            ArrayExpression: addNullElementsToIgnoreList,
 | 
			
		||||
            ArrayPattern: addNullElementsToIgnoreList
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										314
									
								
								node_modules/eslint/lib/rules/comma-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										314
									
								
								node_modules/eslint/lib/rules/comma-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,314 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Comma style - enforces comma styles of two types: last and first
 | 
			
		||||
 * @author Vignesh Anand aka vegetableman
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent comma style",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/comma-style"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["first", "last"]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    exceptions: {
 | 
			
		||||
                        type: "object",
 | 
			
		||||
                        additionalProperties: {
 | 
			
		||||
                            type: "boolean"
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.",
 | 
			
		||||
            expectedCommaFirst: "',' should be placed first.",
 | 
			
		||||
            expectedCommaLast: "',' should be placed last."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const style = context.options[0] || "last",
 | 
			
		||||
            sourceCode = context.sourceCode;
 | 
			
		||||
        const exceptions = {
 | 
			
		||||
            ArrayPattern: true,
 | 
			
		||||
            ArrowFunctionExpression: true,
 | 
			
		||||
            CallExpression: true,
 | 
			
		||||
            FunctionDeclaration: true,
 | 
			
		||||
            FunctionExpression: true,
 | 
			
		||||
            ImportDeclaration: true,
 | 
			
		||||
            ObjectPattern: true,
 | 
			
		||||
            NewExpression: true
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) {
 | 
			
		||||
            const keys = Object.keys(context.options[1].exceptions);
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < keys.length; i++) {
 | 
			
		||||
                exceptions[keys[i]] = context.options[1].exceptions[keys[i]];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Modified text based on the style
 | 
			
		||||
         * @param {string} styleType Style type
 | 
			
		||||
         * @param {string} text Source code text
 | 
			
		||||
         * @returns {string} modified text
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function getReplacedText(styleType, text) {
 | 
			
		||||
            switch (styleType) {
 | 
			
		||||
                case "between":
 | 
			
		||||
                    return `,${text.replace(astUtils.LINEBREAK_MATCHER, "")}`;
 | 
			
		||||
 | 
			
		||||
                case "first":
 | 
			
		||||
                    return `${text},`;
 | 
			
		||||
 | 
			
		||||
                case "last":
 | 
			
		||||
                    return `,${text}`;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    return "";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines the fixer function for a given style.
 | 
			
		||||
         * @param {string} styleType comma style
 | 
			
		||||
         * @param {ASTNode} previousItemToken The token to check.
 | 
			
		||||
         * @param {ASTNode} commaToken The token to check.
 | 
			
		||||
         * @param {ASTNode} currentItemToken The token to check.
 | 
			
		||||
         * @returns {Function} Fixer function
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) {
 | 
			
		||||
            const text =
 | 
			
		||||
                sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) +
 | 
			
		||||
                sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]);
 | 
			
		||||
            const range = [previousItemToken.range[1], currentItemToken.range[0]];
 | 
			
		||||
 | 
			
		||||
            return function(fixer) {
 | 
			
		||||
                return fixer.replaceTextRange(range, getReplacedText(styleType, text));
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Validates the spacing around single items in lists.
 | 
			
		||||
         * @param {Token} previousItemToken The last token from the previous item.
 | 
			
		||||
         * @param {Token} commaToken The token representing the comma.
 | 
			
		||||
         * @param {Token} currentItemToken The first token of the current item.
 | 
			
		||||
         * @param {Token} reportItem The item to use when reporting an error.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) {
 | 
			
		||||
 | 
			
		||||
            // if single line
 | 
			
		||||
            if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
 | 
			
		||||
                    astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {
 | 
			
		||||
 | 
			
		||||
                // do nothing.
 | 
			
		||||
 | 
			
		||||
            } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
 | 
			
		||||
                    !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {
 | 
			
		||||
 | 
			
		||||
                const comment = sourceCode.getCommentsAfter(commaToken)[0];
 | 
			
		||||
                const styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment)
 | 
			
		||||
                    ? style
 | 
			
		||||
                    : "between";
 | 
			
		||||
 | 
			
		||||
                // lone comma
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: reportItem,
 | 
			
		||||
                    loc: commaToken.loc,
 | 
			
		||||
                    messageId: "unexpectedLineBeforeAndAfterComma",
 | 
			
		||||
                    fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken)
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {
 | 
			
		||||
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: reportItem,
 | 
			
		||||
                    loc: commaToken.loc,
 | 
			
		||||
                    messageId: "expectedCommaFirst",
 | 
			
		||||
                    fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            } else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {
 | 
			
		||||
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: reportItem,
 | 
			
		||||
                    loc: commaToken.loc,
 | 
			
		||||
                    messageId: "expectedCommaLast",
 | 
			
		||||
                    fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks the comma placement with regards to a declaration/property/element
 | 
			
		||||
         * @param {ASTNode} node The binary expression node to check
 | 
			
		||||
         * @param {string} property The property of the node containing child nodes.
 | 
			
		||||
         * @private
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function validateComma(node, property) {
 | 
			
		||||
            const items = node[property],
 | 
			
		||||
                arrayLiteral = (node.type === "ArrayExpression" || node.type === "ArrayPattern");
 | 
			
		||||
 | 
			
		||||
            if (items.length > 1 || arrayLiteral) {
 | 
			
		||||
 | 
			
		||||
                // seed as opening [
 | 
			
		||||
                let previousItemToken = sourceCode.getFirstToken(node);
 | 
			
		||||
 | 
			
		||||
                items.forEach(item => {
 | 
			
		||||
                    const commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken,
 | 
			
		||||
                        currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken),
 | 
			
		||||
                        reportItem = item || currentItemToken;
 | 
			
		||||
 | 
			
		||||
                    /*
 | 
			
		||||
                     * This works by comparing three token locations:
 | 
			
		||||
                     * - previousItemToken is the last token of the previous item
 | 
			
		||||
                     * - commaToken is the location of the comma before the current item
 | 
			
		||||
                     * - currentItemToken is the first token of the current item
 | 
			
		||||
                     *
 | 
			
		||||
                     * These values get switched around if item is undefined.
 | 
			
		||||
                     * previousItemToken will refer to the last token not belonging
 | 
			
		||||
                     * to the current item, which could be a comma or an opening
 | 
			
		||||
                     * square bracket. currentItemToken could be a comma.
 | 
			
		||||
                     *
 | 
			
		||||
                     * All comparisons are done based on these tokens directly, so
 | 
			
		||||
                     * they are always valid regardless of an undefined item.
 | 
			
		||||
                     */
 | 
			
		||||
                    if (astUtils.isCommaToken(commaToken)) {
 | 
			
		||||
                        validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (item) {
 | 
			
		||||
                        const tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken);
 | 
			
		||||
 | 
			
		||||
                        previousItemToken = tokenAfterItem
 | 
			
		||||
                            ? sourceCode.getTokenBefore(tokenAfterItem)
 | 
			
		||||
                            : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1];
 | 
			
		||||
                    } else {
 | 
			
		||||
                        previousItemToken = currentItemToken;
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * Special case for array literals that have empty last items, such
 | 
			
		||||
                 * as [ 1, 2, ]. These arrays only have two items show up in the
 | 
			
		||||
                 * AST, so we need to look at the token to verify that there's no
 | 
			
		||||
                 * dangling comma.
 | 
			
		||||
                 */
 | 
			
		||||
                if (arrayLiteral) {
 | 
			
		||||
 | 
			
		||||
                    const lastToken = sourceCode.getLastToken(node),
 | 
			
		||||
                        nextToLastToken = sourceCode.getTokenBefore(lastToken);
 | 
			
		||||
 | 
			
		||||
                    if (astUtils.isCommaToken(nextToLastToken)) {
 | 
			
		||||
                        validateCommaItemSpacing(
 | 
			
		||||
                            sourceCode.getTokenBefore(nextToLastToken),
 | 
			
		||||
                            nextToLastToken,
 | 
			
		||||
                            lastToken,
 | 
			
		||||
                            lastToken
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        const nodes = {};
 | 
			
		||||
 | 
			
		||||
        if (!exceptions.VariableDeclaration) {
 | 
			
		||||
            nodes.VariableDeclaration = function(node) {
 | 
			
		||||
                validateComma(node, "declarations");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.ObjectExpression) {
 | 
			
		||||
            nodes.ObjectExpression = function(node) {
 | 
			
		||||
                validateComma(node, "properties");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.ObjectPattern) {
 | 
			
		||||
            nodes.ObjectPattern = function(node) {
 | 
			
		||||
                validateComma(node, "properties");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.ArrayExpression) {
 | 
			
		||||
            nodes.ArrayExpression = function(node) {
 | 
			
		||||
                validateComma(node, "elements");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.ArrayPattern) {
 | 
			
		||||
            nodes.ArrayPattern = function(node) {
 | 
			
		||||
                validateComma(node, "elements");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.FunctionDeclaration) {
 | 
			
		||||
            nodes.FunctionDeclaration = function(node) {
 | 
			
		||||
                validateComma(node, "params");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.FunctionExpression) {
 | 
			
		||||
            nodes.FunctionExpression = function(node) {
 | 
			
		||||
                validateComma(node, "params");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.ArrowFunctionExpression) {
 | 
			
		||||
            nodes.ArrowFunctionExpression = function(node) {
 | 
			
		||||
                validateComma(node, "params");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.CallExpression) {
 | 
			
		||||
            nodes.CallExpression = function(node) {
 | 
			
		||||
                validateComma(node, "arguments");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.ImportDeclaration) {
 | 
			
		||||
            nodes.ImportDeclaration = function(node) {
 | 
			
		||||
                validateComma(node, "specifiers");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        if (!exceptions.NewExpression) {
 | 
			
		||||
            nodes.NewExpression = function(node) {
 | 
			
		||||
                validateComma(node, "arguments");
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return nodes;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										165
									
								
								node_modules/eslint/lib/rules/complexity.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								node_modules/eslint/lib/rules/complexity.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity.
 | 
			
		||||
 * Counts the number of if, conditional, for, while, try, switch/case,
 | 
			
		||||
 * @author Patrick Brosset
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
const { upperCaseFirst } = require("../shared/string-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce a maximum cyclomatic complexity allowed in a program",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/complexity"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                oneOf: [
 | 
			
		||||
                    {
 | 
			
		||||
                        type: "integer",
 | 
			
		||||
                        minimum: 0
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: "object",
 | 
			
		||||
                        properties: {
 | 
			
		||||
                            maximum: {
 | 
			
		||||
                                type: "integer",
 | 
			
		||||
                                minimum: 0
 | 
			
		||||
                            },
 | 
			
		||||
                            max: {
 | 
			
		||||
                                type: "integer",
 | 
			
		||||
                                minimum: 0
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        additionalProperties: false
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            complex: "{{name}} has a complexity of {{complexity}}. Maximum allowed is {{max}}."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const option = context.options[0];
 | 
			
		||||
        let THRESHOLD = 20;
 | 
			
		||||
 | 
			
		||||
        if (
 | 
			
		||||
            typeof option === "object" &&
 | 
			
		||||
            (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
 | 
			
		||||
        ) {
 | 
			
		||||
            THRESHOLD = option.maximum || option.max;
 | 
			
		||||
        } else if (typeof option === "number") {
 | 
			
		||||
            THRESHOLD = option;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        // Using a stack to store complexity per code path
 | 
			
		||||
        const complexities = [];
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Increase the complexity of the code path in context
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function increaseComplexity() {
 | 
			
		||||
            complexities[complexities.length - 1]++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public API
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            onCodePathStart() {
 | 
			
		||||
 | 
			
		||||
                // The initial complexity is 1, representing one execution path in the CodePath
 | 
			
		||||
                complexities.push(1);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Each branching in the code adds 1 to the complexity
 | 
			
		||||
            CatchClause: increaseComplexity,
 | 
			
		||||
            ConditionalExpression: increaseComplexity,
 | 
			
		||||
            LogicalExpression: increaseComplexity,
 | 
			
		||||
            ForStatement: increaseComplexity,
 | 
			
		||||
            ForInStatement: increaseComplexity,
 | 
			
		||||
            ForOfStatement: increaseComplexity,
 | 
			
		||||
            IfStatement: increaseComplexity,
 | 
			
		||||
            WhileStatement: increaseComplexity,
 | 
			
		||||
            DoWhileStatement: increaseComplexity,
 | 
			
		||||
 | 
			
		||||
            // Avoid `default`
 | 
			
		||||
            "SwitchCase[test]": increaseComplexity,
 | 
			
		||||
 | 
			
		||||
            // Logical assignment operators have short-circuiting behavior
 | 
			
		||||
            AssignmentExpression(node) {
 | 
			
		||||
                if (astUtils.isLogicalAssignmentOperator(node.operator)) {
 | 
			
		||||
                    increaseComplexity();
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onCodePathEnd(codePath, node) {
 | 
			
		||||
                const complexity = complexities.pop();
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * This rule only evaluates complexity of functions, so "program" is excluded.
 | 
			
		||||
                 * Class field initializers and class static blocks are implicit functions. Therefore,
 | 
			
		||||
                 * they shouldn't contribute to the enclosing function's complexity, but their
 | 
			
		||||
                 * own complexity should be evaluated.
 | 
			
		||||
                 */
 | 
			
		||||
                if (
 | 
			
		||||
                    codePath.origin !== "function" &&
 | 
			
		||||
                    codePath.origin !== "class-field-initializer" &&
 | 
			
		||||
                    codePath.origin !== "class-static-block"
 | 
			
		||||
                ) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (complexity > THRESHOLD) {
 | 
			
		||||
                    let name;
 | 
			
		||||
 | 
			
		||||
                    if (codePath.origin === "class-field-initializer") {
 | 
			
		||||
                        name = "class field initializer";
 | 
			
		||||
                    } else if (codePath.origin === "class-static-block") {
 | 
			
		||||
                        name = "class static block";
 | 
			
		||||
                    } else {
 | 
			
		||||
                        name = astUtils.getFunctionNameWithKind(node);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        messageId: "complex",
 | 
			
		||||
                        data: {
 | 
			
		||||
                            name: upperCaseFirst(name),
 | 
			
		||||
                            complexity,
 | 
			
		||||
                            max: THRESHOLD
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										208
									
								
								node_modules/eslint/lib/rules/computed-property-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								node_modules/eslint/lib/rules/computed-property-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,208 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Disallows or enforces spaces inside computed properties.
 | 
			
		||||
 * @author Jamund Ferguson
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent spacing inside computed property brackets",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/computed-property-spacing"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["always", "never"]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    enforceForClassMembers: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: true
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.",
 | 
			
		||||
            unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.",
 | 
			
		||||
 | 
			
		||||
            missingSpaceBefore: "A space is required before '{{tokenValue}}'.",
 | 
			
		||||
            missingSpaceAfter: "A space is required after '{{tokenValue}}'."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
        const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never"
 | 
			
		||||
        const enforceForClassMembers = !context.options[1] || context.options[1].enforceForClassMembers;
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there shouldn't be a space after the first token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @param {Token} tokenAfter The token after `token`.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportNoBeginningSpace(node, token, tokenAfter) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: { start: token.loc.end, end: tokenAfter.loc.start },
 | 
			
		||||
                messageId: "unexpectedSpaceAfter",
 | 
			
		||||
                data: {
 | 
			
		||||
                    tokenValue: token.value
 | 
			
		||||
                },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there shouldn't be a space before the last token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @param {Token} tokenBefore The token before `token`.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportNoEndingSpace(node, token, tokenBefore) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: { start: tokenBefore.loc.end, end: token.loc.start },
 | 
			
		||||
                messageId: "unexpectedSpaceBefore",
 | 
			
		||||
                data: {
 | 
			
		||||
                    tokenValue: token.value
 | 
			
		||||
                },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there should be a space after the first token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportRequiredBeginningSpace(node, token) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: token.loc,
 | 
			
		||||
                messageId: "missingSpaceAfter",
 | 
			
		||||
                data: {
 | 
			
		||||
                    tokenValue: token.value
 | 
			
		||||
                },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.insertTextAfter(token, " ");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that there should be a space before the last token
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @param {Token} token The token to use for the report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportRequiredEndingSpace(node, token) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: token.loc,
 | 
			
		||||
                messageId: "missingSpaceBefore",
 | 
			
		||||
                data: {
 | 
			
		||||
                    tokenValue: token.value
 | 
			
		||||
                },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
                    return fixer.insertTextBefore(token, " ");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Returns a function that checks the spacing of a node on the property name
 | 
			
		||||
         * that was passed in.
 | 
			
		||||
         * @param {string} propertyName The property on the node to check for spacing
 | 
			
		||||
         * @returns {Function} A function that will check spacing on a node
 | 
			
		||||
         */
 | 
			
		||||
        function checkSpacing(propertyName) {
 | 
			
		||||
            return function(node) {
 | 
			
		||||
                if (!node.computed) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const property = node[propertyName];
 | 
			
		||||
 | 
			
		||||
                const before = sourceCode.getTokenBefore(property, astUtils.isOpeningBracketToken),
 | 
			
		||||
                    first = sourceCode.getTokenAfter(before, { includeComments: true }),
 | 
			
		||||
                    after = sourceCode.getTokenAfter(property, astUtils.isClosingBracketToken),
 | 
			
		||||
                    last = sourceCode.getTokenBefore(after, { includeComments: true });
 | 
			
		||||
 | 
			
		||||
                if (astUtils.isTokenOnSameLine(before, first)) {
 | 
			
		||||
                    if (propertyNameMustBeSpaced) {
 | 
			
		||||
                        if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) {
 | 
			
		||||
                            reportRequiredBeginningSpace(node, before);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if (sourceCode.isSpaceBetweenTokens(before, first)) {
 | 
			
		||||
                            reportNoBeginningSpace(node, before, first);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (astUtils.isTokenOnSameLine(last, after)) {
 | 
			
		||||
                    if (propertyNameMustBeSpaced) {
 | 
			
		||||
                        if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) {
 | 
			
		||||
                            reportRequiredEndingSpace(node, after);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if (sourceCode.isSpaceBetweenTokens(last, after)) {
 | 
			
		||||
                            reportNoEndingSpace(node, after, last);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        const listeners = {
 | 
			
		||||
            Property: checkSpacing("key"),
 | 
			
		||||
            MemberExpression: checkSpacing("property")
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (enforceForClassMembers) {
 | 
			
		||||
            listeners.MethodDefinition =
 | 
			
		||||
                listeners.PropertyDefinition = listeners.Property;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return listeners;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										210
									
								
								node_modules/eslint/lib/rules/consistent-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								node_modules/eslint/lib/rules/consistent-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to flag consistent return values
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
const { upperCaseFirst } = require("../shared/string-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks all segments in a set and returns true if all are unreachable.
 | 
			
		||||
 * @param {Set<CodePathSegment>} segments The segments to check.
 | 
			
		||||
 * @returns {boolean} True if all segments are unreachable; false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
function areAllSegmentsUnreachable(segments) {
 | 
			
		||||
 | 
			
		||||
    for (const segment of segments) {
 | 
			
		||||
        if (segment.reachable) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether a given node is a `constructor` method in an ES6 class
 | 
			
		||||
 * @param {ASTNode} node A node to check
 | 
			
		||||
 * @returns {boolean} `true` if the node is a `constructor` method
 | 
			
		||||
 */
 | 
			
		||||
function isClassConstructor(node) {
 | 
			
		||||
    return node.type === "FunctionExpression" &&
 | 
			
		||||
        node.parent &&
 | 
			
		||||
        node.parent.type === "MethodDefinition" &&
 | 
			
		||||
        node.parent.kind === "constructor";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require `return` statements to either always or never specify values",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/consistent-return"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [{
 | 
			
		||||
            type: "object",
 | 
			
		||||
            properties: {
 | 
			
		||||
                treatUndefinedAsUnspecified: {
 | 
			
		||||
                    type: "boolean",
 | 
			
		||||
                    default: false
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            additionalProperties: false
 | 
			
		||||
        }],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingReturn: "Expected to return a value at the end of {{name}}.",
 | 
			
		||||
            missingReturnValue: "{{name}} expected a return value.",
 | 
			
		||||
            unexpectedReturnValue: "{{name}} expected no return value."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const options = context.options[0] || {};
 | 
			
		||||
        const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true;
 | 
			
		||||
        let funcInfo = null;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether of not the implicit returning is consistent if the last
 | 
			
		||||
         * code path segment is reachable.
 | 
			
		||||
         * @param {ASTNode} node A program/function node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkLastSegment(node) {
 | 
			
		||||
            let loc, name;
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Skip if it expected no return value or unreachable.
 | 
			
		||||
             * When unreachable, all paths are returned or thrown.
 | 
			
		||||
             */
 | 
			
		||||
            if (!funcInfo.hasReturnValue ||
 | 
			
		||||
                areAllSegmentsUnreachable(funcInfo.currentSegments) ||
 | 
			
		||||
                astUtils.isES5Constructor(node) ||
 | 
			
		||||
                isClassConstructor(node)
 | 
			
		||||
            ) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Adjust a location and a message.
 | 
			
		||||
            if (node.type === "Program") {
 | 
			
		||||
 | 
			
		||||
                // The head of program.
 | 
			
		||||
                loc = { line: 1, column: 0 };
 | 
			
		||||
                name = "program";
 | 
			
		||||
            } else if (node.type === "ArrowFunctionExpression") {
 | 
			
		||||
 | 
			
		||||
                // `=>` token
 | 
			
		||||
                loc = context.sourceCode.getTokenBefore(node.body, astUtils.isArrowToken).loc;
 | 
			
		||||
            } else if (
 | 
			
		||||
                node.parent.type === "MethodDefinition" ||
 | 
			
		||||
                (node.parent.type === "Property" && node.parent.method)
 | 
			
		||||
            ) {
 | 
			
		||||
 | 
			
		||||
                // Method name.
 | 
			
		||||
                loc = node.parent.key.loc;
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                // Function name or `function` keyword.
 | 
			
		||||
                loc = (node.id || context.sourceCode.getFirstToken(node)).loc;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!name) {
 | 
			
		||||
                name = astUtils.getFunctionNameWithKind(node);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Reports.
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc,
 | 
			
		||||
                messageId: "missingReturn",
 | 
			
		||||
                data: { name }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            // Initializes/Disposes state of each code path.
 | 
			
		||||
            onCodePathStart(codePath, node) {
 | 
			
		||||
                funcInfo = {
 | 
			
		||||
                    upper: funcInfo,
 | 
			
		||||
                    codePath,
 | 
			
		||||
                    hasReturn: false,
 | 
			
		||||
                    hasReturnValue: false,
 | 
			
		||||
                    messageId: "",
 | 
			
		||||
                    node,
 | 
			
		||||
                    currentSegments: new Set()
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
            onCodePathEnd() {
 | 
			
		||||
                funcInfo = funcInfo.upper;
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onUnreachableCodePathSegmentStart(segment) {
 | 
			
		||||
                funcInfo.currentSegments.add(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onUnreachableCodePathSegmentEnd(segment) {
 | 
			
		||||
                funcInfo.currentSegments.delete(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onCodePathSegmentStart(segment) {
 | 
			
		||||
                funcInfo.currentSegments.add(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onCodePathSegmentEnd(segment) {
 | 
			
		||||
                funcInfo.currentSegments.delete(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // Reports a given return statement if it's inconsistent.
 | 
			
		||||
            ReturnStatement(node) {
 | 
			
		||||
                const argument = node.argument;
 | 
			
		||||
                let hasReturnValue = Boolean(argument);
 | 
			
		||||
 | 
			
		||||
                if (treatUndefinedAsUnspecified && hasReturnValue) {
 | 
			
		||||
                    hasReturnValue = !astUtils.isSpecificId(argument, "undefined") && argument.operator !== "void";
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!funcInfo.hasReturn) {
 | 
			
		||||
                    funcInfo.hasReturn = true;
 | 
			
		||||
                    funcInfo.hasReturnValue = hasReturnValue;
 | 
			
		||||
                    funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue";
 | 
			
		||||
                    funcInfo.data = {
 | 
			
		||||
                        name: funcInfo.node.type === "Program"
 | 
			
		||||
                            ? "Program"
 | 
			
		||||
                            : upperCaseFirst(astUtils.getFunctionNameWithKind(funcInfo.node))
 | 
			
		||||
                    };
 | 
			
		||||
                } else if (funcInfo.hasReturnValue !== hasReturnValue) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        messageId: funcInfo.messageId,
 | 
			
		||||
                        data: funcInfo.data
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Reports a given program/function if the implicit returning is not consistent.
 | 
			
		||||
            "Program:exit": checkLastSegment,
 | 
			
		||||
            "FunctionDeclaration:exit": checkLastSegment,
 | 
			
		||||
            "FunctionExpression:exit": checkLastSegment,
 | 
			
		||||
            "ArrowFunctionExpression:exit": checkLastSegment
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										153
									
								
								node_modules/eslint/lib/rules/consistent-this.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								node_modules/eslint/lib/rules/consistent-this.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,153 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce consistent naming of "this" context variables
 | 
			
		||||
 * @author Raphael Pigulla
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent naming when capturing the current execution context",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/consistent-this"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            type: "array",
 | 
			
		||||
            items: {
 | 
			
		||||
                type: "string",
 | 
			
		||||
                minLength: 1
 | 
			
		||||
            },
 | 
			
		||||
            uniqueItems: true
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.",
 | 
			
		||||
            unexpectedAlias: "Unexpected alias '{{name}}' for 'this'."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        let aliases = [];
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        if (context.options.length === 0) {
 | 
			
		||||
            aliases.push("that");
 | 
			
		||||
        } else {
 | 
			
		||||
            aliases = context.options;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that a variable declarator or assignment expression is assigning
 | 
			
		||||
         * a non-'this' value to the specified alias.
 | 
			
		||||
         * @param {ASTNode} node The assigning node.
 | 
			
		||||
         * @param {string} name the name of the alias that was incorrectly used.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportBadAssignment(node, name) {
 | 
			
		||||
            context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks that an assignment to an identifier only assigns 'this' to the
 | 
			
		||||
         * appropriate alias, and the alias is only assigned to 'this'.
 | 
			
		||||
         * @param {ASTNode} node The assigning node.
 | 
			
		||||
         * @param {Identifier} name The name of the variable assigned to.
 | 
			
		||||
         * @param {Expression} value The value of the assignment.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkAssignment(node, name, value) {
 | 
			
		||||
            const isThis = value.type === "ThisExpression";
 | 
			
		||||
 | 
			
		||||
            if (aliases.includes(name)) {
 | 
			
		||||
                if (!isThis || node.operator && node.operator !== "=") {
 | 
			
		||||
                    reportBadAssignment(node, name);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (isThis) {
 | 
			
		||||
                context.report({ node, messageId: "unexpectedAlias", data: { name } });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Ensures that a variable declaration of the alias in a program or function
 | 
			
		||||
         * is assigned to the correct value.
 | 
			
		||||
         * @param {string} alias alias the check the assignment of.
 | 
			
		||||
         * @param {Object} scope scope of the current code we are checking.
 | 
			
		||||
         * @private
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkWasAssigned(alias, scope) {
 | 
			
		||||
            const variable = scope.set.get(alias);
 | 
			
		||||
 | 
			
		||||
            if (!variable) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (variable.defs.some(def => def.node.type === "VariableDeclarator" &&
 | 
			
		||||
                def.node.init !== null)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * The alias has been declared and not assigned: check it was
 | 
			
		||||
             * assigned later in the same scope.
 | 
			
		||||
             */
 | 
			
		||||
            if (!variable.references.some(reference => {
 | 
			
		||||
                const write = reference.writeExpr;
 | 
			
		||||
 | 
			
		||||
                return (
 | 
			
		||||
                    reference.from === scope &&
 | 
			
		||||
                    write && write.type === "ThisExpression" &&
 | 
			
		||||
                    write.parent.operator === "="
 | 
			
		||||
                );
 | 
			
		||||
            })) {
 | 
			
		||||
                variable.defs.map(def => def.node).forEach(node => {
 | 
			
		||||
                    reportBadAssignment(node, alias);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check each alias to ensure that is was assigned to the correct value.
 | 
			
		||||
         * @param {ASTNode} node The node that represents the scope to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function ensureWasAssigned(node) {
 | 
			
		||||
            const scope = sourceCode.getScope(node);
 | 
			
		||||
 | 
			
		||||
            aliases.forEach(alias => {
 | 
			
		||||
                checkWasAssigned(alias, scope);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            "Program:exit": ensureWasAssigned,
 | 
			
		||||
            "FunctionExpression:exit": ensureWasAssigned,
 | 
			
		||||
            "FunctionDeclaration:exit": ensureWasAssigned,
 | 
			
		||||
 | 
			
		||||
            VariableDeclarator(node) {
 | 
			
		||||
                const id = node.id;
 | 
			
		||||
                const isDestructuring =
 | 
			
		||||
                    id.type === "ArrayPattern" || id.type === "ObjectPattern";
 | 
			
		||||
 | 
			
		||||
                if (node.init !== null && !isDestructuring) {
 | 
			
		||||
                    checkAssignment(node, id.name, node.init);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            AssignmentExpression(node) {
 | 
			
		||||
                if (node.left.type === "Identifier") {
 | 
			
		||||
                    checkAssignment(node, node.left.name, node.right);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										446
									
								
								node_modules/eslint/lib/rules/constructor-super.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										446
									
								
								node_modules/eslint/lib/rules/constructor-super.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,446 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview A rule to verify `super()` callings in constructor.
 | 
			
		||||
 * @author Toru Nagashima
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks all segments in a set and returns true if any are reachable.
 | 
			
		||||
 * @param {Set<CodePathSegment>} segments The segments to check.
 | 
			
		||||
 * @returns {boolean} True if any segment is reachable; false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
function isAnySegmentReachable(segments) {
 | 
			
		||||
 | 
			
		||||
    for (const segment of segments) {
 | 
			
		||||
        if (segment.reachable) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given node is a constructor.
 | 
			
		||||
 * @param {ASTNode} node A node to check. This node type is one of
 | 
			
		||||
 *   `Program`, `FunctionDeclaration`, `FunctionExpression`, and
 | 
			
		||||
 *   `ArrowFunctionExpression`.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a constructor.
 | 
			
		||||
 */
 | 
			
		||||
function isConstructorFunction(node) {
 | 
			
		||||
    return (
 | 
			
		||||
        node.type === "FunctionExpression" &&
 | 
			
		||||
        node.parent.type === "MethodDefinition" &&
 | 
			
		||||
        node.parent.kind === "constructor"
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether a given node can be a constructor or not.
 | 
			
		||||
 * @param {ASTNode} node A node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node can be a constructor.
 | 
			
		||||
 */
 | 
			
		||||
function isPossibleConstructor(node) {
 | 
			
		||||
    if (!node) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (node.type) {
 | 
			
		||||
        case "ClassExpression":
 | 
			
		||||
        case "FunctionExpression":
 | 
			
		||||
        case "ThisExpression":
 | 
			
		||||
        case "MemberExpression":
 | 
			
		||||
        case "CallExpression":
 | 
			
		||||
        case "NewExpression":
 | 
			
		||||
        case "ChainExpression":
 | 
			
		||||
        case "YieldExpression":
 | 
			
		||||
        case "TaggedTemplateExpression":
 | 
			
		||||
        case "MetaProperty":
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        case "Identifier":
 | 
			
		||||
            return node.name !== "undefined";
 | 
			
		||||
 | 
			
		||||
        case "AssignmentExpression":
 | 
			
		||||
            if (["=", "&&="].includes(node.operator)) {
 | 
			
		||||
                return isPossibleConstructor(node.right);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (["||=", "??="].includes(node.operator)) {
 | 
			
		||||
                return (
 | 
			
		||||
                    isPossibleConstructor(node.left) ||
 | 
			
		||||
                    isPossibleConstructor(node.right)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * All other assignment operators are mathematical assignment operators (arithmetic or bitwise).
 | 
			
		||||
             * An assignment expression with a mathematical operator can either evaluate to a primitive value,
 | 
			
		||||
             * or throw, depending on the operands. Thus, it cannot evaluate to a constructor function.
 | 
			
		||||
             */
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        case "LogicalExpression":
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * If the && operator short-circuits, the left side was falsy and therefore not a constructor, and if
 | 
			
		||||
             * it doesn't short-circuit, it takes the value from the right side, so the right side must always be a
 | 
			
		||||
             * possible constructor. A future improvement could verify that the left side could be truthy by
 | 
			
		||||
             * excluding falsy literals.
 | 
			
		||||
             */
 | 
			
		||||
            if (node.operator === "&&") {
 | 
			
		||||
                return isPossibleConstructor(node.right);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (
 | 
			
		||||
                isPossibleConstructor(node.left) ||
 | 
			
		||||
                isPossibleConstructor(node.right)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        case "ConditionalExpression":
 | 
			
		||||
            return (
 | 
			
		||||
                isPossibleConstructor(node.alternate) ||
 | 
			
		||||
                isPossibleConstructor(node.consequent)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        case "SequenceExpression": {
 | 
			
		||||
            const lastExpression = node.expressions[node.expressions.length - 1];
 | 
			
		||||
 | 
			
		||||
            return isPossibleConstructor(lastExpression);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "problem",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require `super()` calls in constructors",
 | 
			
		||||
            recommended: true,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/constructor-super"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingSome: "Lacked a call of 'super()' in some code paths.",
 | 
			
		||||
            missingAll: "Expected to call 'super()'.",
 | 
			
		||||
 | 
			
		||||
            duplicate: "Unexpected duplicate 'super()'.",
 | 
			
		||||
            badSuper: "Unexpected 'super()' because 'super' is not a constructor.",
 | 
			
		||||
            unexpected: "Unexpected 'super()'."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]}
 | 
			
		||||
         * Information for each constructor.
 | 
			
		||||
         * - upper:      Information of the upper constructor.
 | 
			
		||||
         * - hasExtends: A flag which shows whether own class has a valid `extends`
 | 
			
		||||
         *               part.
 | 
			
		||||
         * - scope:      The scope of own class.
 | 
			
		||||
         * - codePath:   The code path object of the constructor.
 | 
			
		||||
         */
 | 
			
		||||
        let funcInfo = null;
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * {Map<string, {calledInSomePaths: boolean, calledInEveryPaths: boolean}>}
 | 
			
		||||
         * Information for each code path segment.
 | 
			
		||||
         * - calledInSomePaths:  A flag of be called `super()` in some code paths.
 | 
			
		||||
         * - calledInEveryPaths: A flag of be called `super()` in all code paths.
 | 
			
		||||
         * - validNodes:
 | 
			
		||||
         */
 | 
			
		||||
        let segInfoMap = Object.create(null);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Gets the flag which shows `super()` is called in some paths.
 | 
			
		||||
         * @param {CodePathSegment} segment A code path segment to get.
 | 
			
		||||
         * @returns {boolean} The flag which shows `super()` is called in some paths
 | 
			
		||||
         */
 | 
			
		||||
        function isCalledInSomePath(segment) {
 | 
			
		||||
            return segment.reachable && segInfoMap[segment.id].calledInSomePaths;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Gets the flag which shows `super()` is called in all paths.
 | 
			
		||||
         * @param {CodePathSegment} segment A code path segment to get.
 | 
			
		||||
         * @returns {boolean} The flag which shows `super()` is called in all paths.
 | 
			
		||||
         */
 | 
			
		||||
        function isCalledInEveryPath(segment) {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * If specific segment is the looped segment of the current segment,
 | 
			
		||||
             * skip the segment.
 | 
			
		||||
             * If not skipped, this never becomes true after a loop.
 | 
			
		||||
             */
 | 
			
		||||
            if (segment.nextSegments.length === 1 &&
 | 
			
		||||
                segment.nextSegments[0].isLoopedPrevSegment(segment)
 | 
			
		||||
            ) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            return segment.reachable && segInfoMap[segment.id].calledInEveryPaths;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Stacks a constructor information.
 | 
			
		||||
             * @param {CodePath} codePath A code path which was started.
 | 
			
		||||
             * @param {ASTNode} node The current node.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            onCodePathStart(codePath, node) {
 | 
			
		||||
                if (isConstructorFunction(node)) {
 | 
			
		||||
 | 
			
		||||
                    // Class > ClassBody > MethodDefinition > FunctionExpression
 | 
			
		||||
                    const classNode = node.parent.parent.parent;
 | 
			
		||||
                    const superClass = classNode.superClass;
 | 
			
		||||
 | 
			
		||||
                    funcInfo = {
 | 
			
		||||
                        upper: funcInfo,
 | 
			
		||||
                        isConstructor: true,
 | 
			
		||||
                        hasExtends: Boolean(superClass),
 | 
			
		||||
                        superIsConstructor: isPossibleConstructor(superClass),
 | 
			
		||||
                        codePath,
 | 
			
		||||
                        currentSegments: new Set()
 | 
			
		||||
                    };
 | 
			
		||||
                } else {
 | 
			
		||||
                    funcInfo = {
 | 
			
		||||
                        upper: funcInfo,
 | 
			
		||||
                        isConstructor: false,
 | 
			
		||||
                        hasExtends: false,
 | 
			
		||||
                        superIsConstructor: false,
 | 
			
		||||
                        codePath,
 | 
			
		||||
                        currentSegments: new Set()
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Pops a constructor information.
 | 
			
		||||
             * And reports if `super()` lacked.
 | 
			
		||||
             * @param {CodePath} codePath A code path which was ended.
 | 
			
		||||
             * @param {ASTNode} node The current node.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            onCodePathEnd(codePath, node) {
 | 
			
		||||
                const hasExtends = funcInfo.hasExtends;
 | 
			
		||||
 | 
			
		||||
                // Pop.
 | 
			
		||||
                funcInfo = funcInfo.upper;
 | 
			
		||||
 | 
			
		||||
                if (!hasExtends) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Reports if `super()` lacked.
 | 
			
		||||
                const segments = codePath.returnedSegments;
 | 
			
		||||
                const calledInEveryPaths = segments.every(isCalledInEveryPath);
 | 
			
		||||
                const calledInSomePaths = segments.some(isCalledInSomePath);
 | 
			
		||||
 | 
			
		||||
                if (!calledInEveryPaths) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        messageId: calledInSomePaths
 | 
			
		||||
                            ? "missingSome"
 | 
			
		||||
                            : "missingAll",
 | 
			
		||||
                        node: node.parent
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Initialize information of a given code path segment.
 | 
			
		||||
             * @param {CodePathSegment} segment A code path segment to initialize.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            onCodePathSegmentStart(segment) {
 | 
			
		||||
 | 
			
		||||
                funcInfo.currentSegments.add(segment);
 | 
			
		||||
 | 
			
		||||
                if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Initialize info.
 | 
			
		||||
                const info = segInfoMap[segment.id] = {
 | 
			
		||||
                    calledInSomePaths: false,
 | 
			
		||||
                    calledInEveryPaths: false,
 | 
			
		||||
                    validNodes: []
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                // When there are previous segments, aggregates these.
 | 
			
		||||
                const prevSegments = segment.prevSegments;
 | 
			
		||||
 | 
			
		||||
                if (prevSegments.length > 0) {
 | 
			
		||||
                    info.calledInSomePaths = prevSegments.some(isCalledInSomePath);
 | 
			
		||||
                    info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onUnreachableCodePathSegmentStart(segment) {
 | 
			
		||||
                funcInfo.currentSegments.add(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onUnreachableCodePathSegmentEnd(segment) {
 | 
			
		||||
                funcInfo.currentSegments.delete(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onCodePathSegmentEnd(segment) {
 | 
			
		||||
                funcInfo.currentSegments.delete(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Update information of the code path segment when a code path was
 | 
			
		||||
             * looped.
 | 
			
		||||
             * @param {CodePathSegment} fromSegment The code path segment of the
 | 
			
		||||
             *      end of a loop.
 | 
			
		||||
             * @param {CodePathSegment} toSegment A code path segment of the head
 | 
			
		||||
             *      of a loop.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            onCodePathSegmentLoop(fromSegment, toSegment) {
 | 
			
		||||
                if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Update information inside of the loop.
 | 
			
		||||
                const isRealLoop = toSegment.prevSegments.length >= 2;
 | 
			
		||||
 | 
			
		||||
                funcInfo.codePath.traverseSegments(
 | 
			
		||||
                    { first: toSegment, last: fromSegment },
 | 
			
		||||
                    segment => {
 | 
			
		||||
                        const info = segInfoMap[segment.id];
 | 
			
		||||
                        const prevSegments = segment.prevSegments;
 | 
			
		||||
 | 
			
		||||
                        // Updates flags.
 | 
			
		||||
                        info.calledInSomePaths = prevSegments.some(isCalledInSomePath);
 | 
			
		||||
                        info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath);
 | 
			
		||||
 | 
			
		||||
                        // If flags become true anew, reports the valid nodes.
 | 
			
		||||
                        if (info.calledInSomePaths || isRealLoop) {
 | 
			
		||||
                            const nodes = info.validNodes;
 | 
			
		||||
 | 
			
		||||
                            info.validNodes = [];
 | 
			
		||||
 | 
			
		||||
                            for (let i = 0; i < nodes.length; ++i) {
 | 
			
		||||
                                const node = nodes[i];
 | 
			
		||||
 | 
			
		||||
                                context.report({
 | 
			
		||||
                                    messageId: "duplicate",
 | 
			
		||||
                                    node
 | 
			
		||||
                                });
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                );
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Checks for a call of `super()`.
 | 
			
		||||
             * @param {ASTNode} node A CallExpression node to check.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            "CallExpression:exit"(node) {
 | 
			
		||||
                if (!(funcInfo && funcInfo.isConstructor)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Skips except `super()`.
 | 
			
		||||
                if (node.callee.type !== "Super") {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Reports if needed.
 | 
			
		||||
                if (funcInfo.hasExtends) {
 | 
			
		||||
                    const segments = funcInfo.currentSegments;
 | 
			
		||||
                    let duplicate = false;
 | 
			
		||||
                    let info = null;
 | 
			
		||||
 | 
			
		||||
                    for (const segment of segments) {
 | 
			
		||||
 | 
			
		||||
                        if (segment.reachable) {
 | 
			
		||||
                            info = segInfoMap[segment.id];
 | 
			
		||||
 | 
			
		||||
                            duplicate = duplicate || info.calledInSomePaths;
 | 
			
		||||
                            info.calledInSomePaths = info.calledInEveryPaths = true;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (info) {
 | 
			
		||||
                        if (duplicate) {
 | 
			
		||||
                            context.report({
 | 
			
		||||
                                messageId: "duplicate",
 | 
			
		||||
                                node
 | 
			
		||||
                            });
 | 
			
		||||
                        } else if (!funcInfo.superIsConstructor) {
 | 
			
		||||
                            context.report({
 | 
			
		||||
                                messageId: "badSuper",
 | 
			
		||||
                                node
 | 
			
		||||
                            });
 | 
			
		||||
                        } else {
 | 
			
		||||
                            info.validNodes.push(node);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else if (isAnySegmentReachable(funcInfo.currentSegments)) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        messageId: "unexpected",
 | 
			
		||||
                        node
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Set the mark to the returned path as `super()` was called.
 | 
			
		||||
             * @param {ASTNode} node A ReturnStatement node to check.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            ReturnStatement(node) {
 | 
			
		||||
                if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Skips if no argument.
 | 
			
		||||
                if (!node.argument) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Returning argument is a substitute of 'super()'.
 | 
			
		||||
                const segments = funcInfo.currentSegments;
 | 
			
		||||
 | 
			
		||||
                for (const segment of segments) {
 | 
			
		||||
 | 
			
		||||
                    if (segment.reachable) {
 | 
			
		||||
                        const info = segInfoMap[segment.id];
 | 
			
		||||
 | 
			
		||||
                        info.calledInSomePaths = info.calledInEveryPaths = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Resets state.
 | 
			
		||||
             * @returns {void}
 | 
			
		||||
             */
 | 
			
		||||
            "Program:exit"() {
 | 
			
		||||
                segInfoMap = Object.create(null);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										486
									
								
								node_modules/eslint/lib/rules/curly.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										486
									
								
								node_modules/eslint/lib/rules/curly.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,486 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to flag statements without curly braces
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent brace style for all control statements",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/curly"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            anyOf: [
 | 
			
		||||
                {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["all"]
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    minItems: 0,
 | 
			
		||||
                    maxItems: 1
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["multi", "multi-line", "multi-or-nest"]
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["consistent"]
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    minItems: 0,
 | 
			
		||||
                    maxItems: 2
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingCurlyAfter: "Expected { after '{{name}}'.",
 | 
			
		||||
            missingCurlyAfterCondition: "Expected { after '{{name}}' condition.",
 | 
			
		||||
            unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.",
 | 
			
		||||
            unexpectedCurlyAfterCondition: "Unnecessary { after '{{name}}' condition."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const multiOnly = (context.options[0] === "multi");
 | 
			
		||||
        const multiLine = (context.options[0] === "multi-line");
 | 
			
		||||
        const multiOrNest = (context.options[0] === "multi-or-nest");
 | 
			
		||||
        const consistent = (context.options[1] === "consistent");
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines if a given node is a one-liner that's on the same line as it's preceding code.
 | 
			
		||||
         * @param {ASTNode} node The node to check.
 | 
			
		||||
         * @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code.
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isCollapsedOneLiner(node) {
 | 
			
		||||
            const before = sourceCode.getTokenBefore(node);
 | 
			
		||||
            const last = sourceCode.getLastToken(node);
 | 
			
		||||
            const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last;
 | 
			
		||||
 | 
			
		||||
            return before.loc.start.line === lastExcludingSemicolon.loc.end.line;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines if a given node is a one-liner.
 | 
			
		||||
         * @param {ASTNode} node The node to check.
 | 
			
		||||
         * @returns {boolean} True if the node is a one-liner.
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isOneLiner(node) {
 | 
			
		||||
            if (node.type === "EmptyStatement") {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const first = sourceCode.getFirstToken(node);
 | 
			
		||||
            const last = sourceCode.getLastToken(node);
 | 
			
		||||
            const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last;
 | 
			
		||||
 | 
			
		||||
            return first.loc.start.line === lastExcludingSemicolon.loc.end.line;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines if the given node is a lexical declaration (let, const, function, or class)
 | 
			
		||||
         * @param {ASTNode} node The node to check
 | 
			
		||||
         * @returns {boolean} True if the node is a lexical declaration
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isLexicalDeclaration(node) {
 | 
			
		||||
            if (node.type === "VariableDeclaration") {
 | 
			
		||||
                return node.kind === "const" || node.kind === "let";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return node.type === "FunctionDeclaration" || node.type === "ClassDeclaration";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if the given token is an `else` token or not.
 | 
			
		||||
         * @param {Token} token The token to check.
 | 
			
		||||
         * @returns {boolean} `true` if the token is an `else` token.
 | 
			
		||||
         */
 | 
			
		||||
        function isElseKeywordToken(token) {
 | 
			
		||||
            return token.value === "else" && token.type === "Keyword";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the given node has an `else` keyword token as the first token after.
 | 
			
		||||
         * @param {ASTNode} node The node to check.
 | 
			
		||||
         * @returns {boolean} `true` if the node is followed by an `else` keyword token.
 | 
			
		||||
         */
 | 
			
		||||
        function isFollowedByElseKeyword(node) {
 | 
			
		||||
            const nextToken = sourceCode.getTokenAfter(node);
 | 
			
		||||
 | 
			
		||||
            return Boolean(nextToken) && isElseKeywordToken(nextToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError.
 | 
			
		||||
         * @param {Token} closingBracket The } token
 | 
			
		||||
         * @returns {boolean} `true` if a semicolon needs to be inserted after the last statement in the block.
 | 
			
		||||
         */
 | 
			
		||||
        function needsSemicolon(closingBracket) {
 | 
			
		||||
            const tokenBefore = sourceCode.getTokenBefore(closingBracket);
 | 
			
		||||
            const tokenAfter = sourceCode.getTokenAfter(closingBracket);
 | 
			
		||||
            const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]);
 | 
			
		||||
 | 
			
		||||
            if (astUtils.isSemicolonToken(tokenBefore)) {
 | 
			
		||||
 | 
			
		||||
                // If the last statement already has a semicolon, don't add another one.
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!tokenAfter) {
 | 
			
		||||
 | 
			
		||||
                // If there are no statements after this block, there is no need to add a semicolon.
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (lastBlockNode.type === "BlockStatement" && lastBlockNode.parent.type !== "FunctionExpression" && lastBlockNode.parent.type !== "ArrowFunctionExpression") {
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If the last node surrounded by curly brackets is a BlockStatement (other than a FunctionExpression or an ArrowFunctionExpression),
 | 
			
		||||
                 * don't insert a semicolon. Otherwise, the semicolon would be parsed as a separate statement, which would cause
 | 
			
		||||
                 * a SyntaxError if it was followed by `else`.
 | 
			
		||||
                 */
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (tokenBefore.loc.end.line === tokenAfter.loc.start.line) {
 | 
			
		||||
 | 
			
		||||
                // If the next token is on the same line, insert a semicolon.
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (/^[([/`+-]/u.test(tokenAfter.value)) {
 | 
			
		||||
 | 
			
		||||
                // If the next token starts with a character that would disrupt ASI, insert a semicolon.
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (tokenBefore.type === "Punctuator" && (tokenBefore.value === "++" || tokenBefore.value === "--")) {
 | 
			
		||||
 | 
			
		||||
                // If the last token is ++ or --, insert a semicolon to avoid disrupting ASI.
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Otherwise, do not insert a semicolon.
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the code represented by the given node contains an `if` statement
 | 
			
		||||
         * that would become associated with an `else` keyword directly appended to that code.
 | 
			
		||||
         *
 | 
			
		||||
         * Examples where it returns `true`:
 | 
			
		||||
         *
 | 
			
		||||
         *    if (a)
 | 
			
		||||
         *        foo();
 | 
			
		||||
         *
 | 
			
		||||
         *    if (a) {
 | 
			
		||||
         *        foo();
 | 
			
		||||
         *    }
 | 
			
		||||
         *
 | 
			
		||||
         *    if (a)
 | 
			
		||||
         *        foo();
 | 
			
		||||
         *    else if (b)
 | 
			
		||||
         *        bar();
 | 
			
		||||
         *
 | 
			
		||||
         *    while (a)
 | 
			
		||||
         *        if (b)
 | 
			
		||||
         *            if(c)
 | 
			
		||||
         *                foo();
 | 
			
		||||
         *            else
 | 
			
		||||
         *                bar();
 | 
			
		||||
         *
 | 
			
		||||
         * Examples where it returns `false`:
 | 
			
		||||
         *
 | 
			
		||||
         *    if (a)
 | 
			
		||||
         *        foo();
 | 
			
		||||
         *    else
 | 
			
		||||
         *        bar();
 | 
			
		||||
         *
 | 
			
		||||
         *    while (a) {
 | 
			
		||||
         *        if (b)
 | 
			
		||||
         *            if(c)
 | 
			
		||||
         *                foo();
 | 
			
		||||
         *            else
 | 
			
		||||
         *                bar();
 | 
			
		||||
         *    }
 | 
			
		||||
         *
 | 
			
		||||
         *    while (a)
 | 
			
		||||
         *        if (b) {
 | 
			
		||||
         *            if(c)
 | 
			
		||||
         *                foo();
 | 
			
		||||
         *        }
 | 
			
		||||
         *        else
 | 
			
		||||
         *            bar();
 | 
			
		||||
         * @param {ASTNode} node Node representing the code to check.
 | 
			
		||||
         * @returns {boolean} `true` if an `if` statement within the code would become associated with an `else` appended to that code.
 | 
			
		||||
         */
 | 
			
		||||
        function hasUnsafeIf(node) {
 | 
			
		||||
            switch (node.type) {
 | 
			
		||||
                case "IfStatement":
 | 
			
		||||
                    if (!node.alternate) {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    return hasUnsafeIf(node.alternate);
 | 
			
		||||
                case "ForStatement":
 | 
			
		||||
                case "ForInStatement":
 | 
			
		||||
                case "ForOfStatement":
 | 
			
		||||
                case "LabeledStatement":
 | 
			
		||||
                case "WithStatement":
 | 
			
		||||
                case "WhileStatement":
 | 
			
		||||
                    return hasUnsafeIf(node.body);
 | 
			
		||||
                default:
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the existing curly braces around the single statement are necessary to preserve the semantics of the code.
 | 
			
		||||
         * The braces, which make the given block body, are necessary in either of the following situations:
 | 
			
		||||
         *
 | 
			
		||||
         * 1. The statement is a lexical declaration.
 | 
			
		||||
         * 2. Without the braces, an `if` within the statement would become associated with an `else` after the closing brace:
 | 
			
		||||
         *
 | 
			
		||||
         *     if (a) {
 | 
			
		||||
         *         if (b)
 | 
			
		||||
         *             foo();
 | 
			
		||||
         *     }
 | 
			
		||||
         *     else
 | 
			
		||||
         *         bar();
 | 
			
		||||
         *
 | 
			
		||||
         *     if (a)
 | 
			
		||||
         *         while (b)
 | 
			
		||||
         *             while (c) {
 | 
			
		||||
         *                 while (d)
 | 
			
		||||
         *                     if (e)
 | 
			
		||||
         *                         while(f)
 | 
			
		||||
         *                             foo();
 | 
			
		||||
         *            }
 | 
			
		||||
         *     else
 | 
			
		||||
         *         bar();
 | 
			
		||||
         * @param {ASTNode} node `BlockStatement` body with exactly one statement directly inside. The statement can have its own nested statements.
 | 
			
		||||
         * @returns {boolean} `true` if the braces are necessary - removing them (replacing the given `BlockStatement` body with its single statement content)
 | 
			
		||||
         * would change the semantics of the code or produce a syntax error.
 | 
			
		||||
         */
 | 
			
		||||
        function areBracesNecessary(node) {
 | 
			
		||||
            const statement = node.body[0];
 | 
			
		||||
 | 
			
		||||
            return isLexicalDeclaration(statement) ||
 | 
			
		||||
                hasUnsafeIf(statement) && isFollowedByElseKeyword(node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Prepares to check the body of a node to see if it's a block statement.
 | 
			
		||||
         * @param {ASTNode} node The node to report if there's a problem.
 | 
			
		||||
         * @param {ASTNode} body The body node to check for blocks.
 | 
			
		||||
         * @param {string} name The name to report if there's a problem.
 | 
			
		||||
         * @param {{ condition: boolean }} opts Options to pass to the report functions
 | 
			
		||||
         * @returns {Object} a prepared check object, with "actual", "expected", "check" properties.
 | 
			
		||||
         *   "actual" will be `true` or `false` whether the body is already a block statement.
 | 
			
		||||
         *   "expected" will be `true` or `false` if the body should be a block statement or not, or
 | 
			
		||||
         *   `null` if it doesn't matter, depending on the rule options. It can be modified to change
 | 
			
		||||
         *   the final behavior of "check".
 | 
			
		||||
         *   "check" will be a function reporting appropriate problems depending on the other
 | 
			
		||||
         *   properties.
 | 
			
		||||
         */
 | 
			
		||||
        function prepareCheck(node, body, name, opts) {
 | 
			
		||||
            const hasBlock = (body.type === "BlockStatement");
 | 
			
		||||
            let expected = null;
 | 
			
		||||
 | 
			
		||||
            if (hasBlock && (body.body.length !== 1 || areBracesNecessary(body))) {
 | 
			
		||||
                expected = true;
 | 
			
		||||
            } else if (multiOnly) {
 | 
			
		||||
                expected = false;
 | 
			
		||||
            } else if (multiLine) {
 | 
			
		||||
                if (!isCollapsedOneLiner(body)) {
 | 
			
		||||
                    expected = true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // otherwise, the body is allowed to have braces or not to have braces
 | 
			
		||||
 | 
			
		||||
            } else if (multiOrNest) {
 | 
			
		||||
                if (hasBlock) {
 | 
			
		||||
                    const statement = body.body[0];
 | 
			
		||||
                    const leadingCommentsInBlock = sourceCode.getCommentsBefore(statement);
 | 
			
		||||
 | 
			
		||||
                    expected = !isOneLiner(statement) || leadingCommentsInBlock.length > 0;
 | 
			
		||||
                } else {
 | 
			
		||||
                    expected = !isOneLiner(body);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                // default "all"
 | 
			
		||||
                expected = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                actual: hasBlock,
 | 
			
		||||
                expected,
 | 
			
		||||
                check() {
 | 
			
		||||
                    if (this.expected !== null && this.expected !== this.actual) {
 | 
			
		||||
                        if (this.expected) {
 | 
			
		||||
                            context.report({
 | 
			
		||||
                                node,
 | 
			
		||||
                                loc: body.loc,
 | 
			
		||||
                                messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter",
 | 
			
		||||
                                data: {
 | 
			
		||||
                                    name
 | 
			
		||||
                                },
 | 
			
		||||
                                fix: fixer => fixer.replaceText(body, `{${sourceCode.getText(body)}}`)
 | 
			
		||||
                            });
 | 
			
		||||
                        } else {
 | 
			
		||||
                            context.report({
 | 
			
		||||
                                node,
 | 
			
		||||
                                loc: body.loc,
 | 
			
		||||
                                messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter",
 | 
			
		||||
                                data: {
 | 
			
		||||
                                    name
 | 
			
		||||
                                },
 | 
			
		||||
                                fix(fixer) {
 | 
			
		||||
 | 
			
		||||
                                    /*
 | 
			
		||||
                                     * `do while` expressions sometimes need a space to be inserted after `do`.
 | 
			
		||||
                                     * e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)`
 | 
			
		||||
                                     */
 | 
			
		||||
                                    const needsPrecedingSpace = node.type === "DoWhileStatement" &&
 | 
			
		||||
                                        sourceCode.getTokenBefore(body).range[1] === body.range[0] &&
 | 
			
		||||
                                        !astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(body, { skip: 1 }));
 | 
			
		||||
 | 
			
		||||
                                    const openingBracket = sourceCode.getFirstToken(body);
 | 
			
		||||
                                    const closingBracket = sourceCode.getLastToken(body);
 | 
			
		||||
                                    const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket);
 | 
			
		||||
 | 
			
		||||
                                    if (needsSemicolon(closingBracket)) {
 | 
			
		||||
 | 
			
		||||
                                        /*
 | 
			
		||||
                                         * If removing braces would cause a SyntaxError due to multiple statements on the same line (or
 | 
			
		||||
                                         * change the semantics of the code due to ASI), don't perform a fix.
 | 
			
		||||
                                         */
 | 
			
		||||
                                        return null;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) +
 | 
			
		||||
                                        sourceCode.getText(lastTokenInBlock) +
 | 
			
		||||
                                        sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]);
 | 
			
		||||
 | 
			
		||||
                                    return fixer.replaceText(body, (needsPrecedingSpace ? " " : "") + resultingBodyText);
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Prepares to check the bodies of a "if", "else if" and "else" chain.
 | 
			
		||||
         * @param {ASTNode} node The first IfStatement node of the chain.
 | 
			
		||||
         * @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more
 | 
			
		||||
         *   information.
 | 
			
		||||
         */
 | 
			
		||||
        function prepareIfChecks(node) {
 | 
			
		||||
            const preparedChecks = [];
 | 
			
		||||
 | 
			
		||||
            for (let currentNode = node; currentNode; currentNode = currentNode.alternate) {
 | 
			
		||||
                preparedChecks.push(prepareCheck(currentNode, currentNode.consequent, "if", { condition: true }));
 | 
			
		||||
                if (currentNode.alternate && currentNode.alternate.type !== "IfStatement") {
 | 
			
		||||
                    preparedChecks.push(prepareCheck(currentNode, currentNode.alternate, "else"));
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (consistent) {
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * If any node should have or already have braces, make sure they
 | 
			
		||||
                 * all have braces.
 | 
			
		||||
                 * If all nodes shouldn't have braces, make sure they don't.
 | 
			
		||||
                 */
 | 
			
		||||
                const expected = preparedChecks.some(preparedCheck => {
 | 
			
		||||
                    if (preparedCheck.expected !== null) {
 | 
			
		||||
                        return preparedCheck.expected;
 | 
			
		||||
                    }
 | 
			
		||||
                    return preparedCheck.actual;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                preparedChecks.forEach(preparedCheck => {
 | 
			
		||||
                    preparedCheck.expected = expected;
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return preparedChecks;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            IfStatement(node) {
 | 
			
		||||
                const parent = node.parent;
 | 
			
		||||
                const isElseIf = parent.type === "IfStatement" && parent.alternate === node;
 | 
			
		||||
 | 
			
		||||
                if (!isElseIf) {
 | 
			
		||||
 | 
			
		||||
                    // This is a top `if`, check the whole `if-else-if` chain
 | 
			
		||||
                    prepareIfChecks(node).forEach(preparedCheck => {
 | 
			
		||||
                        preparedCheck.check();
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Skip `else if`, it's already checked (when the top `if` was visited)
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            WhileStatement(node) {
 | 
			
		||||
                prepareCheck(node, node.body, "while", { condition: true }).check();
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            DoWhileStatement(node) {
 | 
			
		||||
                prepareCheck(node, node.body, "do").check();
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            ForStatement(node) {
 | 
			
		||||
                prepareCheck(node, node.body, "for", { condition: true }).check();
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            ForInStatement(node) {
 | 
			
		||||
                prepareCheck(node, node.body, "for-in").check();
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            ForOfStatement(node) {
 | 
			
		||||
                prepareCheck(node, node.body, "for-of").check();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										44
									
								
								node_modules/eslint/lib/rules/default-case-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								node_modules/eslint/lib/rules/default-case-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce default clauses in switch statements to be last
 | 
			
		||||
 * @author Milos Djermanovic
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce default clauses in switch statements to be last",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/default-case-last"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            notLast: "Default clause should be the last clause."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        return {
 | 
			
		||||
            SwitchStatement(node) {
 | 
			
		||||
                const cases = node.cases,
 | 
			
		||||
                    indexOfDefault = cases.findIndex(c => c.test === null);
 | 
			
		||||
 | 
			
		||||
                if (indexOfDefault !== -1 && indexOfDefault !== cases.length - 1) {
 | 
			
		||||
                    const defaultClause = cases[indexOfDefault];
 | 
			
		||||
 | 
			
		||||
                    context.report({ node: defaultClause, messageId: "notLast" });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										97
									
								
								node_modules/eslint/lib/rules/default-case.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								node_modules/eslint/lib/rules/default-case.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview require default case in switch statements
 | 
			
		||||
 * @author Aliaksei Shytkin
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const DEFAULT_COMMENT_PATTERN = /^no default$/iu;
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require `default` cases in `switch` statements",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/default-case"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [{
 | 
			
		||||
            type: "object",
 | 
			
		||||
            properties: {
 | 
			
		||||
                commentPattern: {
 | 
			
		||||
                    type: "string"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            additionalProperties: false
 | 
			
		||||
        }],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingDefaultCase: "Expected a default case."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const options = context.options[0] || {};
 | 
			
		||||
        const commentPattern = options.commentPattern
 | 
			
		||||
            ? new RegExp(options.commentPattern, "u")
 | 
			
		||||
            : DEFAULT_COMMENT_PATTERN;
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Shortcut to get last element of array
 | 
			
		||||
         * @param {*[]} collection Array
 | 
			
		||||
         * @returns {any} Last element
 | 
			
		||||
         */
 | 
			
		||||
        function last(collection) {
 | 
			
		||||
            return collection[collection.length - 1];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            SwitchStatement(node) {
 | 
			
		||||
 | 
			
		||||
                if (!node.cases.length) {
 | 
			
		||||
 | 
			
		||||
                    /*
 | 
			
		||||
                     * skip check of empty switch because there is no easy way
 | 
			
		||||
                     * to extract comments inside it now
 | 
			
		||||
                     */
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const hasDefault = node.cases.some(v => v.test === null);
 | 
			
		||||
 | 
			
		||||
                if (!hasDefault) {
 | 
			
		||||
 | 
			
		||||
                    let comment;
 | 
			
		||||
 | 
			
		||||
                    const lastCase = last(node.cases);
 | 
			
		||||
                    const comments = sourceCode.getCommentsAfter(lastCase);
 | 
			
		||||
 | 
			
		||||
                    if (comments.length) {
 | 
			
		||||
                        comment = last(comments);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (!comment || !commentPattern.test(comment.value.trim())) {
 | 
			
		||||
                        context.report({ node, messageId: "missingDefaultCase" });
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										62
									
								
								node_modules/eslint/lib/rules/default-param-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								node_modules/eslint/lib/rules/default-param-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview enforce default parameters to be last
 | 
			
		||||
 * @author Chiawen Chen
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce default parameters to be last",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/default-param-last"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            shouldBeLast: "Default parameters should be last."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Handler for function contexts.
 | 
			
		||||
         * @param {ASTNode} node function node
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function handleFunction(node) {
 | 
			
		||||
            let hasSeenPlainParam = false;
 | 
			
		||||
 | 
			
		||||
            for (let i = node.params.length - 1; i >= 0; i -= 1) {
 | 
			
		||||
                const param = node.params[i];
 | 
			
		||||
 | 
			
		||||
                if (
 | 
			
		||||
                    param.type !== "AssignmentPattern" &&
 | 
			
		||||
                    param.type !== "RestElement"
 | 
			
		||||
                ) {
 | 
			
		||||
                    hasSeenPlainParam = true;
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (hasSeenPlainParam && param.type === "AssignmentPattern") {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node: param,
 | 
			
		||||
                        messageId: "shouldBeLast"
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            FunctionDeclaration: handleFunction,
 | 
			
		||||
            FunctionExpression: handleFunction,
 | 
			
		||||
            ArrowFunctionExpression: handleFunction
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										108
									
								
								node_modules/eslint/lib/rules/dot-location.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								node_modules/eslint/lib/rules/dot-location.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Validates newlines before and after dots
 | 
			
		||||
 * @author Greg Cochard
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent newlines before and after dots",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/dot-location"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["object", "property"]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            expectedDotAfterObject: "Expected dot to be on same line as object.",
 | 
			
		||||
            expectedDotBeforeProperty: "Expected dot to be on same line as property."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const config = context.options[0];
 | 
			
		||||
 | 
			
		||||
        // default to onObject if no preference is passed
 | 
			
		||||
        const onObject = config === "object" || !config;
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports if the dot between object and property is on the correct location.
 | 
			
		||||
         * @param {ASTNode} node The `MemberExpression` node.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkDotLocation(node) {
 | 
			
		||||
            const property = node.property;
 | 
			
		||||
            const dotToken = sourceCode.getTokenBefore(property);
 | 
			
		||||
 | 
			
		||||
            if (onObject) {
 | 
			
		||||
 | 
			
		||||
                // `obj` expression can be parenthesized, but those paren tokens are not a part of the `obj` node.
 | 
			
		||||
                const tokenBeforeDot = sourceCode.getTokenBefore(dotToken);
 | 
			
		||||
 | 
			
		||||
                if (!astUtils.isTokenOnSameLine(tokenBeforeDot, dotToken)) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        loc: dotToken.loc,
 | 
			
		||||
                        messageId: "expectedDotAfterObject",
 | 
			
		||||
                        *fix(fixer) {
 | 
			
		||||
                            if (dotToken.value.startsWith(".") && astUtils.isDecimalIntegerNumericToken(tokenBeforeDot)) {
 | 
			
		||||
                                yield fixer.insertTextAfter(tokenBeforeDot, ` ${dotToken.value}`);
 | 
			
		||||
                            } else {
 | 
			
		||||
                                yield fixer.insertTextAfter(tokenBeforeDot, dotToken.value);
 | 
			
		||||
                            }
 | 
			
		||||
                            yield fixer.remove(dotToken);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            } else if (!astUtils.isTokenOnSameLine(dotToken, property)) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc: dotToken.loc,
 | 
			
		||||
                    messageId: "expectedDotBeforeProperty",
 | 
			
		||||
                    *fix(fixer) {
 | 
			
		||||
                        yield fixer.remove(dotToken);
 | 
			
		||||
                        yield fixer.insertTextBefore(property, dotToken.value);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks the spacing of the dot within a member expression.
 | 
			
		||||
         * @param {ASTNode} node The node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkNode(node) {
 | 
			
		||||
            if (!node.computed) {
 | 
			
		||||
                checkDotLocation(node);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            MemberExpression: checkNode
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										176
									
								
								node_modules/eslint/lib/rules/dot-notation.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								node_modules/eslint/lib/rules/dot-notation.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,176 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible.
 | 
			
		||||
 * @author Josh Perez
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
const keywords = require("./utils/keywords");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u;
 | 
			
		||||
 | 
			
		||||
// `null` literal must be handled separately.
 | 
			
		||||
const literalTypesToCheck = new Set(["string", "boolean"]);
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce dot notation whenever possible",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/dot-notation"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    allowKeywords: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: true
 | 
			
		||||
                    },
 | 
			
		||||
                    allowPattern: {
 | 
			
		||||
                        type: "string",
 | 
			
		||||
                        default: ""
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            useDot: "[{{key}}] is better written in dot notation.",
 | 
			
		||||
            useBrackets: ".{{key}} is a syntax error."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const options = context.options[0] || {};
 | 
			
		||||
        const allowKeywords = options.allowKeywords === void 0 || options.allowKeywords;
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        let allowPattern;
 | 
			
		||||
 | 
			
		||||
        if (options.allowPattern) {
 | 
			
		||||
            allowPattern = new RegExp(options.allowPattern, "u");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check if the property is valid dot notation
 | 
			
		||||
         * @param {ASTNode} node The dot notation node
 | 
			
		||||
         * @param {string} value Value which is to be checked
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkComputedProperty(node, value) {
 | 
			
		||||
            if (
 | 
			
		||||
                validIdentifier.test(value) &&
 | 
			
		||||
                (allowKeywords || !keywords.includes(String(value))) &&
 | 
			
		||||
                !(allowPattern && allowPattern.test(value))
 | 
			
		||||
            ) {
 | 
			
		||||
                const formattedValue = node.property.type === "Literal" ? JSON.stringify(value) : `\`${value}\``;
 | 
			
		||||
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: node.property,
 | 
			
		||||
                    messageId: "useDot",
 | 
			
		||||
                    data: {
 | 
			
		||||
                        key: formattedValue
 | 
			
		||||
                    },
 | 
			
		||||
                    *fix(fixer) {
 | 
			
		||||
                        const leftBracket = sourceCode.getTokenAfter(node.object, astUtils.isOpeningBracketToken);
 | 
			
		||||
                        const rightBracket = sourceCode.getLastToken(node);
 | 
			
		||||
                        const nextToken = sourceCode.getTokenAfter(node);
 | 
			
		||||
 | 
			
		||||
                        // Don't perform any fixes if there are comments inside the brackets.
 | 
			
		||||
                        if (sourceCode.commentsExistBetween(leftBracket, rightBracket)) {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Replace the brackets by an identifier.
 | 
			
		||||
                        if (!node.optional) {
 | 
			
		||||
                            yield fixer.insertTextBefore(
 | 
			
		||||
                                leftBracket,
 | 
			
		||||
                                astUtils.isDecimalInteger(node.object) ? " ." : "."
 | 
			
		||||
                            );
 | 
			
		||||
                        }
 | 
			
		||||
                        yield fixer.replaceTextRange(
 | 
			
		||||
                            [leftBracket.range[0], rightBracket.range[1]],
 | 
			
		||||
                            value
 | 
			
		||||
                        );
 | 
			
		||||
 | 
			
		||||
                        // Insert a space after the property if it will be connected to the next token.
 | 
			
		||||
                        if (
 | 
			
		||||
                            nextToken &&
 | 
			
		||||
                            rightBracket.range[1] === nextToken.range[0] &&
 | 
			
		||||
                            !astUtils.canTokensBeAdjacent(String(value), nextToken)
 | 
			
		||||
                        ) {
 | 
			
		||||
                            yield fixer.insertTextAfter(node, " ");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            MemberExpression(node) {
 | 
			
		||||
                if (
 | 
			
		||||
                    node.computed &&
 | 
			
		||||
                    node.property.type === "Literal" &&
 | 
			
		||||
                    (literalTypesToCheck.has(typeof node.property.value) || astUtils.isNullLiteral(node.property))
 | 
			
		||||
                ) {
 | 
			
		||||
                    checkComputedProperty(node, node.property.value);
 | 
			
		||||
                }
 | 
			
		||||
                if (
 | 
			
		||||
                    node.computed &&
 | 
			
		||||
                    astUtils.isStaticTemplateLiteral(node.property)
 | 
			
		||||
                ) {
 | 
			
		||||
                    checkComputedProperty(node, node.property.quasis[0].value.cooked);
 | 
			
		||||
                }
 | 
			
		||||
                if (
 | 
			
		||||
                    !allowKeywords &&
 | 
			
		||||
                    !node.computed &&
 | 
			
		||||
                    node.property.type === "Identifier" &&
 | 
			
		||||
                    keywords.includes(String(node.property.name))
 | 
			
		||||
                ) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node: node.property,
 | 
			
		||||
                        messageId: "useBrackets",
 | 
			
		||||
                        data: {
 | 
			
		||||
                            key: node.property.name
 | 
			
		||||
                        },
 | 
			
		||||
                        *fix(fixer) {
 | 
			
		||||
                            const dotToken = sourceCode.getTokenBefore(node.property);
 | 
			
		||||
 | 
			
		||||
                            // A statement that starts with `let[` is parsed as a destructuring variable declaration, not a MemberExpression.
 | 
			
		||||
                            if (node.object.type === "Identifier" && node.object.name === "let" && !node.optional) {
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // Don't perform any fixes if there are comments between the dot and the property name.
 | 
			
		||||
                            if (sourceCode.commentsExistBetween(dotToken, node.property)) {
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // Replace the identifier to brackets.
 | 
			
		||||
                            if (!node.optional) {
 | 
			
		||||
                                yield fixer.remove(dotToken);
 | 
			
		||||
                            }
 | 
			
		||||
                            yield fixer.replaceText(node.property, `["${node.property.name}"]`);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										115
									
								
								node_modules/eslint/lib/rules/eol-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								node_modules/eslint/lib/rules/eol-last.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Require or disallow newline at the end of files
 | 
			
		||||
 * @author Nodeca Team <https://github.com/nodeca>
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require or disallow newline at the end of files",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/eol-last"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["always", "never", "unix", "windows"]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missing: "Newline required at end of file but not found.",
 | 
			
		||||
            unexpected: "Newline not allowed at end of file."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            Program: function checkBadEOF(node) {
 | 
			
		||||
                const sourceCode = context.sourceCode,
 | 
			
		||||
                    src = sourceCode.getText(),
 | 
			
		||||
                    lastLine = sourceCode.lines[sourceCode.lines.length - 1],
 | 
			
		||||
                    location = {
 | 
			
		||||
                        column: lastLine.length,
 | 
			
		||||
                        line: sourceCode.lines.length
 | 
			
		||||
                    },
 | 
			
		||||
                    LF = "\n",
 | 
			
		||||
                    CRLF = `\r${LF}`,
 | 
			
		||||
                    endsWithNewline = src.endsWith(LF);
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * Empty source is always valid: No content in file so we don't
 | 
			
		||||
                 * need to lint for a newline on the last line of content.
 | 
			
		||||
                 */
 | 
			
		||||
                if (!src.length) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let mode = context.options[0] || "always",
 | 
			
		||||
                    appendCRLF = false;
 | 
			
		||||
 | 
			
		||||
                if (mode === "unix") {
 | 
			
		||||
 | 
			
		||||
                    // `"unix"` should behave exactly as `"always"`
 | 
			
		||||
                    mode = "always";
 | 
			
		||||
                }
 | 
			
		||||
                if (mode === "windows") {
 | 
			
		||||
 | 
			
		||||
                    // `"windows"` should behave exactly as `"always"`, but append CRLF in the fixer for backwards compatibility
 | 
			
		||||
                    mode = "always";
 | 
			
		||||
                    appendCRLF = true;
 | 
			
		||||
                }
 | 
			
		||||
                if (mode === "always" && !endsWithNewline) {
 | 
			
		||||
 | 
			
		||||
                    // File is not newline-terminated, but should be
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        loc: location,
 | 
			
		||||
                        messageId: "missing",
 | 
			
		||||
                        fix(fixer) {
 | 
			
		||||
                            return fixer.insertTextAfterRange([0, src.length], appendCRLF ? CRLF : LF);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                } else if (mode === "never" && endsWithNewline) {
 | 
			
		||||
 | 
			
		||||
                    const secondLastLine = sourceCode.lines[sourceCode.lines.length - 2];
 | 
			
		||||
 | 
			
		||||
                    // File is newline-terminated, but shouldn't be
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        loc: {
 | 
			
		||||
                            start: { line: sourceCode.lines.length - 1, column: secondLastLine.length },
 | 
			
		||||
                            end: { line: sourceCode.lines.length, column: 0 }
 | 
			
		||||
                        },
 | 
			
		||||
                        messageId: "unexpected",
 | 
			
		||||
                        fix(fixer) {
 | 
			
		||||
                            const finalEOLs = /(?:\r?\n)+$/u,
 | 
			
		||||
                                match = finalEOLs.exec(sourceCode.text),
 | 
			
		||||
                                start = match.index,
 | 
			
		||||
                                end = sourceCode.text.length;
 | 
			
		||||
 | 
			
		||||
                            return fixer.replaceTextRange([start, end], "");
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										174
									
								
								node_modules/eslint/lib/rules/eqeqeq.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								node_modules/eslint/lib/rules/eqeqeq.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,174 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to flag statements that use != and == instead of !== and ===
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require the use of `===` and `!==`",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/eqeqeq"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            anyOf: [
 | 
			
		||||
                {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["always"]
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: "object",
 | 
			
		||||
                            properties: {
 | 
			
		||||
                                null: {
 | 
			
		||||
                                    enum: ["always", "never", "ignore"]
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            additionalProperties: false
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    additionalItems: false
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["smart", "allow-null"]
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    additionalItems: false
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "code",
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpected: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const config = context.options[0] || "always";
 | 
			
		||||
        const options = context.options[1] || {};
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        const nullOption = (config === "always")
 | 
			
		||||
            ? options.null || "always"
 | 
			
		||||
            : "ignore";
 | 
			
		||||
        const enforceRuleForNull = (nullOption === "always");
 | 
			
		||||
        const enforceInverseRuleForNull = (nullOption === "never");
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if an expression is a typeof expression
 | 
			
		||||
         * @param {ASTNode} node The node to check
 | 
			
		||||
         * @returns {boolean} if the node is a typeof expression
 | 
			
		||||
         */
 | 
			
		||||
        function isTypeOf(node) {
 | 
			
		||||
            return node.type === "UnaryExpression" && node.operator === "typeof";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if either operand of a binary expression is a typeof operation
 | 
			
		||||
         * @param {ASTNode} node The node to check
 | 
			
		||||
         * @returns {boolean} if one of the operands is typeof
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isTypeOfBinary(node) {
 | 
			
		||||
            return isTypeOf(node.left) || isTypeOf(node.right);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if operands are literals of the same type (via typeof)
 | 
			
		||||
         * @param {ASTNode} node The node to check
 | 
			
		||||
         * @returns {boolean} if operands are of same type
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function areLiteralsAndSameType(node) {
 | 
			
		||||
            return node.left.type === "Literal" && node.right.type === "Literal" &&
 | 
			
		||||
                    typeof node.left.value === typeof node.right.value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if one of the operands is a literal null
 | 
			
		||||
         * @param {ASTNode} node The node to check
 | 
			
		||||
         * @returns {boolean} if operands are null
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isNullCheck(node) {
 | 
			
		||||
            return astUtils.isNullLiteral(node.right) || astUtils.isNullLiteral(node.left);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports a message for this rule.
 | 
			
		||||
         * @param {ASTNode} node The binary expression node that was checked
 | 
			
		||||
         * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==')
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function report(node, expectedOperator) {
 | 
			
		||||
            const operatorToken = sourceCode.getFirstTokenBetween(
 | 
			
		||||
                node.left,
 | 
			
		||||
                node.right,
 | 
			
		||||
                token => token.value === node.operator
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                loc: operatorToken.loc,
 | 
			
		||||
                messageId: "unexpected",
 | 
			
		||||
                data: { expectedOperator, actualOperator: node.operator },
 | 
			
		||||
                fix(fixer) {
 | 
			
		||||
 | 
			
		||||
                    // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix.
 | 
			
		||||
                    if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) {
 | 
			
		||||
                        return fixer.replaceText(operatorToken, expectedOperator);
 | 
			
		||||
                    }
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            BinaryExpression(node) {
 | 
			
		||||
                const isNull = isNullCheck(node);
 | 
			
		||||
 | 
			
		||||
                if (node.operator !== "==" && node.operator !== "!=") {
 | 
			
		||||
                    if (enforceInverseRuleForNull && isNull) {
 | 
			
		||||
                        report(node, node.operator.slice(0, -1));
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (config === "smart" && (isTypeOfBinary(node) ||
 | 
			
		||||
                        areLiteralsAndSameType(node) || isNull)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!enforceRuleForNull && isNull) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                report(node, `${node.operator}=`);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										133
									
								
								node_modules/eslint/lib/rules/for-direction.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								node_modules/eslint/lib/rules/for-direction.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview enforce "for" loop update clause moving the counter in the right direction.(for-direction)
 | 
			
		||||
 * @author Aladdin-ADD<hh_2013@foxmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const { getStaticValue } = require("@eslint-community/eslint-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "problem",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce \"for\" loop update clause moving the counter in the right direction",
 | 
			
		||||
            recommended: true,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/for-direction"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: null,
 | 
			
		||||
        schema: [],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            incorrectDirection: "The update clause in this loop moves the variable in the wrong direction."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const { sourceCode } = context;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * report an error.
 | 
			
		||||
         * @param {ASTNode} node the node to report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function report(node) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                messageId: "incorrectDirection"
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * check the right side of the assignment
 | 
			
		||||
         * @param {ASTNode} update UpdateExpression to check
 | 
			
		||||
         * @param {int} dir expected direction that could either be turned around or invalidated
 | 
			
		||||
         * @returns {int} return dir, the negated dir, or zero if the counter does not change or the direction is not clear
 | 
			
		||||
         */
 | 
			
		||||
        function getRightDirection(update, dir) {
 | 
			
		||||
            const staticValue = getStaticValue(update.right, sourceCode.getScope(update));
 | 
			
		||||
 | 
			
		||||
            if (staticValue && ["bigint", "boolean", "number"].includes(typeof staticValue.value)) {
 | 
			
		||||
                const sign = Math.sign(Number(staticValue.value)) || 0; // convert NaN to 0
 | 
			
		||||
 | 
			
		||||
                return dir * sign;
 | 
			
		||||
            }
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * check UpdateExpression add/sub the counter
 | 
			
		||||
         * @param {ASTNode} update UpdateExpression to check
 | 
			
		||||
         * @param {string} counter variable name to check
 | 
			
		||||
         * @returns {int} if add return 1, if sub return -1, if nochange, return 0
 | 
			
		||||
         */
 | 
			
		||||
        function getUpdateDirection(update, counter) {
 | 
			
		||||
            if (update.argument.type === "Identifier" && update.argument.name === counter) {
 | 
			
		||||
                if (update.operator === "++") {
 | 
			
		||||
                    return 1;
 | 
			
		||||
                }
 | 
			
		||||
                if (update.operator === "--") {
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * check AssignmentExpression add/sub the counter
 | 
			
		||||
         * @param {ASTNode} update AssignmentExpression to check
 | 
			
		||||
         * @param {string} counter variable name to check
 | 
			
		||||
         * @returns {int} if add return 1, if sub return -1, if nochange, return 0
 | 
			
		||||
         */
 | 
			
		||||
        function getAssignmentDirection(update, counter) {
 | 
			
		||||
            if (update.left.name === counter) {
 | 
			
		||||
                if (update.operator === "+=") {
 | 
			
		||||
                    return getRightDirection(update, 1);
 | 
			
		||||
                }
 | 
			
		||||
                if (update.operator === "-=") {
 | 
			
		||||
                    return getRightDirection(update, -1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        return {
 | 
			
		||||
            ForStatement(node) {
 | 
			
		||||
 | 
			
		||||
                if (node.test && node.test.type === "BinaryExpression" && node.test.left.type === "Identifier" && node.update) {
 | 
			
		||||
                    const counter = node.test.left.name;
 | 
			
		||||
                    const operator = node.test.operator;
 | 
			
		||||
                    const update = node.update;
 | 
			
		||||
 | 
			
		||||
                    let wrongDirection;
 | 
			
		||||
 | 
			
		||||
                    if (operator === "<" || operator === "<=") {
 | 
			
		||||
                        wrongDirection = -1;
 | 
			
		||||
                    } else if (operator === ">" || operator === ">=") {
 | 
			
		||||
                        wrongDirection = 1;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (update.type === "UpdateExpression") {
 | 
			
		||||
                        if (getUpdateDirection(update, counter) === wrongDirection) {
 | 
			
		||||
                            report(node);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) {
 | 
			
		||||
                        report(node);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										233
									
								
								node_modules/eslint/lib/rules/func-call-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								node_modules/eslint/lib/rules/func-call-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,233 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to control spacing within function calls
 | 
			
		||||
 * @author Matt DuVall <http://www.mattduvall.com>
 | 
			
		||||
 * @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: "Require or disallow spacing between function identifiers and their invocations",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/func-call-spacing"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            anyOf: [
 | 
			
		||||
                {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["never"]
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    minItems: 0,
 | 
			
		||||
                    maxItems: 1
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    type: "array",
 | 
			
		||||
                    items: [
 | 
			
		||||
                        {
 | 
			
		||||
                            enum: ["always"]
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            type: "object",
 | 
			
		||||
                            properties: {
 | 
			
		||||
                                allowNewlines: {
 | 
			
		||||
                                    type: "boolean"
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            additionalProperties: false
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    minItems: 0,
 | 
			
		||||
                    maxItems: 2
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedWhitespace: "Unexpected whitespace between function name and paren.",
 | 
			
		||||
            unexpectedNewline: "Unexpected newline between function name and paren.",
 | 
			
		||||
            missing: "Missing space between function name and paren."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const never = context.options[0] !== "always";
 | 
			
		||||
        const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines;
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
        const text = sourceCode.getText();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check if open space is present in a function name
 | 
			
		||||
         * @param {ASTNode} node node to evaluate
 | 
			
		||||
         * @param {Token} leftToken The last token of the callee. This may be the closing parenthesis that encloses the callee.
 | 
			
		||||
         * @param {Token} rightToken Tha first token of the arguments. this is the opening parenthesis that encloses the arguments.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function checkSpacing(node, leftToken, rightToken) {
 | 
			
		||||
            const textBetweenTokens = text.slice(leftToken.range[1], rightToken.range[0]).replace(/\/\*.*?\*\//gu, "");
 | 
			
		||||
            const hasWhitespace = /\s/u.test(textBetweenTokens);
 | 
			
		||||
            const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens);
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * never allowNewlines hasWhitespace hasNewline message
 | 
			
		||||
             * F     F             F             F          Missing space between function name and paren.
 | 
			
		||||
             * F     F             F             T          (Invalid `!hasWhitespace && hasNewline`)
 | 
			
		||||
             * F     F             T             T          Unexpected newline between function name and paren.
 | 
			
		||||
             * F     F             T             F          (OK)
 | 
			
		||||
             * F     T             T             F          (OK)
 | 
			
		||||
             * F     T             T             T          (OK)
 | 
			
		||||
             * F     T             F             T          (Invalid `!hasWhitespace && hasNewline`)
 | 
			
		||||
             * F     T             F             F          Missing space between function name and paren.
 | 
			
		||||
             * T     T             F             F          (Invalid `never && allowNewlines`)
 | 
			
		||||
             * T     T             F             T          (Invalid `!hasWhitespace && hasNewline`)
 | 
			
		||||
             * T     T             T             T          (Invalid `never && allowNewlines`)
 | 
			
		||||
             * T     T             T             F          (Invalid `never && allowNewlines`)
 | 
			
		||||
             * T     F             T             F          Unexpected space between function name and paren.
 | 
			
		||||
             * T     F             T             T          Unexpected space between function name and paren.
 | 
			
		||||
             * T     F             F             T          (Invalid `!hasWhitespace && hasNewline`)
 | 
			
		||||
             * T     F             F             F          (OK)
 | 
			
		||||
             *
 | 
			
		||||
             * T                   T                        Unexpected space between function name and paren.
 | 
			
		||||
             * F                   F                        Missing space between function name and paren.
 | 
			
		||||
             * F     F                           T          Unexpected newline between function name and paren.
 | 
			
		||||
             */
 | 
			
		||||
 | 
			
		||||
            if (never && hasWhitespace) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc: {
 | 
			
		||||
                        start: leftToken.loc.end,
 | 
			
		||||
                        end: {
 | 
			
		||||
                            line: rightToken.loc.start.line,
 | 
			
		||||
                            column: rightToken.loc.start.column - 1
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    messageId: "unexpectedWhitespace",
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
 | 
			
		||||
                        // Don't remove comments.
 | 
			
		||||
                        if (sourceCode.commentsExistBetween(leftToken, rightToken)) {
 | 
			
		||||
                            return null;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // If `?.` exists, it doesn't hide no-unexpected-multiline errors
 | 
			
		||||
                        if (node.optional) {
 | 
			
		||||
                            return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], "?.");
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        /*
 | 
			
		||||
                         * Only autofix if there is no newline
 | 
			
		||||
                         * https://github.com/eslint/eslint/issues/7787
 | 
			
		||||
                         */
 | 
			
		||||
                        if (hasNewline) {
 | 
			
		||||
                            return null;
 | 
			
		||||
                        }
 | 
			
		||||
                        return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            } else if (!never && !hasWhitespace) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc: {
 | 
			
		||||
                        start: {
 | 
			
		||||
                            line: leftToken.loc.end.line,
 | 
			
		||||
                            column: leftToken.loc.end.column - 1
 | 
			
		||||
                        },
 | 
			
		||||
                        end: rightToken.loc.start
 | 
			
		||||
                    },
 | 
			
		||||
                    messageId: "missing",
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
                        if (node.optional) {
 | 
			
		||||
                            return null; // Not sure if inserting a space to either before/after `?.` token.
 | 
			
		||||
                        }
 | 
			
		||||
                        return fixer.insertTextBefore(rightToken, " ");
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            } else if (!never && !allowNewlines && hasNewline) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc: {
 | 
			
		||||
                        start: leftToken.loc.end,
 | 
			
		||||
                        end: rightToken.loc.start
 | 
			
		||||
                    },
 | 
			
		||||
                    messageId: "unexpectedNewline",
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
 | 
			
		||||
                        /*
 | 
			
		||||
                         * Only autofix if there is no newline
 | 
			
		||||
                         * https://github.com/eslint/eslint/issues/7787
 | 
			
		||||
                         * But if `?.` exists, it doesn't hide no-unexpected-multiline errors
 | 
			
		||||
                         */
 | 
			
		||||
                        if (!node.optional) {
 | 
			
		||||
                            return null;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Don't remove comments.
 | 
			
		||||
                        if (sourceCode.commentsExistBetween(leftToken, rightToken)) {
 | 
			
		||||
                            return null;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        const range = [leftToken.range[1], rightToken.range[0]];
 | 
			
		||||
                        const qdToken = sourceCode.getTokenAfter(leftToken);
 | 
			
		||||
 | 
			
		||||
                        if (qdToken.range[0] === leftToken.range[1]) {
 | 
			
		||||
                            return fixer.replaceTextRange(range, "?. ");
 | 
			
		||||
                        }
 | 
			
		||||
                        if (qdToken.range[1] === rightToken.range[0]) {
 | 
			
		||||
                            return fixer.replaceTextRange(range, " ?.");
 | 
			
		||||
                        }
 | 
			
		||||
                        return fixer.replaceTextRange(range, " ?. ");
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            "CallExpression, NewExpression"(node) {
 | 
			
		||||
                const lastToken = sourceCode.getLastToken(node);
 | 
			
		||||
                const lastCalleeToken = sourceCode.getLastToken(node.callee);
 | 
			
		||||
                const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken);
 | 
			
		||||
                const prevToken = parenToken && sourceCode.getTokenBefore(parenToken, astUtils.isNotQuestionDotToken);
 | 
			
		||||
 | 
			
		||||
                // Parens in NewExpression are optional
 | 
			
		||||
                if (!(parenToken && parenToken.range[1] < node.range[1])) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                checkSpacing(node, prevToken, parenToken);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            ImportExpression(node) {
 | 
			
		||||
                const leftToken = sourceCode.getFirstToken(node);
 | 
			
		||||
                const rightToken = sourceCode.getTokenAfter(leftToken);
 | 
			
		||||
 | 
			
		||||
                checkSpacing(node, leftToken, rightToken);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										253
									
								
								node_modules/eslint/lib/rules/func-name-matching.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								node_modules/eslint/lib/rules/func-name-matching.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,253 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to require function names to match the name of the variable or property to which they are assigned.
 | 
			
		||||
 * @author Annie Zhang, Pavel Strashkin
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
const esutils = require("esutils");
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determines if a pattern is `module.exports` or `module["exports"]`
 | 
			
		||||
 * @param {ASTNode} pattern The left side of the AssignmentExpression
 | 
			
		||||
 * @returns {boolean} True if the pattern is `module.exports` or `module["exports"]`
 | 
			
		||||
 */
 | 
			
		||||
function isModuleExports(pattern) {
 | 
			
		||||
    if (pattern.type === "MemberExpression" && pattern.object.type === "Identifier" && pattern.object.name === "module") {
 | 
			
		||||
 | 
			
		||||
        // module.exports
 | 
			
		||||
        if (pattern.property.type === "Identifier" && pattern.property.name === "exports") {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // module["exports"]
 | 
			
		||||
        if (pattern.property.type === "Literal" && pattern.property.value === "exports") {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determines if a string name is a valid identifier
 | 
			
		||||
 * @param {string} name The string to be checked
 | 
			
		||||
 * @param {int} ecmaVersion The ECMAScript version if specified in the parserOptions config
 | 
			
		||||
 * @returns {boolean} True if the string is a valid identifier
 | 
			
		||||
 */
 | 
			
		||||
function isIdentifier(name, ecmaVersion) {
 | 
			
		||||
    if (ecmaVersion >= 2015) {
 | 
			
		||||
        return esutils.keyword.isIdentifierES6(name);
 | 
			
		||||
    }
 | 
			
		||||
    return esutils.keyword.isIdentifierES5(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const alwaysOrNever = { enum: ["always", "never"] };
 | 
			
		||||
const optionsObject = {
 | 
			
		||||
    type: "object",
 | 
			
		||||
    properties: {
 | 
			
		||||
        considerPropertyDescriptor: {
 | 
			
		||||
            type: "boolean"
 | 
			
		||||
        },
 | 
			
		||||
        includeCommonJSModuleExports: {
 | 
			
		||||
            type: "boolean"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    additionalProperties: false
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require function names to match the name of the variable or property to which they are assigned",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/func-name-matching"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            anyOf: [{
 | 
			
		||||
                type: "array",
 | 
			
		||||
                additionalItems: false,
 | 
			
		||||
                items: [alwaysOrNever, optionsObject]
 | 
			
		||||
            }, {
 | 
			
		||||
                type: "array",
 | 
			
		||||
                additionalItems: false,
 | 
			
		||||
                items: [optionsObject]
 | 
			
		||||
            }]
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            matchProperty: "Function name `{{funcName}}` should match property name `{{name}}`.",
 | 
			
		||||
            matchVariable: "Function name `{{funcName}}` should match variable name `{{name}}`.",
 | 
			
		||||
            notMatchProperty: "Function name `{{funcName}}` should not match property name `{{name}}`.",
 | 
			
		||||
            notMatchVariable: "Function name `{{funcName}}` should not match variable name `{{name}}`."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const options = (typeof context.options[0] === "object" ? context.options[0] : context.options[1]) || {};
 | 
			
		||||
        const nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always";
 | 
			
		||||
        const considerPropertyDescriptor = options.considerPropertyDescriptor;
 | 
			
		||||
        const includeModuleExports = options.includeCommonJSModuleExports;
 | 
			
		||||
        const ecmaVersion = context.languageOptions.ecmaVersion;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check whether node is a certain CallExpression.
 | 
			
		||||
         * @param {string} objName object name
 | 
			
		||||
         * @param {string} funcName function name
 | 
			
		||||
         * @param {ASTNode} node The node to check
 | 
			
		||||
         * @returns {boolean} `true` if node matches CallExpression
 | 
			
		||||
         */
 | 
			
		||||
        function isPropertyCall(objName, funcName, node) {
 | 
			
		||||
            if (!node) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            return node.type === "CallExpression" && astUtils.isSpecificMemberAccess(node.callee, objName, funcName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Compares identifiers based on the nameMatches option
 | 
			
		||||
         * @param {string} x the first identifier
 | 
			
		||||
         * @param {string} y the second identifier
 | 
			
		||||
         * @returns {boolean} whether the two identifiers should warn.
 | 
			
		||||
         */
 | 
			
		||||
        function shouldWarn(x, y) {
 | 
			
		||||
            return (nameMatches === "always" && x !== y) || (nameMatches === "never" && x === y);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports
 | 
			
		||||
         * @param {ASTNode} node The node to report
 | 
			
		||||
         * @param {string} name The variable or property name
 | 
			
		||||
         * @param {string} funcName The function name
 | 
			
		||||
         * @param {boolean} isProp True if the reported node is a property assignment
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function report(node, name, funcName, isProp) {
 | 
			
		||||
            let messageId;
 | 
			
		||||
 | 
			
		||||
            if (nameMatches === "always" && isProp) {
 | 
			
		||||
                messageId = "matchProperty";
 | 
			
		||||
            } else if (nameMatches === "always") {
 | 
			
		||||
                messageId = "matchVariable";
 | 
			
		||||
            } else if (isProp) {
 | 
			
		||||
                messageId = "notMatchProperty";
 | 
			
		||||
            } else {
 | 
			
		||||
                messageId = "notMatchVariable";
 | 
			
		||||
            }
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                messageId,
 | 
			
		||||
                data: {
 | 
			
		||||
                    name,
 | 
			
		||||
                    funcName
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether a given node is a string literal
 | 
			
		||||
         * @param {ASTNode} node The node to check
 | 
			
		||||
         * @returns {boolean} `true` if the node is a string literal
 | 
			
		||||
         */
 | 
			
		||||
        function isStringLiteral(node) {
 | 
			
		||||
            return node.type === "Literal" && typeof node.value === "string";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            VariableDeclarator(node) {
 | 
			
		||||
                if (!node.init || node.init.type !== "FunctionExpression" || node.id.type !== "Identifier") {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (node.init.id && shouldWarn(node.id.name, node.init.id.name)) {
 | 
			
		||||
                    report(node, node.id.name, node.init.id.name, false);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            AssignmentExpression(node) {
 | 
			
		||||
                if (
 | 
			
		||||
                    node.right.type !== "FunctionExpression" ||
 | 
			
		||||
                    (node.left.computed && node.left.property.type !== "Literal") ||
 | 
			
		||||
                    (!includeModuleExports && isModuleExports(node.left)) ||
 | 
			
		||||
                    (node.left.type !== "Identifier" && node.left.type !== "MemberExpression")
 | 
			
		||||
                ) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const isProp = node.left.type === "MemberExpression";
 | 
			
		||||
                const name = isProp ? astUtils.getStaticPropertyName(node.left) : node.left.name;
 | 
			
		||||
 | 
			
		||||
                if (node.right.id && name && isIdentifier(name) && shouldWarn(name, node.right.id.name)) {
 | 
			
		||||
                    report(node, name, node.right.id.name, isProp);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            "Property, PropertyDefinition[value]"(node) {
 | 
			
		||||
                if (!(node.value.type === "FunctionExpression" && node.value.id)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (node.key.type === "Identifier" && !node.computed) {
 | 
			
		||||
                    const functionName = node.value.id.name;
 | 
			
		||||
                    let propertyName = node.key.name;
 | 
			
		||||
 | 
			
		||||
                    if (
 | 
			
		||||
                        considerPropertyDescriptor &&
 | 
			
		||||
                        propertyName === "value" &&
 | 
			
		||||
                        node.parent.type === "ObjectExpression"
 | 
			
		||||
                    ) {
 | 
			
		||||
                        if (isPropertyCall("Object", "defineProperty", node.parent.parent) || isPropertyCall("Reflect", "defineProperty", node.parent.parent)) {
 | 
			
		||||
                            const property = node.parent.parent.arguments[1];
 | 
			
		||||
 | 
			
		||||
                            if (isStringLiteral(property) && shouldWarn(property.value, functionName)) {
 | 
			
		||||
                                report(node, property.value, functionName, true);
 | 
			
		||||
                            }
 | 
			
		||||
                        } else if (isPropertyCall("Object", "defineProperties", node.parent.parent.parent.parent)) {
 | 
			
		||||
                            propertyName = node.parent.parent.key.name;
 | 
			
		||||
                            if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) {
 | 
			
		||||
                                report(node, propertyName, functionName, true);
 | 
			
		||||
                            }
 | 
			
		||||
                        } else if (isPropertyCall("Object", "create", node.parent.parent.parent.parent)) {
 | 
			
		||||
                            propertyName = node.parent.parent.key.name;
 | 
			
		||||
                            if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) {
 | 
			
		||||
                                report(node, propertyName, functionName, true);
 | 
			
		||||
                            }
 | 
			
		||||
                        } else if (shouldWarn(propertyName, functionName)) {
 | 
			
		||||
                            report(node, propertyName, functionName, true);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (shouldWarn(propertyName, functionName)) {
 | 
			
		||||
                        report(node, propertyName, functionName, true);
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (
 | 
			
		||||
                    isStringLiteral(node.key) &&
 | 
			
		||||
                    isIdentifier(node.key.value, ecmaVersion) &&
 | 
			
		||||
                    shouldWarn(node.key.value, node.value.id.name)
 | 
			
		||||
                ) {
 | 
			
		||||
                    report(node, node.key.value, node.value.id.name, true);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										191
									
								
								node_modules/eslint/lib/rules/func-names.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								node_modules/eslint/lib/rules/func-names.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,191 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to warn when a function expression does not have a name.
 | 
			
		||||
 * @author Kyle T. Nunery
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given variable is a function name.
 | 
			
		||||
 * @param {eslint-scope.Variable} variable A variable to check.
 | 
			
		||||
 * @returns {boolean} `true` if the variable is a function name.
 | 
			
		||||
 */
 | 
			
		||||
function isFunctionName(variable) {
 | 
			
		||||
    return variable && variable.defs[0].type === "FunctionName";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require or disallow named `function` expressions",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/func-names"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            definitions: {
 | 
			
		||||
                value: {
 | 
			
		||||
                    enum: [
 | 
			
		||||
                        "always",
 | 
			
		||||
                        "as-needed",
 | 
			
		||||
                        "never"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            items: [
 | 
			
		||||
                {
 | 
			
		||||
                    $ref: "#/definitions/value"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    type: "object",
 | 
			
		||||
                    properties: {
 | 
			
		||||
                        generators: {
 | 
			
		||||
                            $ref: "#/definitions/value"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    additionalProperties: false
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unnamed: "Unexpected unnamed {{name}}.",
 | 
			
		||||
            named: "Unexpected named {{name}}."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Returns the config option for the given node.
 | 
			
		||||
         * @param {ASTNode} node A node to get the config for.
 | 
			
		||||
         * @returns {string} The config option.
 | 
			
		||||
         */
 | 
			
		||||
        function getConfigForNode(node) {
 | 
			
		||||
            if (
 | 
			
		||||
                node.generator &&
 | 
			
		||||
                context.options.length > 1 &&
 | 
			
		||||
                context.options[1].generators
 | 
			
		||||
            ) {
 | 
			
		||||
                return context.options[1].generators;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return context.options[0] || "always";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the current FunctionExpression node is a get, set, or
 | 
			
		||||
         * shorthand method in an object literal or a class.
 | 
			
		||||
         * @param {ASTNode} node A node to check.
 | 
			
		||||
         * @returns {boolean} True if the node is a get, set, or shorthand method.
 | 
			
		||||
         */
 | 
			
		||||
        function isObjectOrClassMethod(node) {
 | 
			
		||||
            const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
            return (parent.type === "MethodDefinition" || (
 | 
			
		||||
                parent.type === "Property" && (
 | 
			
		||||
                    parent.method ||
 | 
			
		||||
                    parent.kind === "get" ||
 | 
			
		||||
                    parent.kind === "set"
 | 
			
		||||
                )
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the current FunctionExpression node has a name that would be
 | 
			
		||||
         * inferred from context in a conforming ES6 environment.
 | 
			
		||||
         * @param {ASTNode} node A node to check.
 | 
			
		||||
         * @returns {boolean} True if the node would have a name assigned automatically.
 | 
			
		||||
         */
 | 
			
		||||
        function hasInferredName(node) {
 | 
			
		||||
            const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
            return isObjectOrClassMethod(node) ||
 | 
			
		||||
                (parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === node) ||
 | 
			
		||||
                (parent.type === "Property" && parent.value === node) ||
 | 
			
		||||
                (parent.type === "PropertyDefinition" && parent.value === node) ||
 | 
			
		||||
                (parent.type === "AssignmentExpression" && parent.left.type === "Identifier" && parent.right === node) ||
 | 
			
		||||
                (parent.type === "AssignmentPattern" && parent.left.type === "Identifier" && parent.right === node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that an unnamed function should be named
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportUnexpectedUnnamedFunction(node) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                messageId: "unnamed",
 | 
			
		||||
                loc: astUtils.getFunctionHeadLoc(node, sourceCode),
 | 
			
		||||
                data: { name: astUtils.getFunctionNameWithKind(node) }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports that a named function should be unnamed
 | 
			
		||||
         * @param {ASTNode} node The node to report in the event of an error.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function reportUnexpectedNamedFunction(node) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node,
 | 
			
		||||
                messageId: "named",
 | 
			
		||||
                loc: astUtils.getFunctionHeadLoc(node, sourceCode),
 | 
			
		||||
                data: { name: astUtils.getFunctionNameWithKind(node) }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The listener for function nodes.
 | 
			
		||||
         * @param {ASTNode} node function node
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function handleFunction(node) {
 | 
			
		||||
 | 
			
		||||
            // Skip recursive functions.
 | 
			
		||||
            const nameVar = sourceCode.getDeclaredVariables(node)[0];
 | 
			
		||||
 | 
			
		||||
            if (isFunctionName(nameVar) && nameVar.references.length > 0) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const hasName = Boolean(node.id && node.id.name);
 | 
			
		||||
            const config = getConfigForNode(node);
 | 
			
		||||
 | 
			
		||||
            if (config === "never") {
 | 
			
		||||
                if (hasName && node.type !== "FunctionDeclaration") {
 | 
			
		||||
                    reportUnexpectedNamedFunction(node);
 | 
			
		||||
                }
 | 
			
		||||
            } else if (config === "as-needed") {
 | 
			
		||||
                if (!hasName && !hasInferredName(node)) {
 | 
			
		||||
                    reportUnexpectedUnnamedFunction(node);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (!hasName && !isObjectOrClassMethod(node)) {
 | 
			
		||||
                    reportUnexpectedUnnamedFunction(node);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            "FunctionExpression:exit": handleFunction,
 | 
			
		||||
            "ExportDefaultDeclaration > FunctionDeclaration": handleFunction
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										98
									
								
								node_modules/eslint/lib/rules/func-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								node_modules/eslint/lib/rules/func-style.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce a particular function style
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce the consistent use of either `function` declarations or expressions",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/func-style"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["declaration", "expression"]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    allowArrowFunctions: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            expression: "Expected a function expression.",
 | 
			
		||||
            declaration: "Expected a function declaration."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const style = context.options[0],
 | 
			
		||||
            allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions,
 | 
			
		||||
            enforceDeclarations = (style === "declaration"),
 | 
			
		||||
            stack = [];
 | 
			
		||||
 | 
			
		||||
        const nodesToCheck = {
 | 
			
		||||
            FunctionDeclaration(node) {
 | 
			
		||||
                stack.push(false);
 | 
			
		||||
 | 
			
		||||
                if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") {
 | 
			
		||||
                    context.report({ node, messageId: "expression" });
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "FunctionDeclaration:exit"() {
 | 
			
		||||
                stack.pop();
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            FunctionExpression(node) {
 | 
			
		||||
                stack.push(false);
 | 
			
		||||
 | 
			
		||||
                if (enforceDeclarations && node.parent.type === "VariableDeclarator") {
 | 
			
		||||
                    context.report({ node: node.parent, messageId: "declaration" });
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "FunctionExpression:exit"() {
 | 
			
		||||
                stack.pop();
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            ThisExpression() {
 | 
			
		||||
                if (stack.length > 0) {
 | 
			
		||||
                    stack[stack.length - 1] = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (!allowArrowFunctions) {
 | 
			
		||||
            nodesToCheck.ArrowFunctionExpression = function() {
 | 
			
		||||
                stack.push(false);
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            nodesToCheck["ArrowFunctionExpression:exit"] = function(node) {
 | 
			
		||||
                const hasThisExpr = stack.pop();
 | 
			
		||||
 | 
			
		||||
                if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") {
 | 
			
		||||
                    context.report({ node: node.parent, messageId: "declaration" });
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return nodesToCheck;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										125
									
								
								node_modules/eslint/lib/rules/function-call-argument-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								node_modules/eslint/lib/rules/function-call-argument-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to enforce line breaks between arguments of a function call
 | 
			
		||||
 * @author Alexey Gonchar <https://github.com/finico>
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce line breaks between arguments of a function call",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/function-call-argument-newline"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["always", "never", "consistent"]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpectedLineBreak: "There should be no line break here.",
 | 
			
		||||
            missingLineBreak: "There should be a line break after this argument."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        const checkers = {
 | 
			
		||||
            unexpected: {
 | 
			
		||||
                messageId: "unexpectedLineBreak",
 | 
			
		||||
                check: (prevToken, currentToken) => prevToken.loc.end.line !== currentToken.loc.start.line,
 | 
			
		||||
                createFix: (token, tokenBefore) => fixer =>
 | 
			
		||||
                    fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ")
 | 
			
		||||
            },
 | 
			
		||||
            missing: {
 | 
			
		||||
                messageId: "missingLineBreak",
 | 
			
		||||
                check: (prevToken, currentToken) => prevToken.loc.end.line === currentToken.loc.start.line,
 | 
			
		||||
                createFix: (token, tokenBefore) => fixer =>
 | 
			
		||||
                    fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n")
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check all arguments for line breaks in the CallExpression
 | 
			
		||||
         * @param {CallExpression} node node to evaluate
 | 
			
		||||
         * @param {{ messageId: string, check: Function }} checker selected checker
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function checkArguments(node, checker) {
 | 
			
		||||
            for (let i = 1; i < node.arguments.length; i++) {
 | 
			
		||||
                const prevArgToken = sourceCode.getLastToken(node.arguments[i - 1]);
 | 
			
		||||
                const currentArgToken = sourceCode.getFirstToken(node.arguments[i]);
 | 
			
		||||
 | 
			
		||||
                if (checker.check(prevArgToken, currentArgToken)) {
 | 
			
		||||
                    const tokenBefore = sourceCode.getTokenBefore(
 | 
			
		||||
                        currentArgToken,
 | 
			
		||||
                        { includeComments: true }
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                    const hasLineCommentBefore = tokenBefore.type === "Line";
 | 
			
		||||
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        loc: {
 | 
			
		||||
                            start: tokenBefore.loc.end,
 | 
			
		||||
                            end: currentArgToken.loc.start
 | 
			
		||||
                        },
 | 
			
		||||
                        messageId: checker.messageId,
 | 
			
		||||
                        fix: hasLineCommentBefore ? null : checker.createFix(currentArgToken, tokenBefore)
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check if open space is present in a function name
 | 
			
		||||
         * @param {CallExpression} node node to evaluate
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function check(node) {
 | 
			
		||||
            if (node.arguments.length < 2) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const option = context.options[0] || "always";
 | 
			
		||||
 | 
			
		||||
            if (option === "never") {
 | 
			
		||||
                checkArguments(node, checkers.unexpected);
 | 
			
		||||
            } else if (option === "always") {
 | 
			
		||||
                checkArguments(node, checkers.missing);
 | 
			
		||||
            } else if (option === "consistent") {
 | 
			
		||||
                const firstArgToken = sourceCode.getLastToken(node.arguments[0]);
 | 
			
		||||
                const secondArgToken = sourceCode.getFirstToken(node.arguments[1]);
 | 
			
		||||
 | 
			
		||||
                if (firstArgToken.loc.end.line === secondArgToken.loc.start.line) {
 | 
			
		||||
                    checkArguments(node, checkers.unexpected);
 | 
			
		||||
                } else {
 | 
			
		||||
                    checkArguments(node, checkers.missing);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            CallExpression: check,
 | 
			
		||||
            NewExpression: check
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										292
									
								
								node_modules/eslint/lib/rules/function-paren-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								node_modules/eslint/lib/rules/function-paren-newline.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,292 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview enforce consistent line breaks inside function parentheses
 | 
			
		||||
 * @author Teddy Katz
 | 
			
		||||
 * @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 line breaks inside function parentheses",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/function-paren-newline"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                oneOf: [
 | 
			
		||||
                    {
 | 
			
		||||
                        enum: ["always", "never", "consistent", "multiline", "multiline-arguments"]
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: "object",
 | 
			
		||||
                        properties: {
 | 
			
		||||
                            minItems: {
 | 
			
		||||
                                type: "integer",
 | 
			
		||||
                                minimum: 0
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        additionalProperties: false
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            expectedBefore: "Expected newline before ')'.",
 | 
			
		||||
            expectedAfter: "Expected newline after '('.",
 | 
			
		||||
            expectedBetween: "Expected newline between arguments/params.",
 | 
			
		||||
            unexpectedBefore: "Unexpected newline before ')'.",
 | 
			
		||||
            unexpectedAfter: "Unexpected newline after '('."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
        const rawOption = context.options[0] || "multiline";
 | 
			
		||||
        const multilineOption = rawOption === "multiline";
 | 
			
		||||
        const multilineArgumentsOption = rawOption === "multiline-arguments";
 | 
			
		||||
        const consistentOption = rawOption === "consistent";
 | 
			
		||||
        let minItems;
 | 
			
		||||
 | 
			
		||||
        if (typeof rawOption === "object") {
 | 
			
		||||
            minItems = rawOption.minItems;
 | 
			
		||||
        } else if (rawOption === "always") {
 | 
			
		||||
            minItems = 0;
 | 
			
		||||
        } else if (rawOption === "never") {
 | 
			
		||||
            minItems = Infinity;
 | 
			
		||||
        } else {
 | 
			
		||||
            minItems = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
        // Helpers
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether there should be newlines inside function parens
 | 
			
		||||
         * @param {ASTNode[]} elements The arguments or parameters in the list
 | 
			
		||||
         * @param {boolean} hasLeftNewline `true` if the left paren has a newline in the current code.
 | 
			
		||||
         * @returns {boolean} `true` if there should be newlines inside the function parens
 | 
			
		||||
         */
 | 
			
		||||
        function shouldHaveNewlines(elements, hasLeftNewline) {
 | 
			
		||||
            if (multilineArgumentsOption && elements.length === 1) {
 | 
			
		||||
                return hasLeftNewline;
 | 
			
		||||
            }
 | 
			
		||||
            if (multilineOption || multilineArgumentsOption) {
 | 
			
		||||
                return elements.some((element, index) => index !== elements.length - 1 && element.loc.end.line !== elements[index + 1].loc.start.line);
 | 
			
		||||
            }
 | 
			
		||||
            if (consistentOption) {
 | 
			
		||||
                return hasLeftNewline;
 | 
			
		||||
            }
 | 
			
		||||
            return elements.length >= minItems;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Validates parens
 | 
			
		||||
         * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token
 | 
			
		||||
         * @param {ASTNode[]} elements The arguments or parameters in the list
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function validateParens(parens, elements) {
 | 
			
		||||
            const leftParen = parens.leftParen;
 | 
			
		||||
            const rightParen = parens.rightParen;
 | 
			
		||||
            const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen);
 | 
			
		||||
            const tokenBeforeRightParen = sourceCode.getTokenBefore(rightParen);
 | 
			
		||||
            const hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen);
 | 
			
		||||
            const hasRightNewline = !astUtils.isTokenOnSameLine(tokenBeforeRightParen, rightParen);
 | 
			
		||||
            const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline);
 | 
			
		||||
 | 
			
		||||
            if (hasLeftNewline && !needsNewlines) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: leftParen,
 | 
			
		||||
                    messageId: "unexpectedAfter",
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
                        return sourceCode.getText().slice(leftParen.range[1], tokenAfterLeftParen.range[0]).trim()
 | 
			
		||||
 | 
			
		||||
                            // If there is a comment between the ( and the first element, don't do a fix.
 | 
			
		||||
                            ? null
 | 
			
		||||
                            : fixer.removeRange([leftParen.range[1], tokenAfterLeftParen.range[0]]);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            } else if (!hasLeftNewline && needsNewlines) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: leftParen,
 | 
			
		||||
                    messageId: "expectedAfter",
 | 
			
		||||
                    fix: fixer => fixer.insertTextAfter(leftParen, "\n")
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (hasRightNewline && !needsNewlines) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: rightParen,
 | 
			
		||||
                    messageId: "unexpectedBefore",
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
                        return sourceCode.getText().slice(tokenBeforeRightParen.range[1], rightParen.range[0]).trim()
 | 
			
		||||
 | 
			
		||||
                            // If there is a comment between the last element and the ), don't do a fix.
 | 
			
		||||
                            ? null
 | 
			
		||||
                            : fixer.removeRange([tokenBeforeRightParen.range[1], rightParen.range[0]]);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            } else if (!hasRightNewline && needsNewlines) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node: rightParen,
 | 
			
		||||
                    messageId: "expectedBefore",
 | 
			
		||||
                    fix: fixer => fixer.insertTextBefore(rightParen, "\n")
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Validates a list of arguments or parameters
 | 
			
		||||
         * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token
 | 
			
		||||
         * @param {ASTNode[]} elements The arguments or parameters in the list
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function validateArguments(parens, elements) {
 | 
			
		||||
            const leftParen = parens.leftParen;
 | 
			
		||||
            const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen);
 | 
			
		||||
            const hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen);
 | 
			
		||||
            const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline);
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i <= elements.length - 2; i++) {
 | 
			
		||||
                const currentElement = elements[i];
 | 
			
		||||
                const nextElement = elements[i + 1];
 | 
			
		||||
                const hasNewLine = currentElement.loc.end.line !== nextElement.loc.start.line;
 | 
			
		||||
 | 
			
		||||
                if (!hasNewLine && needsNewlines) {
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node: currentElement,
 | 
			
		||||
                        messageId: "expectedBetween",
 | 
			
		||||
                        fix: fixer => fixer.insertTextBefore(nextElement, "\n")
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Gets the left paren and right paren tokens of a node.
 | 
			
		||||
         * @param {ASTNode} node The node with parens
 | 
			
		||||
         * @throws {TypeError} Unexpected node type.
 | 
			
		||||
         * @returns {Object} An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token.
 | 
			
		||||
         * Can also return `null` if an expression has no parens (e.g. a NewExpression with no arguments, or an ArrowFunctionExpression
 | 
			
		||||
         * with a single parameter)
 | 
			
		||||
         */
 | 
			
		||||
        function getParenTokens(node) {
 | 
			
		||||
            switch (node.type) {
 | 
			
		||||
                case "NewExpression":
 | 
			
		||||
                    if (!node.arguments.length &&
 | 
			
		||||
                        !(
 | 
			
		||||
                            astUtils.isOpeningParenToken(sourceCode.getLastToken(node, { skip: 1 })) &&
 | 
			
		||||
                            astUtils.isClosingParenToken(sourceCode.getLastToken(node)) &&
 | 
			
		||||
                            node.callee.range[1] < node.range[1]
 | 
			
		||||
                        )
 | 
			
		||||
                    ) {
 | 
			
		||||
 | 
			
		||||
                        // If the NewExpression does not have parens (e.g. `new Foo`), return null.
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // falls through
 | 
			
		||||
 | 
			
		||||
                case "CallExpression":
 | 
			
		||||
                    return {
 | 
			
		||||
                        leftParen: sourceCode.getTokenAfter(node.callee, astUtils.isOpeningParenToken),
 | 
			
		||||
                        rightParen: sourceCode.getLastToken(node)
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                case "FunctionDeclaration":
 | 
			
		||||
                case "FunctionExpression": {
 | 
			
		||||
                    const leftParen = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken);
 | 
			
		||||
                    const rightParen = node.params.length
 | 
			
		||||
                        ? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken)
 | 
			
		||||
                        : sourceCode.getTokenAfter(leftParen);
 | 
			
		||||
 | 
			
		||||
                    return { leftParen, rightParen };
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case "ArrowFunctionExpression": {
 | 
			
		||||
                    const firstToken = sourceCode.getFirstToken(node, { skip: (node.async ? 1 : 0) });
 | 
			
		||||
 | 
			
		||||
                    if (!astUtils.isOpeningParenToken(firstToken)) {
 | 
			
		||||
 | 
			
		||||
                        // If the ArrowFunctionExpression has a single param without parens, return null.
 | 
			
		||||
                        return null;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    const rightParen = node.params.length
 | 
			
		||||
                        ? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken)
 | 
			
		||||
                        : sourceCode.getTokenAfter(firstToken);
 | 
			
		||||
 | 
			
		||||
                    return {
 | 
			
		||||
                        leftParen: firstToken,
 | 
			
		||||
                        rightParen
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case "ImportExpression": {
 | 
			
		||||
                    const leftParen = sourceCode.getFirstToken(node, 1);
 | 
			
		||||
                    const rightParen = sourceCode.getLastToken(node);
 | 
			
		||||
 | 
			
		||||
                    return { leftParen, rightParen };
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new TypeError(`unexpected node with type ${node.type}`);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
        // Public
 | 
			
		||||
        //----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            [[
 | 
			
		||||
                "ArrowFunctionExpression",
 | 
			
		||||
                "CallExpression",
 | 
			
		||||
                "FunctionDeclaration",
 | 
			
		||||
                "FunctionExpression",
 | 
			
		||||
                "ImportExpression",
 | 
			
		||||
                "NewExpression"
 | 
			
		||||
            ]](node) {
 | 
			
		||||
                const parens = getParenTokens(node);
 | 
			
		||||
                let params;
 | 
			
		||||
 | 
			
		||||
                if (node.type === "ImportExpression") {
 | 
			
		||||
                    params = [node.source];
 | 
			
		||||
                } else if (astUtils.isFunction(node)) {
 | 
			
		||||
                    params = node.params;
 | 
			
		||||
                } else {
 | 
			
		||||
                    params = node.arguments;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (parens) {
 | 
			
		||||
                    validateParens(parens, params);
 | 
			
		||||
 | 
			
		||||
                    if (multilineArgumentsOption) {
 | 
			
		||||
                        validateArguments(parens, params);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										209
									
								
								node_modules/eslint/lib/rules/generator-star-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								node_modules/eslint/lib/rules/generator-star-spacing.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,209 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to check the spacing around the * in generator functions.
 | 
			
		||||
 * @author Jamund Ferguson
 | 
			
		||||
 * @deprecated in ESLint v8.53.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const OVERRIDE_SCHEMA = {
 | 
			
		||||
    oneOf: [
 | 
			
		||||
        {
 | 
			
		||||
            enum: ["before", "after", "both", "neither"]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            type: "object",
 | 
			
		||||
            properties: {
 | 
			
		||||
                before: { type: "boolean" },
 | 
			
		||||
                after: { type: "boolean" }
 | 
			
		||||
            },
 | 
			
		||||
            additionalProperties: false
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
        type: "layout",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce consistent spacing around `*` operators in generator functions",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/generator-star-spacing"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: "whitespace",
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                oneOf: [
 | 
			
		||||
                    {
 | 
			
		||||
                        enum: ["before", "after", "both", "neither"]
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        type: "object",
 | 
			
		||||
                        properties: {
 | 
			
		||||
                            before: { type: "boolean" },
 | 
			
		||||
                            after: { type: "boolean" },
 | 
			
		||||
                            named: OVERRIDE_SCHEMA,
 | 
			
		||||
                            anonymous: OVERRIDE_SCHEMA,
 | 
			
		||||
                            method: OVERRIDE_SCHEMA
 | 
			
		||||
                        },
 | 
			
		||||
                        additionalProperties: false
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingBefore: "Missing space before *.",
 | 
			
		||||
            missingAfter: "Missing space after *.",
 | 
			
		||||
            unexpectedBefore: "Unexpected space before *.",
 | 
			
		||||
            unexpectedAfter: "Unexpected space after *."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const optionDefinitions = {
 | 
			
		||||
            before: { before: true, after: false },
 | 
			
		||||
            after: { before: false, after: true },
 | 
			
		||||
            both: { before: true, after: true },
 | 
			
		||||
            neither: { before: false, after: false }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Returns resolved option definitions based on an option and defaults
 | 
			
		||||
         * @param {any} option The option object or string value
 | 
			
		||||
         * @param {Object} defaults The defaults to use if options are not present
 | 
			
		||||
         * @returns {Object} the resolved object definition
 | 
			
		||||
         */
 | 
			
		||||
        function optionToDefinition(option, defaults) {
 | 
			
		||||
            if (!option) {
 | 
			
		||||
                return defaults;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return typeof option === "string"
 | 
			
		||||
                ? optionDefinitions[option]
 | 
			
		||||
                : Object.assign({}, defaults, option);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const modes = (function(option) {
 | 
			
		||||
            const defaults = optionToDefinition(option, optionDefinitions.before);
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                named: optionToDefinition(option.named, defaults),
 | 
			
		||||
                anonymous: optionToDefinition(option.anonymous, defaults),
 | 
			
		||||
                method: optionToDefinition(option.method, defaults)
 | 
			
		||||
            };
 | 
			
		||||
        }(context.options[0] || {}));
 | 
			
		||||
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if the given token is a star token or not.
 | 
			
		||||
         * @param {Token} token The token to check.
 | 
			
		||||
         * @returns {boolean} `true` if the token is a star token.
 | 
			
		||||
         */
 | 
			
		||||
        function isStarToken(token) {
 | 
			
		||||
            return token.value === "*" && token.type === "Punctuator";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Gets the generator star token of the given function node.
 | 
			
		||||
         * @param {ASTNode} node The function node to get.
 | 
			
		||||
         * @returns {Token} Found star token.
 | 
			
		||||
         */
 | 
			
		||||
        function getStarToken(node) {
 | 
			
		||||
            return sourceCode.getFirstToken(
 | 
			
		||||
                (node.parent.method || node.parent.type === "MethodDefinition") ? node.parent : node,
 | 
			
		||||
                isStarToken
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * capitalize a given string.
 | 
			
		||||
         * @param {string} str the given string.
 | 
			
		||||
         * @returns {string} the capitalized string.
 | 
			
		||||
         */
 | 
			
		||||
        function capitalize(str) {
 | 
			
		||||
            return str[0].toUpperCase() + str.slice(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks the spacing between two tokens before or after the star token.
 | 
			
		||||
         * @param {string} kind Either "named", "anonymous", or "method"
 | 
			
		||||
         * @param {string} side Either "before" or "after".
 | 
			
		||||
         * @param {Token} leftToken `function` keyword token if side is "before", or
 | 
			
		||||
         *     star token if side is "after".
 | 
			
		||||
         * @param {Token} rightToken Star token if side is "before", or identifier
 | 
			
		||||
         *     token if side is "after".
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkSpacing(kind, side, leftToken, rightToken) {
 | 
			
		||||
            if (!!(rightToken.range[0] - leftToken.range[1]) !== modes[kind][side]) {
 | 
			
		||||
                const after = leftToken.value === "*";
 | 
			
		||||
                const spaceRequired = modes[kind][side];
 | 
			
		||||
                const node = after ? leftToken : rightToken;
 | 
			
		||||
                const messageId = `${spaceRequired ? "missing" : "unexpected"}${capitalize(side)}`;
 | 
			
		||||
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    messageId,
 | 
			
		||||
                    fix(fixer) {
 | 
			
		||||
                        if (spaceRequired) {
 | 
			
		||||
                            if (after) {
 | 
			
		||||
                                return fixer.insertTextAfter(node, " ");
 | 
			
		||||
                            }
 | 
			
		||||
                            return fixer.insertTextBefore(node, " ");
 | 
			
		||||
                        }
 | 
			
		||||
                        return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Enforces the spacing around the star if node is a generator function.
 | 
			
		||||
         * @param {ASTNode} node A function expression or declaration node.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkFunction(node) {
 | 
			
		||||
            if (!node.generator) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const starToken = getStarToken(node);
 | 
			
		||||
            const prevToken = sourceCode.getTokenBefore(starToken);
 | 
			
		||||
            const nextToken = sourceCode.getTokenAfter(starToken);
 | 
			
		||||
 | 
			
		||||
            let kind = "named";
 | 
			
		||||
 | 
			
		||||
            if (node.parent.type === "MethodDefinition" || (node.parent.type === "Property" && node.parent.method)) {
 | 
			
		||||
                kind = "method";
 | 
			
		||||
            } else if (!node.id) {
 | 
			
		||||
                kind = "anonymous";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Only check before when preceded by `function`|`static` keyword
 | 
			
		||||
            if (!(kind === "method" && starToken === sourceCode.getFirstToken(node.parent))) {
 | 
			
		||||
                checkSpacing(kind, "before", prevToken, starToken);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            checkSpacing(kind, "after", starToken, nextToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            FunctionDeclaration: checkFunction,
 | 
			
		||||
            FunctionExpression: checkFunction
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										204
									
								
								node_modules/eslint/lib/rules/getter-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								node_modules/eslint/lib/rules/getter-return.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Enforces that a return statement is present in property getters.
 | 
			
		||||
 * @author Aladdin-ADD(hh_2013@foxmail.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks all segments in a set and returns true if any are reachable.
 | 
			
		||||
 * @param {Set<CodePathSegment>} segments The segments to check.
 | 
			
		||||
 * @returns {boolean} True if any segment is reachable; false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
function isAnySegmentReachable(segments) {
 | 
			
		||||
 | 
			
		||||
    for (const segment of segments) {
 | 
			
		||||
        if (segment.reachable) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "problem",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce `return` statements in getters",
 | 
			
		||||
            recommended: true,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/getter-return"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        fixable: null,
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    allowImplicit: {
 | 
			
		||||
                        type: "boolean",
 | 
			
		||||
                        default: false
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            expected: "Expected to return a value in {{name}}.",
 | 
			
		||||
            expectedAlways: "Expected {{name}} to always return a value."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const options = context.options[0] || { allowImplicit: false };
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        let funcInfo = {
 | 
			
		||||
            upper: null,
 | 
			
		||||
            codePath: null,
 | 
			
		||||
            hasReturn: false,
 | 
			
		||||
            shouldCheck: false,
 | 
			
		||||
            node: null,
 | 
			
		||||
            currentSegments: []
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether or not the last code path segment is reachable.
 | 
			
		||||
         * Then reports this function if the segment is reachable.
 | 
			
		||||
         *
 | 
			
		||||
         * If the last code path segment is reachable, there are paths which are not
 | 
			
		||||
         * returned or thrown.
 | 
			
		||||
         * @param {ASTNode} node A node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkLastSegment(node) {
 | 
			
		||||
            if (funcInfo.shouldCheck &&
 | 
			
		||||
                isAnySegmentReachable(funcInfo.currentSegments)
 | 
			
		||||
            ) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    loc: astUtils.getFunctionHeadLoc(node, sourceCode),
 | 
			
		||||
                    messageId: funcInfo.hasReturn ? "expectedAlways" : "expected",
 | 
			
		||||
                    data: {
 | 
			
		||||
                        name: astUtils.getFunctionNameWithKind(funcInfo.node)
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether a node means a getter function.
 | 
			
		||||
         * @param {ASTNode} node a node to check.
 | 
			
		||||
         * @returns {boolean} if node means a getter, return true; else return false.
 | 
			
		||||
         */
 | 
			
		||||
        function isGetter(node) {
 | 
			
		||||
            const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
            if (TARGET_NODE_TYPE.test(node.type) && node.body.type === "BlockStatement") {
 | 
			
		||||
                if (parent.kind === "get") {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") {
 | 
			
		||||
 | 
			
		||||
                    // Object.defineProperty() or Reflect.defineProperty()
 | 
			
		||||
                    if (parent.parent.parent.type === "CallExpression") {
 | 
			
		||||
                        const callNode = parent.parent.parent.callee;
 | 
			
		||||
 | 
			
		||||
                        if (astUtils.isSpecificMemberAccess(callNode, "Object", "defineProperty") ||
 | 
			
		||||
                            astUtils.isSpecificMemberAccess(callNode, "Reflect", "defineProperty")) {
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Object.defineProperties() or Object.create()
 | 
			
		||||
                    if (parent.parent.parent.type === "Property" &&
 | 
			
		||||
                        parent.parent.parent.parent.type === "ObjectExpression" &&
 | 
			
		||||
                        parent.parent.parent.parent.parent.type === "CallExpression") {
 | 
			
		||||
                        const callNode = parent.parent.parent.parent.parent.callee;
 | 
			
		||||
 | 
			
		||||
                        return astUtils.isSpecificMemberAccess(callNode, "Object", "defineProperties") ||
 | 
			
		||||
                               astUtils.isSpecificMemberAccess(callNode, "Object", "create");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            // Stacks this function's information.
 | 
			
		||||
            onCodePathStart(codePath, node) {
 | 
			
		||||
                funcInfo = {
 | 
			
		||||
                    upper: funcInfo,
 | 
			
		||||
                    codePath,
 | 
			
		||||
                    hasReturn: false,
 | 
			
		||||
                    shouldCheck: isGetter(node),
 | 
			
		||||
                    node,
 | 
			
		||||
                    currentSegments: new Set()
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Pops this function's information.
 | 
			
		||||
            onCodePathEnd() {
 | 
			
		||||
                funcInfo = funcInfo.upper;
 | 
			
		||||
            },
 | 
			
		||||
            onUnreachableCodePathSegmentStart(segment) {
 | 
			
		||||
                funcInfo.currentSegments.add(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onUnreachableCodePathSegmentEnd(segment) {
 | 
			
		||||
                funcInfo.currentSegments.delete(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onCodePathSegmentStart(segment) {
 | 
			
		||||
                funcInfo.currentSegments.add(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            onCodePathSegmentEnd(segment) {
 | 
			
		||||
                funcInfo.currentSegments.delete(segment);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Checks the return statement is valid.
 | 
			
		||||
            ReturnStatement(node) {
 | 
			
		||||
                if (funcInfo.shouldCheck) {
 | 
			
		||||
                    funcInfo.hasReturn = true;
 | 
			
		||||
 | 
			
		||||
                    // if allowImplicit: false, should also check node.argument
 | 
			
		||||
                    if (!options.allowImplicit && !node.argument) {
 | 
			
		||||
                        context.report({
 | 
			
		||||
                            node,
 | 
			
		||||
                            messageId: "expected",
 | 
			
		||||
                            data: {
 | 
			
		||||
                                name: astUtils.getFunctionNameWithKind(funcInfo.node)
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Reports a given function if the last path is reachable.
 | 
			
		||||
            "FunctionExpression:exit": checkLastSegment,
 | 
			
		||||
            "ArrowFunctionExpression:exit": checkLastSegment
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										90
									
								
								node_modules/eslint/lib/rules/global-require.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								node_modules/eslint/lib/rules/global-require.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule for disallowing require() outside of the top-level module context
 | 
			
		||||
 * @author Jamund Ferguson
 | 
			
		||||
 * @deprecated in ESLint v7.0.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const ACCEPTABLE_PARENTS = new Set([
 | 
			
		||||
    "AssignmentExpression",
 | 
			
		||||
    "VariableDeclarator",
 | 
			
		||||
    "MemberExpression",
 | 
			
		||||
    "ExpressionStatement",
 | 
			
		||||
    "CallExpression",
 | 
			
		||||
    "ConditionalExpression",
 | 
			
		||||
    "Program",
 | 
			
		||||
    "VariableDeclaration",
 | 
			
		||||
    "ChainExpression"
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finds the eslint-scope reference in the given scope.
 | 
			
		||||
 * @param {Object} scope The scope to search.
 | 
			
		||||
 * @param {ASTNode} node The identifier node.
 | 
			
		||||
 * @returns {Reference|null} Returns the found reference or null if none were found.
 | 
			
		||||
 */
 | 
			
		||||
function findReference(scope, node) {
 | 
			
		||||
    const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] &&
 | 
			
		||||
            reference.identifier.range[1] === node.range[1]);
 | 
			
		||||
 | 
			
		||||
    if (references.length === 1) {
 | 
			
		||||
        return references[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* c8 ignore next */
 | 
			
		||||
    return null;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if the given identifier node is shadowed in the given scope.
 | 
			
		||||
 * @param {Object} scope The current scope.
 | 
			
		||||
 * @param {ASTNode} node The identifier node to check.
 | 
			
		||||
 * @returns {boolean} Whether or not the name is shadowed.
 | 
			
		||||
 */
 | 
			
		||||
function isShadowed(scope, node) {
 | 
			
		||||
    const reference = findReference(scope, node);
 | 
			
		||||
 | 
			
		||||
    return reference && reference.resolved && reference.resolved.defs.length > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require `require()` calls to be placed at top-level module scope",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/global-require"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [],
 | 
			
		||||
        messages: {
 | 
			
		||||
            unexpected: "Unexpected require()."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            CallExpression(node) {
 | 
			
		||||
                const currentScope = sourceCode.getScope(node);
 | 
			
		||||
 | 
			
		||||
                if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {
 | 
			
		||||
                    const isGoodRequire = sourceCode.getAncestors(node).every(parent => ACCEPTABLE_PARENTS.has(parent.type));
 | 
			
		||||
 | 
			
		||||
                    if (!isGoodRequire) {
 | 
			
		||||
                        context.report({ node, messageId: "unexpected" });
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										215
									
								
								node_modules/eslint/lib/rules/grouped-accessor-pairs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								node_modules/eslint/lib/rules/grouped-accessor-pairs.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,215 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to require grouped accessor pairs in object literals and classes
 | 
			
		||||
 * @author Milos Djermanovic
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Typedefs
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Property name if it can be computed statically, otherwise the list of the tokens of the key node.
 | 
			
		||||
 * @typedef {string|Token[]} Key
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Accessor nodes with the same key.
 | 
			
		||||
 * @typedef {Object} AccessorData
 | 
			
		||||
 * @property {Key} key Accessor's key
 | 
			
		||||
 * @property {ASTNode[]} getters List of getter nodes.
 | 
			
		||||
 * @property {ASTNode[]} setters List of setter nodes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not the given lists represent the equal tokens in the same order.
 | 
			
		||||
 * Tokens are compared by their properties, not by instance.
 | 
			
		||||
 * @param {Token[]} left First list of tokens.
 | 
			
		||||
 * @param {Token[]} right Second list of tokens.
 | 
			
		||||
 * @returns {boolean} `true` if the lists have same tokens.
 | 
			
		||||
 */
 | 
			
		||||
function areEqualTokenLists(left, right) {
 | 
			
		||||
    if (left.length !== right.length) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < left.length; i++) {
 | 
			
		||||
        const leftToken = left[i],
 | 
			
		||||
            rightToken = right[i];
 | 
			
		||||
 | 
			
		||||
        if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not the given keys are equal.
 | 
			
		||||
 * @param {Key} left First key.
 | 
			
		||||
 * @param {Key} right Second key.
 | 
			
		||||
 * @returns {boolean} `true` if the keys are equal.
 | 
			
		||||
 */
 | 
			
		||||
function areEqualKeys(left, right) {
 | 
			
		||||
    if (typeof left === "string" && typeof right === "string") {
 | 
			
		||||
 | 
			
		||||
        // Statically computed names.
 | 
			
		||||
        return left === right;
 | 
			
		||||
    }
 | 
			
		||||
    if (Array.isArray(left) && Array.isArray(right)) {
 | 
			
		||||
 | 
			
		||||
        // Token lists.
 | 
			
		||||
        return areEqualTokenLists(left, right);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether or not a given node is of an accessor kind ('get' or 'set').
 | 
			
		||||
 * @param {ASTNode} node A node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is of an accessor kind.
 | 
			
		||||
 */
 | 
			
		||||
function isAccessorKind(node) {
 | 
			
		||||
    return node.kind === "get" || node.kind === "set";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require grouped accessor pairs in object literals and classes",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/grouped-accessor-pairs"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["anyOrder", "getBeforeSet", "setBeforeGet"]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            notGrouped: "Accessor pair {{ formerName }} and {{ latterName }} should be grouped.",
 | 
			
		||||
            invalidOrder: "Expected {{ latterName }} to be before {{ formerName }}."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const order = context.options[0] || "anyOrder";
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports the given accessor pair.
 | 
			
		||||
         * @param {string} messageId messageId to report.
 | 
			
		||||
         * @param {ASTNode} formerNode getter/setter node that is defined before `latterNode`.
 | 
			
		||||
         * @param {ASTNode} latterNode getter/setter node that is defined after `formerNode`.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function report(messageId, formerNode, latterNode) {
 | 
			
		||||
            context.report({
 | 
			
		||||
                node: latterNode,
 | 
			
		||||
                messageId,
 | 
			
		||||
                loc: astUtils.getFunctionHeadLoc(latterNode.value, sourceCode),
 | 
			
		||||
                data: {
 | 
			
		||||
                    formerName: astUtils.getFunctionNameWithKind(formerNode.value),
 | 
			
		||||
                    latterName: astUtils.getFunctionNameWithKind(latterNode.value)
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks accessor pairs in the given list of nodes.
 | 
			
		||||
         * @param {ASTNode[]} nodes The list to check.
 | 
			
		||||
         * @param {Function} shouldCheck – Predicate that returns `true` if the node should be checked.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function checkList(nodes, shouldCheck) {
 | 
			
		||||
            const accessors = [];
 | 
			
		||||
            let found = false;
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < nodes.length; i++) {
 | 
			
		||||
                const node = nodes[i];
 | 
			
		||||
 | 
			
		||||
                if (shouldCheck(node) && isAccessorKind(node)) {
 | 
			
		||||
 | 
			
		||||
                    // Creates a new `AccessorData` object for the given getter or setter node.
 | 
			
		||||
                    const name = astUtils.getStaticPropertyName(node);
 | 
			
		||||
                    const key = (name !== null) ? name : sourceCode.getTokens(node.key);
 | 
			
		||||
 | 
			
		||||
                    // Merges the given `AccessorData` object into the given accessors list.
 | 
			
		||||
                    for (let j = 0; j < accessors.length; j++) {
 | 
			
		||||
                        const accessor = accessors[j];
 | 
			
		||||
 | 
			
		||||
                        if (areEqualKeys(accessor.key, key)) {
 | 
			
		||||
                            accessor.getters.push(...node.kind === "get" ? [node] : []);
 | 
			
		||||
                            accessor.setters.push(...node.kind === "set" ? [node] : []);
 | 
			
		||||
                            found = true;
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!found) {
 | 
			
		||||
                        accessors.push({
 | 
			
		||||
                            key,
 | 
			
		||||
                            getters: node.kind === "get" ? [node] : [],
 | 
			
		||||
                            setters: node.kind === "set" ? [node] : []
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    found = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (const { getters, setters } of accessors) {
 | 
			
		||||
 | 
			
		||||
                // Don't report accessor properties that have duplicate getters or setters.
 | 
			
		||||
                if (getters.length === 1 && setters.length === 1) {
 | 
			
		||||
                    const [getter] = getters,
 | 
			
		||||
                        [setter] = setters,
 | 
			
		||||
                        getterIndex = nodes.indexOf(getter),
 | 
			
		||||
                        setterIndex = nodes.indexOf(setter),
 | 
			
		||||
                        formerNode = getterIndex < setterIndex ? getter : setter,
 | 
			
		||||
                        latterNode = getterIndex < setterIndex ? setter : getter;
 | 
			
		||||
 | 
			
		||||
                    if (Math.abs(getterIndex - setterIndex) > 1) {
 | 
			
		||||
                        report("notGrouped", formerNode, latterNode);
 | 
			
		||||
                    } else if (
 | 
			
		||||
                        (order === "getBeforeSet" && getterIndex > setterIndex) ||
 | 
			
		||||
                        (order === "setBeforeGet" && getterIndex < setterIndex)
 | 
			
		||||
                    ) {
 | 
			
		||||
                        report("invalidOrder", formerNode, latterNode);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            ObjectExpression(node) {
 | 
			
		||||
                checkList(node.properties, n => n.type === "Property");
 | 
			
		||||
            },
 | 
			
		||||
            ClassBody(node) {
 | 
			
		||||
                checkList(node.body, n => n.type === "MethodDefinition" && !n.static);
 | 
			
		||||
                checkList(node.body, n => n.type === "MethodDefinition" && n.static);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										76
									
								
								node_modules/eslint/lib/rules/guard-for-in.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								node_modules/eslint/lib/rules/guard-for-in.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to flag for-in loops without if statements inside
 | 
			
		||||
 * @author Nicholas C. Zakas
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require `for-in` loops to include an `if` statement",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/guard-for-in"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [],
 | 
			
		||||
        messages: {
 | 
			
		||||
            wrap: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            ForInStatement(node) {
 | 
			
		||||
                const body = node.body;
 | 
			
		||||
 | 
			
		||||
                // empty statement
 | 
			
		||||
                if (body.type === "EmptyStatement") {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // if statement
 | 
			
		||||
                if (body.type === "IfStatement") {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // empty block
 | 
			
		||||
                if (body.type === "BlockStatement" && body.body.length === 0) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // block with just if statement
 | 
			
		||||
                if (body.type === "BlockStatement" && body.body.length === 1 && body.body[0].type === "IfStatement") {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // block that starts with if statement
 | 
			
		||||
                if (body.type === "BlockStatement" && body.body.length >= 1 && body.body[0].type === "IfStatement") {
 | 
			
		||||
                    const i = body.body[0];
 | 
			
		||||
 | 
			
		||||
                    // ... whose consequent is a continue
 | 
			
		||||
                    if (i.consequent.type === "ContinueStatement") {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // ... whose consequent is a block that contains only a continue
 | 
			
		||||
                    if (i.consequent.type === "BlockStatement" && i.consequent.body.length === 1 && i.consequent.body[0].type === "ContinueStatement") {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                context.report({ node, messageId: "wrap" });
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										101
									
								
								node_modules/eslint/lib/rules/handle-callback-err.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								node_modules/eslint/lib/rules/handle-callback-err.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Ensure handling of errors when we know they exist.
 | 
			
		||||
 * @author Jamund Ferguson
 | 
			
		||||
 * @deprecated in ESLint v7.0.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
 | 
			
		||||
        replacedBy: [],
 | 
			
		||||
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Require error handling in callbacks",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/handle-callback-err"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                type: "string"
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        messages: {
 | 
			
		||||
            expected: "Expected error to be handled."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const errorArgument = context.options[0] || "err";
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if the given argument should be interpreted as a regexp pattern.
 | 
			
		||||
         * @param {string} stringToCheck The string which should be checked.
 | 
			
		||||
         * @returns {boolean} Whether or not the string should be interpreted as a pattern.
 | 
			
		||||
         */
 | 
			
		||||
        function isPattern(stringToCheck) {
 | 
			
		||||
            const firstChar = stringToCheck[0];
 | 
			
		||||
 | 
			
		||||
            return firstChar === "^";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if the given name matches the configured error argument.
 | 
			
		||||
         * @param {string} name The name which should be compared.
 | 
			
		||||
         * @returns {boolean} Whether or not the given name matches the configured error variable name.
 | 
			
		||||
         */
 | 
			
		||||
        function matchesConfiguredErrorName(name) {
 | 
			
		||||
            if (isPattern(errorArgument)) {
 | 
			
		||||
                const regexp = new RegExp(errorArgument, "u");
 | 
			
		||||
 | 
			
		||||
                return regexp.test(name);
 | 
			
		||||
            }
 | 
			
		||||
            return name === errorArgument;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Get the parameters of a given function scope.
 | 
			
		||||
         * @param {Object} scope The function scope.
 | 
			
		||||
         * @returns {Array} All parameters of the given scope.
 | 
			
		||||
         */
 | 
			
		||||
        function getParameters(scope) {
 | 
			
		||||
            return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check to see if we're handling the error object properly.
 | 
			
		||||
         * @param {ASTNode} node The AST node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkForError(node) {
 | 
			
		||||
            const scope = sourceCode.getScope(node),
 | 
			
		||||
                parameters = getParameters(scope),
 | 
			
		||||
                firstParameter = parameters[0];
 | 
			
		||||
 | 
			
		||||
            if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) {
 | 
			
		||||
                if (firstParameter.references.length === 0) {
 | 
			
		||||
                    context.report({ node, messageId: "expected" });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            FunctionDeclaration: checkForError,
 | 
			
		||||
            FunctionExpression: checkForError,
 | 
			
		||||
            ArrowFunctionExpression: checkForError
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										246
									
								
								node_modules/eslint/lib/rules/id-blacklist.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								node_modules/eslint/lib/rules/id-blacklist.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,246 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule that warns when identifier names that are
 | 
			
		||||
 * specified in the configuration are used.
 | 
			
		||||
 * @author Keith Cirkel (http://keithcirkel.co.uk)
 | 
			
		||||
 * @deprecated in ESLint v7.5.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given node represents assignment target in a normal assignment or destructuring.
 | 
			
		||||
 * @param {ASTNode} node The node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is assignment target.
 | 
			
		||||
 */
 | 
			
		||||
function isAssignmentTarget(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
 | 
			
		||||
        // normal assignment
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "AssignmentExpression" &&
 | 
			
		||||
            parent.left === node
 | 
			
		||||
        ) ||
 | 
			
		||||
 | 
			
		||||
        // destructuring
 | 
			
		||||
        parent.type === "ArrayPattern" ||
 | 
			
		||||
        parent.type === "RestElement" ||
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "Property" &&
 | 
			
		||||
            parent.value === node &&
 | 
			
		||||
            parent.parent.type === "ObjectPattern"
 | 
			
		||||
        ) ||
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "AssignmentPattern" &&
 | 
			
		||||
            parent.left === node
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given node represents an imported name that is renamed in the same import/export specifier.
 | 
			
		||||
 *
 | 
			
		||||
 * Examples:
 | 
			
		||||
 * import { a as b } from 'mod'; // node `a` is renamed import
 | 
			
		||||
 * export { a as b } from 'mod'; // node `a` is renamed import
 | 
			
		||||
 * @param {ASTNode} node `Identifier` node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a renamed import.
 | 
			
		||||
 */
 | 
			
		||||
function isRenamedImport(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "ImportSpecifier" &&
 | 
			
		||||
            parent.imported !== parent.local &&
 | 
			
		||||
            parent.imported === node
 | 
			
		||||
        ) ||
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "ExportSpecifier" &&
 | 
			
		||||
            parent.parent.source && // re-export
 | 
			
		||||
            parent.local !== parent.exported &&
 | 
			
		||||
            parent.local === node
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given node is a renamed identifier node in an ObjectPattern destructuring.
 | 
			
		||||
 *
 | 
			
		||||
 * Examples:
 | 
			
		||||
 * const { a : b } = foo; // node `a` is renamed node.
 | 
			
		||||
 * @param {ASTNode} node `Identifier` node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a renamed node in an ObjectPattern destructuring.
 | 
			
		||||
 */
 | 
			
		||||
function isRenamedInDestructuring(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        (
 | 
			
		||||
            !parent.computed &&
 | 
			
		||||
            parent.type === "Property" &&
 | 
			
		||||
            parent.parent.type === "ObjectPattern" &&
 | 
			
		||||
            parent.value !== node &&
 | 
			
		||||
            parent.key === node
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given node represents shorthand definition of a property in an object literal.
 | 
			
		||||
 * @param {ASTNode} node `Identifier` node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a shorthand property definition.
 | 
			
		||||
 */
 | 
			
		||||
function isShorthandPropertyDefinition(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        parent.type === "Property" &&
 | 
			
		||||
        parent.parent.type === "ObjectExpression" &&
 | 
			
		||||
        parent.shorthand
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        deprecated: true,
 | 
			
		||||
        replacedBy: ["id-denylist"],
 | 
			
		||||
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Disallow specified identifiers",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/id-blacklist"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            type: "array",
 | 
			
		||||
            items: {
 | 
			
		||||
                type: "string"
 | 
			
		||||
            },
 | 
			
		||||
            uniqueItems: true
 | 
			
		||||
        },
 | 
			
		||||
        messages: {
 | 
			
		||||
            restricted: "Identifier '{{name}}' is restricted."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const denyList = new Set(context.options);
 | 
			
		||||
        const reportedNodes = new Set();
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        let globalScope;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether the given name is restricted.
 | 
			
		||||
         * @param {string} name The name to check.
 | 
			
		||||
         * @returns {boolean} `true` if the name is restricted.
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isRestricted(name) {
 | 
			
		||||
            return denyList.has(name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether the given node represents a reference to a global variable that is not declared in the source code.
 | 
			
		||||
         * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables.
 | 
			
		||||
         * @param {ASTNode} node `Identifier` node to check.
 | 
			
		||||
         * @returns {boolean} `true` if the node is a reference to a global variable.
 | 
			
		||||
         */
 | 
			
		||||
        function isReferenceToGlobalVariable(node) {
 | 
			
		||||
            const variable = globalScope.set.get(node.name);
 | 
			
		||||
 | 
			
		||||
            return variable && variable.defs.length === 0 &&
 | 
			
		||||
                variable.references.some(ref => ref.identifier === node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the given node should be checked.
 | 
			
		||||
         * @param {ASTNode} node `Identifier` node.
 | 
			
		||||
         * @returns {boolean} `true` if the node should be checked.
 | 
			
		||||
         */
 | 
			
		||||
        function shouldCheck(node) {
 | 
			
		||||
            const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Member access has special rules for checking property names.
 | 
			
		||||
             * Read access to a property with a restricted name is allowed, because it can be on an object that user has no control over.
 | 
			
		||||
             * Write access isn't allowed, because it potentially creates a new property with a restricted name.
 | 
			
		||||
             */
 | 
			
		||||
            if (
 | 
			
		||||
                parent.type === "MemberExpression" &&
 | 
			
		||||
                parent.property === node &&
 | 
			
		||||
                !parent.computed
 | 
			
		||||
            ) {
 | 
			
		||||
                return isAssignmentTarget(parent);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (
 | 
			
		||||
                parent.type !== "CallExpression" &&
 | 
			
		||||
                parent.type !== "NewExpression" &&
 | 
			
		||||
                !isRenamedImport(node) &&
 | 
			
		||||
                !isRenamedInDestructuring(node) &&
 | 
			
		||||
                !(
 | 
			
		||||
                    isReferenceToGlobalVariable(node) &&
 | 
			
		||||
                    !isShorthandPropertyDefinition(node)
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports an AST node as a rule violation.
 | 
			
		||||
         * @param {ASTNode} node The node to report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function report(node) {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * We used the range instead of the node because it's possible
 | 
			
		||||
             * for the same identifier to be represented by two different
 | 
			
		||||
             * nodes, with the most clear example being shorthand properties:
 | 
			
		||||
             * { foo }
 | 
			
		||||
             * In this case, "foo" is represented by one node for the name
 | 
			
		||||
             * and one for the value. The only way to know they are the same
 | 
			
		||||
             * is to look at the range.
 | 
			
		||||
             */
 | 
			
		||||
            if (!reportedNodes.has(node.range.toString())) {
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    messageId: "restricted",
 | 
			
		||||
                    data: {
 | 
			
		||||
                        name: node.name
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                reportedNodes.add(node.range.toString());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            Program(node) {
 | 
			
		||||
                globalScope = sourceCode.getScope(node);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            Identifier(node) {
 | 
			
		||||
                if (isRestricted(node.name) && shouldCheck(node)) {
 | 
			
		||||
                    report(node);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										228
									
								
								node_modules/eslint/lib/rules/id-denylist.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								node_modules/eslint/lib/rules/id-denylist.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,228 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule that warns when identifier names that are
 | 
			
		||||
 * specified in the configuration are used.
 | 
			
		||||
 * @author Keith Cirkel (http://keithcirkel.co.uk)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given node represents assignment target in a normal assignment or destructuring.
 | 
			
		||||
 * @param {ASTNode} node The node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is assignment target.
 | 
			
		||||
 */
 | 
			
		||||
function isAssignmentTarget(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
 | 
			
		||||
        // normal assignment
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "AssignmentExpression" &&
 | 
			
		||||
            parent.left === node
 | 
			
		||||
        ) ||
 | 
			
		||||
 | 
			
		||||
        // destructuring
 | 
			
		||||
        parent.type === "ArrayPattern" ||
 | 
			
		||||
        parent.type === "RestElement" ||
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "Property" &&
 | 
			
		||||
            parent.value === node &&
 | 
			
		||||
            parent.parent.type === "ObjectPattern"
 | 
			
		||||
        ) ||
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "AssignmentPattern" &&
 | 
			
		||||
            parent.left === node
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given node represents an imported name that is renamed in the same import/export specifier.
 | 
			
		||||
 *
 | 
			
		||||
 * Examples:
 | 
			
		||||
 * import { a as b } from 'mod'; // node `a` is renamed import
 | 
			
		||||
 * export { a as b } from 'mod'; // node `a` is renamed import
 | 
			
		||||
 * @param {ASTNode} node `Identifier` node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a renamed import.
 | 
			
		||||
 */
 | 
			
		||||
function isRenamedImport(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "ImportSpecifier" &&
 | 
			
		||||
            parent.imported !== parent.local &&
 | 
			
		||||
            parent.imported === node
 | 
			
		||||
        ) ||
 | 
			
		||||
        (
 | 
			
		||||
            parent.type === "ExportSpecifier" &&
 | 
			
		||||
            parent.parent.source && // re-export
 | 
			
		||||
            parent.local !== parent.exported &&
 | 
			
		||||
            parent.local === node
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether the given node is an ObjectPattern destructuring.
 | 
			
		||||
 *
 | 
			
		||||
 * Examples:
 | 
			
		||||
 * const { a : b } = foo;
 | 
			
		||||
 * @param {ASTNode} node `Identifier` node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is in an ObjectPattern destructuring.
 | 
			
		||||
 */
 | 
			
		||||
function isPropertyNameInDestructuring(node) {
 | 
			
		||||
    const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        (
 | 
			
		||||
            !parent.computed &&
 | 
			
		||||
            parent.type === "Property" &&
 | 
			
		||||
            parent.parent.type === "ObjectPattern" &&
 | 
			
		||||
            parent.key === node
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Disallow specified identifiers",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/id-denylist"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: {
 | 
			
		||||
            type: "array",
 | 
			
		||||
            items: {
 | 
			
		||||
                type: "string"
 | 
			
		||||
            },
 | 
			
		||||
            uniqueItems: true
 | 
			
		||||
        },
 | 
			
		||||
        messages: {
 | 
			
		||||
            restricted: "Identifier '{{name}}' is restricted.",
 | 
			
		||||
            restrictedPrivate: "Identifier '#{{name}}' is restricted."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
 | 
			
		||||
        const denyList = new Set(context.options);
 | 
			
		||||
        const reportedNodes = new Set();
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        let globalScope;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether the given name is restricted.
 | 
			
		||||
         * @param {string} name The name to check.
 | 
			
		||||
         * @returns {boolean} `true` if the name is restricted.
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function isRestricted(name) {
 | 
			
		||||
            return denyList.has(name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks whether the given node represents a reference to a global variable that is not declared in the source code.
 | 
			
		||||
         * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables.
 | 
			
		||||
         * @param {ASTNode} node `Identifier` node to check.
 | 
			
		||||
         * @returns {boolean} `true` if the node is a reference to a global variable.
 | 
			
		||||
         */
 | 
			
		||||
        function isReferenceToGlobalVariable(node) {
 | 
			
		||||
            const variable = globalScope.set.get(node.name);
 | 
			
		||||
 | 
			
		||||
            return variable && variable.defs.length === 0 &&
 | 
			
		||||
                variable.references.some(ref => ref.identifier === node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Determines whether the given node should be checked.
 | 
			
		||||
         * @param {ASTNode} node `Identifier` node.
 | 
			
		||||
         * @returns {boolean} `true` if the node should be checked.
 | 
			
		||||
         */
 | 
			
		||||
        function shouldCheck(node) {
 | 
			
		||||
            const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Member access has special rules for checking property names.
 | 
			
		||||
             * Read access to a property with a restricted name is allowed, because it can be on an object that user has no control over.
 | 
			
		||||
             * Write access isn't allowed, because it potentially creates a new property with a restricted name.
 | 
			
		||||
             */
 | 
			
		||||
            if (
 | 
			
		||||
                parent.type === "MemberExpression" &&
 | 
			
		||||
                parent.property === node &&
 | 
			
		||||
                !parent.computed
 | 
			
		||||
            ) {
 | 
			
		||||
                return isAssignmentTarget(parent);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (
 | 
			
		||||
                parent.type !== "CallExpression" &&
 | 
			
		||||
                parent.type !== "NewExpression" &&
 | 
			
		||||
                !isRenamedImport(node) &&
 | 
			
		||||
                !isPropertyNameInDestructuring(node) &&
 | 
			
		||||
                !isReferenceToGlobalVariable(node)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Reports an AST node as a rule violation.
 | 
			
		||||
         * @param {ASTNode} node The node to report.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function report(node) {
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * We used the range instead of the node because it's possible
 | 
			
		||||
             * for the same identifier to be represented by two different
 | 
			
		||||
             * nodes, with the most clear example being shorthand properties:
 | 
			
		||||
             * { foo }
 | 
			
		||||
             * In this case, "foo" is represented by one node for the name
 | 
			
		||||
             * and one for the value. The only way to know they are the same
 | 
			
		||||
             * is to look at the range.
 | 
			
		||||
             */
 | 
			
		||||
            if (!reportedNodes.has(node.range.toString())) {
 | 
			
		||||
                const isPrivate = node.type === "PrivateIdentifier";
 | 
			
		||||
 | 
			
		||||
                context.report({
 | 
			
		||||
                    node,
 | 
			
		||||
                    messageId: isPrivate ? "restrictedPrivate" : "restricted",
 | 
			
		||||
                    data: {
 | 
			
		||||
                        name: node.name
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                reportedNodes.add(node.range.toString());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
            Program(node) {
 | 
			
		||||
                globalScope = sourceCode.getScope(node);
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            [[
 | 
			
		||||
                "Identifier",
 | 
			
		||||
                "PrivateIdentifier"
 | 
			
		||||
            ]](node) {
 | 
			
		||||
                if (isRestricted(node.name) && shouldCheck(node)) {
 | 
			
		||||
                    report(node);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										177
									
								
								node_modules/eslint/lib/rules/id-length.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								node_modules/eslint/lib/rules/id-length.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule that warns when identifier names are shorter or longer
 | 
			
		||||
 * than the values provided in configuration.
 | 
			
		||||
 * @author Burak Yigit Kaya aka BYK
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const { getGraphemeCount } = require("../shared/string-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce minimum and maximum identifier lengths",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/id-length"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                type: "object",
 | 
			
		||||
                properties: {
 | 
			
		||||
                    min: {
 | 
			
		||||
                        type: "integer",
 | 
			
		||||
                        default: 2
 | 
			
		||||
                    },
 | 
			
		||||
                    max: {
 | 
			
		||||
                        type: "integer"
 | 
			
		||||
                    },
 | 
			
		||||
                    exceptions: {
 | 
			
		||||
                        type: "array",
 | 
			
		||||
                        uniqueItems: true,
 | 
			
		||||
                        items: {
 | 
			
		||||
                            type: "string"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    exceptionPatterns: {
 | 
			
		||||
                        type: "array",
 | 
			
		||||
                        uniqueItems: true,
 | 
			
		||||
                        items: {
 | 
			
		||||
                            type: "string"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    properties: {
 | 
			
		||||
                        enum: ["always", "never"]
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                additionalProperties: false
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        messages: {
 | 
			
		||||
            tooShort: "Identifier name '{{name}}' is too short (< {{min}}).",
 | 
			
		||||
            tooShortPrivate: "Identifier name '#{{name}}' is too short (< {{min}}).",
 | 
			
		||||
            tooLong: "Identifier name '{{name}}' is too long (> {{max}}).",
 | 
			
		||||
            tooLongPrivate: "Identifier name #'{{name}}' is too long (> {{max}})."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const options = context.options[0] || {};
 | 
			
		||||
        const minLength = typeof options.min !== "undefined" ? options.min : 2;
 | 
			
		||||
        const maxLength = typeof options.max !== "undefined" ? options.max : Infinity;
 | 
			
		||||
        const properties = options.properties !== "never";
 | 
			
		||||
        const exceptions = new Set(options.exceptions);
 | 
			
		||||
        const exceptionPatterns = (options.exceptionPatterns || []).map(pattern => new RegExp(pattern, "u"));
 | 
			
		||||
        const reportedNodes = new Set();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks if a string matches the provided exception patterns
 | 
			
		||||
         * @param {string} name The string to check.
 | 
			
		||||
         * @returns {boolean} if the string is a match
 | 
			
		||||
         * @private
 | 
			
		||||
         */
 | 
			
		||||
        function matchesExceptionPattern(name) {
 | 
			
		||||
            return exceptionPatterns.some(pattern => pattern.test(name));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const SUPPORTED_EXPRESSIONS = {
 | 
			
		||||
            MemberExpression: properties && function(parent) {
 | 
			
		||||
                return !parent.computed && (
 | 
			
		||||
 | 
			
		||||
                    // regular property assignment
 | 
			
		||||
                    (parent.parent.left === parent && parent.parent.type === "AssignmentExpression" ||
 | 
			
		||||
 | 
			
		||||
                    // or the last identifier in an ObjectPattern destructuring
 | 
			
		||||
                    parent.parent.type === "Property" && parent.parent.value === parent &&
 | 
			
		||||
                    parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent)
 | 
			
		||||
                );
 | 
			
		||||
            },
 | 
			
		||||
            AssignmentPattern(parent, node) {
 | 
			
		||||
                return parent.left === node;
 | 
			
		||||
            },
 | 
			
		||||
            VariableDeclarator(parent, node) {
 | 
			
		||||
                return parent.id === node;
 | 
			
		||||
            },
 | 
			
		||||
            Property(parent, node) {
 | 
			
		||||
 | 
			
		||||
                if (parent.parent.type === "ObjectPattern") {
 | 
			
		||||
                    const isKeyAndValueSame = parent.value.name === parent.key.name;
 | 
			
		||||
 | 
			
		||||
                    return (
 | 
			
		||||
                        !isKeyAndValueSame && parent.value === node ||
 | 
			
		||||
                        isKeyAndValueSame && parent.key === node && properties
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                return properties && !parent.computed && parent.key.name === node.name;
 | 
			
		||||
            },
 | 
			
		||||
            ImportDefaultSpecifier: true,
 | 
			
		||||
            RestElement: true,
 | 
			
		||||
            FunctionExpression: true,
 | 
			
		||||
            ArrowFunctionExpression: true,
 | 
			
		||||
            ClassDeclaration: true,
 | 
			
		||||
            FunctionDeclaration: true,
 | 
			
		||||
            MethodDefinition: true,
 | 
			
		||||
            PropertyDefinition: true,
 | 
			
		||||
            CatchClause: true,
 | 
			
		||||
            ArrayPattern: true
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            [[
 | 
			
		||||
                "Identifier",
 | 
			
		||||
                "PrivateIdentifier"
 | 
			
		||||
            ]](node) {
 | 
			
		||||
                const name = node.name;
 | 
			
		||||
                const parent = node.parent;
 | 
			
		||||
 | 
			
		||||
                const nameLength = getGraphemeCount(name);
 | 
			
		||||
 | 
			
		||||
                const isShort = nameLength < minLength;
 | 
			
		||||
                const isLong = nameLength > maxLength;
 | 
			
		||||
 | 
			
		||||
                if (!(isShort || isLong) || exceptions.has(name) || matchesExceptionPattern(name)) {
 | 
			
		||||
                    return; // Nothing to report
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type];
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * We used the range instead of the node because it's possible
 | 
			
		||||
                 * for the same identifier to be represented by two different
 | 
			
		||||
                 * nodes, with the most clear example being shorthand properties:
 | 
			
		||||
                 * { foo }
 | 
			
		||||
                 * In this case, "foo" is represented by one node for the name
 | 
			
		||||
                 * and one for the value. The only way to know they are the same
 | 
			
		||||
                 * is to look at the range.
 | 
			
		||||
                 */
 | 
			
		||||
                if (isValidExpression && !reportedNodes.has(node.range.toString()) && (isValidExpression === true || isValidExpression(parent, node))) {
 | 
			
		||||
                    reportedNodes.add(node.range.toString());
 | 
			
		||||
 | 
			
		||||
                    let messageId = isShort ? "tooShort" : "tooLong";
 | 
			
		||||
 | 
			
		||||
                    if (node.type === "PrivateIdentifier") {
 | 
			
		||||
                        messageId += "Private";
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        messageId,
 | 
			
		||||
                        data: { name, min: minLength, max: maxLength }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user