.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / cli-engine / cli-engine.js
index 22336a91de290932a7d41f0feb1ae4aeb11b9822..b1befaa04fcc77111601bf747ad122e3aca28439 100644 (file)
@@ -19,14 +19,29 @@ const fs = require("fs");
 const path = require("path");
 const defaultOptions = require("../../conf/default-cli-options");
 const pkg = require("../../package.json");
-const ConfigOps = require("../shared/config-ops");
-const naming = require("../shared/naming");
-const ModuleResolver = require("../shared/relative-module-resolver");
+
+
+const {
+    Legacy: {
+        ConfigOps,
+        naming,
+        CascadingConfigArrayFactory,
+        IgnorePattern,
+        getUsedExtractedConfigs
+    }
+} = require("@eslint/eslintrc");
+
+/*
+ * For some reason, ModuleResolver must be included via filepath instead of by
+ * API exports in order to work properly. That's why this is separated out onto
+ * its own require() statement.
+ */
+const ModuleResolver = require("@eslint/eslintrc/lib/shared/relative-module-resolver");
+const { FileEnumerator } = require("./file-enumerator");
+
 const { Linter } = require("../linter");
 const builtInRules = require("../rules");
-const { CascadingConfigArrayFactory } = require("./cascading-config-array-factory");
-const { IgnorePattern, getUsedExtractedConfigs } = require("./config-array");
-const { FileEnumerator } = require("./file-enumerator");
+const loadRules = require("./load-rules");
 const hash = require("./hash");
 const LintResultCache = require("./lint-result-cache");
 
@@ -39,6 +54,7 @@ const validFixTypes = new Set(["problem", "suggestion", "layout"]);
 
 // For VSCode IntelliSense
 /** @typedef {import("../shared/types").ConfigData} ConfigData */
+/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */
 /** @typedef {import("../shared/types").LintMessage} LintMessage */
 /** @typedef {import("../shared/types").ParserOptions} ParserOptions */
 /** @typedef {import("../shared/types").Plugin} Plugin */
@@ -50,29 +66,29 @@ const validFixTypes = new Set(["problem", "suggestion", "layout"]);
 /**
  * The options to configure a CLI engine with.
  * @typedef {Object} CLIEngineOptions
- * @property {boolean} allowInlineConfig Enable or disable inline configuration comments.
- * @property {ConfigData} baseConfig Base config object, extended by all configs used with this CLIEngine instance
- * @property {boolean} cache Enable result caching.
- * @property {string} cacheLocation The cache file to use instead of .eslintcache.
- * @property {string} configFile The configuration file to use.
- * @property {string} cwd The value to use for the current working directory.
- * @property {string[]} envs An array of environments to load.
- * @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 {string[]} globals An array of global variables to declare.
- * @property {boolean} ignore False disables use of .eslintignore.
- * @property {string} ignorePath The ignore file to use instead of .eslintignore.
- * @property {string|string[]} ignorePattern One or more glob patterns to ignore.
- * @property {boolean} useEslintrc False disables looking for .eslintrc
- * @property {string} parser The name of the parser to use.
- * @property {ParserOptions} parserOptions An object of parserOption settings to use.
- * @property {string[]} plugins An array of plugins to load.
- * @property {Record<string,RuleConf>} rules An object of rules to use.
- * @property {string[]} rulePaths An array of directories to load custom rules from.
- * @property {boolean} reportUnusedDisableDirectives `true` adds reports for unused eslint-disable directives
- * @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 {string} resolvePluginsRelativeTo The folder where plugins should be resolved from, defaulting to the CWD
+ * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments.
+ * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this CLIEngine instance
+ * @property {boolean} [cache] Enable result caching.
+ * @property {string} [cacheLocation] The cache file to use instead of .eslintcache.
+ * @property {string} [configFile] The configuration file to use.
+ * @property {string} [cwd] The value to use for the current working directory.
+ * @property {string[]} [envs] An array of environments to load.
+ * @property {string[]|null} [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 {string[]} [globals] An array of global variables to declare.
+ * @property {boolean} [ignore] False disables use of .eslintignore.
+ * @property {string} [ignorePath] The ignore file to use instead of .eslintignore.
+ * @property {string|string[]} [ignorePattern] One or more glob patterns to ignore.
+ * @property {boolean} [useEslintrc] False disables looking for .eslintrc
+ * @property {string} [parser] The name of the parser to use.
+ * @property {ParserOptions} [parserOptions] An object of parserOption settings to use.
+ * @property {string[]} [plugins] An array of plugins to load.
+ * @property {Record<string,RuleConf>} [rules] An object of rules to use.
+ * @property {string[]} [rulePaths] An array of directories to load custom rules from.
+ * @property {boolean} [reportUnusedDisableDirectives] `true` adds reports for unused eslint-disable directives
+ * @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 {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD
  */
 
 /**
@@ -88,13 +104,6 @@ const validFixTypes = new Set(["problem", "suggestion", "layout"]);
  * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible.
  */
 
-/**
- * Information of deprecated rules.
- * @typedef {Object} DeprecatedRuleInfo
- * @property {string} ruleId The rule ID.
- * @property {string[]} replacedBy The rule IDs that replace this deprecated rule.
- */
-
 /**
  * Linting results.
  * @typedef {Object} LintReport
@@ -201,7 +210,7 @@ function calculateStatsPerRun(results) {
  * @param {boolean} config.fix If `true` then it does fix.
  * @param {boolean} config.allowInlineConfig If `true` then it uses directive comments.
  * @param {boolean} config.reportUnusedDisableDirectives If `true` then it reports unused `eslint-disable` comments.
- * @param {RegExp} config.extensionRegExp The `RegExp` object that tests if a file path has the allowed file extensions.
+ * @param {FileEnumerator} config.fileEnumerator The file enumerator to check if a path is a target or not.
  * @param {Linter} config.linter The linter instance to verify.
  * @returns {LintResult} The result of linting.
  * @private
@@ -214,7 +223,7 @@ function verifyText({
     fix,
     allowInlineConfig,
     reportUnusedDisableDirectives,
-    extensionRegExp,
+    fileEnumerator,
     linter
 }) {
     const filePath = providedFilePath || "<text>";
@@ -238,13 +247,11 @@ function verifyText({
 
             /**
              * Check if the linter should adopt a given code block or not.
-             * Currently, the linter adopts code blocks if the name matches `--ext` option.
-             * In the future, `overrides` in the configuration would affect the adoption (https://github.com/eslint/rfcs/pull/20).
              * @param {string} blockFilename The virtual filename of a code block.
              * @returns {boolean} `true` if the linter should adopt the code block.
              */
             filterCodeBlock(blockFilename) {
-                return extensionRegExp.test(blockFilename);
+                return fileEnumerator.isTargetPath(blockFilename);
             }
         }
     );
@@ -278,16 +285,14 @@ function verifyText({
  */
 function createIgnoreResult(filePath, baseDir) {
     let message;
-    const isHidden = /^\./u.test(path.basename(filePath));
+    const isHidden = filePath.split(path.sep)
+        .find(segment => /^\./u.test(segment));
     const isInNodeModules = baseDir && path.relative(baseDir, filePath).startsWith("node_modules");
-    const isInBowerComponents = baseDir && path.relative(baseDir, filePath).startsWith("bower_components");
 
     if (isHidden) {
         message = "File ignored by default.  Use a negated ignore pattern (like \"--ignore-pattern '!<relative/path/to/filename>'\") to override.";
     } else if (isInNodeModules) {
         message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override.";
-    } else if (isInBowerComponents) {
-        message = "File ignored by default. Use \"--ignore-pattern '!bower_components/*'\" to override.";
     } else {
         message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override.";
     }
@@ -413,7 +418,7 @@ function getCacheFile(cacheFile, cwd) {
 
     try {
         fileStats = fs.lstatSync(resolvedCacheFile);
-    } catch (ex) {
+    } catch {
         fileStats = null;
     }
 
@@ -526,7 +531,7 @@ function directoryExists(resolvedPath) {
     try {
         return fs.statSync(resolvedPath).isDirectory();
     } catch (error) {
-        if (error && error.code === "ENOENT") {
+        if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
             return false;
         }
         throw error;
@@ -569,7 +574,11 @@ class CLIEngine {
             resolvePluginsRelativeTo: options.resolvePluginsRelativeTo,
             rulePaths: options.rulePaths,
             specificConfigPath: options.configFile,
-            useEslintrc: options.useEslintrc
+            useEslintrc: options.useEslintrc,
+            builtInRules,
+            loadRules,
+            eslintRecommendedPath: path.resolve(__dirname, "../../conf/eslint-recommended.js"),
+            eslintAllPath: path.resolve(__dirname, "../../conf/eslint-all.js")
         });
         const fileEnumerator = new FileEnumerator({
             configArrayFactory,
@@ -580,7 +589,7 @@ class CLIEngine {
             ignore: options.ignore
         });
         const lintResultCache =
-            options.cache ? new LintResultCache(cacheFilePath) : null;
+            options.cache ? new LintResultCache(cacheFilePath, options.cacheStrategy) : null;
         const linter = new Linter({ cwd: options.cwd });
 
         /** @type {ConfigArray[]} */
@@ -704,7 +713,7 @@ class CLIEngine {
             return patterns.filter(Boolean);
         }
 
-        const extensions = options.extensions.map(ext => ext.replace(/^\./u, ""));
+        const extensions = (options.extensions || [".js"]).map(ext => ext.replace(/^\./u, ""));
         const dirSuffix = `/**/*.{${extensions.join(",")}}`;
 
         return patterns.filter(Boolean).map(pathname => {
@@ -803,7 +812,7 @@ class CLIEngine {
                 fix,
                 allowInlineConfig,
                 reportUnusedDisableDirectives,
-                extensionRegExp: fileEnumerator.extensionRegExp,
+                fileEnumerator,
                 linter
             });
 
@@ -825,16 +834,22 @@ class CLIEngine {
             lintResultCache.reconcile();
         }
 
-        // Collect used deprecated rules.
-        const usedDeprecatedRules = Array.from(
-            iterateRuleDeprecationWarnings(lastConfigArrays)
-        );
-
         debug(`Linting complete in: ${Date.now() - startTime}ms`);
+        let usedDeprecatedRules;
+
         return {
             results,
             ...calculateStatsPerRun(results),
-            usedDeprecatedRules
+
+            // Initialize it lazily because CLI and `ESLint` API don't use it.
+            get usedDeprecatedRules() {
+                if (!usedDeprecatedRules) {
+                    usedDeprecatedRules = Array.from(
+                        iterateRuleDeprecationWarnings(lastConfigArrays)
+                    );
+                }
+                return usedDeprecatedRules;
+            }
         };
     }
 
@@ -862,9 +877,9 @@ class CLIEngine {
         const startTime = Date.now();
         const resolvedFilename = filename && path.resolve(cwd, filename);
 
+
         // Clear the last used config arrays.
         lastConfigArrays.length = 0;
-
         if (resolvedFilename && this.isPathIgnored(resolvedFilename)) {
             if (warnIgnored) {
                 results.push(createIgnoreResult(resolvedFilename, cwd));
@@ -891,21 +906,27 @@ class CLIEngine {
                 fix,
                 allowInlineConfig,
                 reportUnusedDisableDirectives,
-                extensionRegExp: fileEnumerator.extensionRegExp,
+                fileEnumerator,
                 linter
             }));
         }
 
-        // Collect used deprecated rules.
-        const usedDeprecatedRules = Array.from(
-            iterateRuleDeprecationWarnings(lastConfigArrays)
-        );
-
         debug(`Linting complete in: ${Date.now() - startTime}ms`);
+        let usedDeprecatedRules;
+
         return {
             results,
             ...calculateStatsPerRun(results),
-            usedDeprecatedRules
+
+            // Initialize it lazily because CLI and `ESLint` API don't use it.
+            get usedDeprecatedRules() {
+                if (!usedDeprecatedRules) {
+                    usedDeprecatedRules = Array.from(
+                        iterateRuleDeprecationWarnings(lastConfigArrays)
+                    );
+                }
+                return usedDeprecatedRules;
+            }
         };
     }
 
@@ -959,11 +980,10 @@ class CLIEngine {
     }
 
     /**
-     * Returns the formatter representing the given format or null if no formatter
-     * with the given name can be found.
+     * Returns the formatter representing the given format or null if the `format` is not a string.
      * @param {string} [format] The name of the format to load or the path to a
      *      custom formatter.
-     * @returns {Function} The formatter function or null if not found.
+     * @returns {(Function|null)} The formatter function or null if the `format` is not a string.
      */
     getFormatter(format) {
 
@@ -990,7 +1010,7 @@ class CLIEngine {
                     const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter");
 
                     formatterPath = ModuleResolver.resolve(npmFormat, path.join(cwd, "__placeholder__.js"));
-                } catch (e) {
+                } catch {
                     formatterPath = path.resolve(__dirname, "formatters", normalizedFormatName);
                 }
             }