-
-
-Gyandeep Singh
-
- |

Pig Fang
|
+
+
+YeonJuan
+
+ |

Milos Djermanovic
@@ -262,17 +250,11 @@ The following companies, organizations, and individuals support ESLint's ongoing
Gold Sponsors
- 
Silver Sponsors
+ 
Silver Sponsors

Bronze Sponsors
- 
+ 
## Technology Sponsors
* Site search ([eslint.org](https://eslint.org)) is sponsored by [Algolia](https://www.algolia.com)
-
-
-[npm-image]: https://img.shields.io/npm/v/eslint.svg?style=flat-square
-[npm-url]: https://www.npmjs.com/package/eslint
-[downloads-image]: https://img.shields.io/npm/dm/eslint.svg?style=flat-square
-[downloads-url]: https://www.npmjs.com/package/eslint
diff --git a/tools/node_modules/eslint/conf/category-list.json b/tools/node_modules/eslint/conf/category-list.json
index 5427667b09e332..6609734950a443 100644
--- a/tools/node_modules/eslint/conf/category-list.json
+++ b/tools/node_modules/eslint/conf/category-list.json
@@ -10,12 +10,12 @@
],
"deprecated": {
"name": "Deprecated",
- "description": "These rules have been deprecated in accordance with the [deprecation policy](/docs/user-guide/rule-deprecation), and replaced by newer rules:",
+ "description": "These rules have been deprecated in accordance with the deprecation policy, and replaced by newer rules:",
"rules": []
},
"removed": {
"name": "Removed",
- "description": "These rules from older versions of ESLint (before the [deprecation policy](/docs/user-guide/rule-deprecation) existed) have been replaced by newer rules:",
+ "description": "These rules from older versions of ESLint (before the deprecation policy existed) have been replaced by newer rules:",
"rules": [
{ "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
{ "removed": "global-strict", "replacedBy": ["strict"] },
diff --git a/tools/node_modules/eslint/conf/default-cli-options.js b/tools/node_modules/eslint/conf/default-cli-options.js
index 0f7b377fb362ec..e09a829d17cee2 100644
--- a/tools/node_modules/eslint/conf/default-cli-options.js
+++ b/tools/node_modules/eslint/conf/default-cli-options.js
@@ -12,7 +12,7 @@ module.exports = {
useEslintrc: true,
envs: [],
globals: [],
- extensions: [".js"],
+ extensions: null,
ignore: true,
ignorePath: void 0,
cache: false,
diff --git a/tools/node_modules/eslint/conf/environments.js b/tools/node_modules/eslint/conf/environments.js
index 10e6fdaa70fca5..ee5ee1b4e5b2ab 100644
--- a/tools/node_modules/eslint/conf/environments.js
+++ b/tools/node_modules/eslint/conf/environments.js
@@ -15,7 +15,7 @@ const globals = require("globals");
//------------------------------------------------------------------------------
/**
- * Get the object that has differentce.
+ * Get the object that has difference.
* @param {Record} current The newer object.
* @param {Record} prev The older object.
* @returns {Record} The difference object.
diff --git a/tools/node_modules/eslint/conf/eslint-recommended.js b/tools/node_modules/eslint/conf/eslint-recommended.js
index e915ec449040e9..2137685fb7c63e 100644
--- a/tools/node_modules/eslint/conf/eslint-recommended.js
+++ b/tools/node_modules/eslint/conf/eslint-recommended.js
@@ -26,6 +26,7 @@ module.exports = {
"no-delete-var": "error",
"no-dupe-args": "error",
"no-dupe-class-members": "error",
+ "no-dupe-else-if": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-empty": "error",
@@ -37,6 +38,7 @@ module.exports = {
"no-fallthrough": "error",
"no-func-assign": "error",
"no-global-assign": "error",
+ "no-import-assign": "error",
"no-inner-declarations": "error",
"no-invalid-regexp": "error",
"no-irregular-whitespace": "error",
@@ -49,6 +51,7 @@ module.exports = {
"no-redeclare": "error",
"no-regex-spaces": "error",
"no-self-assign": "error",
+ "no-setter-return": "error",
"no-shadow-restricted-names": "error",
"no-sparse-arrays": "error",
"no-this-before-super": "error",
diff --git a/tools/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js b/tools/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js
index 52703a873bb67e..f91dea4c448276 100644
--- a/tools/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js
+++ b/tools/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js
@@ -26,6 +26,7 @@
const os = require("os");
const path = require("path");
const { validateConfigArray } = require("../shared/config-validator");
+const { emitDeprecationWarning } = require("../shared/deprecation-warnings");
const { ConfigArrayFactory } = require("./config-array-factory");
const { ConfigArray, ConfigDependency, IgnorePattern } = require("./config-array");
const loadRules = require("./load-rules");
@@ -105,6 +106,7 @@ function createBaseConfigArray({
*/
if (rulePaths && rulePaths.length > 0) {
baseConfigArray.push({
+ type: "config",
name: "--rulesdir",
filePath: "",
plugins: {
@@ -290,10 +292,11 @@ class CascadingConfigArrayFactory {
/**
* Load and normalize config files from the ancestor directories.
* @param {string} directoryPath The path to a leaf directory.
+ * @param {boolean} configsExistInSubdirs `true` if configurations exist in subdirectories.
* @returns {ConfigArray} The loaded config.
* @private
*/
- _loadConfigInAncestors(directoryPath) {
+ _loadConfigInAncestors(directoryPath, configsExistInSubdirs = false) {
const {
baseConfigArray,
configArrayFactory,
@@ -320,6 +323,16 @@ class CascadingConfigArrayFactory {
// Consider this is root.
if (directoryPath === homePath && cwd !== homePath) {
debug("Stop traversing because of considered root.");
+ if (configsExistInSubdirs) {
+ const filePath = ConfigArrayFactory.getPathToConfigFileInDirectory(directoryPath);
+
+ if (filePath) {
+ emitDeprecationWarning(
+ filePath,
+ "ESLINT_PERSONAL_CONFIG_SUPPRESS"
+ );
+ }
+ }
return this._cacheConfig(directoryPath, baseConfigArray);
}
@@ -344,7 +357,10 @@ class CascadingConfigArrayFactory {
// Load from the ancestors and merge it.
const parentPath = path.dirname(directoryPath);
const parentConfigArray = parentPath && parentPath !== directoryPath
- ? this._loadConfigInAncestors(parentPath)
+ ? this._loadConfigInAncestors(
+ parentPath,
+ configsExistInSubdirs || configArray.length > 0
+ )
: baseConfigArray;
if (configArray.length > 0) {
@@ -400,12 +416,29 @@ class CascadingConfigArrayFactory {
configArray.every(c => !c.filePath) &&
cliConfigArray.every(c => !c.filePath) // `--config` option can be a file.
) {
- debug("Loading the config file of the home directory.");
+ const homePath = os.homedir();
+
+ debug("Loading the config file of the home directory:", homePath);
- finalConfigArray = configArrayFactory.loadInDirectory(
- os.homedir(),
- { name: "PersonalConfig", parent: finalConfigArray }
+ const personalConfigArray = configArrayFactory.loadInDirectory(
+ homePath,
+ { name: "PersonalConfig" }
);
+
+ if (
+ personalConfigArray.length > 0 &&
+ !directoryPath.startsWith(homePath)
+ ) {
+ const lastElement =
+ personalConfigArray[personalConfigArray.length - 1];
+
+ emitDeprecationWarning(
+ lastElement.filePath,
+ "ESLINT_PERSONAL_CONFIG_LOAD"
+ );
+ }
+
+ finalConfigArray = finalConfigArray.concat(personalConfigArray);
}
// Apply CLI options.
diff --git a/tools/node_modules/eslint/lib/cli-engine/cli-engine.js b/tools/node_modules/eslint/lib/cli-engine/cli-engine.js
index 22336a91de2909..9d2ef8cbcdef04 100644
--- a/tools/node_modules/eslint/lib/cli-engine/cli-engine.js
+++ b/tools/node_modules/eslint/lib/cli-engine/cli-engine.js
@@ -57,7 +57,7 @@ const validFixTypes = new Set(["problem", "suggestion", "layout"]);
* @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 {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.
@@ -201,7 +201,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 +214,7 @@ function verifyText({
fix,
allowInlineConfig,
reportUnusedDisableDirectives,
- extensionRegExp,
+ fileEnumerator,
linter
}) {
const filePath = providedFilePath || "";
@@ -238,13 +238,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);
}
}
);
@@ -280,14 +278,11 @@ function createIgnoreResult(filePath, baseDir) {
let message;
const isHidden = /^\./u.test(path.basename(filePath));
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 '!'\") 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.";
}
@@ -704,7 +699,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 +798,7 @@ class CLIEngine {
fix,
allowInlineConfig,
reportUnusedDisableDirectives,
- extensionRegExp: fileEnumerator.extensionRegExp,
+ fileEnumerator,
linter
});
@@ -891,7 +886,7 @@ class CLIEngine {
fix,
allowInlineConfig,
reportUnusedDisableDirectives,
- extensionRegExp: fileEnumerator.extensionRegExp,
+ fileEnumerator,
linter
}));
}
diff --git a/tools/node_modules/eslint/lib/cli-engine/config-array-factory.js b/tools/node_modules/eslint/lib/cli-engine/config-array-factory.js
index 76c4ccd70212cd..997a7e15318dfd 100644
--- a/tools/node_modules/eslint/lib/cli-engine/config-array-factory.js
+++ b/tools/node_modules/eslint/lib/cli-engine/config-array-factory.js
@@ -436,6 +436,29 @@ class ConfigArrayFactory {
);
}
+ /**
+ * Check if a config file on a given directory exists or not.
+ * @param {string} directoryPath The path to a directory.
+ * @returns {string | null} The path to the found config file. If not found then null.
+ */
+ static getPathToConfigFileInDirectory(directoryPath) {
+ for (const filename of configFilenames) {
+ const filePath = path.join(directoryPath, filename);
+
+ if (fs.existsSync(filePath)) {
+ if (filename === "package.json") {
+ try {
+ loadPackageJSONConfigFile(filePath);
+ return filePath;
+ } catch (error) { /* ignore */ }
+ } else {
+ return filePath;
+ }
+ }
+ }
+ return null;
+ }
+
/**
* Load `.eslintignore` file.
* @param {string} filePath The path to a `.eslintignore` file to load.
@@ -542,7 +565,7 @@ class ConfigArrayFactory {
*/
*_normalizeESLintIgnoreData(ignorePatterns, filePath, name) {
const elements = this._normalizeObjectConfigData(
- { ignorePatterns },
+ { type: "ignore", ignorePatterns },
filePath,
name
);
@@ -644,6 +667,7 @@ class ConfigArrayFactory {
root,
rules,
settings,
+ type = "config",
overrides: overrideList = []
},
filePath,
@@ -675,6 +699,7 @@ class ConfigArrayFactory {
yield {
// Debug information.
+ type,
name,
filePath,
@@ -1024,6 +1049,7 @@ class ConfigArrayFactory {
if (processorId.startsWith(".")) {
yield* this._normalizeObjectConfigData(
{
+ type: "implicit-processor",
files: [`*${processorId}`],
processor: `${pluginId}/${processorId}`
},
diff --git a/tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js b/tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js
index 4fae8deaca1b69..b3f7c1e7350033 100644
--- a/tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js
+++ b/tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js
@@ -5,7 +5,7 @@
* config file, base config files that were extended, loaded parsers, and loaded
* plugins.
*
- * `ConfigArray` class provies three properties and two methods.
+ * `ConfigArray` class provides three properties and two methods.
*
* - `pluginEnvironments`
* - `pluginProcessors`
@@ -454,6 +454,25 @@ class ConfigArray extends Array {
return cache.get(cacheKey);
}
+
+ /**
+ * Check if a given path is an additional lint target.
+ * @param {string} filePath The absolute path to the target file.
+ * @returns {boolean} `true` if the file is an additional lint target.
+ */
+ isAdditionalTargetPath(filePath) {
+ for (const { criteria, type } of this) {
+ if (
+ type === "config" &&
+ criteria &&
+ !criteria.endsWithWildcard &&
+ criteria.test(filePath)
+ ) {
+ return true;
+ }
+ }
+ return false;
+ }
}
const exportObject = {
diff --git a/tools/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js b/tools/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js
index 6140194433e861..92690b9f8ae342 100644
--- a/tools/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js
+++ b/tools/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js
@@ -103,8 +103,8 @@ function dirSuffix(filePath) {
return isDir ? "/" : "";
}
-const DefaultPatterns = Object.freeze(["/node_modules/*", "/bower_components/*"]);
-const DotPatterns = Object.freeze([".*", "!../"]);
+const DefaultPatterns = Object.freeze(["/**/node_modules/*"]);
+const DotPatterns = Object.freeze([".*", "!.eslintrc.*", "!../"]);
//------------------------------------------------------------------------------
// Public
diff --git a/tools/node_modules/eslint/lib/cli-engine/config-array/override-tester.js b/tools/node_modules/eslint/lib/cli-engine/config-array/override-tester.js
index 67c8a6ed8a0cbb..e7ba1202f1cb08 100644
--- a/tools/node_modules/eslint/lib/cli-engine/config-array/override-tester.js
+++ b/tools/node_modules/eslint/lib/cli-engine/config-array/override-tester.js
@@ -96,14 +96,22 @@ class OverrideTester {
static create(files, excludedFiles, basePath) {
const includePatterns = normalizePatterns(files);
const excludePatterns = normalizePatterns(excludedFiles);
- const allPatterns = includePatterns.concat(excludePatterns);
+ let endsWithWildcard = false;
- if (allPatterns.length === 0) {
+ if (includePatterns.length === 0) {
return null;
}
// Rejects absolute paths or relative paths to parents.
- for (const pattern of allPatterns) {
+ for (const pattern of includePatterns) {
+ if (path.isAbsolute(pattern) || pattern.includes("..")) {
+ throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`);
+ }
+ if (pattern.endsWith("*")) {
+ endsWithWildcard = true;
+ }
+ }
+ for (const pattern of excludePatterns) {
if (path.isAbsolute(pattern) || pattern.includes("..")) {
throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`);
}
@@ -112,7 +120,11 @@ class OverrideTester {
const includes = toMatcher(includePatterns);
const excludes = toMatcher(excludePatterns);
- return new OverrideTester([{ includes, excludes }], basePath);
+ return new OverrideTester(
+ [{ includes, excludes }],
+ basePath,
+ endsWithWildcard
+ );
}
/**
@@ -125,28 +137,44 @@ class OverrideTester {
*/
static and(a, b) {
if (!b) {
- return a && new OverrideTester(a.patterns, a.basePath);
+ return a && new OverrideTester(
+ a.patterns,
+ a.basePath,
+ a.endsWithWildcard
+ );
}
if (!a) {
- return new OverrideTester(b.patterns, b.basePath);
+ return new OverrideTester(
+ b.patterns,
+ b.basePath,
+ b.endsWithWildcard
+ );
}
assert.strictEqual(a.basePath, b.basePath);
- return new OverrideTester(a.patterns.concat(b.patterns), a.basePath);
+ return new OverrideTester(
+ a.patterns.concat(b.patterns),
+ a.basePath,
+ a.endsWithWildcard || b.endsWithWildcard
+ );
}
/**
* Initialize this instance.
* @param {Pattern[]} patterns The matchers.
* @param {string} basePath The base path.
+ * @param {boolean} endsWithWildcard If `true` then a pattern ends with `*`.
*/
- constructor(patterns, basePath) {
+ constructor(patterns, basePath, endsWithWildcard = false) {
/** @type {Pattern[]} */
this.patterns = patterns;
/** @type {string} */
this.basePath = basePath;
+
+ /** @type {boolean} */
+ this.endsWithWildcard = endsWithWildcard;
}
/**
diff --git a/tools/node_modules/eslint/lib/cli-engine/file-enumerator.js b/tools/node_modules/eslint/lib/cli-engine/file-enumerator.js
index c67e01aef9b1c8..7c433d32f44b1c 100644
--- a/tools/node_modules/eslint/lib/cli-engine/file-enumerator.js
+++ b/tools/node_modules/eslint/lib/cli-engine/file-enumerator.js
@@ -6,7 +6,7 @@
* 1. Find target files by processing glob patterns.
* 2. Tie each target file and appropriate configuration.
*
- * It provies a method:
+ * It provides a method:
*
* - `iterateFiles(patterns)`
* Iterate files which are matched by given patterns together with the
@@ -88,7 +88,7 @@ const IGNORED = 2;
* @typedef {Object} FileEnumeratorInternalSlots
* @property {CascadingConfigArrayFactory} configArrayFactory The factory for config arrays.
* @property {string} cwd The base directory to start lookup.
- * @property {RegExp} extensionRegExp The RegExp to test if a string ends with specific file extensions.
+ * @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.
@@ -127,12 +127,12 @@ function statSafeSync(filePath) {
/**
* Get filenames in a given path to a directory.
* @param {string} directoryPath The path to target directory.
- * @returns {string[]} The filenames.
+ * @returns {import("fs").Dirent[]} The filenames.
* @private
*/
function readdirSafeSync(directoryPath) {
try {
- return fs.readdirSync(directoryPath);
+ return fs.readdirSync(directoryPath, { withFileTypes: true });
} catch (error) {
/* istanbul ignore next */
if (error.code !== "ENOENT") {
@@ -142,6 +142,27 @@ function readdirSafeSync(directoryPath) {
}
}
+/**
+ * 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.
*/
@@ -188,7 +209,7 @@ class FileEnumerator {
constructor({
cwd = process.cwd(),
configArrayFactory = new CascadingConfigArrayFactory({ cwd }),
- extensions = [".js"],
+ extensions = null,
globInputPaths = true,
errorOnUnmatchedPattern = true,
ignore = true
@@ -197,17 +218,7 @@ class FileEnumerator {
configArrayFactory,
cwd,
defaultIgnores: IgnorePattern.createDefaultIgnore(cwd),
- extensionRegExp: new RegExp(
- `.\\.(?:${extensions
- .map(ext => escapeRegExp(
- ext.startsWith(".")
- ? ext.slice(1)
- : ext
- ))
- .join("|")
- })$`,
- "u"
- ),
+ extensionRegExp: createExtensionRegExp(extensions),
globInputPaths,
errorOnUnmatchedPattern,
ignoreFlag: ignore
@@ -215,11 +226,36 @@ class FileEnumerator {
}
/**
- * The `RegExp` object that tests if a file path has the allowed file extensions.
- * @type {RegExp}
+ * 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.
*/
- get extensionRegExp() {
- return internalSlotsMap.get(this).extensionRegExp;
+ 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);
}
/**
@@ -247,7 +283,7 @@ class FileEnumerator {
continue;
}
- // Iterate files of this pttern.
+ // Iterate files of this pattern.
for (const { config, filePath, flag } of this._iterateFiles(pattern)) {
foundRegardlessOfIgnored = true;
if (flag === IGNORED_SILENTLY) {
@@ -380,18 +416,17 @@ class FileEnumerator {
*/
*_iterateFilesRecursive(directoryPath, options) {
debug(`Enter the directory: ${directoryPath}`);
- const { configArrayFactory, extensionRegExp } = internalSlotsMap.get(this);
+ const { configArrayFactory } = internalSlotsMap.get(this);
/** @type {ConfigArray|null} */
let config = null;
// Enumerate the files of this directory.
- for (const filename of readdirSafeSync(directoryPath)) {
- const filePath = path.join(directoryPath, filename);
- const stat = statSafeSync(filePath); // TODO: Use `withFileTypes` in the future.
+ for (const entry of readdirSafeSync(directoryPath)) {
+ const filePath = path.join(directoryPath, entry.name);
// Check if the file is matched.
- if (stat && stat.isFile()) {
+ if (entry.isFile()) {
if (!config) {
config = configArrayFactory.getConfigArrayForFile(
filePath,
@@ -404,29 +439,30 @@ class FileEnumerator {
{ ignoreNotFoundError: true }
);
}
- const ignored = this._isIgnoredFile(filePath, { ...options, config });
- const flag = ignored ? IGNORED_SILENTLY : NONE;
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.
- : extensionRegExp.test(filePath);
+ : this.isTargetPath(filePath, config);
if (matched) {
- debug(`Yield: ${filename}${ignored ? " but ignored" : ""}`);
+ 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: ${filename}`);
+ debug(`Didn't match: ${entry.name}`);
}
// Dive into the sub directory.
- } else if (options.recursive && stat && stat.isDirectory()) {
+ } else if (options.recursive && entry.isDirectory()) {
if (!config) {
config = configArrayFactory.getConfigArrayForFile(
filePath,
diff --git a/tools/node_modules/eslint/lib/cli-engine/formatters/junit.js b/tools/node_modules/eslint/lib/cli-engine/formatters/junit.js
index c32425883f7cac..a994b4b1980eea 100644
--- a/tools/node_modules/eslint/lib/cli-engine/formatters/junit.js
+++ b/tools/node_modules/eslint/lib/cli-engine/formatters/junit.js
@@ -32,7 +32,7 @@ function getMessageType(message) {
* @private
*/
function pathWithoutExt(filePath) {
- return path.posix.join(path.posix.dirname(filePath), path.basename(filePath, path.extname(filePath)));
+ return path.join(path.dirname(filePath), path.basename(filePath, path.extname(filePath)));
}
//------------------------------------------------------------------------------
diff --git a/tools/node_modules/eslint/lib/cli.js b/tools/node_modules/eslint/lib/cli.js
index 944b4b79353b3d..815ce68c22fe2e 100644
--- a/tools/node_modules/eslint/lib/cli.js
+++ b/tools/node_modules/eslint/lib/cli.js
@@ -17,7 +17,6 @@
const fs = require("fs"),
path = require("path"),
- mkdirp = require("mkdirp"),
{ CLIEngine } = require("./cli-engine"),
options = require("./options"),
log = require("./shared/logging"),
@@ -115,7 +114,7 @@ function printResults(engine, results, format, outputFile) {
}
try {
- mkdirp.sync(path.dirname(filePath));
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
fs.writeFileSync(filePath, output);
} catch (ex) {
log.error("There was a problem writing the output file:\n%s", ex);
diff --git a/tools/node_modules/eslint/lib/init/npm-utils.js b/tools/node_modules/eslint/lib/init/npm-utils.js
index 28c198fc8ada67..555ea2b2b28cb2 100644
--- a/tools/node_modules/eslint/lib/init/npm-utils.js
+++ b/tools/node_modules/eslint/lib/init/npm-utils.js
@@ -135,7 +135,7 @@ function check(packages, opt) {
*
* Convenience wrapper around check().
* @param {string[]} packages Array of node modules to check.
- * @param {string} rootDir The directory contianing a package.json
+ * @param {string} rootDir The directory containing a package.json
* @returns {Object} An object whose keys are the module names
* and values are booleans indicating installation.
*/
diff --git a/tools/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js b/tools/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js
index 6822ae2be0a6cd..8a623e33ea0681 100644
--- a/tools/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js
+++ b/tools/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js
@@ -518,6 +518,7 @@ function processCodePathToExit(analyzer, node) {
case "ImportExpression":
case "MemberExpression":
case "NewExpression":
+ case "YieldExpression":
state.makeFirstThrowablePathInTryBlock();
break;
diff --git a/tools/node_modules/eslint/lib/linter/code-path-analysis/debug-helpers.js b/tools/node_modules/eslint/lib/linter/code-path-analysis/debug-helpers.js
index 35a4cb2dacb1ca..bde4e0a38ad24b 100644
--- a/tools/node_modules/eslint/lib/linter/code-path-analysis/debug-helpers.js
+++ b/tools/node_modules/eslint/lib/linter/code-path-analysis/debug-helpers.js
@@ -70,7 +70,7 @@ module.exports = {
/**
* Dumps a DOT code of a given code path.
- * The DOT code can be visialized with Graphvis.
+ * The DOT code can be visualized with Graphvis.
* @param {CodePath} codePath A code path to dump.
* @returns {void}
* @see http://www.graphviz.org
@@ -135,7 +135,7 @@ module.exports = {
/**
* Makes a DOT code of a given code path.
- * The DOT code can be visialized with Graphvis.
+ * 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.
diff --git a/tools/node_modules/eslint/lib/linter/code-path-analysis/fork-context.js b/tools/node_modules/eslint/lib/linter/code-path-analysis/fork-context.js
index eb1d2de5a7db5b..2e872b5c0dbf5a 100644
--- a/tools/node_modules/eslint/lib/linter/code-path-analysis/fork-context.js
+++ b/tools/node_modules/eslint/lib/linter/code-path-analysis/fork-context.js
@@ -211,7 +211,7 @@ class ForkContext {
}
/**
- * Clears all secments in this context.
+ * Clears all segments in this context.
* @returns {void}
*/
clear() {
diff --git a/tools/node_modules/eslint/lib/linter/linter.js b/tools/node_modules/eslint/lib/linter/linter.js
index 6d88cb5aa1245f..1d021d1e82e7fb 100644
--- a/tools/node_modules/eslint/lib/linter/linter.js
+++ b/tools/node_modules/eslint/lib/linter/linter.js
@@ -267,6 +267,15 @@ function createDisableDirectives(options) {
return result;
}
+/**
+ * Remove the ignored part from a given directive comment and trim it.
+ * @param {string} value The comment text to strip.
+ * @returns {string} The stripped text.
+ */
+function stripDirectiveComment(value) {
+ return value.split(/\s-{2,}\s/u)[0].trim();
+}
+
/**
* Parses comments in file to extract file-specific config of rules, globals
* and environments and merges them with global config; also code blocks
@@ -286,7 +295,7 @@ function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) {
const disableDirectives = [];
ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
- const trimmedCommentText = comment.value.trim();
+ const trimmedCommentText = stripDirectiveComment(comment.value);
const match = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(trimmedCommentText);
if (!match) {
@@ -444,8 +453,11 @@ function findEslintEnv(text) {
eslintEnvPattern.lastIndex = 0;
- while ((match = eslintEnvPattern.exec(text))) {
- retv = Object.assign(retv || {}, commentParser.parseListConfig(match[1]));
+ while ((match = eslintEnvPattern.exec(text)) !== null) {
+ retv = Object.assign(
+ retv || {},
+ commentParser.parseListConfig(stripDirectiveComment(match[1]))
+ );
}
return retv;
@@ -1260,7 +1272,7 @@ class Linter {
* @param {string|SourceCode} textOrSourceCode The source code.
* @param {ConfigData|ExtractedConfig} config The config array.
* @param {VerifyOptions&ProcessorOptions} options The options.
- * @param {ConfigArray} [configForRecursive] The `CofnigArray` object to apply multiple processors recursively.
+ * @param {ConfigArray} [configForRecursive] The `ConfigArray` object to apply multiple processors recursively.
* @returns {LintMessage[]} The found problems.
*/
_verifyWithProcessor(textOrSourceCode, config, options, configForRecursive) {
diff --git a/tools/node_modules/eslint/lib/rule-tester/rule-tester.js b/tools/node_modules/eslint/lib/rule-tester/rule-tester.js
index 44e01dadf09b5d..5180f87a316f85 100644
--- a/tools/node_modules/eslint/lib/rule-tester/rule-tester.js
+++ b/tools/node_modules/eslint/lib/rule-tester/rule-tester.js
@@ -50,6 +50,52 @@ const
const ajv = require("../shared/ajv")({ strictDefaults: true });
+
+//------------------------------------------------------------------------------
+// Typedefs
+//------------------------------------------------------------------------------
+
+/**
+ * A test case that is expected to pass lint.
+ * @typedef {Object} ValidTestCase
+ * @property {string} code Code for the test case.
+ * @property {any[]} [options] Options for the test case.
+ * @property {{ [name: string]: any }} [settings] Settings for the test case.
+ * @property {string} [filename] The fake filename for the test case. Useful for rules that make assertion about filenames.
+ * @property {string} [parser] The absolute path for the parser.
+ * @property {{ [name: string]: any }} [parserOptions] Options for the parser.
+ * @property {{ [name: string]: "readonly" | "writable" | "off" }} [globals] The additional global variables.
+ * @property {{ [name: string]: boolean }} [env] Environments for the test case.
+ */
+
+/**
+ * A test case that is expected to fail lint.
+ * @typedef {Object} InvalidTestCase
+ * @property {string} code Code for the test case.
+ * @property {number | Array} errors Expected errors.
+ * @property {string | null} [output] The expected code after autofixes are applied. If set to `null`, the test runner will assert that no autofix is suggested.
+ * @property {any[]} [options] Options for the test case.
+ * @property {{ [name: string]: any }} [settings] Settings for the test case.
+ * @property {string} [filename] The fake filename for the test case. Useful for rules that make assertion about filenames.
+ * @property {string} [parser] The absolute path for the parser.
+ * @property {{ [name: string]: any }} [parserOptions] Options for the parser.
+ * @property {{ [name: string]: "readonly" | "writable" | "off" }} [globals] The additional global variables.
+ * @property {{ [name: string]: boolean }} [env] Environments for the test case.
+ */
+
+/**
+ * A description of a reported error used in a rule tester test.
+ * @typedef {Object} TestCaseError
+ * @property {string | RegExp} [message] Message.
+ * @property {string} [messageId] Message ID.
+ * @property {string} [type] The type of the reported AST node.
+ * @property {{ [name: string]: string }} [data] The data used to fill the message template.
+ * @property {number} [line] The 1-based line number of the reported start location.
+ * @property {number} [column] The 1-based column number of the reported start location.
+ * @property {number} [endLine] The 1-based line number of the reported end location.
+ * @property {number} [endColumn] The 1-based column number of the reported end location.
+ */
+
//------------------------------------------------------------------------------
// Private Members
//------------------------------------------------------------------------------
@@ -73,6 +119,32 @@ const RuleTesterParameters = [
"output"
];
+/*
+ * All allowed property names in error objects.
+ */
+const errorObjectParameters = new Set([
+ "message",
+ "messageId",
+ "data",
+ "type",
+ "line",
+ "column",
+ "endLine",
+ "endColumn",
+ "suggestions"
+]);
+const friendlyErrorObjectParameterList = `[${[...errorObjectParameters].map(key => `'${key}'`).join(", ")}]`;
+
+/*
+ * All allowed property names in suggestion objects.
+ */
+const suggestionObjectParameters = new Set([
+ "desc",
+ "messageId",
+ "output"
+]);
+const friendlySuggestionObjectParameterList = `[${[...suggestionObjectParameters].map(key => `'${key}'`).join(", ")}]`;
+
const hasOwnProperty = Function.call.bind(Object.hasOwnProperty);
/**
@@ -128,7 +200,7 @@ function freezeDeeply(x) {
*/
function sanitize(text) {
return text.replace(
- /[\u0000-\u0009|\u000b-\u001a]/gu, // eslint-disable-line no-control-regex
+ /[\u0000-\u0009\u000b-\u001a]/gu, // eslint-disable-line no-control-regex
c => `\\u${c.codePointAt(0).toString(16).padStart(4, "0")}`
);
}
@@ -273,7 +345,10 @@ class RuleTester {
* Adds a new rule test to execute.
* @param {string} ruleName The name of the rule to run.
* @param {Function} rule The rule to test.
- * @param {Object} test The collection of tests to run.
+ * @param {{
+ * valid: (ValidTestCase | string)[],
+ * invalid: InvalidTestCase[]
+ * }} test The collection of tests to run.
* @returns {void}
*/
run(ruleName, rule, test) {
@@ -524,13 +599,21 @@ class RuleTester {
// Just an error message.
assertMessageMatches(message.message, error);
- } else if (typeof error === "object") {
+ } else if (typeof error === "object" && error !== null) {
/*
* Error object.
* This may have a message, messageId, data, node type, line, and/or
* column.
*/
+
+ Object.keys(error).forEach(propertyName => {
+ assert.ok(
+ errorObjectParameters.has(propertyName),
+ `Invalid error property name '${propertyName}'. Expected one of ${friendlyErrorObjectParameterList}.`
+ );
+ });
+
if (hasOwnProperty(error, "message")) {
assert.ok(!hasOwnProperty(error, "messageId"), "Error should not specify both 'message' and a 'messageId'.");
assert.ok(!hasOwnProperty(error, "data"), "Error should not specify both 'data' and 'message'.");
@@ -605,6 +688,17 @@ class RuleTester {
assert.strictEqual(message.suggestions.length, error.suggestions.length, `Error should have ${error.suggestions.length} suggestions. Instead found ${message.suggestions.length} suggestions`);
error.suggestions.forEach((expectedSuggestion, index) => {
+ assert.ok(
+ typeof expectedSuggestion === "object" && expectedSuggestion !== null,
+ "Test suggestion in 'suggestions' array must be an object."
+ );
+ Object.keys(expectedSuggestion).forEach(propertyName => {
+ assert.ok(
+ suggestionObjectParameters.has(propertyName),
+ `Invalid suggestion property name '${propertyName}'. Expected one of ${friendlySuggestionObjectParameterList}.`
+ );
+ });
+
const actualSuggestion = message.suggestions[index];
/**
diff --git a/tools/node_modules/eslint/lib/rules/accessor-pairs.js b/tools/node_modules/eslint/lib/rules/accessor-pairs.js
index 3a32db6eac7214..02548258ca2e28 100644
--- a/tools/node_modules/eslint/lib/rules/accessor-pairs.js
+++ b/tools/node_modules/eslint/lib/rules/accessor-pairs.js
@@ -171,7 +171,7 @@ module.exports = {
},
enforceForClassMembers: {
type: "boolean",
- default: false
+ default: true
}
},
additionalProperties: false
@@ -190,7 +190,7 @@ module.exports = {
const config = context.options[0] || {};
const checkGetWithoutSet = config.getWithoutSet === true;
const checkSetWithoutGet = config.setWithoutGet !== false;
- const enforceForClassMembers = config.enforceForClassMembers === true;
+ const enforceForClassMembers = config.enforceForClassMembers !== false;
const sourceCode = context.getSourceCode();
/**
diff --git a/tools/node_modules/eslint/lib/rules/array-callback-return.js b/tools/node_modules/eslint/lib/rules/array-callback-return.js
index d632a3f30c28a3..eb38965024f05d 100644
--- a/tools/node_modules/eslint/lib/rules/array-callback-return.js
+++ b/tools/node_modules/eslint/lib/rules/array-callback-return.js
@@ -18,7 +18,7 @@ const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
-const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/u;
+const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort)$/u;
/**
* Checks a given code path segment is reachable.
@@ -61,12 +61,13 @@ function isTargetMethod(node) {
/**
* Checks whether or not a given node is a function expression which is the
- * callback of an array method.
+ * callback of an array method, returning the method name.
* @param {ASTNode} node A node to check. This is one of
* FunctionExpression or ArrowFunctionExpression.
- * @returns {boolean} `true` if the node is the callback of an array method.
+ * @returns {string} The method name if the node is a callback method,
+ * null otherwise.
*/
-function isCallbackOfArrayMethod(node) {
+function getArrayMethodName(node) {
let currentNode = node;
while (currentNode) {
@@ -95,7 +96,7 @@ function isCallbackOfArrayMethod(node) {
const func = astUtils.getUpperFunction(parent);
if (func === null || !astUtils.isCallee(func)) {
- return false;
+ return null;
}
currentNode = func.parent;
break;
@@ -108,27 +109,31 @@ function isCallbackOfArrayMethod(node) {
*/
case "CallExpression":
if (astUtils.isArrayFromMethod(parent.callee)) {
- return (
+ if (
parent.arguments.length >= 2 &&
parent.arguments[1] === currentNode
- );
+ ) {
+ return "from";
+ }
}
if (isTargetMethod(parent.callee)) {
- return (
+ if (
parent.arguments.length >= 1 &&
parent.arguments[0] === currentNode
- );
+ ) {
+ return astUtils.getStaticPropertyName(parent.callee);
+ }
}
- return false;
+ return null;
// Otherwise this node is not target.
default:
- return false;
+ return null;
}
}
/* istanbul ignore next: unreachable */
- return false;
+ return null;
}
//------------------------------------------------------------------------------
@@ -153,6 +158,10 @@ module.exports = {
allowImplicit: {
type: "boolean",
default: false
+ },
+ checkForEach: {
+ type: "boolean",
+ default: false
}
},
additionalProperties: false
@@ -162,15 +171,17 @@ module.exports = {
messages: {
expectedAtEnd: "Expected to return a value at the end of {{name}}.",
expectedInside: "Expected to return a value in {{name}}.",
- expectedReturnValue: "{{name}} expected a return value."
+ expectedReturnValue: "{{name}} expected a return value.",
+ expectedNoReturnValue: "{{name}} did not expect a return value."
}
},
create(context) {
- const options = context.options[0] || { allowImplicit: false };
+ const options = context.options[0] || { allowImplicit: false, checkForEach: false };
let funcInfo = {
+ arrayMethodName: null,
upper: null,
codePath: null,
hasReturn: false,
@@ -188,18 +199,32 @@ module.exports = {
* @returns {void}
*/
function checkLastSegment(node) {
- if (funcInfo.shouldCheck &&
- funcInfo.codePath.currentSegments.some(isReachable)
- ) {
+
+ if (!funcInfo.shouldCheck) {
+ return;
+ }
+
+ let messageId = null;
+
+ if (funcInfo.arrayMethodName === "forEach") {
+ if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) {
+ messageId = "expectedNoReturnValue";
+ }
+ } else {
+ if (node.body.type === "BlockStatement" && funcInfo.codePath.currentSegments.some(isReachable)) {
+ messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
+ }
+ }
+
+ if (messageId) {
+ let name = astUtils.getFunctionNameWithKind(funcInfo.node);
+
+ name = messageId === "expectedNoReturnValue" ? lodash.upperFirst(name) : name;
context.report({
node,
loc: getLocation(node, context.getSourceCode()).loc.start,
- messageId: funcInfo.hasReturn
- ? "expectedAtEnd"
- : "expectedInside",
- data: {
- name: astUtils.getFunctionNameWithKind(funcInfo.node)
- }
+ messageId,
+ data: { name }
});
}
}
@@ -208,14 +233,20 @@ module.exports = {
// 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:
- TARGET_NODE_TYPE.test(node.type) &&
- node.body.type === "BlockStatement" &&
- isCallbackOfArrayMethod(node) &&
+ methodName &&
!node.async &&
!node.generator,
node
@@ -229,20 +260,38 @@ module.exports = {
// Checks the return statement is valid.
ReturnStatement(node) {
- if (funcInfo.shouldCheck) {
- funcInfo.hasReturn = true;
+
+ if (!funcInfo.shouldCheck) {
+ return;
+ }
+
+ funcInfo.hasReturn = true;
+
+ let messageId = null;
+
+ if (funcInfo.arrayMethodName === "forEach") {
+
+ // if checkForEach: true, returning a value at any path inside a forEach is not allowed
+ if (options.checkForEach && node.argument) {
+ messageId = "expectedNoReturnValue";
+ }
+ } else {
// if allowImplicit: false, should also check node.argument
if (!options.allowImplicit && !node.argument) {
- context.report({
- node,
- messageId: "expectedReturnValue",
- data: {
- name: lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node))
- }
- });
+ messageId = "expectedReturnValue";
}
}
+
+ if (messageId) {
+ context.report({
+ node,
+ messageId,
+ data: {
+ name: lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node))
+ }
+ });
+ }
},
// Reports a given function if the last path is reachable.
diff --git a/tools/node_modules/eslint/lib/rules/array-element-newline.js b/tools/node_modules/eslint/lib/rules/array-element-newline.js
index 1da67667bee849..b7a967865b92a1 100644
--- a/tools/node_modules/eslint/lib/rules/array-element-newline.js
+++ b/tools/node_modules/eslint/lib/rules/array-element-newline.js
@@ -24,28 +24,52 @@ module.exports = {
fixable: "whitespace",
- schema: [
- {
- oneOf: [
- {
- enum: ["always", "never", "consistent"]
- },
- {
- type: "object",
- properties: {
- multiline: {
- type: "boolean"
+ schema: {
+ definitions: {
+ basicConfig: {
+ oneOf: [
+ {
+ enum: ["always", "never", "consistent"]
+ },
+ {
+ type: "object",
+ properties: {
+ multiline: {
+ type: "boolean"
+ },
+ minItems: {
+ type: ["integer", "null"],
+ minimum: 0
+ }
},
- minItems: {
- type: ["integer", "null"],
- minimum: 0
- }
+ additionalProperties: false
+ }
+ ]
+ }
+ },
+ items: [
+ {
+ oneOf: [
+ {
+ $ref: "#/definitions/basicConfig"
},
- additionalProperties: false
- }
- ]
- }
- ],
+ {
+ type: "object",
+ properties: {
+ ArrayExpression: {
+ $ref: "#/definitions/basicConfig"
+ },
+ ArrayPattern: {
+ $ref: "#/definitions/basicConfig"
+ }
+ },
+ additionalProperties: false,
+ minProperties: 1
+ }
+ ]
+ }
+ ]
+ },
messages: {
unexpectedLineBreak: "There should be no linebreak here.",
@@ -93,6 +117,20 @@ module.exports = {
* @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 };
@@ -177,6 +215,10 @@ module.exports = {
const normalizedOptions = normalizeOptions(context.options[0]);
const options = normalizedOptions[node.type];
+ if (!options) {
+ return;
+ }
+
let elementBreak = false;
/*
diff --git a/tools/node_modules/eslint/lib/rules/arrow-body-style.js b/tools/node_modules/eslint/lib/rules/arrow-body-style.js
index 8d3b400037a6d5..9d5c77d8573d6a 100644
--- a/tools/node_modules/eslint/lib/rules/arrow-body-style.js
+++ b/tools/node_modules/eslint/lib/rules/arrow-body-style.js
@@ -91,7 +91,7 @@ module.exports = {
* @returns {Token} The found closing parenthesis token.
*/
function findClosingParen(token) {
- let node = sourceCode.getNodeByRangeIndex(token.range[1]);
+ let node = sourceCode.getNodeByRangeIndex(token.range[0]);
while (!astUtils.isParenthesised(sourceCode, node)) {
node = node.parent;
@@ -206,24 +206,35 @@ module.exports = {
fix(fixer) {
const fixes = [];
const arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken);
- const firstBodyToken = sourceCode.getTokenAfter(arrowToken);
- const lastBodyToken = sourceCode.getLastToken(node);
+ const [firstTokenAfterArrow, secondTokenAfterArrow] = sourceCode.getTokensAfter(arrowToken, { count: 2 });
+ const lastToken = sourceCode.getLastToken(node);
const isParenthesisedObjectLiteral =
- astUtils.isOpeningParenToken(firstBodyToken) &&
- astUtils.isOpeningBraceToken(sourceCode.getTokenAfter(firstBodyToken));
-
- // Wrap the value by a block and a return statement.
- fixes.push(
- fixer.insertTextBefore(firstBodyToken, "{return "),
- fixer.insertTextAfter(lastBodyToken, "}")
- );
+ astUtils.isOpeningParenToken(firstTokenAfterArrow) &&
+ astUtils.isOpeningBraceToken(secondTokenAfterArrow);
// If the value is object literal, remove parentheses which were forced by syntax.
if (isParenthesisedObjectLiteral) {
- fixes.push(
- fixer.remove(firstBodyToken),
- fixer.remove(findClosingParen(firstBodyToken))
- );
+ 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(openingBraceToken)));
+ fixes.push(fixer.insertTextAfter(lastToken, "}"));
+
+ } else {
+ fixes.push(fixer.insertTextBefore(firstTokenAfterArrow, "{return "));
+ fixes.push(fixer.insertTextAfter(lastToken, "}"));
}
return fixes;
diff --git a/tools/node_modules/eslint/lib/rules/complexity.js b/tools/node_modules/eslint/lib/rules/complexity.js
index 91180e989540ce..7fc8bf9bc2ea8c 100644
--- a/tools/node_modules/eslint/lib/rules/complexity.js
+++ b/tools/node_modules/eslint/lib/rules/complexity.js
@@ -1,6 +1,6 @@
/**
* @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, whilte, try, switch/case,
+ * Counts the number of if, conditional, for, while, try, switch/case,
* @author Patrick Brosset
*/
diff --git a/tools/node_modules/eslint/lib/rules/computed-property-spacing.js b/tools/node_modules/eslint/lib/rules/computed-property-spacing.js
index a0bd7f48ced66b..53fdb8f4e41f95 100644
--- a/tools/node_modules/eslint/lib/rules/computed-property-spacing.js
+++ b/tools/node_modules/eslint/lib/rules/computed-property-spacing.js
@@ -32,7 +32,7 @@ module.exports = {
properties: {
enforceForClassMembers: {
type: "boolean",
- default: false
+ default: true
}
},
additionalProperties: false
@@ -51,7 +51,7 @@ module.exports = {
create(context) {
const sourceCode = context.getSourceCode();
const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never"
- const enforceForClassMembers = context.options[1] && context.options[1].enforceForClassMembers;
+ const enforceForClassMembers = !context.options[1] || context.options[1].enforceForClassMembers;
//--------------------------------------------------------------------------
// Helpers
@@ -67,7 +67,7 @@ module.exports = {
function reportNoBeginningSpace(node, token, tokenAfter) {
context.report({
node,
- loc: token.loc.start,
+ loc: { start: token.loc.end, end: tokenAfter.loc.start },
messageId: "unexpectedSpaceAfter",
data: {
tokenValue: token.value
@@ -88,7 +88,7 @@ module.exports = {
function reportNoEndingSpace(node, token, tokenBefore) {
context.report({
node,
- loc: token.loc.start,
+ loc: { start: tokenBefore.loc.end, end: token.loc.start },
messageId: "unexpectedSpaceBefore",
data: {
tokenValue: token.value
@@ -108,7 +108,7 @@ module.exports = {
function reportRequiredBeginningSpace(node, token) {
context.report({
node,
- loc: token.loc.start,
+ loc: token.loc,
messageId: "missingSpaceAfter",
data: {
tokenValue: token.value
@@ -128,7 +128,7 @@ module.exports = {
function reportRequiredEndingSpace(node, token) {
context.report({
node,
- loc: token.loc.start,
+ loc: token.loc,
messageId: "missingSpaceBefore",
data: {
tokenValue: token.value
diff --git a/tools/node_modules/eslint/lib/rules/consistent-this.js b/tools/node_modules/eslint/lib/rules/consistent-this.js
index 16f53b5374cd24..e5bc9678daef3c 100644
--- a/tools/node_modules/eslint/lib/rules/consistent-this.js
+++ b/tools/node_modules/eslint/lib/rules/consistent-this.js
@@ -114,7 +114,7 @@ module.exports = {
}
/**
- * Check each alias to ensure that is was assinged to the correct value.
+ * Check each alias to ensure that is was assigned to the correct value.
* @returns {void}
*/
function ensureWasAssigned() {
diff --git a/tools/node_modules/eslint/lib/rules/curly.js b/tools/node_modules/eslint/lib/rules/curly.js
index ee2fe4dceb82bf..29f00c0ad0b617 100644
--- a/tools/node_modules/eslint/lib/rules/curly.js
+++ b/tools/node_modules/eslint/lib/rules/curly.js
@@ -141,33 +141,14 @@ module.exports = {
}
/**
- * Checks a given IfStatement node requires braces of the consequent chunk.
- * This returns `true` when below:
- *
- * 1. The given node has the `alternate` node.
- * 2. There is a `IfStatement` which doesn't have `alternate` node in the
- * trailing statement chain of the `consequent` node.
- * @param {ASTNode} node A IfStatement node to check.
- * @returns {boolean} `true` if the node requires braces of the consequent chunk.
+ * 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 requiresBraceOfConsequent(node) {
- if (node.alternate && node.consequent.type === "BlockStatement") {
- if (node.consequent.body.length >= 2) {
- return true;
- }
-
- for (
- let currentNode = node.consequent.body[0];
- currentNode;
- currentNode = astUtils.getTrailingStatement(currentNode)
- ) {
- if (currentNode.type === "IfStatement" && !currentNode.alternate) {
- return true;
- }
- }
- }
+ function isFollowedByElseKeyword(node) {
+ const nextToken = sourceCode.getTokenAfter(node);
- return false;
+ return Boolean(nextToken) && isElseKeywordToken(nextToken);
}
/**
@@ -224,6 +205,110 @@ module.exports = {
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.
@@ -242,30 +327,29 @@ module.exports = {
const hasBlock = (body.type === "BlockStatement");
let expected = null;
- if (node.type === "IfStatement" && node.consequent === body && requiresBraceOfConsequent(node)) {
+ if (hasBlock && (body.body.length !== 1 || areBracesNecessary(body))) {
expected = true;
} else if (multiOnly) {
- if (hasBlock && body.body.length === 1 && !isLexicalDeclaration(body.body[0])) {
- expected = false;
- }
+ 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 && body.body.length === 1 && isOneLiner(body.body[0])) {
- const leadingComments = sourceCode.getCommentsBefore(body.body[0]);
- const isLexDef = isLexicalDeclaration(body.body[0]);
-
- if (isLexDef) {
- expected = true;
- } else {
- expected = leadingComments.length > 0;
- }
- } else if (!isOneLiner(body)) {
- expected = true;
+ 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;
}
diff --git a/tools/node_modules/eslint/lib/rules/default-case-last.js b/tools/node_modules/eslint/lib/rules/default-case-last.js
new file mode 100644
index 00000000000000..80c5d6bda73958
--- /dev/null
+++ b/tools/node_modules/eslint/lib/rules/default-case-last.js
@@ -0,0 +1,44 @@
+/**
+ * @fileoverview Rule to enforce default clauses in switch statements to be last
+ * @author Milos Djermanovic
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ type: "suggestion",
+
+ docs: {
+ description: "enforce default clauses in switch statements to be last",
+ category: "Best Practices",
+ recommended: false,
+ url: "https://eslint.org/docs/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" });
+ }
+ }
+ };
+ }
+};
diff --git a/tools/node_modules/eslint/lib/rules/func-names.js b/tools/node_modules/eslint/lib/rules/func-names.js
index 1341d03630823f..ecfedb9e0e99c7 100644
--- a/tools/node_modules/eslint/lib/rules/func-names.js
+++ b/tools/node_modules/eslint/lib/rules/func-names.js
@@ -119,8 +119,7 @@ module.exports = {
(parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === node) ||
(parent.type === "Property" && parent.value === node) ||
(parent.type === "AssignmentExpression" && parent.left.type === "Identifier" && parent.right === node) ||
- (parent.type === "ExportDefaultDeclaration" && parent.declaration === node) ||
- (parent.type === "AssignmentPattern" && parent.right === node);
+ (parent.type === "AssignmentPattern" && parent.left.type === "Identifier" && parent.right === node);
}
/**
@@ -151,33 +150,41 @@ module.exports = {
});
}
- return {
- "FunctionExpression:exit"(node) {
+ /**
+ * The listener for function nodes.
+ * @param {ASTNode} node function node
+ * @returns {void}
+ */
+ function handleFunction(node) {
- // Skip recursive functions.
- const nameVar = context.getDeclaredVariables(node)[0];
+ // Skip recursive functions.
+ const nameVar = context.getDeclaredVariables(node)[0];
- if (isFunctionName(nameVar) && nameVar.references.length > 0) {
- return;
- }
+ 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) {
- reportUnexpectedNamedFunction(node);
- }
- } else if (config === "as-needed") {
- if (!hasName && !hasInferredName(node)) {
- reportUnexpectedUnnamedFunction(node);
- }
- } else {
- if (!hasName && !isObjectOrClassMethod(node)) {
- reportUnexpectedUnnamedFunction(node);
- }
+ 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
};
}
};
diff --git a/tools/node_modules/eslint/lib/rules/id-blacklist.js b/tools/node_modules/eslint/lib/rules/id-blacklist.js
index 53be62e68a3626..ddff9363aee8a8 100644
--- a/tools/node_modules/eslint/lib/rules/id-blacklist.js
+++ b/tools/node_modules/eslint/lib/rules/id-blacklist.js
@@ -41,6 +41,7 @@ module.exports = {
//--------------------------------------------------------------------------
const blacklist = context.options;
+ const reportedNodes = new Set();
/**
@@ -54,16 +55,69 @@ module.exports = {
}
/**
- * Verifies if we should report an error or not based on the effective
- * parent node and the identifier name.
- * @param {ASTNode} effectiveParent The effective parent node of the node to be reported
- * @param {string} name The identifier name of the identifier 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
+ )
+ );
+ }
+
+ /**
+ * Verifies if we should report an error or not.
+ * @param {ASTNode} node The node to check
* @returns {boolean} whether an error should be reported or not
*/
- function shouldReport(effectiveParent, name) {
- return effectiveParent.type !== "CallExpression" &&
- effectiveParent.type !== "NewExpression" &&
- isInvalid(name);
+ function shouldReport(node) {
+ const parent = node.parent;
+
+ return (
+ parent.type !== "CallExpression" &&
+ parent.type !== "NewExpression" &&
+ !isRenamedImport(node) &&
+ !isRenamedInDestructuring(node) &&
+ isInvalid(node.name)
+ );
}
/**
@@ -73,50 +127,63 @@ module.exports = {
* @private
*/
function report(node) {
- context.report({
- node,
- messageId: "blacklisted",
- data: {
- name: node.name
- }
- });
+ if (!reportedNodes.has(node)) {
+ context.report({
+ node,
+ messageId: "blacklisted",
+ data: {
+ name: node.name
+ }
+ });
+ reportedNodes.add(node);
+ }
}
return {
Identifier(node) {
- const name = node.name,
- effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent;
// MemberExpressions get special rules
if (node.parent.type === "MemberExpression") {
+ const name = node.name,
+ effectiveParent = node.parent.parent;
// Always check object names
if (node.parent.object.type === "Identifier" &&
- node.parent.object.name === node.name) {
+ node.parent.object.name === name) {
if (isInvalid(name)) {
report(node);
}
- // Report AssignmentExpressions only if they are the left side of the assignment
+ // Report AssignmentExpressions only if they are the left side of the assignment
} else if (effectiveParent.type === "AssignmentExpression" &&
(effectiveParent.right.type !== "MemberExpression" ||
- effectiveParent.left.type === "MemberExpression" &&
- effectiveParent.left.property.name === node.name)) {
+ effectiveParent.left.type === "MemberExpression" &&
+ effectiveParent.left.property.name === name)) {
if (isInvalid(name)) {
report(node);
}
- }
- // Properties have their own rules
- } else if (node.parent.type === "Property") {
-
- if (shouldReport(effectiveParent, name)) {
- report(node);
+ // Report the last identifier in an ObjectPattern destructuring.
+ } else if (
+ (
+ effectiveParent.type === "Property" &&
+ effectiveParent.value === node.parent &&
+ effectiveParent.parent.type === "ObjectPattern"
+ ) ||
+ effectiveParent.type === "RestElement" ||
+ effectiveParent.type === "ArrayPattern" ||
+ (
+ effectiveParent.type === "AssignmentPattern" &&
+ effectiveParent.left === node.parent
+ )
+ ) {
+ if (isInvalid(name)) {
+ report(node);
+ }
}
- // Report anything that is a match and not a CallExpression
- } else if (shouldReport(effectiveParent, name)) {
+ } else if (shouldReport(node)) {
report(node);
}
}
diff --git a/tools/node_modules/eslint/lib/rules/id-length.js b/tools/node_modules/eslint/lib/rules/id-length.js
index c8586ea3481895..a68873ac06289b 100644
--- a/tools/node_modules/eslint/lib/rules/id-length.js
+++ b/tools/node_modules/eslint/lib/rules/id-length.js
@@ -63,6 +63,7 @@ module.exports = {
return obj;
}, {});
+ const reportedNode = new Set();
const SUPPORTED_EXPRESSIONS = {
MemberExpression: properties && function(parent) {
@@ -82,8 +83,15 @@ module.exports = {
VariableDeclarator(parent, node) {
return parent.id === node;
},
- Property: properties && function(parent, node) {
- return parent.key === node;
+ Property(parent, node) {
+
+ if (parent.parent.type === "ObjectPattern") {
+ return (
+ parent.value !== parent.key && parent.value === node ||
+ parent.value === parent.key && parent.key === node && properties
+ );
+ }
+ return properties && !parent.computed && parent.key === node;
},
ImportDefaultSpecifier: true,
RestElement: true,
@@ -92,7 +100,8 @@ module.exports = {
ClassDeclaration: true,
FunctionDeclaration: true,
MethodDefinition: true,
- CatchClause: true
+ CatchClause: true,
+ ArrayPattern: true
};
return {
@@ -109,7 +118,8 @@ module.exports = {
const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type];
- if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) {
+ if (isValidExpression && !reportedNode.has(node) && (isValidExpression === true || isValidExpression(parent, node))) {
+ reportedNode.add(node);
context.report({
node,
messageId: isShort ? "tooShort" : "tooLong",
diff --git a/tools/node_modules/eslint/lib/rules/indent-legacy.js b/tools/node_modules/eslint/lib/rules/indent-legacy.js
index f1c024c368475d..50010d3f7acb16 100644
--- a/tools/node_modules/eslint/lib/rules/indent-legacy.js
+++ b/tools/node_modules/eslint/lib/rules/indent-legacy.js
@@ -696,20 +696,6 @@ module.exports = {
return startLine === endLine;
}
- /**
- * Check to see if the first element inside an array is an object and on the same line as the node
- * If the node is not an array then it will return false.
- * @param {ASTNode} node node to check
- * @returns {boolean} success/failure
- */
- function isFirstArrayElementOnSameLine(node) {
- if (node.type === "ArrayExpression" && node.elements[0]) {
- return node.elements[0].loc.start.line === node.loc.start.line && node.elements[0].type === "ObjectExpression";
- }
- return false;
-
- }
-
/**
* Check indent for array block content or object block content
* @param {ASTNode} node node to examine
@@ -776,8 +762,6 @@ module.exports = {
nodeIndent += indentSize;
}
}
- } else if (!parentVarNode && !isFirstArrayElementOnSameLine(parent) && parent.type !== "MemberExpression" && parent.type !== "ExpressionStatement" && parent.type !== "AssignmentExpression" && parent.type !== "Property") {
- nodeIndent += indentSize;
}
checkFirstNodeLineIndent(node, nodeIndent);
diff --git a/tools/node_modules/eslint/lib/rules/indent.js b/tools/node_modules/eslint/lib/rules/indent.js
index 694cf7d9e6ed4f..d576fde0382461 100644
--- a/tools/node_modules/eslint/lib/rules/indent.js
+++ b/tools/node_modules/eslint/lib/rules/indent.js
@@ -540,8 +540,15 @@ module.exports = {
]
},
outerIIFEBody: {
- type: "integer",
- minimum: 0
+ oneOf: [
+ {
+ type: "integer",
+ minimum: 0
+ },
+ {
+ enum: ["off"]
+ }
+ ]
},
MemberExpression: {
oneOf: [
@@ -590,6 +597,10 @@ module.exports = {
type: "boolean",
default: false
},
+ offsetTernaryExpressions: {
+ type: "boolean",
+ default: false
+ },
ignoredNodes: {
type: "array",
items: {
@@ -922,7 +933,11 @@ module.exports = {
parameterParens.add(openingParen);
parameterParens.add(closingParen);
- offsets.setDesiredOffset(openingParen, sourceCode.getTokenBefore(openingParen), 0);
+
+ const offsetAfterToken = node.callee.type === "TaggedTemplateExpression" ? sourceCode.getFirstToken(node.callee.quasi) : openingParen;
+ const offsetToken = sourceCode.getTokenBefore(offsetAfterToken);
+
+ offsets.setDesiredOffset(openingParen, offsetToken, 0);
addElementListIndent(node.arguments, openingParen, closingParen, options.CallExpression.arguments);
}
@@ -1088,7 +1103,6 @@ module.exports = {
},
"BlockStatement, ClassBody"(node) {
-
let blockIndentLevel;
if (node.parent && isOuterIIFE(node.parent)) {
@@ -1108,6 +1122,7 @@ module.exports = {
if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
offsets.setDesiredOffset(sourceCode.getFirstToken(node), sourceCode.getFirstToken(node.parent), 0);
}
+
addElementListIndent(node.body, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), blockIndentLevel);
},
@@ -1142,7 +1157,8 @@ module.exports = {
offsets.setDesiredOffset(questionMarkToken, firstToken, 1);
offsets.setDesiredOffset(colonToken, firstToken, 1);
- offsets.setDesiredOffset(firstConsequentToken, firstToken, 1);
+ offsets.setDesiredOffset(firstConsequentToken, firstToken,
+ options.offsetTernaryExpressions ? 2 : 1);
/*
* The alternate and the consequent should usually have the same indentation.
@@ -1167,7 +1183,9 @@ module.exports = {
* If `baz` were aligned with `bar` rather than being offset by 1 from `foo`, `baz` would end up
* having no expected indentation.
*/
- offsets.setDesiredOffset(firstAlternateToken, firstToken, 1);
+ offsets.setDesiredOffset(firstAlternateToken, firstToken,
+ firstAlternateToken.type === "Punctuator" &&
+ options.offsetTernaryExpressions ? 2 : 1);
}
}
},
diff --git a/tools/node_modules/eslint/lib/rules/index.js b/tools/node_modules/eslint/lib/rules/index.js
index d3fbe412080360..7f563eb2ebfb96 100644
--- a/tools/node_modules/eslint/lib/rules/index.js
+++ b/tools/node_modules/eslint/lib/rules/index.js
@@ -37,6 +37,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
"constructor-super": () => require("./constructor-super"),
curly: () => require("./curly"),
"default-case": () => require("./default-case"),
+ "default-case-last": () => require("./default-case-last"),
"default-param-last": () => require("./default-param-last"),
"dot-location": () => require("./dot-location"),
"dot-notation": () => require("./dot-notation"),
@@ -178,6 +179,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
"no-prototype-builtins": () => require("./no-prototype-builtins"),
"no-redeclare": () => require("./no-redeclare"),
"no-regex-spaces": () => require("./no-regex-spaces"),
+ "no-restricted-exports": () => require("./no-restricted-exports"),
"no-restricted-globals": () => require("./no-restricted-globals"),
"no-restricted-imports": () => require("./no-restricted-imports"),
"no-restricted-modules": () => require("./no-restricted-modules"),
@@ -215,6 +217,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
"no-unused-labels": () => require("./no-unused-labels"),
"no-unused-vars": () => require("./no-unused-vars"),
"no-use-before-define": () => require("./no-use-before-define"),
+ "no-useless-backreference": () => require("./no-useless-backreference"),
"no-useless-call": () => require("./no-useless-call"),
"no-useless-catch": () => require("./no-useless-catch"),
"no-useless-computed-key": () => require("./no-useless-computed-key"),
diff --git a/tools/node_modules/eslint/lib/rules/key-spacing.js b/tools/node_modules/eslint/lib/rules/key-spacing.js
index 6d1b9121c78c5f..c405043794c7d1 100644
--- a/tools/node_modules/eslint/lib/rules/key-spacing.js
+++ b/tools/node_modules/eslint/lib/rules/key-spacing.js
@@ -414,8 +414,7 @@ module.exports = {
if (property.computed) {
return sourceCode.getText().slice(key.range[0], key.range[1]);
}
-
- return property.key.name || property.key.value;
+ return astUtils.getStaticPropertyName(property);
}
/**
diff --git a/tools/node_modules/eslint/lib/rules/linebreak-style.js b/tools/node_modules/eslint/lib/rules/linebreak-style.js
index 97d552ea07c966..078eaf2cd268d2 100644
--- a/tools/node_modules/eslint/lib/rules/linebreak-style.js
+++ b/tools/node_modules/eslint/lib/rules/linebreak-style.js
@@ -64,7 +64,7 @@ module.exports = {
//--------------------------------------------------------------------------
return {
- Program: function checkForlinebreakStyle(node) {
+ Program: function checkForLinebreakStyle(node) {
const linebreakStyle = context.options[0] || "unix",
expectedLF = linebreakStyle === "unix",
expectedLFChars = expectedLF ? "\n" : "\r\n",
diff --git a/tools/node_modules/eslint/lib/rules/max-len.js b/tools/node_modules/eslint/lib/rules/max-len.js
index b29099ed4c4f09..995e0c52026385 100644
--- a/tools/node_modules/eslint/lib/rules/max-len.js
+++ b/tools/node_modules/eslint/lib/rules/max-len.js
@@ -183,12 +183,27 @@ module.exports = {
(end.line > lineNumber || (end.line === lineNumber && end.column === line.length));
}
+ /**
+ * Check if a node is a JSXEmptyExpression contained in a single line JSXExpressionContainer.
+ * @param {ASTNode} node A node to check.
+ * @returns {boolean} True if the node is a JSXEmptyExpression contained in a single line JSXExpressionContainer.
+ */
+ function isJSXEmptyExpressionInSingleLineContainer(node) {
+ if (!node || !node.parent || node.type !== "JSXEmptyExpression" || node.parent.type !== "JSXExpressionContainer") {
+ return false;
+ }
+
+ const parent = node.parent;
+
+ return parent.loc.start.line === parent.loc.end.line;
+ }
+
/**
* Gets the line after the comment and any remaining trailing whitespace is
* stripped.
* @param {string} line The source line with a trailing comment
* @param {ASTNode} comment The comment to remove
- * @returns {string} Line without comment and trailing whitepace
+ * @returns {string} Line without comment and trailing whitespace
*/
function stripTrailingComment(line, comment) {
@@ -252,6 +267,33 @@ module.exports = {
return acc;
}
+ /**
+ * Returns an array of all comments in the source code.
+ * If the element in the array is a JSXEmptyExpression contained with a single line JSXExpressionContainer,
+ * the element is changed with JSXExpressionContainer node.
+ * @returns {ASTNode[]} An array of comment nodes
+ */
+ function getAllComments() {
+ const comments = [];
+
+ sourceCode.getAllComments()
+ .forEach(commentNode => {
+ const containingNode = sourceCode.getNodeByRangeIndex(commentNode.range[0]);
+
+ if (isJSXEmptyExpressionInSingleLineContainer(containingNode)) {
+
+ // push a unique node only
+ if (comments[comments.length - 1] !== containingNode.parent) {
+ comments.push(containingNode.parent);
+ }
+ } else {
+ comments.push(commentNode);
+ }
+ });
+
+ return comments;
+ }
+
/**
* Check the program for max length
* @param {ASTNode} node Node to examine
@@ -264,7 +306,7 @@ module.exports = {
const lines = sourceCode.lines,
// list of comments to ignore
- comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? sourceCode.getAllComments() : [];
+ comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? getAllComments() : [];
// we iterate over comments in parallel with the lines
let commentsIndex = 0;
diff --git a/tools/node_modules/eslint/lib/rules/max-lines-per-function.js b/tools/node_modules/eslint/lib/rules/max-lines-per-function.js
index 0cfc1f8da9e65e..03539fae470078 100644
--- a/tools/node_modules/eslint/lib/rules/max-lines-per-function.js
+++ b/tools/node_modules/eslint/lib/rules/max-lines-per-function.js
@@ -54,9 +54,6 @@ const OPTIONS_OR_INTEGER_SCHEMA = {
function getCommentLineNumbers(comments) {
const map = new Map();
- if (!comments) {
- return map;
- }
comments.forEach(comment => {
for (let i = comment.loc.start.line; i <= comment.loc.end.line; i++) {
map.set(i, comment);
diff --git a/tools/node_modules/eslint/lib/rules/multiline-comment-style.js b/tools/node_modules/eslint/lib/rules/multiline-comment-style.js
index fb50e1522ea11d..9524818b8bd74d 100644
--- a/tools/node_modules/eslint/lib/rules/multiline-comment-style.js
+++ b/tools/node_modules/eslint/lib/rules/multiline-comment-style.js
@@ -316,6 +316,10 @@ module.exports = {
const [, prefix = "", initialOffset = ""] = lineTextToAlignWith.match(/^(\s*(?:\/?\*)?(\s*))/u) || [];
offset = `${commentTextPrefix.slice(prefix.length)}${initialOffset}`;
+
+ if (/^\s*\//u.test(lineText) && offset.length === 0) {
+ offset += " ";
+ }
break;
}
diff --git a/tools/node_modules/eslint/lib/rules/new-cap.js b/tools/node_modules/eslint/lib/rules/new-cap.js
index cee979310ea7cc..7cce968c5aed0e 100644
--- a/tools/node_modules/eslint/lib/rules/new-cap.js
+++ b/tools/node_modules/eslint/lib/rules/new-cap.js
@@ -9,6 +9,8 @@
// Requirements
//------------------------------------------------------------------------------
+const astUtils = require("./utils/ast-utils");
+
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
@@ -160,13 +162,7 @@ module.exports = {
let name = "";
if (node.callee.type === "MemberExpression") {
- const property = node.callee.property;
-
- if (property.type === "Literal" && (typeof property.value === "string")) {
- name = property.value;
- } else if (property.type === "Identifier" && !node.callee.computed) {
- name = property.name;
- }
+ name = astUtils.getStaticPropertyName(node.callee) || "";
} else {
name = node.callee.name;
}
diff --git a/tools/node_modules/eslint/lib/rules/no-confusing-arrow.js b/tools/node_modules/eslint/lib/rules/no-confusing-arrow.js
index b9a0e6ed0a70b5..9009b64fa1559a 100644
--- a/tools/node_modules/eslint/lib/rules/no-confusing-arrow.js
+++ b/tools/node_modules/eslint/lib/rules/no-confusing-arrow.js
@@ -1,6 +1,6 @@
/**
* @fileoverview A rule to warn against using arrow functions when they could be
- * confused with comparisions
+ * confused with comparisons
* @author Jxck
*/
@@ -71,7 +71,7 @@ module.exports = {
messageId: "confusing",
fix(fixer) {
- // if `allowParens` is not set to true dont bother wrapping in parens
+ // if `allowParens` is not set to true don't bother wrapping in parens
return allowParens && fixer.replaceText(node.body, `(${sourceCode.getText(node.body)})`);
}
});
diff --git a/tools/node_modules/eslint/lib/rules/no-constant-condition.js b/tools/node_modules/eslint/lib/rules/no-constant-condition.js
index d6d04174298cff..5e5838641028fe 100644
--- a/tools/node_modules/eslint/lib/rules/no-constant-condition.js
+++ b/tools/node_modules/eslint/lib/rules/no-constant-condition.js
@@ -90,13 +90,27 @@ module.exports = {
* @private
*/
function isConstant(node, inBooleanPosition) {
+
+ // node.elements can return null values in the case of sparse arrays ex. [,]
+ if (!node) {
+ return true;
+ }
switch (node.type) {
case "Literal":
case "ArrowFunctionExpression":
case "FunctionExpression":
case "ObjectExpression":
- case "ArrayExpression":
return true;
+ case "TemplateLiteral":
+ return (inBooleanPosition && node.quasis.some(quasi => quasi.value.cooked.length)) ||
+ node.expressions.every(exp => isConstant(exp, inBooleanPosition));
+
+ case "ArrayExpression": {
+ if (node.parent.type === "BinaryExpression" && node.parent.operator === "+") {
+ return node.elements.every(element => isConstant(element, false));
+ }
+ return true;
+ }
case "UnaryExpression":
if (node.operator === "void") {
diff --git a/tools/node_modules/eslint/lib/rules/no-control-regex.js b/tools/node_modules/eslint/lib/rules/no-control-regex.js
index 24e6b197be0b44..b39f731c3cdf29 100644
--- a/tools/node_modules/eslint/lib/rules/no-control-regex.js
+++ b/tools/node_modules/eslint/lib/rules/no-control-regex.js
@@ -1,5 +1,5 @@
/**
- * @fileoverview Rule to forbid control charactes from regular expressions.
+ * @fileoverview Rule to forbid control characters from regular expressions.
* @author Nicholas C. Zakas
*/
diff --git a/tools/node_modules/eslint/lib/rules/no-dupe-class-members.js b/tools/node_modules/eslint/lib/rules/no-dupe-class-members.js
index 6041e9e371ce5e..b12939d57bc884 100644
--- a/tools/node_modules/eslint/lib/rules/no-dupe-class-members.js
+++ b/tools/node_modules/eslint/lib/rules/no-dupe-class-members.js
@@ -5,6 +5,8 @@
"use strict";
+const astUtils = require("./utils/ast-utils");
+
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -53,21 +55,6 @@ module.exports = {
return stateMap[key][isStatic ? "static" : "nonStatic"];
}
- /**
- * Gets the name text of a given node.
- * @param {ASTNode} node A node to get the name.
- * @returns {string} The name text of the node.
- */
- function getName(node) {
- switch (node.type) {
- case "Identifier": return node.name;
- case "Literal": return String(node.value);
-
- /* istanbul ignore next: syntax error */
- default: return "";
- }
- }
-
return {
// Initializes the stack of state of member declarations.
@@ -87,11 +74,12 @@ module.exports = {
// Reports the node if its name has been declared already.
MethodDefinition(node) {
- if (node.computed) {
+ const name = astUtils.getStaticPropertyName(node);
+
+ if (name === null || node.kind === "constructor") {
return;
}
- const name = getName(node.key);
const state = getState(name, node.static);
let isDuplicate = false;
diff --git a/tools/node_modules/eslint/lib/rules/no-dupe-else-if.js b/tools/node_modules/eslint/lib/rules/no-dupe-else-if.js
index a165e16607d2f0..cbeb437da1e7ec 100644
--- a/tools/node_modules/eslint/lib/rules/no-dupe-else-if.js
+++ b/tools/node_modules/eslint/lib/rules/no-dupe-else-if.js
@@ -53,7 +53,7 @@ module.exports = {
docs: {
description: "disallow duplicate conditions in if-else-if chains",
category: "Possible Errors",
- recommended: false,
+ recommended: true,
url: "https://eslint.org/docs/rules/no-dupe-else-if"
},
diff --git a/tools/node_modules/eslint/lib/rules/no-eval.js b/tools/node_modules/eslint/lib/rules/no-eval.js
index 9e56fb00b9fc5b..a293b04aa37de2 100644
--- a/tools/node_modules/eslint/lib/rules/no-eval.js
+++ b/tools/node_modules/eslint/lib/rules/no-eval.js
@@ -158,7 +158,7 @@ module.exports = {
context.report({
node: reportNode,
- loc: locationNode.loc.start,
+ loc: locationNode.loc,
messageId: "unexpected"
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-extra-boolean-cast.js b/tools/node_modules/eslint/lib/rules/no-extra-boolean-cast.js
index 336f601d1652de..8ccd0bce9060b1 100644
--- a/tools/node_modules/eslint/lib/rules/no-extra-boolean-cast.js
+++ b/tools/node_modules/eslint/lib/rules/no-extra-boolean-cast.js
@@ -26,7 +26,16 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-extra-boolean-cast"
},
- schema: [],
+ schema: [{
+ type: "object",
+ properties: {
+ enforceForLogicalOperands: {
+ type: "boolean",
+ default: false
+ }
+ },
+ additionalProperties: false
+ }],
fixable: "code",
messages: {
@@ -47,23 +56,67 @@ module.exports = {
"ForStatement"
];
+ /**
+ * Check if a node is a Boolean function or constructor.
+ * @param {ASTNode} node the node
+ * @returns {boolean} If the node is Boolean function or constructor
+ */
+ function isBooleanFunctionOrConstructorCall(node) {
+
+ // Boolean() and new Boolean()
+ return (node.type === "CallExpression" || node.type === "NewExpression") &&
+ node.callee.type === "Identifier" &&
+ node.callee.name === "Boolean";
+ }
+
+ /**
+ * Checks whether the node is a logical expression and that the option is enabled
+ * @param {ASTNode} node the node
+ * @returns {boolean} if the node is a logical expression and option is enabled
+ */
+ function isLogicalContext(node) {
+ return node.type === "LogicalExpression" &&
+ (node.operator === "||" || node.operator === "&&") &&
+ (context.options.length && context.options[0].enforceForLogicalOperands === true);
+
+ }
+
+
/**
* Check if a node is in a context where its value would be coerced to a boolean at runtime.
* @param {ASTNode} node The node
- * @param {ASTNode} parent Its parent
* @returns {boolean} If it is in a boolean context
*/
- function isInBooleanContext(node, parent) {
+ function isInBooleanContext(node) {
return (
- (BOOLEAN_NODE_TYPES.indexOf(parent.type) !== -1 &&
- node === parent.test) ||
+ (isBooleanFunctionOrConstructorCall(node.parent) &&
+ node === node.parent.arguments[0]) ||
+
+ (BOOLEAN_NODE_TYPES.indexOf(node.parent.type) !== -1 &&
+ node === node.parent.test) ||
// !
- (parent.type === "UnaryExpression" &&
- parent.operator === "!")
+ (node.parent.type === "UnaryExpression" &&
+ node.parent.operator === "!")
+ );
+ }
+
+ /**
+ * Checks whether the node is a context that should report an error
+ * Acts recursively if it is in a logical context
+ * @param {ASTNode} node the node
+ * @returns {boolean} If the node is in one of the flagged contexts
+ */
+ function isInFlaggedContext(node) {
+ return isInBooleanContext(node) ||
+ (isLogicalContext(node.parent) &&
+
+ // For nested logical statements
+ isInFlaggedContext(node.parent)
);
}
+
/**
* Check if a node has comments inside.
* @param {ASTNode} node The node to check.
@@ -75,24 +128,18 @@ module.exports = {
return {
UnaryExpression(node) {
- const ancestors = context.getAncestors(),
- parent = ancestors.pop(),
- grandparent = ancestors.pop();
+ const parent = node.parent;
+
// Exit early if it's guaranteed not to match
if (node.operator !== "!" ||
- parent.type !== "UnaryExpression" ||
- parent.operator !== "!") {
+ parent.type !== "UnaryExpression" ||
+ parent.operator !== "!") {
return;
}
- if (isInBooleanContext(parent, grandparent) ||
- // Boolean() and new Boolean()
- ((grandparent.type === "CallExpression" || grandparent.type === "NewExpression") &&
- grandparent.callee.type === "Identifier" &&
- grandparent.callee.name === "Boolean")
- ) {
+ if (isInFlaggedContext(parent)) {
context.report({
node: parent,
messageId: "unexpectedNegation",
@@ -110,6 +157,10 @@ module.exports = {
prefix = " ";
}
+ if (astUtils.getPrecedence(node.argument) < astUtils.getPrecedence(parent.parent)) {
+ return fixer.replaceText(parent, `(${sourceCode.getText(node.argument)})`);
+ }
+
return fixer.replaceText(parent, prefix + sourceCode.getText(node.argument));
}
});
@@ -122,7 +173,7 @@ module.exports = {
return;
}
- if (isInBooleanContext(node, parent)) {
+ if (isInFlaggedContext(node)) {
context.report({
node,
messageId: "unexpectedCall",
diff --git a/tools/node_modules/eslint/lib/rules/no-extra-parens.js b/tools/node_modules/eslint/lib/rules/no-extra-parens.js
index f96e572bfeef54..a5488c3c1c6aa4 100644
--- a/tools/node_modules/eslint/lib/rules/no-extra-parens.js
+++ b/tools/node_modules/eslint/lib/rules/no-extra-parens.js
@@ -169,6 +169,28 @@ module.exports = {
return ruleApplies(node) && isParenthesisedTwice(node);
}
+ /**
+ * Determines if a node that is expected to be parenthesised is surrounded by
+ * (potentially) invalid extra parentheses with considering precedence level of the node.
+ * If the preference level of the node is not higher or equal to precedence lower limit, it also checks
+ * whether the node is surrounded by parentheses twice or not.
+ * @param {ASTNode} node The node to be checked.
+ * @param {number} precedenceLowerLimit The lower limit of precedence.
+ * @returns {boolean} True if the node is has an unexpected extra pair of parentheses.
+ * @private
+ */
+ function hasExcessParensWithPrecedence(node, precedenceLowerLimit) {
+ if (ruleApplies(node) && isParenthesised(node)) {
+ if (
+ precedence(node) >= precedenceLowerLimit ||
+ isParenthesisedTwice(node)
+ ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Determines if a node test expression is allowed to have a parenthesised assignment
* @param {ASTNode} node The node to be checked.
@@ -320,6 +342,17 @@ module.exports = {
return node.type === "CallExpression" && node.callee.type === "FunctionExpression";
}
+ /**
+ * Determines if the given node can be the assignment target in destructuring or the LHS of an assignment.
+ * This is to avoid an autofix that could change behavior because parsers mistakenly allow invalid syntax,
+ * such as `(a = b) = c` and `[(a = b) = c] = []`. Ideally, this function shouldn't be necessary.
+ * @param {ASTNode} [node] The node to check
+ * @returns {boolean} `true` if the given node can be a valid assignment target
+ */
+ function canBeAssignmentTarget(node) {
+ return node && (node.type === "Identifier" || node.type === "MemberExpression");
+ }
+
/**
* Report the node
* @param {ASTNode} node node to evaluate
@@ -370,17 +403,13 @@ module.exports = {
}
/**
- * Evaluate Unary update
+ * Evaluate a argument of the node.
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
- function checkUnaryUpdate(node) {
- if (node.type === "UnaryExpression" && node.argument.type === "BinaryExpression" && node.argument.operator === "**") {
- return;
- }
-
- if (hasExcessParens(node.argument) && precedence(node.argument) >= precedence(node)) {
+ function checkArgumentWithPrecedence(node) {
+ if (hasExcessParensWithPrecedence(node.argument, precedence(node))) {
report(node.argument);
}
}
@@ -411,25 +440,24 @@ module.exports = {
function checkCallNew(node) {
const callee = node.callee;
- if (hasExcessParens(callee) && precedence(callee) >= precedence(node)) {
+ if (hasExcessParensWithPrecedence(callee, precedence(node))) {
const hasNewParensException = callee.type === "NewExpression" && !isNewExpressionWithParens(callee);
if (
hasDoubleExcessParens(callee) ||
!isIIFE(node) && !hasNewParensException && !(
- /*
- * Allow extra parens around a new expression if
- * there are intervening parentheses.
- */
- (callee.type === "MemberExpression" && doesMemberExpressionContainCallExpression(callee))
+ // Allow extra parens around a new expression if they are intervening parentheses.
+ node.type === "NewExpression" &&
+ callee.type === "MemberExpression" &&
+ doesMemberExpressionContainCallExpression(callee)
)
) {
report(node.callee);
}
}
node.arguments
- .filter(arg => hasExcessParens(arg) && precedence(arg) >= PRECEDENCE_OF_ASSIGNMENT_EXPR)
+ .filter(arg => hasExcessParensWithPrecedence(arg, PRECEDENCE_OF_ASSIGNMENT_EXPR))
.forEach(report);
}
@@ -444,15 +472,26 @@ module.exports = {
const leftPrecedence = precedence(node.left);
const rightPrecedence = precedence(node.right);
const isExponentiation = node.operator === "**";
- const shouldSkipLeft = (NESTED_BINARY && (node.left.type === "BinaryExpression" || node.left.type === "LogicalExpression")) ||
- node.left.type === "UnaryExpression" && isExponentiation;
+ const shouldSkipLeft = NESTED_BINARY && (node.left.type === "BinaryExpression" || node.left.type === "LogicalExpression");
const shouldSkipRight = NESTED_BINARY && (node.right.type === "BinaryExpression" || node.right.type === "LogicalExpression");
- if (!shouldSkipLeft && hasExcessParens(node.left) && (leftPrecedence > prec || (leftPrecedence === prec && !isExponentiation))) {
- report(node.left);
+ if (!shouldSkipLeft && hasExcessParens(node.left)) {
+ if (
+ !(node.left.type === "UnaryExpression" && isExponentiation) &&
+ (leftPrecedence > prec || (leftPrecedence === prec && !isExponentiation)) ||
+ isParenthesisedTwice(node.left)
+ ) {
+ report(node.left);
+ }
}
- if (!shouldSkipRight && hasExcessParens(node.right) && (rightPrecedence > prec || (rightPrecedence === prec && isExponentiation))) {
- report(node.right);
+
+ if (!shouldSkipRight && hasExcessParens(node.right)) {
+ if (
+ (rightPrecedence > prec || (rightPrecedence === prec && isExponentiation)) ||
+ isParenthesisedTwice(node.right)
+ ) {
+ report(node.right);
+ }
}
}
@@ -485,11 +524,7 @@ module.exports = {
* @returns {void}
*/
function checkSpreadOperator(node) {
- const hasExtraParens = precedence(node.argument) >= PRECEDENCE_OF_ASSIGNMENT_EXPR
- ? hasExcessParens(node.argument)
- : hasDoubleExcessParens(node.argument);
-
- if (hasExtraParens) {
+ if (hasExcessParensWithPrecedence(node.argument, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.argument);
}
}
@@ -651,7 +686,13 @@ module.exports = {
return {
ArrayExpression(node) {
node.elements
- .filter(e => e && hasExcessParens(e) && precedence(e) >= PRECEDENCE_OF_ASSIGNMENT_EXPR)
+ .filter(e => e && hasExcessParensWithPrecedence(e, PRECEDENCE_OF_ASSIGNMENT_EXPR))
+ .forEach(report);
+ },
+
+ ArrayPattern(node) {
+ node.elements
+ .filter(e => canBeAssignmentTarget(e) && hasExcessParens(e))
.forEach(report);
},
@@ -661,8 +702,7 @@ module.exports = {
}
if (node.body.type === "ConditionalExpression" &&
- IGNORE_ARROW_CONDITIONALS &&
- !isParenthesisedTwice(node.body)
+ IGNORE_ARROW_CONDITIONALS
) {
return;
}
@@ -674,18 +714,18 @@ module.exports = {
if (astUtils.isOpeningParenToken(tokenBeforeFirst) && astUtils.isOpeningBraceToken(firstBodyToken)) {
tokensToIgnore.add(firstBodyToken);
}
- if (hasExcessParens(node.body) && precedence(node.body) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
+ if (hasExcessParensWithPrecedence(node.body, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.body);
}
}
},
AssignmentExpression(node) {
- if (isReturnAssignException(node)) {
- return;
+ if (canBeAssignmentTarget(node.left) && hasExcessParens(node.left)) {
+ report(node.left);
}
- if (hasExcessParens(node.right) && precedence(node.right) >= precedence(node)) {
+ if (!isReturnAssignException(node) && hasExcessParensWithPrecedence(node.right, precedence(node))) {
report(node.right);
}
},
@@ -702,8 +742,8 @@ module.exports = {
ClassBody(node) {
node.body
- .filter(member => member.type === "MethodDefinition" && member.computed &&
- member.key && hasExcessParens(member.key) && precedence(member.key) >= PRECEDENCE_OF_ASSIGNMENT_EXPR)
+ .filter(member => member.type === "MethodDefinition" && member.computed && member.key)
+ .filter(member => hasExcessParensWithPrecedence(member.key, PRECEDENCE_OF_ASSIGNMENT_EXPR))
.forEach(member => report(member.key));
},
@@ -711,16 +751,18 @@ module.exports = {
if (isReturnAssignException(node)) {
return;
}
-
- if (hasExcessParens(node.test) && precedence(node.test) >= precedence({ type: "LogicalExpression", operator: "||" })) {
+ if (
+ !isCondAssignException(node) &&
+ hasExcessParensWithPrecedence(node.test, precedence({ type: "LogicalExpression", operator: "||" }))
+ ) {
report(node.test);
}
- if (hasExcessParens(node.consequent) && precedence(node.consequent) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
+ if (hasExcessParensWithPrecedence(node.consequent, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.consequent);
}
- if (hasExcessParens(node.alternate) && precedence(node.alternate) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
+ if (hasExcessParensWithPrecedence(node.alternate, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(node.alternate);
}
},
@@ -757,9 +799,19 @@ module.exports = {
tokensToIgnore.add(firstLeftToken);
}
}
- if (!(node.type === "ForOfStatement" && node.right.type === "SequenceExpression") && hasExcessParens(node.right)) {
+
+ if (node.type === "ForOfStatement") {
+ const hasExtraParens = node.right.type === "SequenceExpression"
+ ? hasDoubleExcessParens(node.right)
+ : hasExcessParens(node.right);
+
+ if (hasExtraParens) {
+ report(node.right);
+ }
+ } else if (hasExcessParens(node.right)) {
report(node.right);
}
+
if (hasExcessParens(node.left)) {
report(node.left);
}
@@ -910,11 +962,17 @@ module.exports = {
NewExpression: checkCallNew,
ObjectExpression(node) {
+ node.properties
+ .filter(property => property.value && hasExcessParensWithPrecedence(property.value, PRECEDENCE_OF_ASSIGNMENT_EXPR))
+ .forEach(property => report(property.value));
+ },
+
+ ObjectPattern(node) {
node.properties
.filter(property => {
const value = property.value;
- return value && hasExcessParens(value) && precedence(value) >= PRECEDENCE_OF_ASSIGNMENT_EXPR;
+ return canBeAssignmentTarget(value) && hasExcessParens(value);
}).forEach(property => report(property.value));
},
@@ -922,12 +980,20 @@ module.exports = {
if (node.computed) {
const { key } = node;
- if (key && hasExcessParens(key) && precedence(key) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
+ if (key && hasExcessParensWithPrecedence(key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(key);
}
}
},
+ RestElement(node) {
+ const argument = node.argument;
+
+ if (canBeAssignmentTarget(argument) && hasExcessParens(argument)) {
+ report(argument);
+ }
+ },
+
ReturnStatement(node) {
const returnToken = sourceCode.getFirstToken(node);
@@ -945,8 +1011,10 @@ module.exports = {
},
SequenceExpression(node) {
+ const precedenceOfNode = precedence(node);
+
node.expressions
- .filter(e => hasExcessParens(e) && precedence(e) >= precedence(node))
+ .filter(e => hasExcessParensWithPrecedence(e, precedenceOfNode))
.forEach(report);
},
@@ -970,16 +1038,17 @@ module.exports = {
}
},
- UnaryExpression: checkUnaryUpdate,
- UpdateExpression: checkUnaryUpdate,
- AwaitExpression: checkUnaryUpdate,
+ UnaryExpression: checkArgumentWithPrecedence,
+ UpdateExpression: checkArgumentWithPrecedence,
+ AwaitExpression: checkArgumentWithPrecedence,
VariableDeclarator(node) {
- if (node.init && hasExcessParens(node.init) &&
- precedence(node.init) >= PRECEDENCE_OF_ASSIGNMENT_EXPR &&
+ if (
+ node.init && hasExcessParensWithPrecedence(node.init, PRECEDENCE_OF_ASSIGNMENT_EXPR) &&
- // RegExp literal is allowed to have parens (#1589)
- !(node.init.type === "Literal" && node.init.regex)) {
+ // RegExp literal is allowed to have parens (#1589)
+ !(node.init.type === "Literal" && node.init.regex)
+ ) {
report(node.init);
}
},
@@ -1022,9 +1091,13 @@ module.exports = {
},
AssignmentPattern(node) {
- const { right } = node;
+ const { left, right } = node;
+
+ if (canBeAssignmentTarget(left) && hasExcessParens(left)) {
+ report(left);
+ }
- if (right && hasExcessParens(right) && precedence(right) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
+ if (right && hasExcessParensWithPrecedence(right, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
report(right);
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-func-assign.js b/tools/node_modules/eslint/lib/rules/no-func-assign.js
index 66756e62bef5b2..33d0ad9ecd1433 100644
--- a/tools/node_modules/eslint/lib/rules/no-func-assign.js
+++ b/tools/node_modules/eslint/lib/rules/no-func-assign.js
@@ -22,7 +22,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-func-assign"
},
- schema: []
+ schema: [],
+
+ messages: {
+ isAFunction: "'{{name}}' is a function."
+ }
},
create(context) {
@@ -34,7 +38,13 @@ module.exports = {
*/
function checkReference(references) {
astUtils.getModifyingReferences(references).forEach(reference => {
- context.report({ node: reference.identifier, message: "'{{name}}' is a function.", data: { name: reference.identifier.name } });
+ context.report({
+ node: reference.identifier,
+ messageId: "isAFunction",
+ data: {
+ name: reference.identifier.name
+ }
+ });
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-global-assign.js b/tools/node_modules/eslint/lib/rules/no-global-assign.js
index 4ab0c706446256..ea854c4aa8cd9b 100644
--- a/tools/node_modules/eslint/lib/rules/no-global-assign.js
+++ b/tools/node_modules/eslint/lib/rules/no-global-assign.js
@@ -32,7 +32,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ globalShouldNotBeModified: "Read-only global '{{name}}' should not be modified."
+ }
},
create(context) {
@@ -60,8 +64,10 @@ module.exports = {
) {
context.report({
node: identifier,
- message: "Read-only global '{{name}}' should not be modified.",
- data: identifier
+ messageId: "globalShouldNotBeModified",
+ data: {
+ name: identifier.name
+ }
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-implicit-coercion.js b/tools/node_modules/eslint/lib/rules/no-implicit-coercion.js
index c80f9813020be5..6d5ee61e96bd5b 100644
--- a/tools/node_modules/eslint/lib/rules/no-implicit-coercion.js
+++ b/tools/node_modules/eslint/lib/rules/no-implicit-coercion.js
@@ -187,7 +187,11 @@ module.exports = {
}
},
additionalProperties: false
- }]
+ }],
+
+ messages: {
+ useRecommendation: "use `{{recommendation}}` instead."
+ }
},
create(context) {
@@ -204,7 +208,7 @@ module.exports = {
function report(node, recommendation, shouldFix) {
context.report({
node,
- message: "use `{{recommendation}}` instead.",
+ messageId: "useRecommendation",
data: {
recommendation
},
diff --git a/tools/node_modules/eslint/lib/rules/no-implied-eval.js b/tools/node_modules/eslint/lib/rules/no-implied-eval.js
index e0764d8223db0a..46bb5d4f76e5f7 100644
--- a/tools/node_modules/eslint/lib/rules/no-implied-eval.js
+++ b/tools/node_modules/eslint/lib/rules/no-implied-eval.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-implied-eval"
},
- schema: []
+ schema: [],
+
+ messages: {
+ impliedEval: "Implied eval. Consider passing a function instead of a string."
+ }
},
create(context) {
@@ -107,7 +111,10 @@ module.exports = {
// remove the entire substack, to avoid duplicate reports
const substack = impliedEvalAncestorsStack.pop();
- context.report({ node: substack[0], message: "Implied eval. Consider passing a function instead of a string." });
+ context.report({
+ node: substack[0],
+ messageId: "impliedEval"
+ });
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-import-assign.js b/tools/node_modules/eslint/lib/rules/no-import-assign.js
index 0865cf9a97704d..32e445ff68b3ef 100644
--- a/tools/node_modules/eslint/lib/rules/no-import-assign.js
+++ b/tools/node_modules/eslint/lib/rules/no-import-assign.js
@@ -180,7 +180,7 @@ module.exports = {
docs: {
description: "disallow assigning to imported bindings",
category: "Possible Errors",
- recommended: false,
+ recommended: true,
url: "https://eslint.org/docs/rules/no-import-assign"
},
diff --git a/tools/node_modules/eslint/lib/rules/no-inline-comments.js b/tools/node_modules/eslint/lib/rules/no-inline-comments.js
index bd226ecc35fde1..41b0f1e664c776 100644
--- a/tools/node_modules/eslint/lib/rules/no-inline-comments.js
+++ b/tools/node_modules/eslint/lib/rules/no-inline-comments.js
@@ -21,7 +21,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-inline-comments"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedInlineComment: "Unexpected comment inline with code."
+ }
},
create(context) {
@@ -64,7 +68,10 @@ module.exports = {
return;
}
- context.report({ node, message: "Unexpected comment inline with code." });
+ context.report({
+ node,
+ messageId: "unexpectedInlineComment"
+ });
}
//--------------------------------------------------------------------------
diff --git a/tools/node_modules/eslint/lib/rules/no-inner-declarations.js b/tools/node_modules/eslint/lib/rules/no-inner-declarations.js
index 60508d3e864eda..e1c29e0a3b4f3f 100644
--- a/tools/node_modules/eslint/lib/rules/no-inner-declarations.js
+++ b/tools/node_modules/eslint/lib/rules/no-inner-declarations.js
@@ -24,7 +24,11 @@ module.exports = {
{
enum: ["functions", "both"]
}
- ]
+ ],
+
+ messages: {
+ moveDeclToRoot: "Move {{type}} declaration to {{body}} root."
+ }
},
create(context) {
@@ -68,7 +72,7 @@ module.exports = {
if (!valid) {
context.report({
node,
- message: "Move {{type}} declaration to {{body}} root.",
+ messageId: "moveDeclToRoot",
data: {
type: (node.type === "FunctionDeclaration" ? "function" : "variable"),
body: (body.type === "Program" ? "program" : "function body")
diff --git a/tools/node_modules/eslint/lib/rules/no-invalid-regexp.js b/tools/node_modules/eslint/lib/rules/no-invalid-regexp.js
index 852efbbb935b90..c09e36fd017697 100644
--- a/tools/node_modules/eslint/lib/rules/no-invalid-regexp.js
+++ b/tools/node_modules/eslint/lib/rules/no-invalid-regexp.js
@@ -39,7 +39,11 @@ module.exports = {
}
},
additionalProperties: false
- }]
+ }],
+
+ messages: {
+ regexMessage: "{{message}}."
+ }
},
create(context) {
@@ -116,7 +120,7 @@ module.exports = {
if (message) {
context.report({
node,
- message: "{{message}}.",
+ messageId: "regexMessage",
data: { message }
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-invalid-this.js b/tools/node_modules/eslint/lib/rules/no-invalid-this.js
index 5398fc3b5f842c..a79c586d719852 100644
--- a/tools/node_modules/eslint/lib/rules/no-invalid-this.js
+++ b/tools/node_modules/eslint/lib/rules/no-invalid-this.js
@@ -37,7 +37,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unexpectedThis: "Unexpected 'this'."
+ }
},
create(context) {
@@ -130,7 +134,10 @@ module.exports = {
const current = stack.getCurrent();
if (current && !current.valid) {
- context.report({ node, message: "Unexpected 'this'." });
+ context.report({
+ node,
+ messageId: "unexpectedThis"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js b/tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js
index f339fa6c8f34c9..21842331f21ff0 100644
--- a/tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js
+++ b/tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js
@@ -1,5 +1,5 @@
/**
- * @fileoverview Rule to disalow whitespace that is not a tab or space, whitespace inside strings and comments are allowed
+ * @fileoverview Rule to disallow whitespace that is not a tab or space, whitespace inside strings and comments are allowed
* @author Jonathan Kingston
* @author Christophe Porteneuve
*/
@@ -59,7 +59,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ noIrregularWhitespace: "Irregular whitespace not allowed."
+ }
},
create(context) {
@@ -161,7 +165,11 @@ module.exports = {
column: match.index
};
- errors.push({ node, message: "Irregular whitespace not allowed.", loc: location });
+ errors.push({
+ node,
+ messageId: "noIrregularWhitespace",
+ loc: location
+ });
}
});
}
@@ -186,7 +194,11 @@ module.exports = {
column: sourceLines[lineIndex].length
};
- errors.push({ node, message: "Irregular whitespace not allowed.", loc: location });
+ errors.push({
+ node,
+ messageId: "noIrregularWhitespace",
+ loc: location
+ });
lastLineIndex = lineIndex;
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-iterator.js b/tools/node_modules/eslint/lib/rules/no-iterator.js
index 82319a3fb1dfb6..9ba1e7aefdbc3b 100644
--- a/tools/node_modules/eslint/lib/rules/no-iterator.js
+++ b/tools/node_modules/eslint/lib/rules/no-iterator.js
@@ -5,6 +5,12 @@
"use strict";
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const { getStaticPropertyName } = require("./utils/ast-utils");
+
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -20,7 +26,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-iterator"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noIterator: "Reserved name '__iterator__'."
+ }
},
create(context) {
@@ -29,10 +39,11 @@ module.exports = {
MemberExpression(node) {
- if (node.property &&
- (node.property.type === "Identifier" && node.property.name === "__iterator__" && !node.computed) ||
- (node.property.type === "Literal" && node.property.value === "__iterator__")) {
- context.report({ node, message: "Reserved name '__iterator__'." });
+ if (getStaticPropertyName(node) === "__iterator__") {
+ context.report({
+ node,
+ messageId: "noIterator"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-label-var.js b/tools/node_modules/eslint/lib/rules/no-label-var.js
index a9fd042a390225..570db03285cf97 100644
--- a/tools/node_modules/eslint/lib/rules/no-label-var.js
+++ b/tools/node_modules/eslint/lib/rules/no-label-var.js
@@ -26,7 +26,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-label-var"
},
- schema: []
+ schema: [],
+
+ messages: {
+ identifierClashWithLabel: "Found identifier with same name as label."
+ }
},
create(context) {
@@ -62,7 +66,10 @@ module.exports = {
* with the innermost scope.
*/
if (findIdentifier(scope, node.label.name)) {
- context.report({ node, message: "Found identifier with same name as label." });
+ context.report({
+ node,
+ messageId: "identifierClashWithLabel"
+ });
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-labels.js b/tools/node_modules/eslint/lib/rules/no-labels.js
index 52f4b0f5168b71..85760d80dbedd7 100644
--- a/tools/node_modules/eslint/lib/rules/no-labels.js
+++ b/tools/node_modules/eslint/lib/rules/no-labels.js
@@ -40,7 +40,13 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unexpectedLabel: "Unexpected labeled statement.",
+ unexpectedLabelInBreak: "Unexpected label in break statement.",
+ unexpectedLabelInContinue: "Unexpected label in continue statement."
+ }
},
create(context) {
@@ -113,7 +119,7 @@ module.exports = {
if (!isAllowed(scopeInfo.kind)) {
context.report({
node,
- message: "Unexpected labeled statement."
+ messageId: "unexpectedLabel"
});
}
@@ -124,7 +130,7 @@ module.exports = {
if (node.label && !isAllowed(getKind(node.label.name))) {
context.report({
node,
- message: "Unexpected label in break statement."
+ messageId: "unexpectedLabelInBreak"
});
}
},
@@ -133,7 +139,7 @@ module.exports = {
if (node.label && !isAllowed(getKind(node.label.name))) {
context.report({
node,
- message: "Unexpected label in continue statement."
+ messageId: "unexpectedLabelInContinue"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-lone-blocks.js b/tools/node_modules/eslint/lib/rules/no-lone-blocks.js
index 37561b0f9a3055..d7069887b8e460 100644
--- a/tools/node_modules/eslint/lib/rules/no-lone-blocks.js
+++ b/tools/node_modules/eslint/lib/rules/no-lone-blocks.js
@@ -20,7 +20,12 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-lone-blocks"
},
- schema: []
+ schema: [],
+
+ messages: {
+ redundantBlock: "Block is redundant.",
+ redundantNestedBlock: "Nested block is redundant."
+ }
},
create(context) {
@@ -35,9 +40,12 @@ module.exports = {
* @returns {void}
*/
function report(node) {
- const message = node.parent.type === "BlockStatement" ? "Nested block is redundant." : "Block is redundant.";
+ const messageId = node.parent.type === "BlockStatement" ? "redundantNestedBlock" : "redundantBlock";
- context.report({ node, message });
+ context.report({
+ node,
+ messageId
+ });
}
/**
diff --git a/tools/node_modules/eslint/lib/rules/no-lonely-if.js b/tools/node_modules/eslint/lib/rules/no-lonely-if.js
index b62d176a264210..6552adc5752852 100644
--- a/tools/node_modules/eslint/lib/rules/no-lonely-if.js
+++ b/tools/node_modules/eslint/lib/rules/no-lonely-if.js
@@ -1,5 +1,5 @@
/**
- * @fileoverview Rule to disallow if as the only statmenet in an else block
+ * @fileoverview Rule to disallow if as the only statement in an else block
* @author Brandon Mills
*/
"use strict";
@@ -20,7 +20,11 @@ module.exports = {
},
schema: [],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ unexpectedLonelyIf: "Unexpected if as the only statement in an else block."
+ }
},
create(context) {
@@ -38,7 +42,7 @@ module.exports = {
parent === grandparent.alternate) {
context.report({
node,
- message: "Unexpected if as the only statement in an else block.",
+ messageId: "unexpectedLonelyIf",
fix(fixer) {
const openingElseCurly = sourceCode.getFirstToken(parent);
const closingElseCurly = sourceCode.getLastToken(parent);
diff --git a/tools/node_modules/eslint/lib/rules/no-magic-numbers.js b/tools/node_modules/eslint/lib/rules/no-magic-numbers.js
index 0909e3166d952e..5dd6feaab0dbff 100644
--- a/tools/node_modules/eslint/lib/rules/no-magic-numbers.js
+++ b/tools/node_modules/eslint/lib/rules/no-magic-numbers.js
@@ -5,10 +5,24 @@
"use strict";
+const { isNumericLiteral } = require("./utils/ast-utils");
+
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
+/**
+ * Convert the value to bigint if it's a string. Otherwise return the value as-is.
+ * @param {bigint|number|string} x The value to normalize.
+ * @returns {bigint|number} The normalized value.
+ */
+function normalizeIgnoreValue(x) {
+ if (typeof x === "string") {
+ return BigInt(x.slice(0, -1));
+ }
+ return x;
+}
+
module.exports = {
meta: {
type: "suggestion",
@@ -34,7 +48,10 @@ module.exports = {
ignore: {
type: "array",
items: {
- type: "number"
+ anyOf: [
+ { type: "number" },
+ { type: "string", pattern: "^[+-]?(?:0|[1-9][0-9]*)n$" }
+ ]
},
uniqueItems: true
},
@@ -56,18 +73,9 @@ module.exports = {
const config = context.options[0] || {},
detectObjects = !!config.detectObjects,
enforceConst = !!config.enforceConst,
- ignore = config.ignore || [],
+ ignore = (config.ignore || []).map(normalizeIgnoreValue),
ignoreArrayIndexes = !!config.ignoreArrayIndexes;
- /**
- * Returns whether the node is number literal
- * @param {Node} node the node literal being evaluated
- * @returns {boolean} true if the node is a number literal
- */
- function isNumber(node) {
- return typeof node.value === "number";
- }
-
/**
* Returns whether the number should be ignored
* @param {number} num the number
@@ -102,18 +110,21 @@ module.exports = {
/**
* Returns whether the number should be ignored when used as an array index with enabled 'ignoreArrayIndexes' option.
- * @param {ASTNode} parent the non-"UnaryExpression" parent.
+ * @param {ASTNode} node Node to check
* @returns {boolean} true if the number should be ignored
*/
- function shouldIgnoreArrayIndexes(parent) {
- return parent.type === "MemberExpression" && ignoreArrayIndexes;
+ function shouldIgnoreArrayIndexes(node) {
+ const parent = node.parent;
+
+ return ignoreArrayIndexes &&
+ parent.type === "MemberExpression" && parent.property === node;
}
return {
Literal(node) {
const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"];
- if (!isNumber(node)) {
+ if (!isNumericLiteral(node)) {
return;
}
@@ -137,7 +148,7 @@ module.exports = {
if (shouldIgnoreNumber(value) ||
shouldIgnoreParseInt(parent, fullNumberNode) ||
- shouldIgnoreArrayIndexes(parent) ||
+ shouldIgnoreArrayIndexes(fullNumberNode) ||
shouldIgnoreJSXNumbers(parent)) {
return;
}
diff --git a/tools/node_modules/eslint/lib/rules/no-mixed-operators.js b/tools/node_modules/eslint/lib/rules/no-mixed-operators.js
index 80fac79affdb0e..37e8906e827a4c 100644
--- a/tools/node_modules/eslint/lib/rules/no-mixed-operators.js
+++ b/tools/node_modules/eslint/lib/rules/no-mixed-operators.js
@@ -112,7 +112,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unexpectedMixedOperator: "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'."
+ }
},
create(context) {
@@ -188,8 +192,6 @@ module.exports = {
const parent = node.parent;
const left = (getChildNode(parent) === node) ? node : parent;
const right = (getChildNode(parent) !== node) ? node : parent;
- const message =
- "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'.";
const data = {
leftOperator: left.operator || "?:",
rightOperator: right.operator || "?:"
@@ -198,13 +200,13 @@ module.exports = {
context.report({
node: left,
loc: getOperatorToken(left).loc,
- message,
+ messageId: "unexpectedMixedOperator",
data
});
context.report({
node: right,
loc: getOperatorToken(right).loc,
- message,
+ messageId: "unexpectedMixedOperator",
data
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-mixed-requires.js b/tools/node_modules/eslint/lib/rules/no-mixed-requires.js
index fda8a11d9e2e74..8e988e32c24f84 100644
--- a/tools/node_modules/eslint/lib/rules/no-mixed-requires.js
+++ b/tools/node_modules/eslint/lib/rules/no-mixed-requires.js
@@ -40,7 +40,12 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ noMixRequire: "Do not mix 'require' and other declarations.",
+ noMixCoreModuleFileComputed: "Do not mix core, module, file and computed requires."
+ }
},
create(context) {
@@ -211,9 +216,15 @@ module.exports = {
VariableDeclaration(node) {
if (isMixed(node.declarations)) {
- context.report({ node, message: "Do not mix 'require' and other declarations." });
+ context.report({
+ node,
+ messageId: "noMixRequire"
+ });
} else if (grouping && !isGrouped(node.declarations)) {
- context.report({ node, message: "Do not mix core, module, file and computed requires." });
+ context.report({
+ node,
+ messageId: "noMixCoreModuleFileComputed"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js b/tools/node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js
index 7b1e2c4a2a760c..16c2bd4122e851 100644
--- a/tools/node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js
+++ b/tools/node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js
@@ -23,14 +23,17 @@ module.exports = {
{
enum: ["smart-tabs", true, false]
}
- ]
+ ],
+
+ messages: {
+ mixedSpacesAndTabs: "Mixed spaces and tabs."
+ }
},
create(context) {
const sourceCode = context.getSourceCode();
let smartTabs;
- const ignoredLocs = [];
switch (context.options[0]) {
case true: // Support old syntax, maybe add deprecation warning here
@@ -41,47 +44,23 @@ module.exports = {
smartTabs = false;
}
- /**
- * Determines if a given line and column are before a location.
- * @param {Location} loc The location object from an AST node.
- * @param {int} line The line to check.
- * @param {int} column The column to check.
- * @returns {boolean} True if the line and column are before the location, false if not.
- * @private
- */
- function beforeLoc(loc, line, column) {
- if (line < loc.start.line) {
- return true;
- }
- return line === loc.start.line && column < loc.start.column;
- }
-
- /**
- * Determines if a given line and column are after a location.
- * @param {Location} loc The location object from an AST node.
- * @param {int} line The line to check.
- * @param {int} column The column to check.
- * @returns {boolean} True if the line and column are after the location, false if not.
- * @private
- */
- function afterLoc(loc, line, column) {
- if (line > loc.end.line) {
- return true;
- }
- return line === loc.end.line && column > loc.end.column;
- }
-
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
- TemplateElement(node) {
- ignoredLocs.push(node.loc);
- },
-
"Program:exit"(node) {
+ const lines = sourceCode.lines,
+ comments = sourceCode.getAllComments(),
+ ignoredCommentLines = new Set();
+
+ // Add all lines except the first ones.
+ comments.forEach(comment => {
+ for (let i = comment.loc.start.line + 1; i <= comment.loc.end.line; i++) {
+ ignoredCommentLines.add(i);
+ }
+ });
/*
* At least one space followed by a tab
@@ -89,24 +68,6 @@ module.exports = {
* characters begin.
*/
let regex = /^(?=[\t ]*(\t | \t))/u;
- const lines = sourceCode.lines,
- comments = sourceCode.getAllComments();
-
- comments.forEach(comment => {
- ignoredLocs.push(comment.loc);
- });
-
- ignoredLocs.sort((first, second) => {
- if (beforeLoc(first, second.start.line, second.start.column)) {
- return 1;
- }
-
- if (beforeLoc(second, first.start.line, second.start.column)) {
- return -1;
- }
-
- return 0;
- });
if (smartTabs) {
@@ -122,25 +83,23 @@ module.exports = {
if (match) {
const lineNumber = i + 1,
- column = match.index + 1;
-
- for (let j = 0; j < ignoredLocs.length; j++) {
- if (beforeLoc(ignoredLocs[j], lineNumber, column)) {
- continue;
+ column = match.index + 1,
+ loc = { line: lineNumber, column };
+
+ if (!ignoredCommentLines.has(lineNumber)) {
+ const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc));
+
+ if (!(containingNode && ["Literal", "TemplateElement"].includes(containingNode.type))) {
+ context.report({
+ node,
+ loc,
+ messageId: "mixedSpacesAndTabs"
+ });
}
- if (afterLoc(ignoredLocs[j], lineNumber, column)) {
- continue;
- }
-
- return;
}
-
- context.report({ node, loc: { line: lineNumber, column }, message: "Mixed spaces and tabs." });
}
});
}
-
};
-
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-multi-assign.js b/tools/node_modules/eslint/lib/rules/no-multi-assign.js
index 8524a1a571ef9e..ab6430c19ef070 100644
--- a/tools/node_modules/eslint/lib/rules/no-multi-assign.js
+++ b/tools/node_modules/eslint/lib/rules/no-multi-assign.js
@@ -21,7 +21,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-multi-assign"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedChain: "Unexpected chained assignment."
+ }
},
create(context) {
@@ -35,7 +39,7 @@ module.exports = {
if (["AssignmentExpression", "VariableDeclarator"].indexOf(node.parent.type) !== -1) {
context.report({
node,
- message: "Unexpected chained assignment."
+ messageId: "unexpectedChain"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-multi-spaces.js b/tools/node_modules/eslint/lib/rules/no-multi-spaces.js
index 403d04da9dd9ec..d43ed736337945 100644
--- a/tools/node_modules/eslint/lib/rules/no-multi-spaces.js
+++ b/tools/node_modules/eslint/lib/rules/no-multi-spaces.js
@@ -44,7 +44,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ multipleSpaces: "Multiple spaces found before '{{displayValue}}'."
+ }
},
create(context) {
@@ -122,7 +126,7 @@ module.exports = {
context.report({
node: rightToken,
loc: { start: leftToken.loc.end, end: rightToken.loc.start },
- message: "Multiple spaces found before '{{displayValue}}'.",
+ messageId: "multipleSpaces",
data: { displayValue },
fix: fixer => fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ")
});
diff --git a/tools/node_modules/eslint/lib/rules/no-multi-str.js b/tools/node_modules/eslint/lib/rules/no-multi-str.js
index f6832f3341777f..7cf1ae367942fe 100644
--- a/tools/node_modules/eslint/lib/rules/no-multi-str.js
+++ b/tools/node_modules/eslint/lib/rules/no-multi-str.js
@@ -26,7 +26,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-multi-str"
},
- schema: []
+ schema: [],
+
+ messages: {
+ multilineString: "Multiline support is limited to browsers supporting ES5 only."
+ }
},
create(context) {
@@ -49,7 +53,10 @@ module.exports = {
Literal(node) {
if (astUtils.LINEBREAK_MATCHER.test(node.raw) && !isJSXElement(node.parent)) {
- context.report({ node, message: "Multiline support is limited to browsers supporting ES5 only." });
+ context.report({
+ node,
+ messageId: "multilineString"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-multiple-empty-lines.js b/tools/node_modules/eslint/lib/rules/no-multiple-empty-lines.js
index 41e6be3a289584..9cccef3088a56e 100644
--- a/tools/node_modules/eslint/lib/rules/no-multiple-empty-lines.js
+++ b/tools/node_modules/eslint/lib/rules/no-multiple-empty-lines.js
@@ -42,7 +42,13 @@ module.exports = {
required: ["max"],
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ blankBeginningOfFile: "Too many blank lines at the beginning of file. Max of {{max}} allowed.",
+ blankEndOfFile: "Too many blank lines at the end of file. Max of {{max}} allowed.",
+ consecutiveBlank: "More than {{max}} blank {{pluralizedLines}} not allowed."
+ }
},
create(context) {
@@ -94,25 +100,31 @@ module.exports = {
// Given two line numbers of non-empty lines, report the lines between if the difference is too large.
.reduce((lastLineNumber, lineNumber) => {
- let message, maxAllowed;
+ let messageId, maxAllowed;
if (lastLineNumber === 0) {
- message = "Too many blank lines at the beginning of file. Max of {{max}} allowed.";
+ messageId = "blankBeginningOfFile";
maxAllowed = maxBOF;
} else if (lineNumber === allLines.length + 1) {
- message = "Too many blank lines at the end of file. Max of {{max}} allowed.";
+ messageId = "blankEndOfFile";
maxAllowed = maxEOF;
} else {
- message = "More than {{max}} blank {{pluralizedLines}} not allowed.";
+ messageId = "consecutiveBlank";
maxAllowed = max;
}
if (lineNumber - lastLineNumber - 1 > maxAllowed) {
context.report({
node,
- loc: { start: { line: lastLineNumber + maxAllowed + 1, column: 0 }, end: { line: lineNumber, column: 0 } },
- message,
- data: { max: maxAllowed, pluralizedLines: maxAllowed === 1 ? "line" : "lines" },
+ loc: {
+ start: { line: lastLineNumber + maxAllowed + 1, column: 0 },
+ end: { line: lineNumber, column: 0 }
+ },
+ messageId,
+ data: {
+ max: maxAllowed,
+ pluralizedLines: maxAllowed === 1 ? "line" : "lines"
+ },
fix(fixer) {
const rangeStart = sourceCode.getIndexFromLoc({ line: lastLineNumber + 1, column: 0 });
diff --git a/tools/node_modules/eslint/lib/rules/no-native-reassign.js b/tools/node_modules/eslint/lib/rules/no-native-reassign.js
index eb233c80b1cca0..833e3b7ce409b3 100644
--- a/tools/node_modules/eslint/lib/rules/no-native-reassign.js
+++ b/tools/node_modules/eslint/lib/rules/no-native-reassign.js
@@ -37,7 +37,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ nativeReassign: "Read-only global '{{name}}' should not be modified."
+ }
},
create(context) {
@@ -65,7 +69,7 @@ module.exports = {
) {
context.report({
node: identifier,
- message: "Read-only global '{{name}}' should not be modified.",
+ messageId: "nativeReassign",
data: identifier
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-negated-condition.js b/tools/node_modules/eslint/lib/rules/no-negated-condition.js
index e55a8287487de3..8a9eba881df04c 100644
--- a/tools/node_modules/eslint/lib/rules/no-negated-condition.js
+++ b/tools/node_modules/eslint/lib/rules/no-negated-condition.js
@@ -19,7 +19,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-negated-condition"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedNegated: "Unexpected negated condition."
+ }
},
create(context) {
@@ -72,12 +76,18 @@ module.exports = {
}
if (isNegatedIf(node)) {
- context.report({ node, message: "Unexpected negated condition." });
+ context.report({
+ node,
+ messageId: "unexpectedNegated"
+ });
}
},
ConditionalExpression(node) {
if (isNegatedIf(node)) {
- context.report({ node, message: "Unexpected negated condition." });
+ context.report({
+ node,
+ messageId: "unexpectedNegated"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-negated-in-lhs.js b/tools/node_modules/eslint/lib/rules/no-negated-in-lhs.js
index 0084ad1570bb00..1229cedd1190dc 100644
--- a/tools/node_modules/eslint/lib/rules/no-negated-in-lhs.js
+++ b/tools/node_modules/eslint/lib/rules/no-negated-in-lhs.js
@@ -24,7 +24,11 @@ module.exports = {
replacedBy: ["no-unsafe-negation"],
deprecated: true,
- schema: []
+ schema: [],
+
+ messages: {
+ negatedLHS: "The 'in' expression's left operand is negated."
+ }
},
create(context) {
@@ -33,7 +37,7 @@ module.exports = {
BinaryExpression(node) {
if (node.operator === "in" && node.left.type === "UnaryExpression" && node.left.operator === "!") {
- context.report({ node, message: "The 'in' expression's left operand is negated." });
+ context.report({ node, messageId: "negatedLHS" });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-nested-ternary.js b/tools/node_modules/eslint/lib/rules/no-nested-ternary.js
index 87a11e87962a8f..383bb238887d2a 100644
--- a/tools/node_modules/eslint/lib/rules/no-nested-ternary.js
+++ b/tools/node_modules/eslint/lib/rules/no-nested-ternary.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-nested-ternary"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noNestedTernary: "Do not nest ternary expressions."
+ }
},
create(context) {
@@ -29,7 +33,10 @@ module.exports = {
ConditionalExpression(node) {
if (node.alternate.type === "ConditionalExpression" ||
node.consequent.type === "ConditionalExpression") {
- context.report({ node, message: "Do not nest ternary expressions." });
+ context.report({
+ node,
+ messageId: "noNestedTernary"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-new-func.js b/tools/node_modules/eslint/lib/rules/no-new-func.js
index 23e92f7bf3030c..d1360e9dee036d 100644
--- a/tools/node_modules/eslint/lib/rules/no-new-func.js
+++ b/tools/node_modules/eslint/lib/rules/no-new-func.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-new-func"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noFunctionConstructor: "The Function constructor is eval."
+ }
},
create(context) {
@@ -36,7 +40,10 @@ module.exports = {
* @private
*/
function report(node) {
- context.report({ node, message: "The Function constructor is eval." });
+ context.report({
+ node,
+ messageId: "noFunctionConstructor"
+ });
}
return {
diff --git a/tools/node_modules/eslint/lib/rules/no-new-object.js b/tools/node_modules/eslint/lib/rules/no-new-object.js
index f5cc28664f4e1c..f3e99c9bd13502 100644
--- a/tools/node_modules/eslint/lib/rules/no-new-object.js
+++ b/tools/node_modules/eslint/lib/rules/no-new-object.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-new-object"
},
- schema: []
+ schema: [],
+
+ messages: {
+ preferLiteral: "The object literal notation {} is preferrable."
+ }
},
create(context) {
@@ -29,7 +33,10 @@ module.exports = {
NewExpression(node) {
if (node.callee.name === "Object") {
- context.report({ node, message: "The object literal notation {} is preferrable." });
+ context.report({
+ node,
+ messageId: "preferLiteral"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-new-require.js b/tools/node_modules/eslint/lib/rules/no-new-require.js
index 1eae0659430fbd..df12a424e3527e 100644
--- a/tools/node_modules/eslint/lib/rules/no-new-require.js
+++ b/tools/node_modules/eslint/lib/rules/no-new-require.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-new-require"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noNewRequire: "Unexpected use of new with require."
+ }
},
create(context) {
@@ -29,7 +33,10 @@ module.exports = {
NewExpression(node) {
if (node.callee.type === "Identifier" && node.callee.name === "require") {
- context.report({ node, message: "Unexpected use of new with require." });
+ context.report({
+ node,
+ messageId: "noNewRequire"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-new-symbol.js b/tools/node_modules/eslint/lib/rules/no-new-symbol.js
index ccf757ed6a0cee..cb7e4f0fc88d69 100644
--- a/tools/node_modules/eslint/lib/rules/no-new-symbol.js
+++ b/tools/node_modules/eslint/lib/rules/no-new-symbol.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-new-symbol"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noNewSymbol: "`Symbol` cannot be called as a constructor."
+ }
},
create(context) {
@@ -35,7 +39,10 @@ module.exports = {
const node = ref.identifier;
if (node.parent && node.parent.type === "NewExpression") {
- context.report({ node, message: "`Symbol` cannot be called as a constructor." });
+ context.report({
+ node,
+ messageId: "noNewSymbol"
+ });
}
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-new-wrappers.js b/tools/node_modules/eslint/lib/rules/no-new-wrappers.js
index ae2aeec0341243..0a2861fa5f7799 100644
--- a/tools/node_modules/eslint/lib/rules/no-new-wrappers.js
+++ b/tools/node_modules/eslint/lib/rules/no-new-wrappers.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-new-wrappers"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noConstructor: "Do not use {{fn}} as a constructor."
+ }
},
create(context) {
@@ -31,7 +35,11 @@ module.exports = {
const wrapperObjects = ["String", "Number", "Boolean", "Math", "JSON"];
if (wrapperObjects.indexOf(node.callee.name) > -1) {
- context.report({ node, message: "Do not use {{fn}} as a constructor.", data: { fn: node.callee.name } });
+ context.report({
+ node,
+ messageId: "noConstructor",
+ data: { fn: node.callee.name }
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-new.js b/tools/node_modules/eslint/lib/rules/no-new.js
index 2e0702597eade3..aa8a4e26876609 100644
--- a/tools/node_modules/eslint/lib/rules/no-new.js
+++ b/tools/node_modules/eslint/lib/rules/no-new.js
@@ -21,14 +21,21 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-new"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noNewStatement: "Do not use 'new' for side effects."
+ }
},
create(context) {
return {
"ExpressionStatement > NewExpression"(node) {
- context.report({ node: node.parent, message: "Do not use 'new' for side effects." });
+ context.report({
+ node: node.parent,
+ messageId: "noNewStatement"
+ });
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-obj-calls.js b/tools/node_modules/eslint/lib/rules/no-obj-calls.js
index 5102d5594949ba..9ff666b03281ca 100644
--- a/tools/node_modules/eslint/lib/rules/no-obj-calls.js
+++ b/tools/node_modules/eslint/lib/rules/no-obj-calls.js
@@ -47,8 +47,8 @@ module.exports = {
const tracker = new ReferenceTracker(scope);
const traceMap = {};
- for (const global of nonCallableGlobals) {
- traceMap[global] = {
+ for (const g of nonCallableGlobals) {
+ traceMap[g] = {
[CALL]: true
};
}
diff --git a/tools/node_modules/eslint/lib/rules/no-octal.js b/tools/node_modules/eslint/lib/rules/no-octal.js
index 5ee69f0309ee03..e9940befafa889 100644
--- a/tools/node_modules/eslint/lib/rules/no-octal.js
+++ b/tools/node_modules/eslint/lib/rules/no-octal.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-octal"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noOcatal: "Octal literals should not be used."
+ }
},
create(context) {
@@ -29,7 +33,10 @@ module.exports = {
Literal(node) {
if (typeof node.value === "number" && /^0[0-9]/u.test(node.raw)) {
- context.report({ node, message: "Octal literals should not be used." });
+ context.report({
+ node,
+ messageId: "noOcatal"
+ });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-param-reassign.js b/tools/node_modules/eslint/lib/rules/no-param-reassign.js
index d65eb34762aaf2..6874af44f389b7 100644
--- a/tools/node_modules/eslint/lib/rules/no-param-reassign.js
+++ b/tools/node_modules/eslint/lib/rules/no-param-reassign.js
@@ -58,7 +58,12 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ assignmentToFunctionParam: "Assignment to function parameter '{{name}}'.",
+ assignmentToFunctionParamProp: "Assignment to property of function parameter '{{name}}'."
+ }
},
create(context) {
@@ -177,9 +182,17 @@ module.exports = {
(index === 0 || references[index - 1].identifier !== identifier)
) {
if (reference.isWrite()) {
- context.report({ node: identifier, message: "Assignment to function parameter '{{name}}'.", data: { name: identifier.name } });
+ context.report({
+ node: identifier,
+ messageId: "assignmentToFunctionParam",
+ data: { name: identifier.name }
+ });
} else if (props && isModifyingProp(reference) && !isIgnoredPropertyAssignment(identifier.name)) {
- context.report({ node: identifier, message: "Assignment to property of function parameter '{{name}}'.", data: { name: identifier.name } });
+ context.report({
+ node: identifier,
+ messageId: "assignmentToFunctionParamProp",
+ data: { name: identifier.name }
+ });
}
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-path-concat.js b/tools/node_modules/eslint/lib/rules/no-path-concat.js
index abe0d5247db719..9fa8b852fe8358 100644
--- a/tools/node_modules/eslint/lib/rules/no-path-concat.js
+++ b/tools/node_modules/eslint/lib/rules/no-path-concat.js
@@ -19,7 +19,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-path-concat"
},
- schema: []
+ schema: [],
+
+ messages: {
+ usePathFunctions: "Use path.join() or path.resolve() instead of + to create paths."
+ }
},
create(context) {
@@ -42,7 +46,10 @@ module.exports = {
(right.type === "Identifier" && MATCHER.test(right.name)))
) {
- context.report({ node, message: "Use path.join() or path.resolve() instead of + to create paths." });
+ context.report({
+ node,
+ messageId: "usePathFunctions"
+ });
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-plusplus.js b/tools/node_modules/eslint/lib/rules/no-plusplus.js
index 1d122dcd31f086..f55303863d25ca 100644
--- a/tools/node_modules/eslint/lib/rules/no-plusplus.js
+++ b/tools/node_modules/eslint/lib/rules/no-plusplus.js
@@ -32,7 +32,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unexpectedUnaryOp: "Unary operator '{{operator}}' used."
+ }
},
create(context) {
@@ -52,7 +56,7 @@ module.exports = {
}
context.report({
node,
- message: "Unary operator '{{operator}}' used.",
+ messageId: "unexpectedUnaryOp",
data: {
operator: node.operator
}
diff --git a/tools/node_modules/eslint/lib/rules/no-process-env.js b/tools/node_modules/eslint/lib/rules/no-process-env.js
index a66d9709b09b4f..0f8d7f8a339d0e 100644
--- a/tools/node_modules/eslint/lib/rules/no-process-env.js
+++ b/tools/node_modules/eslint/lib/rules/no-process-env.js
@@ -19,7 +19,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-process-env"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedProcessEnv: "Unexpected use of process.env."
+ }
},
create(context) {
@@ -31,7 +35,7 @@ module.exports = {
propertyName = node.property.name;
if (objectName === "process" && !node.computed && propertyName && propertyName === "env") {
- context.report({ node, message: "Unexpected use of process.env." });
+ context.report({ node, messageId: "unexpectedProcessEnv" });
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-process-exit.js b/tools/node_modules/eslint/lib/rules/no-process-exit.js
index fcfc6b2af59d0e..29871660cc6ee1 100644
--- a/tools/node_modules/eslint/lib/rules/no-process-exit.js
+++ b/tools/node_modules/eslint/lib/rules/no-process-exit.js
@@ -19,7 +19,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-process-exit"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noProcessExit: "Don't use process.exit(); throw an error instead."
+ }
},
create(context) {
@@ -30,7 +34,7 @@ module.exports = {
return {
"CallExpression > MemberExpression.callee[object.name = 'process'][property.name = 'exit']"(node) {
- context.report({ node: node.parent, message: "Don't use process.exit(); throw an error instead." });
+ context.report({ node: node.parent, messageId: "noProcessExit" });
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-proto.js b/tools/node_modules/eslint/lib/rules/no-proto.js
index 80b9650941696d..82ce02fa4e3b9e 100644
--- a/tools/node_modules/eslint/lib/rules/no-proto.js
+++ b/tools/node_modules/eslint/lib/rules/no-proto.js
@@ -5,6 +5,12 @@
"use strict";
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const { getStaticPropertyName } = require("./utils/ast-utils");
+
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -20,7 +26,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-proto"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedProto: "The '__proto__' property is deprecated."
+ }
},
create(context) {
@@ -28,11 +38,8 @@ module.exports = {
return {
MemberExpression(node) {
-
- if (node.property &&
- (node.property.type === "Identifier" && node.property.name === "__proto__" && !node.computed) ||
- (node.property.type === "Literal" && node.property.value === "__proto__")) {
- context.report({ node, message: "The '__proto__' property is deprecated." });
+ if (getStaticPropertyName(node) === "__proto__") {
+ context.report({ node, messageId: "unexpectedProto" });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-prototype-builtins.js b/tools/node_modules/eslint/lib/rules/no-prototype-builtins.js
index 87a760156e3693..5bed2539a6486b 100644
--- a/tools/node_modules/eslint/lib/rules/no-prototype-builtins.js
+++ b/tools/node_modules/eslint/lib/rules/no-prototype-builtins.js
@@ -19,7 +19,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-prototype-builtins"
},
- schema: []
+ schema: [],
+
+ messages: {
+ prototypeBuildIn: "Do not access Object.prototype method '{{prop}}' from target object."
+ }
},
create(context) {
@@ -42,7 +46,7 @@ module.exports = {
if (DISALLOWED_PROPS.indexOf(propName) > -1) {
context.report({
- message: "Do not access Object.prototype method '{{prop}}' from target object.",
+ messageId: "prototypeBuildIn",
loc: node.callee.property.loc.start,
data: { prop: propName },
node
diff --git a/tools/node_modules/eslint/lib/rules/no-regex-spaces.js b/tools/node_modules/eslint/lib/rules/no-regex-spaces.js
index 7581e9271fdf14..afb26d70259f1b 100644
--- a/tools/node_modules/eslint/lib/rules/no-regex-spaces.js
+++ b/tools/node_modules/eslint/lib/rules/no-regex-spaces.js
@@ -45,7 +45,11 @@ module.exports = {
},
schema: [],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ multipleSpaces: "Spaces are hard to count. Use {{{length}}}."
+ }
},
create(context) {
@@ -96,7 +100,7 @@ module.exports = {
) {
context.report({
node: nodeToReport,
- message: "Spaces are hard to count. Use {{{length}}}.",
+ messageId: "multipleSpaces",
data: { length },
fix(fixer) {
if (pattern !== rawPattern) {
@@ -109,7 +113,7 @@ module.exports = {
}
});
- // Report only the first occurence of consecutive spaces
+ // Report only the first occurrence of consecutive spaces
return;
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-restricted-exports.js b/tools/node_modules/eslint/lib/rules/no-restricted-exports.js
new file mode 100644
index 00000000000000..5b5c7d9bffb99c
--- /dev/null
+++ b/tools/node_modules/eslint/lib/rules/no-restricted-exports.js
@@ -0,0 +1,84 @@
+/**
+ * @fileoverview Rule to disallow specified names in exports
+ * @author Milos Djermanovic
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ type: "suggestion",
+
+ docs: {
+ description: "disallow specified names in exports",
+ category: "ECMAScript 6",
+ recommended: false,
+ url: "https://eslint.org/docs/rules/no-restricted-exports"
+ },
+
+ schema: [{
+ type: "object",
+ properties: {
+ restrictedNamedExports: {
+ type: "array",
+ items: {
+ type: "string"
+ },
+ uniqueItems: true
+ }
+ },
+ additionalProperties: false
+ }],
+
+ messages: {
+ restrictedNamed: "'{{name}}' is restricted from being used as an exported name."
+ }
+ },
+
+ create(context) {
+
+ const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports);
+
+ /**
+ * Checks and reports given exported identifier.
+ * @param {ASTNode} node exported `Identifer` node to check.
+ * @returns {void}
+ */
+ function checkExportedName(node) {
+ const name = node.name;
+
+ if (restrictedNames.has(name)) {
+ context.report({
+ node,
+ messageId: "restrictedNamed",
+ data: { name }
+ });
+ }
+ }
+
+ return {
+ ExportNamedDeclaration(node) {
+ const declaration = node.declaration;
+
+ if (declaration) {
+ if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") {
+ checkExportedName(declaration.id);
+ } else if (declaration.type === "VariableDeclaration") {
+ context.getDeclaredVariables(declaration)
+ .map(v => v.defs.find(d => d.parent === declaration))
+ .map(d => d.name) // Identifier nodes
+ .forEach(checkExportedName);
+ }
+ } else {
+ node.specifiers
+ .map(s => s.exported)
+ .forEach(checkExportedName);
+ }
+ }
+ };
+ }
+};
diff --git a/tools/node_modules/eslint/lib/rules/no-restricted-globals.js b/tools/node_modules/eslint/lib/rules/no-restricted-globals.js
index 1a2629a8ec95e8..2c932a7307c0b2 100644
--- a/tools/node_modules/eslint/lib/rules/no-restricted-globals.js
+++ b/tools/node_modules/eslint/lib/rules/no-restricted-globals.js
@@ -4,13 +4,6 @@
*/
"use strict";
-//------------------------------------------------------------------------------
-// Helpers
-//------------------------------------------------------------------------------
-
-const DEFAULT_MESSAGE_TEMPLATE = "Unexpected use of '{{name}}'.",
- CUSTOM_MESSAGE_TEMPLATE = "Unexpected use of '{{name}}'. {{customMessage}}";
-
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -46,6 +39,12 @@ module.exports = {
},
uniqueItems: true,
minItems: 0
+ },
+
+ messages: {
+ defaultMessage: "Unexpected use of '{{name}}'.",
+ // eslint-disable-next-line eslint-plugin/report-message-format
+ customMessage: "Unexpected use of '{{name}}'. {{customMessage}}"
}
},
@@ -75,13 +74,13 @@ module.exports = {
function reportReference(reference) {
const name = reference.identifier.name,
customMessage = restrictedGlobalMessages[name],
- message = customMessage
- ? CUSTOM_MESSAGE_TEMPLATE
- : DEFAULT_MESSAGE_TEMPLATE;
+ messageId = customMessage
+ ? "customMessage"
+ : "defaultMessage";
context.report({
node: reference.identifier,
- message,
+ messageId,
data: {
name,
customMessage
diff --git a/tools/node_modules/eslint/lib/rules/no-restricted-imports.js b/tools/node_modules/eslint/lib/rules/no-restricted-imports.js
index ec0696f99a2de0..c205dad8bdb79d 100644
--- a/tools/node_modules/eslint/lib/rules/no-restricted-imports.js
+++ b/tools/node_modules/eslint/lib/rules/no-restricted-imports.js
@@ -64,7 +64,11 @@ module.exports = {
everything: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted.",
// eslint-disable-next-line eslint-plugin/report-message-format
- everythingWithCustomMessage: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted. {{customMessage}}"
+ everythingWithCustomMessage: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted. {{customMessage}}",
+
+ importName: "'{{importName}}' import from '{{importSource}}' is restricted.",
+ // eslint-disable-next-line eslint-plugin/report-message-format
+ importNameWithCustomMessage: "'{{importName}}' import from '{{importSource}}' is restricted. {{customMessage}}"
},
schema: {
@@ -87,6 +91,7 @@ module.exports = {
},
create(context) {
+ const sourceCode = context.getSourceCode();
const options = Array.isArray(context.options) ? context.options : [];
const isPathAndPatternsObject =
typeof options[0] === "object" &&
@@ -95,6 +100,11 @@ module.exports = {
const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || [];
const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || [];
+ // if no imports are restricted we don"t need to check
+ if (Object.keys(restrictedPaths).length === 0 && restrictedPatterns.length === 0) {
+ return {};
+ }
+
const restrictedPathMessages = restrictedPaths.reduce((memo, importSource) => {
if (typeof importSource === "string") {
memo[importSource] = { message: null };
@@ -107,40 +117,68 @@ module.exports = {
return memo;
}, {});
- // if no imports are restricted we don"t need to check
- if (Object.keys(restrictedPaths).length === 0 && restrictedPatterns.length === 0) {
- return {};
- }
-
const restrictedPatternsMatcher = ignore().add(restrictedPatterns);
- /**
- * Checks to see if "*" is being used to import everything.
- * @param {Set.} importNames Set of import names that are being imported
- * @returns {boolean} whether everything is imported or not
- */
- function isEverythingImported(importNames) {
- return importNames.has("*");
- }
-
/**
* Report a restricted path.
+ * @param {string} importSource path of the import
+ * @param {Map} importNames Map of import names that are being imported
* @param {node} node representing the restricted path reference
* @returns {void}
* @private
*/
- function reportPath(node) {
- const importSource = node.source.value.trim();
- const customMessage = restrictedPathMessages[importSource] && restrictedPathMessages[importSource].message;
+ function checkRestrictedPathAndReport(importSource, importNames, node) {
+ if (!Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource)) {
+ return;
+ }
- context.report({
- node,
- messageId: customMessage ? "pathWithCustomMessage" : "path",
- data: {
- importSource,
- customMessage
+ const customMessage = restrictedPathMessages[importSource].message;
+ const restrictedImportNames = restrictedPathMessages[importSource].importNames;
+
+ if (restrictedImportNames) {
+ if (importNames.has("*")) {
+ const specifierData = importNames.get("*")[0];
+
+ context.report({
+ node,
+ messageId: customMessage ? "everythingWithCustomMessage" : "everything",
+ loc: specifierData.loc,
+ data: {
+ importSource,
+ importNames: restrictedImportNames,
+ customMessage
+ }
+ });
}
- });
+
+ restrictedImportNames.forEach(importName => {
+ if (importNames.has(importName)) {
+ const specifiers = importNames.get(importName);
+
+ specifiers.forEach(specifier => {
+ context.report({
+ node,
+ messageId: customMessage ? "importNameWithCustomMessage" : "importName",
+ loc: specifier.loc,
+ data: {
+ importSource,
+ customMessage,
+ importName
+ }
+ });
+ });
+ }
+ });
+ } else {
+ context.report({
+ node,
+ messageId: customMessage ? "pathWithCustomMessage" : "path",
+ data: {
+ importSource,
+ customMessage
+ }
+ });
+ }
}
/**
@@ -161,75 +199,6 @@ module.exports = {
});
}
- /**
- * Report a restricted path specifically when using the '*' import.
- * @param {string} importSource path of the import
- * @param {node} node representing the restricted path reference
- * @returns {void}
- * @private
- */
- function reportPathForEverythingImported(importSource, node) {
- const importNames = restrictedPathMessages[importSource].importNames;
- const customMessage = restrictedPathMessages[importSource] && restrictedPathMessages[importSource].message;
-
- context.report({
- node,
- messageId: customMessage ? "everythingWithCustomMessage" : "everything",
- data: {
- importSource,
- importNames,
- customMessage
- }
- });
- }
-
- /**
- * Check if the given importSource is restricted because '*' is being imported.
- * @param {string} importSource path of the import
- * @param {Set.} importNames Set of import names that are being imported
- * @returns {boolean} whether the path is restricted
- * @private
- */
- function isRestrictedForEverythingImported(importSource, importNames) {
- return Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource) &&
- restrictedPathMessages[importSource].importNames &&
- isEverythingImported(importNames);
- }
-
- /**
- * Check if the given importNames are restricted given a list of restrictedImportNames.
- * @param {Set.} importNames Set of import names that are being imported
- * @param {string[]} restrictedImportNames array of import names that are restricted for this import
- * @returns {boolean} whether the objectName is restricted
- * @private
- */
- function isRestrictedObject(importNames, restrictedImportNames) {
- return restrictedImportNames.some(restrictedObjectName => (
- importNames.has(restrictedObjectName)
- ));
- }
-
- /**
- * Check if the given importSource is a restricted path.
- * @param {string} importSource path of the import
- * @param {Set.} importNames Set of import names that are being imported
- * @returns {boolean} whether the variable is a restricted path or not
- * @private
- */
- function isRestrictedPath(importSource, importNames) {
- let isRestricted = false;
-
- if (Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource)) {
- if (restrictedPathMessages[importSource].importNames) {
- isRestricted = isRestrictedObject(importNames, restrictedPathMessages[importSource].importNames);
- } else {
- isRestricted = true;
- }
- }
-
- return isRestricted;
- }
-
/**
* Check if the given importSource is restricted by a pattern.
* @param {string} importSource path of the import
@@ -248,26 +217,39 @@ module.exports = {
*/
function checkNode(node) {
const importSource = node.source.value.trim();
- const importNames = node.specifiers ? node.specifiers.reduce((set, specifier) => {
- if (specifier.type === "ImportDefaultSpecifier") {
- set.add("default");
- } else if (specifier.type === "ImportNamespaceSpecifier") {
- set.add("*");
- } else if (specifier.imported) {
- set.add(specifier.imported.name);
- } else if (specifier.local) {
- set.add(specifier.local.name);
- }
- return set;
- }, new Set()) : new Set();
+ const importNames = new Map();
+
+ if (node.type === "ExportAllDeclaration") {
+ const starToken = sourceCode.getFirstToken(node, 1);
+
+ importNames.set("*", [{ loc: starToken.loc }]);
+ } else if (node.specifiers) {
+ for (const specifier of node.specifiers) {
+ let name;
+ const specifierData = { loc: specifier.loc };
+
+ if (specifier.type === "ImportDefaultSpecifier") {
+ name = "default";
+ } else if (specifier.type === "ImportNamespaceSpecifier") {
+ name = "*";
+ } else if (specifier.imported) {
+ name = specifier.imported.name;
+ } else if (specifier.local) {
+ name = specifier.local.name;
+ }
- if (isRestrictedForEverythingImported(importSource, importNames)) {
- reportPathForEverythingImported(importSource, node);
+ if (name) {
+ if (importNames.has(name)) {
+ importNames.get(name).push(specifierData);
+ } else {
+ importNames.set(name, [specifierData]);
+ }
+ }
+ }
}
- if (isRestrictedPath(importSource, importNames)) {
- reportPath(node);
- }
+ checkRestrictedPathAndReport(importSource, importNames, node);
+
if (isRestrictedPattern(importSource)) {
reportPathForPatterns(node);
}
diff --git a/tools/node_modules/eslint/lib/rules/no-restricted-modules.js b/tools/node_modules/eslint/lib/rules/no-restricted-modules.js
index ef8748a7d04baf..abd8d5cbe29381 100644
--- a/tools/node_modules/eslint/lib/rules/no-restricted-modules.js
+++ b/tools/node_modules/eslint/lib/rules/no-restricted-modules.js
@@ -4,13 +4,6 @@
*/
"use strict";
-//------------------------------------------------------------------------------
-// Helpers
-//------------------------------------------------------------------------------
-
-const DEFAULT_MESSAGE_TEMPLATE = "'{{moduleName}}' module is restricted from being used.";
-const CUSTOM_MESSAGE_TEMPLATE = "'{{moduleName}}' module is restricted from being used. {{customMessage}}";
-
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -72,6 +65,13 @@ module.exports = {
additionalItems: false
}
]
+ },
+
+ messages: {
+ defaultMessage: "'{{name}}' module is restricted from being used.",
+ // eslint-disable-next-line eslint-plugin/report-message-format
+ customMessage: "'{{name}}' module is restricted from being used. {{customMessage}}",
+ patternMessage: "'{{name}}' module is restricted from being used by a pattern."
}
},
@@ -106,10 +106,19 @@ module.exports = {
* @param {ASTNode} node The node to check.
* @returns {boolean} If the node is a string literal.
*/
- function isString(node) {
+ function isStringLiteral(node) {
return node && node.type === "Literal" && typeof node.value === "string";
}
+ /**
+ * Function to check if a node is a static string template literal.
+ * @param {ASTNode} node The node to check.
+ * @returns {boolean} If the node is a string template literal.
+ */
+ function isStaticTemplateLiteral(node) {
+ return node && node.type === "TemplateLiteral" && node.expressions.length === 0;
+ }
+
/**
* Function to check if a node is a require call.
* @param {ASTNode} node The node to check.
@@ -119,24 +128,41 @@ module.exports = {
return node.callee.type === "Identifier" && node.callee.name === "require";
}
+ /**
+ * Extract string from Literal or TemplateLiteral node
+ * @param {ASTNode} node The node to extract from
+ * @returns {string|null} Extracted string or null if node doesn't represent a string
+ */
+ function getFirstArgumentString(node) {
+ if (isStringLiteral(node)) {
+ return node.value.trim();
+ }
+
+ if (isStaticTemplateLiteral(node)) {
+ return node.quasis[0].value.cooked.trim();
+ }
+
+ return null;
+ }
+
/**
* Report a restricted path.
* @param {node} node representing the restricted path reference
+ * @param {string} name restricted path
* @returns {void}
* @private
*/
- function reportPath(node) {
- const moduleName = node.arguments[0].value.trim();
- const customMessage = restrictedPathMessages[moduleName];
- const message = customMessage
- ? CUSTOM_MESSAGE_TEMPLATE
- : DEFAULT_MESSAGE_TEMPLATE;
+ function reportPath(node, name) {
+ const customMessage = restrictedPathMessages[name];
+ const messageId = customMessage
+ ? "customMessage"
+ : "defaultMessage";
context.report({
node,
- message,
+ messageId,
data: {
- moduleName,
+ name,
customMessage
}
});
@@ -156,21 +182,25 @@ module.exports = {
CallExpression(node) {
if (isRequireCall(node)) {
- // node has arguments and first argument is string
- if (node.arguments.length && isString(node.arguments[0])) {
- const moduleName = node.arguments[0].value.trim();
-
- // check if argument value is in restricted modules array
- if (isRestrictedPath(moduleName)) {
- reportPath(node);
- }
-
- if (restrictedPatterns.length > 0 && ig.ignores(moduleName)) {
- context.report({
- node,
- message: "'{{moduleName}}' module is restricted from being used by a pattern.",
- data: { moduleName }
- });
+ // node has arguments
+ if (node.arguments.length) {
+ const name = getFirstArgumentString(node.arguments[0]);
+
+ // if first argument is a string literal or a static string template literal
+ if (name) {
+
+ // check if argument value is in restricted modules array
+ if (isRestrictedPath(name)) {
+ reportPath(node, name);
+ }
+
+ if (restrictedPatterns.length > 0 && ig.ignores(name)) {
+ context.report({
+ node,
+ messageId: "patternMessage",
+ data: { name }
+ });
+ }
}
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-restricted-properties.js b/tools/node_modules/eslint/lib/rules/no-restricted-properties.js
index bdab22b19c4edc..7ab83995a3ebbf 100644
--- a/tools/node_modules/eslint/lib/rules/no-restricted-properties.js
+++ b/tools/node_modules/eslint/lib/rules/no-restricted-properties.js
@@ -61,6 +61,13 @@ module.exports = {
]
},
uniqueItems: true
+ },
+
+ messages: {
+ // eslint-disable-next-line eslint-plugin/report-message-format
+ restrictedObjectProperty: "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}",
+ // eslint-disable-next-line eslint-plugin/report-message-format
+ restrictedProperty: "'{{propertyName}}' is restricted from being used.{{message}}"
}
},
@@ -114,8 +121,7 @@ module.exports = {
context.report({
node,
- // eslint-disable-next-line eslint-plugin/report-message-format
- message: "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}",
+ messageId: "restrictedObjectProperty",
data: {
objectName,
propertyName,
@@ -127,8 +133,7 @@ module.exports = {
context.report({
node,
- // eslint-disable-next-line eslint-plugin/report-message-format
- message: "'{{propertyName}}' is restricted from being used.{{message}}",
+ messageId: "restrictedProperty",
data: {
propertyName,
message
diff --git a/tools/node_modules/eslint/lib/rules/no-restricted-syntax.js b/tools/node_modules/eslint/lib/rules/no-restricted-syntax.js
index 41aa9fa390a88d..9572603a82485a 100644
--- a/tools/node_modules/eslint/lib/rules/no-restricted-syntax.js
+++ b/tools/node_modules/eslint/lib/rules/no-restricted-syntax.js
@@ -39,6 +39,11 @@ module.exports = {
},
uniqueItems: true,
minItems: 0
+ },
+
+ messages: {
+ // eslint-disable-next-line eslint-plugin/report-message-format
+ restrictedSyntax: "{{message}}"
}
},
@@ -48,14 +53,14 @@ module.exports = {
const hasCustomMessage = !isStringFormat && Boolean(selectorOrObject.message);
const selector = isStringFormat ? selectorOrObject : selectorOrObject.selector;
- const message = hasCustomMessage ? selectorOrObject.message : "Using '{{selector}}' is not allowed.";
+ const message = hasCustomMessage ? selectorOrObject.message : `Using '${selector}' is not allowed.`;
return Object.assign(result, {
[selector](node) {
context.report({
node,
- message,
- data: hasCustomMessage ? {} : { selector }
+ messageId: "restrictedSyntax",
+ data: { message }
});
}
});
diff --git a/tools/node_modules/eslint/lib/rules/no-return-assign.js b/tools/node_modules/eslint/lib/rules/no-return-assign.js
index ea6a6bb49fcf6d..4b57d42eb9952b 100644
--- a/tools/node_modules/eslint/lib/rules/no-return-assign.js
+++ b/tools/node_modules/eslint/lib/rules/no-return-assign.js
@@ -35,7 +35,12 @@ module.exports = {
{
enum: ["except-parens", "always"]
}
- ]
+ ],
+
+ messages: {
+ returnAssignment: "Return statement should not contain assignment.",
+ arrowAssignment: "Arrow function should not return assignment."
+ }
},
create(context) {
@@ -61,12 +66,12 @@ module.exports = {
if (parent && parent.type === "ReturnStatement") {
context.report({
node: parent,
- message: "Return statement should not contain assignment."
+ messageId: "returnAssignment"
});
} else if (parent && parent.type === "ArrowFunctionExpression" && parent.body === currentChild) {
context.report({
node: parent,
- message: "Arrow function should not return assignment."
+ messageId: "arrowAssignment"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-return-await.js b/tools/node_modules/eslint/lib/rules/no-return-await.js
index 6652b5932dc1b8..d1d89826856dc4 100644
--- a/tools/node_modules/eslint/lib/rules/no-return-await.js
+++ b/tools/node_modules/eslint/lib/rules/no-return-await.js
@@ -10,8 +10,6 @@ const astUtils = require("./utils/ast-utils");
// Rule Definition
//------------------------------------------------------------------------------
-const message = "Redundant use of `await` on a return value.";
-
module.exports = {
meta: {
type: "suggestion",
@@ -28,7 +26,11 @@ module.exports = {
fixable: null,
schema: [
- ]
+ ],
+
+ messages: {
+ redundantUseOfAwait: "Redundant use of `await` on a return value."
+ }
},
create(context) {
@@ -42,7 +44,7 @@ module.exports = {
context.report({
node: context.getSourceCode().getFirstToken(node),
loc: node.loc,
- message
+ messageId: "redundantUseOfAwait"
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-script-url.js b/tools/node_modules/eslint/lib/rules/no-script-url.js
index 40e9bfe8b27544..2078fc1dcea122 100644
--- a/tools/node_modules/eslint/lib/rules/no-script-url.js
+++ b/tools/node_modules/eslint/lib/rules/no-script-url.js
@@ -22,7 +22,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-script-url"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedScriptURL: "Script URL is a form of eval."
+ }
},
create(context) {
@@ -34,7 +38,7 @@ module.exports = {
const value = node.value.toLowerCase();
if (value.indexOf("javascript:") === 0) {
- context.report({ node, message: "Script URL is a form of eval." });
+ context.report({ node, messageId: "unexpectedScriptURL" });
}
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-self-assign.js b/tools/node_modules/eslint/lib/rules/no-self-assign.js
index 705d0f409c4128..170e46b05930d1 100644
--- a/tools/node_modules/eslint/lib/rules/no-self-assign.js
+++ b/tools/node_modules/eslint/lib/rules/no-self-assign.js
@@ -196,7 +196,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ selfAssignment: "'{{name}}' is assigned to itself."
+ }
},
create(context) {
@@ -211,7 +215,7 @@ module.exports = {
function report(node) {
context.report({
node,
- message: "'{{name}}' is assigned to itself.",
+ messageId: "selfAssignment",
data: {
name: sourceCode.getText(node).replace(SPACES, "")
}
diff --git a/tools/node_modules/eslint/lib/rules/no-self-compare.js b/tools/node_modules/eslint/lib/rules/no-self-compare.js
index 8986240ec5c842..79b6ac7ea0f28d 100644
--- a/tools/node_modules/eslint/lib/rules/no-self-compare.js
+++ b/tools/node_modules/eslint/lib/rules/no-self-compare.js
@@ -21,7 +21,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-self-compare"
},
- schema: []
+ schema: [],
+
+ messages: {
+ comparingToSelf: "Comparing to itself is potentially pointless."
+ }
},
create(context) {
@@ -47,7 +51,7 @@ module.exports = {
const operators = new Set(["===", "==", "!==", "!=", ">", "<", ">=", "<="]);
if (operators.has(node.operator) && hasSameTokens(node.left, node.right)) {
- context.report({ node, message: "Comparing to itself is potentially pointless." });
+ context.report({ node, messageId: "comparingToSelf" });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-sequences.js b/tools/node_modules/eslint/lib/rules/no-sequences.js
index 8046a8711a3e9a..d67635d117549e 100644
--- a/tools/node_modules/eslint/lib/rules/no-sequences.js
+++ b/tools/node_modules/eslint/lib/rules/no-sequences.js
@@ -26,7 +26,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-sequences"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedCommaExpression: "Unexpected use of comma operator."
+ }
},
create(context) {
@@ -107,7 +111,7 @@ module.exports = {
const firstCommaToken = sourceCode.getTokenAfter(node.expressions[0], astUtils.isCommaToken);
- context.report({ node, loc: firstCommaToken.loc, message: "Unexpected use of comma operator." });
+ context.report({ node, loc: firstCommaToken.loc, messageId: "unexpectedCommaExpression" });
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-setter-return.js b/tools/node_modules/eslint/lib/rules/no-setter-return.js
index e0948696c347f5..a558640c357d92 100644
--- a/tools/node_modules/eslint/lib/rules/no-setter-return.js
+++ b/tools/node_modules/eslint/lib/rules/no-setter-return.js
@@ -145,7 +145,7 @@ module.exports = {
docs: {
description: "disallow returning values from setters",
category: "Possible Errors",
- recommended: false,
+ recommended: true,
url: "https://eslint.org/docs/rules/no-setter-return"
},
diff --git a/tools/node_modules/eslint/lib/rules/no-shadow-restricted-names.js b/tools/node_modules/eslint/lib/rules/no-shadow-restricted-names.js
index 9030d523b705d2..9647e9a1bcdd9e 100644
--- a/tools/node_modules/eslint/lib/rules/no-shadow-restricted-names.js
+++ b/tools/node_modules/eslint/lib/rules/no-shadow-restricted-names.js
@@ -32,7 +32,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-shadow-restricted-names"
},
- schema: []
+ schema: [],
+
+ messages: {
+ shadowingRestrictedName: "Shadowing of global property '{{name}}'."
+ }
},
create(context) {
@@ -46,9 +50,9 @@ module.exports = {
if (variable.defs.length > 0 && RESTRICTED.has(variable.name) && !safelyShadowsUndefined(variable)) {
context.report({
node: variable.defs[0].name,
- message: "Shadowing of global property '{{idName}}'.",
+ messageId: "shadowingRestrictedName",
data: {
- idName: variable.name
+ name: variable.name
}
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-shadow.js b/tools/node_modules/eslint/lib/rules/no-shadow.js
index bad6cb5f3094cc..1be8590e47abcb 100644
--- a/tools/node_modules/eslint/lib/rules/no-shadow.js
+++ b/tools/node_modules/eslint/lib/rules/no-shadow.js
@@ -41,7 +41,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ noShadow: "'{{name}}' is already declared in the upper scope."
+ }
},
create(context) {
@@ -163,7 +167,7 @@ module.exports = {
) {
context.report({
node: variable.identifiers[0],
- message: "'{{name}}' is already declared in the upper scope.",
+ messageId: "noShadow",
data: variable
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-spaced-func.js b/tools/node_modules/eslint/lib/rules/no-spaced-func.js
index 8535881f435e48..961bc681f7eac5 100644
--- a/tools/node_modules/eslint/lib/rules/no-spaced-func.js
+++ b/tools/node_modules/eslint/lib/rules/no-spaced-func.js
@@ -26,7 +26,11 @@ module.exports = {
replacedBy: ["func-call-spacing"],
fixable: "whitespace",
- schema: []
+ schema: [],
+
+ messages: {
+ noSpacedFunction: "Unexpected space between function name and paren."
+ }
},
create(context) {
@@ -62,7 +66,7 @@ module.exports = {
context.report({
node,
loc: lastCalleeToken.loc.start,
- message: "Unexpected space between function name and paren.",
+ messageId: "noSpacedFunction",
fix(fixer) {
return fixer.removeRange([prevToken.range[1], parenToken.range[0]]);
}
diff --git a/tools/node_modules/eslint/lib/rules/no-sparse-arrays.js b/tools/node_modules/eslint/lib/rules/no-sparse-arrays.js
index 985109c36b267d..e8407c3faede2d 100644
--- a/tools/node_modules/eslint/lib/rules/no-sparse-arrays.js
+++ b/tools/node_modules/eslint/lib/rules/no-sparse-arrays.js
@@ -19,7 +19,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-sparse-arrays"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedSparseArray: "Unexpected comma in middle of array."
+ }
},
create(context) {
@@ -36,7 +40,7 @@ module.exports = {
const emptySpot = node.elements.indexOf(null) > -1;
if (emptySpot) {
- context.report({ node, message: "Unexpected comma in middle of array." });
+ context.report({ node, messageId: "unexpectedSparseArray" });
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-sync.js b/tools/node_modules/eslint/lib/rules/no-sync.js
index 578bac96d3d061..d8111059631734 100644
--- a/tools/node_modules/eslint/lib/rules/no-sync.js
+++ b/tools/node_modules/eslint/lib/rules/no-sync.js
@@ -33,7 +33,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ noSync: "Unexpected sync method: '{{propertyName}}'."
+ }
},
create(context) {
@@ -45,7 +49,7 @@ module.exports = {
[selector](node) {
context.report({
node,
- message: "Unexpected sync method: '{{propertyName}}'.",
+ messageId: "noSync",
data: {
propertyName: node.property.name
}
diff --git a/tools/node_modules/eslint/lib/rules/no-tabs.js b/tools/node_modules/eslint/lib/rules/no-tabs.js
index 3fc0b78b6e741c..ca7be261653c02 100644
--- a/tools/node_modules/eslint/lib/rules/no-tabs.js
+++ b/tools/node_modules/eslint/lib/rules/no-tabs.js
@@ -35,7 +35,11 @@ module.exports = {
}
},
additionalProperties: false
- }]
+ }],
+
+ messages: {
+ unexpectedTab: "Unexpected tab character."
+ }
},
create(context) {
@@ -64,7 +68,7 @@ module.exports = {
column: match.index + match[0].length
}
},
- message: "Unexpected tab character."
+ messageId: "unexpectedTab"
});
}
});
diff --git a/tools/node_modules/eslint/lib/rules/no-template-curly-in-string.js b/tools/node_modules/eslint/lib/rules/no-template-curly-in-string.js
index f7822e961cc1e7..539cd5be5ff9c5 100644
--- a/tools/node_modules/eslint/lib/rules/no-template-curly-in-string.js
+++ b/tools/node_modules/eslint/lib/rules/no-template-curly-in-string.js
@@ -19,7 +19,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-template-curly-in-string"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedTemplateExpression: "Unexpected template string expression."
+ }
},
create(context) {
@@ -30,7 +34,7 @@ module.exports = {
if (typeof node.value === "string" && regex.test(node.value)) {
context.report({
node,
- message: "Unexpected template string expression."
+ messageId: "unexpectedTemplateExpression"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-ternary.js b/tools/node_modules/eslint/lib/rules/no-ternary.js
index 890f2abfa0c59a..b3ced86056614c 100644
--- a/tools/node_modules/eslint/lib/rules/no-ternary.js
+++ b/tools/node_modules/eslint/lib/rules/no-ternary.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-ternary"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noTernaryOperator: "Ternary operator used."
+ }
},
create(context) {
@@ -28,7 +32,7 @@ module.exports = {
return {
ConditionalExpression(node) {
- context.report({ node, message: "Ternary operator used." });
+ context.report({ node, messageId: "noTernaryOperator" });
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-this-before-super.js b/tools/node_modules/eslint/lib/rules/no-this-before-super.js
index 6975ea060bf00d..44288c0c97136e 100644
--- a/tools/node_modules/eslint/lib/rules/no-this-before-super.js
+++ b/tools/node_modules/eslint/lib/rules/no-this-before-super.js
@@ -45,7 +45,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-this-before-super"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noBeforeSuper: "'{{kind}}' is not allowed before 'super()'."
+ }
},
create(context) {
@@ -187,7 +191,7 @@ module.exports = {
const invalidNode = info.invalidNodes[i];
context.report({
- message: "'{{kind}}' is not allowed before 'super()'.",
+ messageId: "noBeforeSuper",
node: invalidNode,
data: {
kind: invalidNode.type === "Super" ? "super" : "this"
diff --git a/tools/node_modules/eslint/lib/rules/no-trailing-spaces.js b/tools/node_modules/eslint/lib/rules/no-trailing-spaces.js
index 3a4124f4c0f7a4..98ae62c896359c 100644
--- a/tools/node_modules/eslint/lib/rules/no-trailing-spaces.js
+++ b/tools/node_modules/eslint/lib/rules/no-trailing-spaces.js
@@ -42,7 +42,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ trailingSpace: "Trailing spaces not allowed."
+ }
},
create(context) {
@@ -74,7 +78,7 @@ module.exports = {
context.report({
node,
loc: location,
- message: "Trailing spaces not allowed.",
+ messageId: "trailingSpace",
fix(fixer) {
return fixer.removeRange(fixRange);
}
diff --git a/tools/node_modules/eslint/lib/rules/no-undef-init.js b/tools/node_modules/eslint/lib/rules/no-undef-init.js
index 1fdccb867b3c24..5c240fef742b83 100644
--- a/tools/node_modules/eslint/lib/rules/no-undef-init.js
+++ b/tools/node_modules/eslint/lib/rules/no-undef-init.js
@@ -23,7 +23,11 @@ module.exports = {
},
schema: [],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ unnecessaryUndefinedInit: "It's not necessary to initialize '{{name}}' to undefined."
+ }
},
create(context) {
@@ -43,7 +47,7 @@ module.exports = {
if (init === "undefined" && node.parent.kind !== "const" && !shadowed) {
context.report({
node,
- message: "It's not necessary to initialize '{{name}}' to undefined.",
+ messageId: "unnecessaryUndefinedInit",
data: { name },
fix(fixer) {
if (node.parent.kind === "var") {
diff --git a/tools/node_modules/eslint/lib/rules/no-undefined.js b/tools/node_modules/eslint/lib/rules/no-undefined.js
index b92f6700637c30..a075d903e21e98 100644
--- a/tools/node_modules/eslint/lib/rules/no-undefined.js
+++ b/tools/node_modules/eslint/lib/rules/no-undefined.js
@@ -19,7 +19,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-undefined"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedUndefined: "Unexpected use of undefined."
+ }
},
create(context) {
@@ -32,7 +36,7 @@ module.exports = {
function report(node) {
context.report({
node,
- message: "Unexpected use of undefined."
+ messageId: "unexpectedUndefined"
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-underscore-dangle.js b/tools/node_modules/eslint/lib/rules/no-underscore-dangle.js
index e910e2739a740a..cac594e10047e8 100644
--- a/tools/node_modules/eslint/lib/rules/no-underscore-dangle.js
+++ b/tools/node_modules/eslint/lib/rules/no-underscore-dangle.js
@@ -49,7 +49,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unexpectedUnderscore: "Unexpected dangling '_' in '{{identifier}}'."
+ }
},
create(context) {
@@ -134,7 +138,7 @@ module.exports = {
if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !isAllowed(identifier)) {
context.report({
node,
- message: "Unexpected dangling '_' in '{{identifier}}'.",
+ messageId: "unexpectedUnderscore",
data: {
identifier
}
@@ -156,7 +160,7 @@ module.exports = {
!isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) {
context.report({
node,
- message: "Unexpected dangling '_' in '{{identifier}}'.",
+ messageId: "unexpectedUnderscore",
data: {
identifier
}
@@ -183,7 +187,7 @@ module.exports = {
!isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) {
context.report({
node,
- message: "Unexpected dangling '_' in '{{identifier}}'.",
+ messageId: "unexpectedUnderscore",
data: {
identifier
}
@@ -201,10 +205,10 @@ module.exports = {
const identifier = node.key.name;
const isMethod = node.type === "MethodDefinition" || node.type === "Property" && node.method;
- if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasTrailingUnderscore(identifier)) {
+ if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasTrailingUnderscore(identifier) && !isAllowed(identifier)) {
context.report({
node,
- message: "Unexpected dangling '_' in '{{identifier}}'.",
+ messageId: "unexpectedUnderscore",
data: {
identifier
}
diff --git a/tools/node_modules/eslint/lib/rules/no-unmodified-loop-condition.js b/tools/node_modules/eslint/lib/rules/no-unmodified-loop-condition.js
index 3b8e7417d5b586..7031a4dd8b83fc 100644
--- a/tools/node_modules/eslint/lib/rules/no-unmodified-loop-condition.js
+++ b/tools/node_modules/eslint/lib/rules/no-unmodified-loop-condition.js
@@ -167,7 +167,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-unmodified-loop-condition"
},
- schema: []
+ schema: [],
+
+ messages: {
+ loopConditionNotModified: "'{{name}}' is not modified in this loop."
+ }
},
create(context) {
@@ -184,7 +188,7 @@ module.exports = {
context.report({
node,
- message: "'{{name}}' is not modified in this loop.",
+ messageId: "loopConditionNotModified",
data: node
});
}
diff --git a/tools/node_modules/eslint/lib/rules/no-unneeded-ternary.js b/tools/node_modules/eslint/lib/rules/no-unneeded-ternary.js
index 893baa34f74917..d4438e2fe08fbe 100644
--- a/tools/node_modules/eslint/lib/rules/no-unneeded-ternary.js
+++ b/tools/node_modules/eslint/lib/rules/no-unneeded-ternary.js
@@ -47,7 +47,12 @@ module.exports = {
}
],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ unnecessaryConditionalExpression: "Unnecessary use of boolean literals in conditional expression.",
+ unnecessaryConditionalAssignment: "Unnecessary use of conditional expression for default assignment."
+ }
},
create(context) {
@@ -118,7 +123,7 @@ module.exports = {
context.report({
node,
loc: node.consequent.loc.start,
- message: "Unnecessary use of boolean literals in conditional expression.",
+ messageId: "unnecessaryConditionalExpression",
fix(fixer) {
if (node.consequent.value === node.alternate.value) {
@@ -140,7 +145,7 @@ module.exports = {
context.report({
node,
loc: node.consequent.loc.start,
- message: "Unnecessary use of conditional expression for default assignment.",
+ messageId: "unnecessaryConditionalAssignment",
fix: fixer => {
const shouldParenthesizeAlternate = (
astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE &&
diff --git a/tools/node_modules/eslint/lib/rules/no-unreachable.js b/tools/node_modules/eslint/lib/rules/no-unreachable.js
index 91c4ca7150903f..415631a6f7d726 100644
--- a/tools/node_modules/eslint/lib/rules/no-unreachable.js
+++ b/tools/node_modules/eslint/lib/rules/no-unreachable.js
@@ -110,7 +110,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-unreachable"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unreachableCode: "Unreachable code."
+ }
},
create(context) {
@@ -154,7 +158,7 @@ module.exports = {
*/
if (!range.isEmpty) {
context.report({
- message: "Unreachable code.",
+ messageId: "unreachableCode",
loc: range.location,
node: range.startNode
});
diff --git a/tools/node_modules/eslint/lib/rules/no-unsafe-finally.js b/tools/node_modules/eslint/lib/rules/no-unsafe-finally.js
index a41dff9c80372f..11bf06e872a813 100644
--- a/tools/node_modules/eslint/lib/rules/no-unsafe-finally.js
+++ b/tools/node_modules/eslint/lib/rules/no-unsafe-finally.js
@@ -29,7 +29,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-unsafe-finally"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unsafeUsage: "Unsafe usage of {{nodeType}}."
+ }
},
create(context) {
@@ -86,7 +90,7 @@ module.exports = {
function check(node) {
if (isInFinallyBlock(node, node.label)) {
context.report({
- message: "Unsafe usage of {{nodeType}}.",
+ messageId: "unsafeUsage",
data: {
nodeType: node.type
},
diff --git a/tools/node_modules/eslint/lib/rules/no-unused-expressions.js b/tools/node_modules/eslint/lib/rules/no-unused-expressions.js
index fd0440256be016..26a25b7584bc80 100644
--- a/tools/node_modules/eslint/lib/rules/no-unused-expressions.js
+++ b/tools/node_modules/eslint/lib/rules/no-unused-expressions.js
@@ -38,7 +38,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unusedExpression: "Expected an assignment or function call and instead saw an expression."
+ }
},
create(context) {
@@ -127,7 +131,7 @@ module.exports = {
return {
ExpressionStatement(node) {
if (!isValidExpression(node.expression) && !isDirective(node, context.getAncestors())) {
- context.report({ node, message: "Expected an assignment or function call and instead saw an expression." });
+ context.report({ node, messageId: "unusedExpression" });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-unused-vars.js b/tools/node_modules/eslint/lib/rules/no-unused-vars.js
index 63e6e048ef1e46..18c48bf0d7810c 100644
--- a/tools/node_modules/eslint/lib/rules/no-unused-vars.js
+++ b/tools/node_modules/eslint/lib/rules/no-unused-vars.js
@@ -11,6 +11,18 @@
const astUtils = require("./utils/ast-utils");
+//------------------------------------------------------------------------------
+// Typedefs
+//------------------------------------------------------------------------------
+
+/**
+ * Bag of data used for formatting the `unusedVar` lint message.
+ * @typedef {Object} UnusedVarMessageData
+ * @property {string} varName The name of the unused var.
+ * @property {'defined'|'assigned a value'} action Description of the vars state.
+ * @property {string} additional Any additional info to be appended at the end.
+ */
+
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -60,7 +72,11 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ unusedVar: "'{{varName}}' is {{action}} but never used{{additional}}."
+ }
},
create(context) {
@@ -101,12 +117,12 @@ module.exports = {
}
/**
- * Generate the warning message about the variable being
- * defined and unused, including the ignore pattern if configured.
+ * Generates the message data about the variable being defined and unused,
+ * including the ignore pattern if configured.
* @param {Variable} unusedVar eslint-scope variable object.
- * @returns {string} The warning message to be used with this unused variable.
+ * @returns {UnusedVarMessageData} The message data to be used with this unused variable.
*/
- function getDefinedMessage(unusedVar) {
+ function getDefinedMessageData(unusedVar) {
const defType = unusedVar.defs && unusedVar.defs[0] && unusedVar.defs[0].type;
let type;
let pattern;
@@ -122,20 +138,29 @@ module.exports = {
pattern = config.varsIgnorePattern.toString();
}
- const additional = type ? ` Allowed unused ${type} must match ${pattern}.` : "";
+ const additional = type ? `. Allowed unused ${type} must match ${pattern}` : "";
- return `'{{name}}' is defined but never used.${additional}`;
+ return {
+ varName: unusedVar.name,
+ action: "defined",
+ additional
+ };
}
/**
* Generate the warning message about the variable being
* assigned and unused, including the ignore pattern if configured.
- * @returns {string} The warning message to be used with this unused variable.
+ * @param {Variable} unusedVar eslint-scope variable object.
+ * @returns {UnusedVarMessageData} The message data to be used with this unused variable.
*/
- function getAssignedMessage() {
- const additional = config.varsIgnorePattern ? ` Allowed unused vars must match ${config.varsIgnorePattern.toString()}.` : "";
-
- return `'{{name}}' is assigned a value but never used.${additional}`;
+ function getAssignedMessageData(unusedVar) {
+ const additional = config.varsIgnorePattern ? `. Allowed unused vars must match ${config.varsIgnorePattern.toString()}` : "";
+
+ return {
+ varName: unusedVar.name,
+ action: "assigned a value",
+ additional
+ };
}
//--------------------------------------------------------------------------
@@ -282,7 +307,7 @@ module.exports = {
function getRhsNode(ref, prevRhsNode) {
const id = ref.identifier;
const parent = id.parent;
- const granpa = parent.parent;
+ const grandparent = parent.parent;
const refScope = ref.from.variableScope;
const varScope = ref.resolved.scope.variableScope;
const canBeUsedLater = refScope !== varScope || astUtils.isInLoop(id);
@@ -296,7 +321,7 @@ module.exports = {
}
if (parent.type === "AssignmentExpression" &&
- granpa.type === "ExpressionStatement" &&
+ grandparent.type === "ExpressionStatement" &&
id === parent.left &&
!canBeUsedLater
) {
@@ -342,7 +367,7 @@ module.exports = {
/*
* If it encountered statements, this is a complex pattern.
- * Since analyzeing complex patterns is hard, this returns `true` to avoid false positive.
+ * Since analyzing complex patterns is hard, this returns `true` to avoid false positive.
*/
return true;
}
@@ -389,7 +414,7 @@ module.exports = {
function isReadForItself(ref, rhsNode) {
const id = ref.identifier;
const parent = id.parent;
- const granpa = parent.parent;
+ const grandparent = parent.parent;
return ref.isRead() && (
@@ -397,12 +422,12 @@ module.exports = {
(// in RHS of an assignment for itself. e.g. `a = a + 1`
((
parent.type === "AssignmentExpression" &&
- granpa.type === "ExpressionStatement" &&
+ grandparent.type === "ExpressionStatement" &&
parent.left === id
) ||
(
parent.type === "UpdateExpression" &&
- granpa.type === "ExpressionStatement"
+ grandparent.type === "ExpressionStatement"
) || rhsNode &&
isInside(id, rhsNode) &&
!isInsideOfStorableFunction(id, rhsNode)))
@@ -595,10 +620,10 @@ module.exports = {
if (unusedVar.defs.length > 0) {
context.report({
node: unusedVar.identifiers[0],
- message: unusedVar.references.some(ref => ref.isWrite())
- ? getAssignedMessage()
- : getDefinedMessage(unusedVar),
- data: unusedVar
+ messageId: "unusedVar",
+ data: unusedVar.references.some(ref => ref.isWrite())
+ ? getAssignedMessageData(unusedVar)
+ : getDefinedMessageData(unusedVar)
});
// If there are no regular declaration, report the first `/*globals*/` comment directive.
@@ -608,8 +633,8 @@ module.exports = {
context.report({
node: programNode,
loc: astUtils.getNameLocationInGlobalDirectiveComment(sourceCode, directiveComment, unusedVar.name),
- message: getDefinedMessage(unusedVar),
- data: unusedVar
+ messageId: "unusedVar",
+ data: getDefinedMessageData(unusedVar)
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-use-before-define.js b/tools/node_modules/eslint/lib/rules/no-use-before-define.js
index ed3540532f9095..c7300567ede0b7 100644
--- a/tools/node_modules/eslint/lib/rules/no-use-before-define.js
+++ b/tools/node_modules/eslint/lib/rules/no-use-before-define.js
@@ -157,7 +157,11 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ usedBeforeDefined: "'{{name}}' was used before it was defined."
+ }
},
create(context) {
@@ -212,7 +216,7 @@ module.exports = {
// Reports.
context.report({
node: reference.identifier,
- message: "'{{name}}' was used before it was defined.",
+ messageId: "usedBeforeDefined",
data: reference.identifier
});
});
diff --git a/tools/node_modules/eslint/lib/rules/no-useless-backreference.js b/tools/node_modules/eslint/lib/rules/no-useless-backreference.js
new file mode 100644
index 00000000000000..8a6fbe14daafe6
--- /dev/null
+++ b/tools/node_modules/eslint/lib/rules/no-useless-backreference.js
@@ -0,0 +1,193 @@
+/**
+ * @fileoverview Rule to disallow useless backreferences in regular expressions
+ * @author Milos Djermanovic
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const { CALL, CONSTRUCT, ReferenceTracker, getStringIfConstant } = require("eslint-utils");
+const { RegExpParser, visitRegExpAST } = require("regexpp");
+const lodash = require("lodash");
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+const parser = new RegExpParser();
+
+/**
+ * Finds the path from the given `regexpp` AST node to the root node.
+ * @param {regexpp.Node} node Node.
+ * @returns {regexpp.Node[]} Array that starts with the given node and ends with the root node.
+ */
+function getPathToRoot(node) {
+ const path = [];
+ let current = node;
+
+ do {
+ path.push(current);
+ current = current.parent;
+ } while (current);
+
+ return path;
+}
+
+/**
+ * Determines whether the given `regexpp` AST node is a lookaround node.
+ * @param {regexpp.Node} node Node.
+ * @returns {boolean} `true` if it is a lookaround node.
+ */
+function isLookaround(node) {
+ return node.type === "Assertion" &&
+ (node.kind === "lookahead" || node.kind === "lookbehind");
+}
+
+/**
+ * Determines whether the given `regexpp` AST node is a negative lookaround node.
+ * @param {regexpp.Node} node Node.
+ * @returns {boolean} `true` if it is a negative lookaround node.
+ */
+function isNegativeLookaround(node) {
+ return isLookaround(node) && node.negate;
+}
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ type: "problem",
+
+ docs: {
+ description: "disallow useless backreferences in regular expressions",
+ category: "Possible Errors",
+ recommended: false,
+ url: "https://eslint.org/docs/rules/no-useless-backreference"
+ },
+
+ schema: [],
+
+ messages: {
+ nested: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' from within that group.",
+ forward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears later in the pattern.",
+ backward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears before in the same lookbehind.",
+ disjunctive: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in another alternative.",
+ intoNegativeLookaround: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in a negative lookaround."
+ }
+ },
+
+ create(context) {
+
+ /**
+ * Checks and reports useless backreferences in the given regular expression.
+ * @param {ASTNode} node Node that represents regular expression. A regex literal or RegExp constructor call.
+ * @param {string} pattern Regular expression pattern.
+ * @param {string} flags Regular expression flags.
+ * @returns {void}
+ */
+ function checkRegex(node, pattern, flags) {
+ let regExpAST;
+
+ try {
+ regExpAST = parser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
+ } catch (e) {
+
+ // Ignore regular expressions with syntax errors
+ return;
+ }
+
+ visitRegExpAST(regExpAST, {
+ onBackreferenceEnter(bref) {
+ const group = bref.resolved,
+ brefPath = getPathToRoot(bref),
+ groupPath = getPathToRoot(group);
+ let messageId = null;
+
+ if (brefPath.includes(group)) {
+
+ // group is bref's ancestor => bref is nested ('nested reference') => group hasn't matched yet when bref starts to match.
+ messageId = "nested";
+ } else {
+
+ // Start from the root to find the lowest common ancestor.
+ let i = brefPath.length - 1,
+ j = groupPath.length - 1;
+
+ do {
+ i--;
+ j--;
+ } while (brefPath[i] === groupPath[j]);
+
+ const indexOfLowestCommonAncestor = j + 1,
+ groupCut = groupPath.slice(0, indexOfLowestCommonAncestor),
+ commonPath = groupPath.slice(indexOfLowestCommonAncestor),
+ lowestCommonLookaround = commonPath.find(isLookaround),
+ isMatchingBackward = lowestCommonLookaround && lowestCommonLookaround.kind === "lookbehind";
+
+ if (!isMatchingBackward && bref.end <= group.start) {
+
+ // bref is left, group is right ('forward reference') => group hasn't matched yet when bref starts to match.
+ messageId = "forward";
+ } else if (isMatchingBackward && group.end <= bref.start) {
+
+ // the opposite of the previous when the regex is matching backward in a lookbehind context.
+ messageId = "backward";
+ } else if (lodash.last(groupCut).type === "Alternative") {
+
+ // group's and bref's ancestor nodes below the lowest common ancestor are sibling alternatives => they're disjunctive.
+ messageId = "disjunctive";
+ } else if (groupCut.some(isNegativeLookaround)) {
+
+ // group is in a negative lookaround which isn't bref's ancestor => group has already failed when bref starts to match.
+ messageId = "intoNegativeLookaround";
+ }
+ }
+
+ if (messageId) {
+ context.report({
+ node,
+ messageId,
+ data: {
+ bref: bref.raw,
+ group: group.raw
+ }
+ });
+ }
+ }
+ });
+ }
+
+ return {
+ "Literal[regex]"(node) {
+ const { pattern, flags } = node.regex;
+
+ checkRegex(node, pattern, flags);
+ },
+ Program() {
+ const scope = context.getScope(),
+ tracker = new ReferenceTracker(scope),
+ traceMap = {
+ RegExp: {
+ [CALL]: true,
+ [CONSTRUCT]: true
+ }
+ };
+
+ for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
+ const [patternNode, flagsNode] = node.arguments,
+ pattern = getStringIfConstant(patternNode, scope),
+ flags = getStringIfConstant(flagsNode, scope);
+
+ if (typeof pattern === "string") {
+ checkRegex(node, pattern, flags || "");
+ }
+ }
+ }
+ };
+ }
+};
diff --git a/tools/node_modules/eslint/lib/rules/no-useless-call.js b/tools/node_modules/eslint/lib/rules/no-useless-call.js
index 11cf524d124211..afc729d5de0d9b 100644
--- a/tools/node_modules/eslint/lib/rules/no-useless-call.js
+++ b/tools/node_modules/eslint/lib/rules/no-useless-call.js
@@ -58,7 +58,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-useless-call"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unnecessaryCall: "Unnecessary '.{{name}}()'."
+ }
},
create(context) {
@@ -75,7 +79,7 @@ module.exports = {
const thisArg = node.arguments[0];
if (isValidThisArg(expectedThis, thisArg, sourceCode)) {
- context.report({ node, message: "unnecessary '.{{name}}()'.", data: { name: node.callee.property.name } });
+ context.report({ node, messageId: "unnecessaryCall", data: { name: node.callee.property.name } });
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-useless-catch.js b/tools/node_modules/eslint/lib/rules/no-useless-catch.js
index 37bf453aecd932..f303c272948489 100644
--- a/tools/node_modules/eslint/lib/rules/no-useless-catch.js
+++ b/tools/node_modules/eslint/lib/rules/no-useless-catch.js
@@ -20,7 +20,12 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-useless-catch"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unnecessaryCatchClause: "Unnecessary catch clause.",
+ unnecessaryCatch: "Unnecessary try/catch wrapper."
+ }
},
create(context) {
@@ -37,12 +42,12 @@ module.exports = {
if (node.parent.finalizer) {
context.report({
node,
- message: "Unnecessary catch clause."
+ messageId: "unnecessaryCatchClause"
});
} else {
context.report({
node: node.parent,
- message: "Unnecessary try/catch wrapper."
+ messageId: "unnecessaryCatch"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-useless-computed-key.js b/tools/node_modules/eslint/lib/rules/no-useless-computed-key.js
index b5e53174e42be7..e0505a318efaae 100644
--- a/tools/node_modules/eslint/lib/rules/no-useless-computed-key.js
+++ b/tools/node_modules/eslint/lib/rules/no-useless-computed-key.js
@@ -15,8 +15,6 @@ const astUtils = require("./utils/ast-utils");
// Rule Definition
//------------------------------------------------------------------------------
-const MESSAGE_UNNECESSARY_COMPUTED = "Unnecessarily computed property [{{property}}] found.";
-
module.exports = {
meta: {
type: "suggestion",
@@ -38,7 +36,11 @@ module.exports = {
},
additionalProperties: false
}],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ unnecessarilyComputedProperty: "Unnecessarily computed property [{{property}}] found."
+ }
},
create(context) {
const sourceCode = context.getSourceCode();
@@ -68,17 +70,14 @@ module.exports = {
if (key.type === "Literal" && (nodeType === "string" || nodeType === "number") && key.value !== allowedKey) {
context.report({
node,
- message: MESSAGE_UNNECESSARY_COMPUTED,
+ messageId: "unnecessarilyComputedProperty",
data: { property: sourceCode.getText(key) },
fix(fixer) {
- const leftSquareBracket = sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken);
- const rightSquareBracket = sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken);
- const tokensBetween = sourceCode.getTokensBetween(leftSquareBracket, rightSquareBracket, 1);
-
- if (tokensBetween.slice(0, -1).some((token, index) =>
- sourceCode.getText().slice(token.range[1], tokensBetween[index + 1].range[0]).trim())) {
+ const leftSquareBracket = sourceCode.getTokenBefore(key, astUtils.isOpeningBracketToken);
+ const rightSquareBracket = sourceCode.getTokenAfter(key, astUtils.isClosingBracketToken);
- // If there are comments between the brackets and the property name, don't do a fix.
+ // If there are comments between the brackets and the property name, don't do a fix.
+ if (sourceCode.commentsExistBetween(leftSquareBracket, rightSquareBracket)) {
return null;
}
diff --git a/tools/node_modules/eslint/lib/rules/no-useless-concat.js b/tools/node_modules/eslint/lib/rules/no-useless-concat.js
index cdaca273eb003f..aa46742abdd5ca 100644
--- a/tools/node_modules/eslint/lib/rules/no-useless-concat.js
+++ b/tools/node_modules/eslint/lib/rules/no-useless-concat.js
@@ -1,5 +1,5 @@
/**
- * @fileoverview disallow unncessary concatenation of template strings
+ * @fileoverview disallow unnecessary concatenation of template strings
* @author Henry Zhu
*/
"use strict";
@@ -75,7 +75,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-useless-concat"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedConcat: "Unexpected string concatenation of literals."
+ }
},
create(context) {
@@ -102,7 +106,7 @@ module.exports = {
context.report({
node,
loc: operatorToken.loc.start,
- message: "Unexpected string concatenation of literals."
+ messageId: "unexpectedConcat"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-useless-constructor.js b/tools/node_modules/eslint/lib/rules/no-useless-constructor.js
index 7cf033805f99d9..4c34aeda715937 100644
--- a/tools/node_modules/eslint/lib/rules/no-useless-constructor.js
+++ b/tools/node_modules/eslint/lib/rules/no-useless-constructor.js
@@ -115,7 +115,7 @@ function isPassingThrough(ctorParams, superArgs) {
* Checks whether the constructor body is a redundant super call.
* @param {Array} body constructor body content.
* @param {Array} ctorParams The params to check against super call.
- * @returns {boolean} true if the construtor body is redundant
+ * @returns {boolean} true if the constructor body is redundant
*/
function isRedundantSuperCall(body, ctorParams) {
return (
@@ -143,7 +143,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-useless-constructor"
},
- schema: []
+ schema: [],
+
+ messages: {
+ noUselessConstructor: "Useless constructor."
+ }
},
create(context) {
@@ -165,7 +169,7 @@ module.exports = {
if (superClass ? isRedundantSuperCall(body, ctorParams) : (body.length === 0)) {
context.report({
node,
- message: "Useless constructor."
+ messageId: "noUselessConstructor"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/no-useless-rename.js b/tools/node_modules/eslint/lib/rules/no-useless-rename.js
index eb570a3ef5c1d3..fa88f37f50b79c 100644
--- a/tools/node_modules/eslint/lib/rules/no-useless-rename.js
+++ b/tools/node_modules/eslint/lib/rules/no-useless-rename.js
@@ -32,7 +32,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unnecessarilyRenamed: "{{type}} {{name}} unnecessarily renamed."
+ }
},
create(context) {
@@ -59,7 +63,7 @@ module.exports = {
return context.report({
node,
- message: "{{type}} {{name}} unnecessarily renamed.",
+ messageId: "unnecessarilyRenamed",
data: {
name,
type
diff --git a/tools/node_modules/eslint/lib/rules/no-useless-return.js b/tools/node_modules/eslint/lib/rules/no-useless-return.js
index 942d4eede9964e..111cb21015fb81 100644
--- a/tools/node_modules/eslint/lib/rules/no-useless-return.js
+++ b/tools/node_modules/eslint/lib/rules/no-useless-return.js
@@ -32,7 +32,7 @@ function remove(array, element) {
/**
* Checks whether it can remove the given return statement or not.
* @param {ASTNode} node The return statement node to check.
- * @returns {boolean} `true` if the node is removeable.
+ * @returns {boolean} `true` if the node is removable.
*/
function isRemovable(node) {
return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type);
@@ -73,7 +73,11 @@ module.exports = {
},
fixable: "code",
- schema: []
+ schema: [],
+
+ messages: {
+ unnecessaryReturn: "Unnecessary return statement."
+ }
},
create(context) {
@@ -208,7 +212,7 @@ module.exports = {
context.report({
node,
loc: node.loc,
- message: "Unnecessary return statement.",
+ messageId: "unnecessaryReturn",
fix(fixer) {
if (isRemovable(node) && !sourceCode.getCommentsInside(node).length) {
diff --git a/tools/node_modules/eslint/lib/rules/no-var.js b/tools/node_modules/eslint/lib/rules/no-var.js
index 74203f8bf3bebf..f2cb96b1f708e9 100644
--- a/tools/node_modules/eslint/lib/rules/no-var.js
+++ b/tools/node_modules/eslint/lib/rules/no-var.js
@@ -191,7 +191,11 @@ module.exports = {
},
schema: [],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ unexpectedVar: "Unexpected var, use let or const instead."
+ }
},
create(context) {
@@ -307,7 +311,7 @@ module.exports = {
function report(node) {
context.report({
node,
- message: "Unexpected var, use let or const instead.",
+ messageId: "unexpectedVar",
fix(fixer) {
const varToken = sourceCode.getFirstToken(node, { filter: t => t.value === "var" });
diff --git a/tools/node_modules/eslint/lib/rules/no-void.js b/tools/node_modules/eslint/lib/rules/no-void.js
index d2b5d2f9631dff..99c83785552ab8 100644
--- a/tools/node_modules/eslint/lib/rules/no-void.js
+++ b/tools/node_modules/eslint/lib/rules/no-void.js
@@ -19,22 +19,46 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-void"
},
- schema: []
+ messages: {
+ noVoid: "Expected 'undefined' and instead saw 'void'."
+ },
+
+ schema: [
+ {
+ type: "object",
+ properties: {
+ allowAsStatement: {
+ type: "boolean",
+ default: false
+ }
+ },
+ additionalProperties: false
+ }
+ ]
},
create(context) {
+ const allowAsStatement =
+ context.options[0] && context.options[0].allowAsStatement;
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
- UnaryExpression(node) {
- if (node.operator === "void") {
- context.report({ node, message: "Expected 'undefined' and instead saw 'void'." });
+ 'UnaryExpression[operator="void"]'(node) {
+ if (
+ allowAsStatement &&
+ node.parent &&
+ node.parent.type === "ExpressionStatement"
+ ) {
+ return;
}
+ context.report({
+ node,
+ messageId: "noVoid"
+ });
}
};
-
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-warning-comments.js b/tools/node_modules/eslint/lib/rules/no-warning-comments.js
index a400c446767ff7..d70bd5dd5c4002 100644
--- a/tools/node_modules/eslint/lib/rules/no-warning-comments.js
+++ b/tools/node_modules/eslint/lib/rules/no-warning-comments.js
@@ -39,7 +39,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unexpectedComment: "Unexpected '{{matchedTerm}}' comment."
+ }
},
create(context) {
@@ -140,7 +144,7 @@ module.exports = {
matches.forEach(matchedTerm => {
context.report({
node,
- message: "Unexpected '{{matchedTerm}}' comment.",
+ messageId: "unexpectedComment",
data: {
matchedTerm
}
diff --git a/tools/node_modules/eslint/lib/rules/no-whitespace-before-property.js b/tools/node_modules/eslint/lib/rules/no-whitespace-before-property.js
index 9541401a3176b7..ccd0b091b744e3 100644
--- a/tools/node_modules/eslint/lib/rules/no-whitespace-before-property.js
+++ b/tools/node_modules/eslint/lib/rules/no-whitespace-before-property.js
@@ -26,7 +26,11 @@ module.exports = {
},
fixable: "whitespace",
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedWhitespace: "Unexpected whitespace before property {{propName}}."
+ }
},
create(context) {
@@ -49,7 +53,7 @@ module.exports = {
context.report({
node,
- message: "Unexpected whitespace before property {{propName}}.",
+ messageId: "unexpectedWhitespace",
data: {
propName: sourceCode.getText(node.property)
},
diff --git a/tools/node_modules/eslint/lib/rules/no-with.js b/tools/node_modules/eslint/lib/rules/no-with.js
index 5763661584c061..d3e52e02f3d15a 100644
--- a/tools/node_modules/eslint/lib/rules/no-with.js
+++ b/tools/node_modules/eslint/lib/rules/no-with.js
@@ -20,14 +20,18 @@ module.exports = {
url: "https://eslint.org/docs/rules/no-with"
},
- schema: []
+ schema: [],
+
+ messages: {
+ unexpectedWith: "Unexpected use of 'with' statement."
+ }
},
create(context) {
return {
WithStatement(node) {
- context.report({ node, message: "Unexpected use of 'with' statement." });
+ context.report({ node, messageId: "unexpectedWith" });
}
};
diff --git a/tools/node_modules/eslint/lib/rules/nonblock-statement-body-position.js b/tools/node_modules/eslint/lib/rules/nonblock-statement-body-position.js
index 01763cea92f381..34e6eeac39de50 100644
--- a/tools/node_modules/eslint/lib/rules/nonblock-statement-body-position.js
+++ b/tools/node_modules/eslint/lib/rules/nonblock-statement-body-position.js
@@ -40,7 +40,12 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ expectNoLinebreak: "Expected no linebreak before this statement.",
+ expectLinebreak: "Expected a linebreak before this statement."
+ }
},
create(context) {
@@ -79,13 +84,13 @@ module.exports = {
if (tokenBefore.loc.end.line === node.loc.start.line && option === "below") {
context.report({
node,
- message: "Expected a linebreak before this statement.",
+ messageId: "expectLinebreak",
fix: fixer => fixer.insertTextBefore(node, "\n")
});
} else if (tokenBefore.loc.end.line !== node.loc.start.line && option === "beside") {
context.report({
node,
- message: "Expected no linebreak before this statement.",
+ messageId: "expectNoLinebreak",
fix(fixer) {
if (sourceCode.getText().slice(tokenBefore.range[1], node.range[0]).trim()) {
return null;
diff --git a/tools/node_modules/eslint/lib/rules/object-curly-newline.js b/tools/node_modules/eslint/lib/rules/object-curly-newline.js
index e870a69a954180..b48b2526a0b2bd 100644
--- a/tools/node_modules/eslint/lib/rules/object-curly-newline.js
+++ b/tools/node_modules/eslint/lib/rules/object-curly-newline.js
@@ -159,7 +159,14 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ unexpectedLinebreakBeforeClosingBrace: "Unexpected line break before this closing brace.",
+ unexpectedLinebreakAfterOpeningBrace: "Unexpected line break after this opening brace.",
+ expectedLinebreakBeforeClosingBrace: "Expected a line break before this closing brace.",
+ expectedLinebreakAfterOpeningBrace: "Expected a line break after this opening brace."
+ }
},
create(context) {
@@ -215,7 +222,7 @@ module.exports = {
if (needsLineBreaks) {
if (astUtils.isTokenOnSameLine(openBrace, first)) {
context.report({
- message: "Expected a line break after this opening brace.",
+ messageId: "expectedLinebreakAfterOpeningBrace",
node,
loc: openBrace.loc.start,
fix(fixer) {
@@ -229,7 +236,7 @@ module.exports = {
}
if (astUtils.isTokenOnSameLine(last, closeBrace)) {
context.report({
- message: "Expected a line break before this closing brace.",
+ messageId: "expectedLinebreakBeforeClosingBrace",
node,
loc: closeBrace.loc.start,
fix(fixer) {
@@ -251,7 +258,7 @@ module.exports = {
(consistent && hasLineBreakBetweenOpenBraceAndFirst && !hasLineBreakBetweenCloseBraceAndLast)
) {
context.report({
- message: "Unexpected line break after this opening brace.",
+ messageId: "unexpectedLinebreakAfterOpeningBrace",
node,
loc: openBrace.loc.start,
fix(fixer) {
@@ -271,7 +278,7 @@ module.exports = {
(consistent && !hasLineBreakBetweenOpenBraceAndFirst && hasLineBreakBetweenCloseBraceAndLast)
) {
context.report({
- message: "Unexpected line break before this closing brace.",
+ messageId: "unexpectedLinebreakBeforeClosingBrace",
node,
loc: closeBrace.loc.start,
fix(fixer) {
diff --git a/tools/node_modules/eslint/lib/rules/object-curly-spacing.js b/tools/node_modules/eslint/lib/rules/object-curly-spacing.js
index 117a7a35426103..c0044f5033c005 100644
--- a/tools/node_modules/eslint/lib/rules/object-curly-spacing.js
+++ b/tools/node_modules/eslint/lib/rules/object-curly-spacing.js
@@ -39,7 +39,14 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ requireSpaceBefore: "A space is required before '{{token}}'.",
+ requireSpaceAfter: "A space is required after '{{token}}'.",
+ unexpectedSpaceBefore: "There should be no space before '{{token}}'.",
+ unexpectedSpaceAfter: "There should be no space after '{{token}}'."
+ }
},
create(context) {
@@ -79,7 +86,7 @@ module.exports = {
context.report({
node,
loc: { start: token.loc.end, end: nextToken.loc.start },
- message: "There should be no space after '{{token}}'.",
+ messageId: "unexpectedSpaceAfter",
data: {
token: token.value
},
@@ -101,7 +108,7 @@ module.exports = {
context.report({
node,
loc: { start: previousToken.loc.end, end: token.loc.start },
- message: "There should be no space before '{{token}}'.",
+ messageId: "unexpectedSpaceBefore",
data: {
token: token.value
},
@@ -121,7 +128,7 @@ module.exports = {
context.report({
node,
loc: token.loc,
- message: "A space is required after '{{token}}'.",
+ messageId: "requireSpaceAfter",
data: {
token: token.value
},
@@ -141,7 +148,7 @@ module.exports = {
context.report({
node,
loc: token.loc,
- message: "A space is required before '{{token}}'.",
+ messageId: "requireSpaceBefore",
data: {
token: token.value
},
diff --git a/tools/node_modules/eslint/lib/rules/object-property-newline.js b/tools/node_modules/eslint/lib/rules/object-property-newline.js
index bf777b5ff65ba2..074bc775ae35a3 100644
--- a/tools/node_modules/eslint/lib/rules/object-property-newline.js
+++ b/tools/node_modules/eslint/lib/rules/object-property-newline.js
@@ -37,16 +37,21 @@ module.exports = {
}
],
- fixable: "whitespace"
+ fixable: "whitespace",
+
+ messages: {
+ propertiesOnNewlineAll: "Object properties must go on a new line if they aren't all on the same line.",
+ propertiesOnNewline: "Object properties must go on a new line."
+ }
},
create(context) {
const allowSameLine = context.options[0] && (
(context.options[0].allowAllPropertiesOnSameLine || context.options[0].allowMultiplePropertiesPerLine /* Deprecated */)
);
- const errorMessage = allowSameLine
- ? "Object properties must go on a new line if they aren't all on the same line."
- : "Object properties must go on a new line.";
+ const messageId = allowSameLine
+ ? "propertiesOnNewlineAll"
+ : "propertiesOnNewline";
const sourceCode = context.getSourceCode();
@@ -73,7 +78,7 @@ module.exports = {
context.report({
node,
loc: firstTokenOfCurrentProperty.loc.start,
- message: errorMessage,
+ messageId,
fix(fixer) {
const comma = sourceCode.getTokenBefore(firstTokenOfCurrentProperty);
const rangeAfterComma = [comma.range[1], firstTokenOfCurrentProperty.range[0]];
diff --git a/tools/node_modules/eslint/lib/rules/object-shorthand.js b/tools/node_modules/eslint/lib/rules/object-shorthand.js
index d4afd09c5a52c4..3999ff8b99fb29 100644
--- a/tools/node_modules/eslint/lib/rules/object-shorthand.js
+++ b/tools/node_modules/eslint/lib/rules/object-shorthand.js
@@ -92,6 +92,16 @@ module.exports = {
maxItems: 2
}
]
+ },
+
+ messages: {
+ expectedAllPropertiesShorthanded: "Expected shorthand for all properties.",
+ expectedLiteralMethodLongform: "Expected longform method syntax for string literal keys.",
+ expectedPropertyShorthand: "Expected property shorthand.",
+ expectedPropertyLongform: "Expected longform property syntax.",
+ expectedMethodShorthand: "Expected method shorthand.",
+ expectedMethodLongform: "Expected longform method syntax.",
+ unexpectedMix: "Unexpected mix of shorthand and non-shorthand properties."
}
},
@@ -211,7 +221,7 @@ module.exports = {
// We have at least 1 shorthand property
if (shorthandProperties.length > 0) {
- context.report({ node, message: "Unexpected mix of shorthand and non-shorthand properties." });
+ context.report({ node, messageId: "unexpectedMix" });
} else if (checkRedundancy) {
/*
@@ -221,7 +231,7 @@ module.exports = {
const canAlwaysUseShorthand = properties.every(isRedundant);
if (canAlwaysUseShorthand) {
- context.report({ node, message: "Expected shorthand for all properties." });
+ context.report({ node, messageId: "expectedAllPropertiesShorthanded" });
}
}
}
@@ -430,12 +440,12 @@ module.exports = {
// Checks for property/method shorthand.
if (isConciseProperty) {
if (node.method && (APPLY_NEVER || AVOID_QUOTES && isStringLiteral(node.key))) {
- const message = APPLY_NEVER ? "Expected longform method syntax." : "Expected longform method syntax for string literal keys.";
+ const messageId = APPLY_NEVER ? "expectedMethodLongform" : "expectedLiteralMethodLongform";
// { x() {} } should be written as { x: function() {} }
context.report({
node,
- message,
+ messageId,
fix: fixer => makeFunctionLongform(fixer, node)
});
} else if (APPLY_NEVER) {
@@ -443,7 +453,7 @@ module.exports = {
// { x } should be written as { x: x }
context.report({
node,
- message: "Expected longform property syntax.",
+ messageId: "expectedPropertyLongform",
fix: fixer => fixer.insertTextAfter(node.key, `: ${node.key.name}`)
});
}
@@ -464,7 +474,7 @@ module.exports = {
) {
context.report({
node,
- message: "Expected method shorthand.",
+ messageId: "expectedMethodShorthand",
fix: fixer => makeFunctionShorthand(fixer, node)
});
}
@@ -473,7 +483,7 @@ module.exports = {
// {x: x} should be written as {x}
context.report({
node,
- message: "Expected property shorthand.",
+ messageId: "expectedPropertyShorthand",
fix(fixer) {
return fixer.replaceText(node, node.value.name);
}
@@ -486,7 +496,7 @@ module.exports = {
// {"x": x} should be written as {x}
context.report({
node,
- message: "Expected property shorthand.",
+ messageId: "expectedPropertyShorthand",
fix(fixer) {
return fixer.replaceText(node, node.value.name);
}
diff --git a/tools/node_modules/eslint/lib/rules/one-var-declaration-per-line.js b/tools/node_modules/eslint/lib/rules/one-var-declaration-per-line.js
index b64656eefed0a9..30ca2cf49834fe 100644
--- a/tools/node_modules/eslint/lib/rules/one-var-declaration-per-line.js
+++ b/tools/node_modules/eslint/lib/rules/one-var-declaration-per-line.js
@@ -25,12 +25,15 @@ module.exports = {
}
],
- fixable: "whitespace"
+ fixable: "whitespace",
+
+ messages: {
+ expectVarOnNewline: "Expected variable declaration to be on a new line."
+ }
},
create(context) {
- const ERROR_MESSAGE = "Expected variable declaration to be on a new line.";
const always = context.options[0] === "always";
//--------------------------------------------------------------------------
@@ -67,7 +70,7 @@ module.exports = {
if (always || prev.init || current.init) {
context.report({
node,
- message: ERROR_MESSAGE,
+ messageId: "expectVarOnNewline",
loc: current.loc.start,
fix: fixer => fixer.insertTextBefore(current, "\n")
});
diff --git a/tools/node_modules/eslint/lib/rules/one-var.js b/tools/node_modules/eslint/lib/rules/one-var.js
index e79461ce46c5be..c31a0d2b13c187 100644
--- a/tools/node_modules/eslint/lib/rules/one-var.js
+++ b/tools/node_modules/eslint/lib/rules/one-var.js
@@ -60,7 +60,17 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ combineUninitialized: "Combine this with the previous '{{type}}' statement with uninitialized variables.",
+ combineInitialized: "Combine this with the previous '{{type}}' statement with initialized variables.",
+ splitUninitialized: "Split uninitialized '{{type}}' declarations into multiple statements.",
+ splitInitialized: "Split initialized '{{type}}' declarations into multiple statements.",
+ splitRequires: "Split requires to be separated into a single block.",
+ combine: "Combine this with the previous '{{type}}' statement.",
+ split: "Split '{{type}}' declarations into multiple statements."
+ }
},
create(context) {
@@ -361,7 +371,7 @@ module.exports = {
if (options.separateRequires && mixedRequires) {
context.report({
node,
- message: "Split requires to be separated into a single block."
+ messageId: "splitRequires"
});
}
}
@@ -384,7 +394,7 @@ module.exports = {
if (options[type].initialized === MODE_CONSECUTIVE && options[type].uninitialized === MODE_CONSECUTIVE) {
context.report({
node,
- message: "Combine this with the previous '{{type}}' statement.",
+ messageId: "combine",
data: {
type
},
@@ -393,7 +403,7 @@ module.exports = {
} else if (options[type].initialized === MODE_CONSECUTIVE && declarationCounts.initialized > 0 && previousDeclCounts.initialized > 0) {
context.report({
node,
- message: "Combine this with the previous '{{type}}' statement with initialized variables.",
+ messageId: "combineInitialized",
data: {
type
},
@@ -404,7 +414,7 @@ module.exports = {
previousDeclCounts.uninitialized > 0) {
context.report({
node,
- message: "Combine this with the previous '{{type}}' statement with uninitialized variables.",
+ messageId: "combineUninitialized",
data: {
type
},
@@ -419,7 +429,7 @@ module.exports = {
if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) {
context.report({
node,
- message: "Combine this with the previous '{{type}}' statement.",
+ messageId: "combine",
data: {
type
},
@@ -429,7 +439,7 @@ module.exports = {
if (options[type].initialized === MODE_ALWAYS && declarationCounts.initialized > 0) {
context.report({
node,
- message: "Combine this with the previous '{{type}}' statement with initialized variables.",
+ messageId: "combineInitialized",
data: {
type
},
@@ -442,7 +452,7 @@ module.exports = {
}
context.report({
node,
- message: "Combine this with the previous '{{type}}' statement with uninitialized variables.",
+ messageId: "combineUninitialized",
data: {
type
},
@@ -462,7 +472,7 @@ module.exports = {
// both initialized and uninitialized
context.report({
node,
- message: "Split '{{type}}' declarations into multiple statements.",
+ messageId: "split",
data: {
type
},
@@ -473,7 +483,7 @@ module.exports = {
// initialized
context.report({
node,
- message: "Split initialized '{{type}}' declarations into multiple statements.",
+ messageId: "splitInitialized",
data: {
type
},
@@ -484,7 +494,7 @@ module.exports = {
// uninitialized
context.report({
node,
- message: "Split uninitialized '{{type}}' declarations into multiple statements.",
+ messageId: "splitUninitialized",
data: {
type
},
diff --git a/tools/node_modules/eslint/lib/rules/operator-assignment.js b/tools/node_modules/eslint/lib/rules/operator-assignment.js
index b19ba0d02e1a1b..c4c8671f327a93 100644
--- a/tools/node_modules/eslint/lib/rules/operator-assignment.js
+++ b/tools/node_modules/eslint/lib/rules/operator-assignment.js
@@ -26,10 +26,10 @@ function isCommutativeOperatorWithShorthand(operator) {
}
/**
- * Checks whether an operator is not commuatative and has an operator assignment
+ * Checks whether an operator is not commutative and has an operator assignment
* shorthand form.
* @param {string} operator Operator to check.
- * @returns {boolean} True if the operator is not commuatative and has
+ * @returns {boolean} True if the operator is not commutative and has
* a shorthand form.
*/
function isNonCommutativeOperatorWithShorthand(operator) {
@@ -219,7 +219,7 @@ module.exports = {
if (
operatorToken.range[1] === firstRightToken.range[0] &&
- !astUtils.canTokensBeAdjacent(newOperator, firstRightToken)
+ !astUtils.canTokensBeAdjacent({ type: "Punctuator", value: newOperator }, firstRightToken)
) {
rightTextPrefix = " "; // foo+=+bar -> foo= foo+ +bar
}
diff --git a/tools/node_modules/eslint/lib/rules/operator-linebreak.js b/tools/node_modules/eslint/lib/rules/operator-linebreak.js
index bce0ef56a0cc6c..c2fddcffd25c7f 100644
--- a/tools/node_modules/eslint/lib/rules/operator-linebreak.js
+++ b/tools/node_modules/eslint/lib/rules/operator-linebreak.js
@@ -47,7 +47,14 @@ module.exports = {
}
],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ operatorAtBeginning: "'{{operator}}' should be placed at the beginning of the line.",
+ operatorAtEnd: "'{{operator}}' should be placed at the end of the line.",
+ badLinebreak: "Bad line breaking before and after '{{operator}}'.",
+ noLinebreak: "There should be no line break before or after '{{operator}}'."
+ }
},
create(context) {
@@ -169,7 +176,7 @@ module.exports = {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
},
- message: "Bad line breaking before and after '{{operator}}'.",
+ messageId: "badLinebreak",
data: {
operator
},
@@ -184,7 +191,7 @@ module.exports = {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
},
- message: "'{{operator}}' should be placed at the beginning of the line.",
+ messageId: "operatorAtBeginning",
data: {
operator
},
@@ -199,7 +206,7 @@ module.exports = {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
},
- message: "'{{operator}}' should be placed at the end of the line.",
+ messageId: "operatorAtEnd",
data: {
operator
},
@@ -214,7 +221,7 @@ module.exports = {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
},
- message: "There should be no line break before or after '{{operator}}'.",
+ messageId: "noLinebreak",
data: {
operator
},
diff --git a/tools/node_modules/eslint/lib/rules/padded-blocks.js b/tools/node_modules/eslint/lib/rules/padded-blocks.js
index dafa88115edd78..f58a7535ba86c2 100644
--- a/tools/node_modules/eslint/lib/rules/padded-blocks.js
+++ b/tools/node_modules/eslint/lib/rules/padded-blocks.js
@@ -60,7 +60,12 @@ module.exports = {
}
}
}
- ]
+ ],
+
+ messages: {
+ alwaysPadBlock: "Block must be padded by blank lines.",
+ neverPadBlock: "Block must not be padded by blank lines."
+ }
},
create(context) {
@@ -90,9 +95,6 @@ module.exports = {
options.allowSingleLineBlocks = exceptOptions.allowSingleLineBlocks === true;
}
- const ALWAYS_MESSAGE = "Block must be padded by blank lines.",
- NEVER_MESSAGE = "Block must not be padded by blank lines.";
-
const sourceCode = context.getSourceCode();
/**
@@ -145,9 +147,9 @@ module.exports = {
}
/**
- * Checks if the given token is preceeded by a blank line.
+ * Checks if the given token is preceded by a blank line.
* @param {Token} token The token to check
- * @returns {boolean} Whether or not the token is preceeded by a blank line
+ * @returns {boolean} Whether or not the token is preceded by a blank line
*/
function getLastBlockToken(token) {
let last = token,
@@ -208,7 +210,7 @@ module.exports = {
fix(fixer) {
return fixer.insertTextAfter(tokenBeforeFirst, "\n");
},
- message: ALWAYS_MESSAGE
+ messageId: "alwaysPadBlock"
});
}
if (!blockHasBottomPadding) {
@@ -218,7 +220,7 @@ module.exports = {
fix(fixer) {
return fixer.insertTextBefore(tokenAfterLast, "\n");
},
- message: ALWAYS_MESSAGE
+ messageId: "alwaysPadBlock"
});
}
} else {
@@ -230,7 +232,7 @@ module.exports = {
fix(fixer) {
return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n");
},
- message: NEVER_MESSAGE
+ messageId: "neverPadBlock"
});
}
@@ -239,7 +241,7 @@ module.exports = {
context.report({
node,
loc: { line: tokenAfterLast.loc.end.line, column: tokenAfterLast.loc.end.column - 1 },
- message: NEVER_MESSAGE,
+ messageId: "neverPadBlock",
fix(fixer) {
return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n");
}
diff --git a/tools/node_modules/eslint/lib/rules/padding-line-between-statements.js b/tools/node_modules/eslint/lib/rules/padding-line-between-statements.js
index 350a9dbf2aba15..eea19f5ce5811b 100644
--- a/tools/node_modules/eslint/lib/rules/padding-line-between-statements.js
+++ b/tools/node_modules/eslint/lib/rules/padding-line-between-statements.js
@@ -243,7 +243,7 @@ function verifyForNever(context, _, nextNode, paddingLines) {
context.report({
node: nextNode,
- message: "Unexpected blank line before this statement.",
+ messageId: "unexpectedBlankLine",
fix(fixer) {
if (paddingLines.length >= 2) {
return null;
@@ -282,7 +282,7 @@ function verifyForAlways(context, prevNode, nextNode, paddingLines) {
context.report({
node: nextNode,
- message: "Expected blank line before this statement.",
+ messageId: "expectedBlankLine",
fix(fixer) {
const sourceCode = context.getSourceCode();
let prevToken = getActualLastToken(sourceCode, prevNode);
@@ -468,6 +468,11 @@ module.exports = {
required: ["blankLine", "prev", "next"]
},
additionalItems: false
+ },
+
+ messages: {
+ unexpectedBlankLine: "Unexpected blank line before this statement.",
+ expectedBlankLine: "Expected blank line before this statement."
}
},
diff --git a/tools/node_modules/eslint/lib/rules/prefer-arrow-callback.js b/tools/node_modules/eslint/lib/rules/prefer-arrow-callback.js
index 08126e5b1a5459..d4e0251940c503 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-arrow-callback.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-arrow-callback.js
@@ -56,7 +56,7 @@ function getVariableOfArguments(scope) {
}
/**
- * Checkes whether or not a given node is a callback.
+ * Checks whether or not a given node is a callback.
* @param {ASTNode} node A node to check.
* @returns {Object}
* {boolean} retv.isCallback - `true` if the node is a callback.
@@ -158,7 +158,11 @@ module.exports = {
}
],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ preferArrowCallback: "Unexpected function expression."
+ }
},
create(context) {
@@ -267,7 +271,7 @@ module.exports = {
) {
context.report({
node,
- message: "Unexpected function expression.",
+ messageId: "preferArrowCallback",
fix(fixer) {
if ((!callbackInfo.isLexicalThis && scopeInfo.this) || hasDuplicateParams(node.params)) {
diff --git a/tools/node_modules/eslint/lib/rules/prefer-destructuring.js b/tools/node_modules/eslint/lib/rules/prefer-destructuring.js
index eff37294a9b6ef..1a51956dde53ff 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-destructuring.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-destructuring.js
@@ -82,7 +82,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ preferDestructuring: "Use {{type}} destructuring."
+ }
},
create(context) {
@@ -137,7 +141,7 @@ module.exports = {
function report(reportNode, type, fix) {
context.report({
node: reportNode,
- message: "Use {{type}} destructuring.",
+ messageId: "preferDestructuring",
data: { type },
fix
});
diff --git a/tools/node_modules/eslint/lib/rules/prefer-object-spread.js b/tools/node_modules/eslint/lib/rules/prefer-object-spread.js
index bbcd88bee3d071..1344433f52fa93 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-object-spread.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-object-spread.js
@@ -25,6 +25,36 @@ function hasArraySpread(node) {
return node.arguments.some(arg => arg.type === "SpreadElement");
}
+/**
+ * Determines whether the given node is an accessor property (getter/setter).
+ * @param {ASTNode} node Node to check.
+ * @returns {boolean} `true` if the node is a getter or a setter.
+ */
+function isAccessorProperty(node) {
+ return node.type === "Property" &&
+ (node.kind === "get" || node.kind === "set");
+}
+
+/**
+ * Determines whether the given object expression node has accessor properties (getters/setters).
+ * @param {ASTNode} node `ObjectExpression` node to check.
+ * @returns {boolean} `true` if the node has at least one getter/setter.
+ */
+function hasAccessors(node) {
+ return node.properties.some(isAccessorProperty);
+}
+
+/**
+ * Determines whether the given call expression node has object expression arguments with accessor properties (getters/setters).
+ * @param {ASTNode} node `CallExpression` node to check.
+ * @returns {boolean} `true` if the node has at least one argument that is an object expression with at least one getter/setter.
+ */
+function hasArgumentsWithAccessors(node) {
+ return node.arguments
+ .filter(arg => arg.type === "ObjectExpression")
+ .some(hasAccessors);
+}
+
/**
* Helper that checks if the node needs parentheses to be valid JS.
* The default is to wrap the node in parentheses to avoid parsing errors.
@@ -68,7 +98,7 @@ function argNeedsParens(node, sourceCode) {
/**
* Get the parenthesis tokens of a given ObjectExpression node.
- * This incldues the braces of the object literal and enclosing parentheses.
+ * This includes the braces of the object literal and enclosing parentheses.
* @param {ASTNode} node The node to get.
* @param {Token} leftArgumentListParen The opening paren token of the argument list.
* @param {SourceCode} sourceCode The source code object to get tokens.
@@ -249,7 +279,11 @@ module.exports = {
if (
node.arguments.length >= 1 &&
node.arguments[0].type === "ObjectExpression" &&
- !hasArraySpread(node)
+ !hasArraySpread(node) &&
+ !(
+ node.arguments.length > 1 &&
+ hasArgumentsWithAccessors(node)
+ )
) {
const messageId = node.arguments.length === 1
? "useLiteralMessage"
diff --git a/tools/node_modules/eslint/lib/rules/prefer-promise-reject-errors.js b/tools/node_modules/eslint/lib/rules/prefer-promise-reject-errors.js
index e142a96b55c78f..56911b67adcc99 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-promise-reject-errors.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-promise-reject-errors.js
@@ -31,7 +31,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ rejectAnError: "Expected the Promise rejection reason to be an Error."
+ }
},
create(context) {
@@ -58,7 +62,7 @@ module.exports = {
) {
context.report({
node: callExpression,
- message: "Expected the Promise rejection reason to be an Error."
+ messageId: "rejectAnError"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/prefer-reflect.js b/tools/node_modules/eslint/lib/rules/prefer-reflect.js
index 796bbdf05fd446..fb2de923bea379 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-reflect.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-reflect.js
@@ -49,7 +49,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ preferReflect: "Avoid using {{existing}}, instead use {{substitute}}."
+ }
},
create(context) {
@@ -65,7 +69,7 @@ module.exports = {
preventExtensions: "Object.preventExtensions"
};
- const reflectSubsitutes = {
+ const reflectSubstitutes = {
apply: "Reflect.apply",
call: "Reflect.apply",
defineProperty: "Reflect.defineProperty",
@@ -89,7 +93,7 @@ module.exports = {
function report(node, existing, substitute) {
context.report({
node,
- message: "Avoid using {{existing}}, instead use {{substitute}}.",
+ messageId: "preferReflect",
data: {
existing,
substitute
@@ -101,11 +105,11 @@ module.exports = {
CallExpression(node) {
const methodName = (node.callee.property || {}).name;
const isReflectCall = (node.callee.object || {}).name === "Reflect";
- const hasReflectSubsitute = Object.prototype.hasOwnProperty.call(reflectSubsitutes, methodName);
+ const hasReflectSubsitute = Object.prototype.hasOwnProperty.call(reflectSubstitutes, methodName);
const userConfiguredException = exceptions.indexOf(methodName) !== -1;
if (hasReflectSubsitute && !isReflectCall && !userConfiguredException) {
- report(node, existingNames[methodName], reflectSubsitutes[methodName]);
+ report(node, existingNames[methodName], reflectSubstitutes[methodName]);
}
},
UnaryExpression(node) {
diff --git a/tools/node_modules/eslint/lib/rules/prefer-rest-params.js b/tools/node_modules/eslint/lib/rules/prefer-rest-params.js
index 3a28584f6bc126..3ecea732af8b94 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-rest-params.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-rest-params.js
@@ -70,7 +70,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/prefer-rest-params"
},
- schema: []
+ schema: [],
+
+ messages: {
+ preferRestParams: "Use the rest parameters instead of 'arguments'."
+ }
},
create(context) {
@@ -84,7 +88,7 @@ module.exports = {
context.report({
node: reference.identifier,
loc: reference.identifier.loc,
- message: "Use the rest parameters instead of 'arguments'."
+ messageId: "preferRestParams"
});
}
diff --git a/tools/node_modules/eslint/lib/rules/prefer-spread.js b/tools/node_modules/eslint/lib/rules/prefer-spread.js
index 14c05bd97103de..bcb0dc0dd4c1a9 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-spread.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-spread.js
@@ -59,7 +59,11 @@ module.exports = {
},
schema: [],
- fixable: null
+ fixable: null,
+
+ messages: {
+ preferSpread: "Use the spread operator instead of '.apply()'."
+ }
},
create(context) {
@@ -78,7 +82,7 @@ module.exports = {
if (isValidThisArg(expectedThis, thisArg, sourceCode)) {
context.report({
node,
- message: "Use the spread operator instead of '.apply()'."
+ messageId: "preferSpread"
});
}
}
diff --git a/tools/node_modules/eslint/lib/rules/prefer-template.js b/tools/node_modules/eslint/lib/rules/prefer-template.js
index fa6e58d9721e12..e8f980ebd38c6f 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-template.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-template.js
@@ -142,7 +142,11 @@ module.exports = {
},
schema: [],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ unexpectedStringConcatenation: "Unexpected string concatenation."
+ }
},
create(context) {
@@ -261,7 +265,7 @@ module.exports = {
if (hasNonStringLiteral(topBinaryExpr)) {
context.report({
node: topBinaryExpr,
- message: "Unexpected string concatenation.",
+ messageId: "unexpectedStringConcatenation",
fix: fixer => fixNonStringBinaryExpression(fixer, node)
});
}
diff --git a/tools/node_modules/eslint/lib/rules/quote-props.js b/tools/node_modules/eslint/lib/rules/quote-props.js
index ab09b8fa938e63..a2a4e1d47923ff 100644
--- a/tools/node_modules/eslint/lib/rules/quote-props.js
+++ b/tools/node_modules/eslint/lib/rules/quote-props.js
@@ -8,8 +8,9 @@
// Requirements
//------------------------------------------------------------------------------
-const espree = require("espree"),
- keywords = require("./utils/keywords");
+const espree = require("espree");
+const astUtils = require("./utils/ast-utils");
+const keywords = require("./utils/keywords");
//------------------------------------------------------------------------------
// Rule Definition
@@ -66,7 +67,16 @@ module.exports = {
]
},
- fixable: "code"
+ fixable: "code",
+ messages: {
+ requireQuotesDueToReservedWord: "Properties should be quoted as '{{property}}' is a reserved word.",
+ inconsistentlyQuotedProperty: "Inconsistently quoted property '{{key}}' found.",
+ unnecessarilyQuotedProperty: "Unnecessarily quoted property '{{property}}' found.",
+ unquotedReservedProperty: "Unquoted reserved word '{{property}}' used as key.",
+ unquotedNumericProperty: "Unquoted number literal '{{property}}' used as key.",
+ unquotedPropertyFound: "Unquoted property '{{property}}' found.",
+ redundantQuoting: "Properties shouldn't be quoted as all quotes are redundant."
+ }
},
create(context) {
@@ -76,10 +86,6 @@ module.exports = {
CHECK_UNNECESSARY = !context.options[1] || context.options[1].unnecessary !== false,
NUMBERS = context.options[1] && context.options[1].numbers,
- MESSAGE_UNNECESSARY = "Unnecessarily quoted property '{{property}}' found.",
- MESSAGE_UNQUOTED = "Unquoted property '{{property}}' found.",
- MESSAGE_NUMERIC = "Unquoted number literal '{{property}}' used as key.",
- MESSAGE_RESERVED = "Unquoted reserved word '{{property}}' used as key.",
sourceCode = context.getSourceCode();
@@ -165,7 +171,7 @@ module.exports = {
if (CHECK_UNNECESSARY && areQuotesRedundant(key.value, tokens, NUMBERS)) {
context.report({
node,
- message: MESSAGE_UNNECESSARY,
+ messageId: "unnecessarilyQuotedProperty",
data: { property: key.value },
fix: fixer => fixer.replaceText(key, getUnquotedKey(key))
});
@@ -173,14 +179,14 @@ module.exports = {
} else if (KEYWORDS && key.type === "Identifier" && isKeyword(key.name)) {
context.report({
node,
- message: MESSAGE_RESERVED,
+ messageId: "unquotedReservedProperty",
data: { property: key.name },
fix: fixer => fixer.replaceText(key, getQuotedKey(key))
});
- } else if (NUMBERS && key.type === "Literal" && typeof key.value === "number") {
+ } else if (NUMBERS && key.type === "Literal" && astUtils.isNumericLiteral(key)) {
context.report({
node,
- message: MESSAGE_NUMERIC,
+ messageId: "unquotedNumericProperty",
data: { property: key.value },
fix: fixer => fixer.replaceText(key, getQuotedKey(key))
});
@@ -198,7 +204,7 @@ module.exports = {
if (!node.method && !node.computed && !node.shorthand && !(key.type === "Literal" && typeof key.value === "string")) {
context.report({
node,
- message: MESSAGE_UNQUOTED,
+ messageId: "unquotedPropertyFound",
data: { property: key.name || key.value },
fix: fixer => fixer.replaceText(key, getQuotedKey(key))
});
@@ -253,7 +259,7 @@ module.exports = {
quotedProps.forEach(property => {
context.report({
node: property,
- message: "Properties shouldn't be quoted as all quotes are redundant.",
+ messageId: "redundantQuoting",
fix: fixer => fixer.replaceText(property.key, getUnquotedKey(property.key))
});
});
@@ -261,7 +267,7 @@ module.exports = {
unquotedProps.forEach(property => {
context.report({
node: property,
- message: "Properties should be quoted as '{{property}}' is a reserved word.",
+ messageId: "requireQuotesDueToReservedWord",
data: { property: keywordKeyName },
fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key))
});
@@ -270,7 +276,7 @@ module.exports = {
unquotedProps.forEach(property => {
context.report({
node: property,
- message: "Inconsistently quoted property '{{key}}' found.",
+ messageId: "inconsistentlyQuotedProperty",
data: { key: property.key.name || property.key.value },
fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key))
});
diff --git a/tools/node_modules/eslint/lib/rules/quotes.js b/tools/node_modules/eslint/lib/rules/quotes.js
index f78d1129425633..d1f4443b9033c9 100644
--- a/tools/node_modules/eslint/lib/rules/quotes.js
+++ b/tools/node_modules/eslint/lib/rules/quotes.js
@@ -110,7 +110,11 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ wrongQuotes: "Strings must use {{description}}."
+ }
},
create(context) {
@@ -273,7 +277,7 @@ module.exports = {
if (!isValid) {
context.report({
node,
- message: "Strings must use {{description}}.",
+ messageId: "wrongQuotes",
data: {
description: settings.description
},
@@ -304,7 +308,7 @@ module.exports = {
context.report({
node,
- message: "Strings must use {{description}}.",
+ messageId: "wrongQuotes",
data: {
description: settings.description
},
diff --git a/tools/node_modules/eslint/lib/rules/radix.js b/tools/node_modules/eslint/lib/rules/radix.js
index ed3c5cb66b8cdc..3903cb2a6a2b01 100644
--- a/tools/node_modules/eslint/lib/rules/radix.js
+++ b/tools/node_modules/eslint/lib/rules/radix.js
@@ -18,6 +18,8 @@ const astUtils = require("./utils/ast-utils");
const MODE_ALWAYS = "always",
MODE_AS_NEEDED = "as-needed";
+const validRadixValues = new Set(Array.from({ length: 37 - 2 }, (_, index) => index + 2));
+
/**
* Checks whether a given variable is shadowed or not.
* @param {eslint-scope.Variable} variable A variable to check.
@@ -47,14 +49,14 @@ function isParseIntMethod(node) {
*
* The following values are invalid.
*
- * - A literal except numbers.
+ * - A literal except integers between 2 and 36.
* - undefined.
* @param {ASTNode} radix A node of radix to check.
* @returns {boolean} `true` if the node is valid.
*/
function isValidRadix(radix) {
return !(
- (radix.type === "Literal" && typeof radix.value !== "number") ||
+ (radix.type === "Literal" && !validRadixValues.has(radix.value)) ||
(radix.type === "Identifier" && radix.name === "undefined")
);
}
@@ -87,7 +89,14 @@ module.exports = {
{
enum: ["always", "as-needed"]
}
- ]
+ ],
+
+ messages: {
+ missingParameters: "Missing parameters.",
+ redundantRadix: "Redundant radix parameter.",
+ missingRadix: "Missing radix parameter.",
+ invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36."
+ }
},
create(context) {
@@ -106,7 +115,7 @@ module.exports = {
case 0:
context.report({
node,
- message: "Missing parameters."
+ messageId: "missingParameters"
});
break;
@@ -114,7 +123,7 @@ module.exports = {
if (mode === MODE_ALWAYS) {
context.report({
node,
- message: "Missing radix parameter."
+ messageId: "missingRadix"
});
}
break;
@@ -123,12 +132,12 @@ module.exports = {
if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) {
context.report({
node,
- message: "Redundant radix parameter."
+ messageId: "redundantRadix"
});
} else if (!isValidRadix(args[1])) {
context.report({
node,
- message: "Invalid radix parameter."
+ messageId: "invalidRadix"
});
}
break;
@@ -142,7 +151,7 @@ module.exports = {
// Check `parseInt()`
variable = astUtils.getVariableByName(scope, "parseInt");
- if (!isShadowed(variable)) {
+ if (variable && !isShadowed(variable)) {
variable.references.forEach(reference => {
const node = reference.identifier;
@@ -154,7 +163,7 @@ module.exports = {
// Check `Number.parseInt()`
variable = astUtils.getVariableByName(scope, "Number");
- if (!isShadowed(variable)) {
+ if (variable && !isShadowed(variable)) {
variable.references.forEach(reference => {
const node = reference.identifier.parent;
diff --git a/tools/node_modules/eslint/lib/rules/require-atomic-updates.js b/tools/node_modules/eslint/lib/rules/require-atomic-updates.js
index bdd6d81ebc4758..4f6acceab804d1 100644
--- a/tools/node_modules/eslint/lib/rules/require-atomic-updates.js
+++ b/tools/node_modules/eslint/lib/rules/require-atomic-updates.js
@@ -223,7 +223,7 @@ module.exports = {
/*
* Register the variable to verify after ESLint traversed the `writeExpr` node
- * if this reference is an assignment to a variable which is referred from other clausure.
+ * if this reference is an assignment to a variable which is referred from other closure.
*/
if (writeExpr &&
writeExpr.parent.right === writeExpr && // ← exclude variable declarations.
diff --git a/tools/node_modules/eslint/lib/rules/require-await.js b/tools/node_modules/eslint/lib/rules/require-await.js
index 22c111b6dc852e..274e241cfc7d5b 100644
--- a/tools/node_modules/eslint/lib/rules/require-await.js
+++ b/tools/node_modules/eslint/lib/rules/require-await.js
@@ -39,7 +39,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/require-await"
},
- schema: []
+ schema: [],
+
+ messages: {
+ missingAwait: "{{name}} has no 'await' expression."
+ }
},
create(context) {
@@ -68,7 +72,7 @@ module.exports = {
context.report({
node,
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
- message: "{{name}} has no 'await' expression.",
+ messageId: "missingAwait",
data: {
name: capitalizeFirstLetter(
astUtils.getFunctionNameWithKind(node)
diff --git a/tools/node_modules/eslint/lib/rules/require-jsdoc.js b/tools/node_modules/eslint/lib/rules/require-jsdoc.js
index 416a22ce6c4375..e581b2bee4646a 100644
--- a/tools/node_modules/eslint/lib/rules/require-jsdoc.js
+++ b/tools/node_modules/eslint/lib/rules/require-jsdoc.js
@@ -52,7 +52,11 @@ module.exports = {
],
deprecated: true,
- replacedBy: []
+ replacedBy: [],
+
+ messages: {
+ missingJSDocComment: "Missing JSDoc comment."
+ }
},
create(context) {
@@ -72,7 +76,7 @@ module.exports = {
* @returns {void}
*/
function report(node) {
- context.report({ node, message: "Missing JSDoc comment." });
+ context.report({ node, messageId: "missingJSDocComment" });
}
/**
diff --git a/tools/node_modules/eslint/lib/rules/require-yield.js b/tools/node_modules/eslint/lib/rules/require-yield.js
index dbfd759948af78..af2344dfa6b8ff 100644
--- a/tools/node_modules/eslint/lib/rules/require-yield.js
+++ b/tools/node_modules/eslint/lib/rules/require-yield.js
@@ -20,7 +20,11 @@ module.exports = {
url: "https://eslint.org/docs/rules/require-yield"
},
- schema: []
+ schema: [],
+
+ messages: {
+ missingYield: "This generator function does not have 'yield'."
+ }
},
create(context) {
@@ -51,7 +55,7 @@ module.exports = {
const countYield = stack.pop();
if (countYield === 0 && node.body.body.length > 0) {
- context.report({ node, message: "This generator function does not have 'yield'." });
+ context.report({ node, messageId: "missingYield" });
}
}
diff --git a/tools/node_modules/eslint/lib/rules/rest-spread-spacing.js b/tools/node_modules/eslint/lib/rules/rest-spread-spacing.js
index cd740fd3a99057..4bb5f787c6c568 100644
--- a/tools/node_modules/eslint/lib/rules/rest-spread-spacing.js
+++ b/tools/node_modules/eslint/lib/rules/rest-spread-spacing.js
@@ -26,7 +26,12 @@ module.exports = {
{
enum: ["always", "never"]
}
- ]
+ ],
+
+ messages: {
+ unexpectedWhitespace: "Unexpected whitespace after {{type}} operator.",
+ expectedWhitespace: "Expected whitespace after {{type}} operator."
+ }
},
create(context) {
@@ -78,7 +83,7 @@ module.exports = {
line: operator.loc.end.line,
column: operator.loc.end.column
},
- message: "Expected whitespace after {{type}} operator.",
+ messageId: "expectedWhitespace",
data: {
type
},
@@ -93,7 +98,7 @@ module.exports = {
line: operator.loc.end.line,
column: operator.loc.end.column
},
- message: "Unexpected whitespace after {{type}} operator.",
+ messageId: "unexpectedWhitespace",
data: {
type
},
diff --git a/tools/node_modules/eslint/lib/rules/semi-spacing.js b/tools/node_modules/eslint/lib/rules/semi-spacing.js
index 083dc26199f7bd..92948533d2789e 100644
--- a/tools/node_modules/eslint/lib/rules/semi-spacing.js
+++ b/tools/node_modules/eslint/lib/rules/semi-spacing.js
@@ -39,7 +39,14 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unexpectedWhitespaceBefore: "Unexpected whitespace before semicolon.",
+ unexpectedWhitespaceAfter: "Unexpected whitespace after semicolon.",
+ missingWhitespaceBefore: "Missing whitespace before semicolon.",
+ missingWhitespaceAfter: "Missing whitespace after semicolon."
+ }
},
create(context) {
@@ -124,7 +131,7 @@ module.exports = {
context.report({
node,
loc: location,
- message: "Unexpected whitespace before semicolon.",
+ messageId: "unexpectedWhitespaceBefore",
fix(fixer) {
const tokenBefore = sourceCode.getTokenBefore(token);
@@ -137,7 +144,7 @@ module.exports = {
context.report({
node,
loc: location,
- message: "Missing whitespace before semicolon.",
+ messageId: "missingWhitespaceBefore",
fix(fixer) {
return fixer.insertTextBefore(token, " ");
}
@@ -151,7 +158,7 @@ module.exports = {
context.report({
node,
loc: location,
- message: "Unexpected whitespace after semicolon.",
+ messageId: "unexpectedWhitespaceAfter",
fix(fixer) {
const tokenAfter = sourceCode.getTokenAfter(token);
@@ -164,7 +171,7 @@ module.exports = {
context.report({
node,
loc: location,
- message: "Missing whitespace after semicolon.",
+ messageId: "missingWhitespaceAfter",
fix(fixer) {
return fixer.insertTextAfter(token, " ");
}
diff --git a/tools/node_modules/eslint/lib/rules/semi-style.js b/tools/node_modules/eslint/lib/rules/semi-style.js
index da3c4a38742b88..0c9bec4c85ede8 100644
--- a/tools/node_modules/eslint/lib/rules/semi-style.js
+++ b/tools/node_modules/eslint/lib/rules/semi-style.js
@@ -75,7 +75,11 @@ module.exports = {
},
schema: [{ enum: ["last", "first"] }],
- fixable: "whitespace"
+ fixable: "whitespace",
+
+ messages: {
+ expectedSemiColon: "Expected this semicolon to be at {{pos}}."
+ }
},
create(context) {
@@ -97,7 +101,7 @@ module.exports = {
if ((expected === "last" && !prevIsSameLine) || (expected === "first" && !nextIsSameLine)) {
context.report({
loc: semiToken.loc,
- message: "Expected this semicolon to be at {{pos}}.",
+ messageId: "expectedSemiColon",
data: {
pos: (expected === "last")
? "the end of the previous line"
diff --git a/tools/node_modules/eslint/lib/rules/semi.js b/tools/node_modules/eslint/lib/rules/semi.js
index 22e299efe72e49..d2f0670427b3ab 100644
--- a/tools/node_modules/eslint/lib/rules/semi.js
+++ b/tools/node_modules/eslint/lib/rules/semi.js
@@ -67,6 +67,11 @@ module.exports = {
maxItems: 2
}
]
+ },
+
+ messages: {
+ missingSemi: "Missing semicolon.",
+ extraSemi: "Extra semicolon."
}
},
@@ -91,12 +96,12 @@ module.exports = {
*/
function report(node, missing) {
const lastToken = sourceCode.getLastToken(node);
- let message,
+ let messageId,
fix,
loc;
if (!missing) {
- message = "Missing semicolon.";
+ messageId = "missingSemi";
loc = {
start: lastToken.loc.end,
end: astUtils.getNextLocation(sourceCode, lastToken.loc.end)
@@ -105,7 +110,7 @@ module.exports = {
return fixer.insertTextAfter(lastToken, ";");
};
} else {
- message = "Extra semicolon.";
+ messageId = "extraSemi";
loc = lastToken.loc;
fix = function(fixer) {
@@ -123,14 +128,14 @@ module.exports = {
context.report({
node,
loc,
- message,
+ messageId,
fix
});
}
/**
- * Check whether a given semicolon token is redandant.
+ * Check whether a given semicolon token is redundant.
* @param {Token} semiToken A semicolon token to check.
* @returns {boolean} `true` if the next token is `;` or `}`.
*/
diff --git a/tools/node_modules/eslint/lib/rules/sort-imports.js b/tools/node_modules/eslint/lib/rules/sort-imports.js
index 3b7f1d010348ad..65ad9a18a93112 100644
--- a/tools/node_modules/eslint/lib/rules/sort-imports.js
+++ b/tools/node_modules/eslint/lib/rules/sort-imports.js
@@ -50,7 +50,13 @@ module.exports = {
}
],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ sortImportsAlphabetically: "Imports should be sorted alphabetically.",
+ sortMembersAlphabetically: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.",
+ unexpectedSyntaxOrder: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax."
+ }
},
create(context) {
@@ -132,7 +138,7 @@ module.exports = {
if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) {
context.report({
node,
- message: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax.",
+ messageId: "unexpectedSyntaxOrder",
data: {
syntaxA: memberSyntaxSortOrder[currentMemberSyntaxGroupIndex],
syntaxB: memberSyntaxSortOrder[previousMemberSyntaxGroupIndex]
@@ -146,7 +152,7 @@ module.exports = {
) {
context.report({
node,
- message: "Imports should be sorted alphabetically."
+ messageId: "sortImportsAlphabetically"
});
}
}
@@ -163,7 +169,7 @@ module.exports = {
if (firstUnsortedIndex !== -1) {
context.report({
node: importSpecifiers[firstUnsortedIndex],
- message: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.",
+ messageId: "sortMembersAlphabetically",
data: { memberName: importSpecifiers[firstUnsortedIndex].local.name },
fix(fixer) {
if (importSpecifiers.some(specifier =>
diff --git a/tools/node_modules/eslint/lib/rules/sort-keys.js b/tools/node_modules/eslint/lib/rules/sort-keys.js
index a5ce445f71ae93..8a95ee25d61948 100644
--- a/tools/node_modules/eslint/lib/rules/sort-keys.js
+++ b/tools/node_modules/eslint/lib/rules/sort-keys.js
@@ -41,7 +41,7 @@ function getPropertyName(node) {
* Functions which check that the given 2 names are in specific order.
*
* Postfix `I` is meant insensitive.
- * Postfix `N` is meant natual.
+ * Postfix `N` is meant natural.
* @private
*/
const isValidOrders = {
@@ -109,7 +109,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ sortKeys: "Expected object keys to be in {{natural}}{{insensitive}}{{order}}ending order. '{{thisName}}' should be before '{{prevName}}'."
+ }
},
create(context) {
@@ -118,10 +122,10 @@ module.exports = {
const order = context.options[0] || "asc";
const options = context.options[1];
const insensitive = options && options.caseSensitive === false;
- const natual = options && options.natural;
+ const natural = options && options.natural;
const minKeys = options && options.minKeys;
const isValidOrder = isValidOrders[
- order + (insensitive ? "I" : "") + (natual ? "N" : "")
+ order + (insensitive ? "I" : "") + (natural ? "N" : "")
];
// The stack to save the previous property's name for each object literals.
@@ -167,13 +171,13 @@ module.exports = {
context.report({
node,
loc: node.key.loc,
- message: "Expected object keys to be in {{natual}}{{insensitive}}{{order}}ending order. '{{thisName}}' should be before '{{prevName}}'.",
+ messageId: "sortKeys",
data: {
thisName,
prevName,
order,
insensitive: insensitive ? "insensitive " : "",
- natual: natual ? "natural " : ""
+ natural: natural ? "natural " : ""
}
});
}
diff --git a/tools/node_modules/eslint/lib/rules/sort-vars.js b/tools/node_modules/eslint/lib/rules/sort-vars.js
index e85c6534e3a189..7add2cf74b2940 100644
--- a/tools/node_modules/eslint/lib/rules/sort-vars.js
+++ b/tools/node_modules/eslint/lib/rules/sort-vars.js
@@ -33,7 +33,11 @@ module.exports = {
}
],
- fixable: "code"
+ fixable: "code",
+
+ messages: {
+ sortVars: "Variables within the same declaration block should be sorted alphabetically."
+ }
},
create(context) {
@@ -56,7 +60,7 @@ module.exports = {
if (currentVariableName < lastVariableName) {
context.report({
node: decl,
- message: "Variables within the same declaration block should be sorted alphabetically.",
+ messageId: "sortVars",
fix(fixer) {
if (unfixable || fixed) {
return null;
diff --git a/tools/node_modules/eslint/lib/rules/space-before-blocks.js b/tools/node_modules/eslint/lib/rules/space-before-blocks.js
index 038e88db5215f5..9b56481bf355fb 100644
--- a/tools/node_modules/eslint/lib/rules/space-before-blocks.js
+++ b/tools/node_modules/eslint/lib/rules/space-before-blocks.js
@@ -47,7 +47,12 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ unexpectedSpace: "Unexpected space before opening brace.",
+ missingSpace: "Missing space before opening brace."
+ }
},
create(context) {
@@ -114,7 +119,7 @@ module.exports = {
if (requireSpace && !hasSpace) {
context.report({
node,
- message: "Missing space before opening brace.",
+ messageId: "missingSpace",
fix(fixer) {
return fixer.insertTextBefore(node, " ");
}
@@ -122,7 +127,7 @@ module.exports = {
} else if (requireNoSpace && hasSpace) {
context.report({
node,
- message: "Unexpected space before opening brace.",
+ messageId: "unexpectedSpace",
fix(fixer) {
return fixer.removeRange([precedingToken.range[1], node.range[0]]);
}
diff --git a/tools/node_modules/eslint/lib/rules/space-before-function-paren.js b/tools/node_modules/eslint/lib/rules/space-before-function-paren.js
index 3a6d430f362051..af609c2e7c72fa 100644
--- a/tools/node_modules/eslint/lib/rules/space-before-function-paren.js
+++ b/tools/node_modules/eslint/lib/rules/space-before-function-paren.js
@@ -50,7 +50,12 @@ module.exports = {
}
]
}
- ]
+ ],
+
+ messages: {
+ unexpectedSpace: "Unexpected space before function parentheses.",
+ missingSpace: "Missing space before function parentheses."
+ }
},
create(context) {
@@ -123,7 +128,7 @@ module.exports = {
context.report({
node,
loc: leftToken.loc.end,
- message: "Unexpected space before function parentheses.",
+ messageId: "unexpectedSpace",
fix(fixer) {
const comments = sourceCode.getCommentsBefore(rightToken);
@@ -141,7 +146,7 @@ module.exports = {
context.report({
node,
loc: leftToken.loc.end,
- message: "Missing space before function parentheses.",
+ messageId: "missingSpace",
fix: fixer => fixer.insertTextAfter(leftToken, " ")
});
}
diff --git a/tools/node_modules/eslint/lib/rules/space-in-parens.js b/tools/node_modules/eslint/lib/rules/space-in-parens.js
index 85ee74210d6007..b0a604d955d788 100644
--- a/tools/node_modules/eslint/lib/rules/space-in-parens.js
+++ b/tools/node_modules/eslint/lib/rules/space-in-parens.js
@@ -169,7 +169,7 @@ module.exports = {
}
/**
- * Determines if a closing paren is immediately preceeded by a required space
+ * Determines if a closing paren is immediately preceded by a required space
* @param {Object} tokenBeforeClosingParen The token before the paren
* @param {Object} closingParenToken The paren token
* @returns {boolean} True if the closing paren is missing a required space
@@ -190,7 +190,7 @@ module.exports = {
}
/**
- * Determines if a closer paren is immediately preceeded by a disallowed space
+ * Determines if a closer paren is immediately preceded by a disallowed space
* @param {Object} tokenBeforeClosingParen The token before the paren
* @param {Object} closingParenToken The paren token
* @returns {boolean} True if the closing paren has a disallowed space
diff --git a/tools/node_modules/eslint/lib/rules/space-infix-ops.js b/tools/node_modules/eslint/lib/rules/space-infix-ops.js
index bd2c0ae0e1d3b7..471c22210eb613 100644
--- a/tools/node_modules/eslint/lib/rules/space-infix-ops.js
+++ b/tools/node_modules/eslint/lib/rules/space-infix-ops.js
@@ -32,7 +32,11 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ missingSpace: "Operator '{{operator}}' must be spaced."
+ }
},
create(context) {
@@ -70,7 +74,7 @@ module.exports = {
context.report({
node: mainNode,
loc: culpritToken.loc,
- message: "Operator '{{operator}}' must be spaced.",
+ messageId: "missingSpace",
data: {
operator: culpritToken.value
},
@@ -123,11 +127,11 @@ module.exports = {
* @private
*/
function checkConditional(node) {
- const nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent, "?");
+ const nonSpacedConsequentNode = getFirstNonSpacedToken(node.test, node.consequent, "?");
const nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate, ":");
- if (nonSpacedConsequesntNode) {
- report(node, nonSpacedConsequesntNode);
+ if (nonSpacedConsequentNode) {
+ report(node, nonSpacedConsequentNode);
} else if (nonSpacedAlternateNode) {
report(node, nonSpacedAlternateNode);
}
diff --git a/tools/node_modules/eslint/lib/rules/spaced-comment.js b/tools/node_modules/eslint/lib/rules/spaced-comment.js
index daf56cd6bb42d0..d3221f0ea798ac 100644
--- a/tools/node_modules/eslint/lib/rules/spaced-comment.js
+++ b/tools/node_modules/eslint/lib/rules/spaced-comment.js
@@ -221,7 +221,16 @@ module.exports = {
},
additionalProperties: false
}
- ]
+ ],
+
+ messages: {
+ unexpectedSpaceAfterMarker: "Unexpected space or tab after marker ({{refChar}}) in comment.",
+ expectedExceptionAfter: "Expected exception block, space or tab after '{{refChar}}' in comment.",
+ unexpectedSpaceBefore: "Unexpected space or tab before '*/' in comment.",
+ unexpectedSpaceAfter: "Unexpected space or tab after '{{refChar}}' in comment.",
+ expectedSpaceBefore: "Expected space or tab before '*/' in comment.",
+ expectedSpaceAfter: "Expected space or tab after '{{refChar}}' in comment."
+ }
},
create(context) {
@@ -259,12 +268,12 @@ module.exports = {
/**
* Reports a beginning spacing error with an appropriate message.
* @param {ASTNode} node A comment node to check.
- * @param {string} message An error message to report.
+ * @param {string} messageId An error message to report.
* @param {Array} match An array of match results for markers.
* @param {string} refChar Character used for reference in the error message.
* @returns {void}
*/
- function reportBegin(node, message, match, refChar) {
+ function reportBegin(node, messageId, match, refChar) {
const type = node.type.toLowerCase(),
commentIdentifier = type === "block" ? "/*" : "//";
@@ -284,7 +293,7 @@ module.exports = {
return fixer.replaceTextRange([start, end], commentIdentifier + (match[1] ? match[1] : ""));
},
- message,
+ messageId,
data: { refChar }
});
}
@@ -292,11 +301,11 @@ module.exports = {
/**
* Reports an ending spacing error with an appropriate message.
* @param {ASTNode} node A comment node to check.
- * @param {string} message An error message to report.
+ * @param {string} messageId An error message to report.
* @param {string} match An array of the matched whitespace characters.
* @returns {void}
*/
- function reportEnd(node, message, match) {
+ function reportEnd(node, messageId, match) {
context.report({
node,
fix(fixer) {
@@ -309,7 +318,7 @@ module.exports = {
return fixer.replaceTextRange([start, end], "");
},
- message
+ messageId
});
}
@@ -338,26 +347,26 @@ module.exports = {
const marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier;
if (rule.hasExceptions) {
- reportBegin(node, "Expected exception block, space or tab after '{{refChar}}' in comment.", hasMarker, marker);
+ reportBegin(node, "expectedExceptionAfter", hasMarker, marker);
} else {
- reportBegin(node, "Expected space or tab after '{{refChar}}' in comment.", hasMarker, marker);
+ reportBegin(node, "expectedSpaceAfter", hasMarker, marker);
}
}
if (balanced && type === "block" && !endMatch) {
- reportEnd(node, "Expected space or tab before '*/' in comment.");
+ reportEnd(node, "expectedSpaceBefore");
}
} else {
if (beginMatch) {
if (!beginMatch[1]) {
- reportBegin(node, "Unexpected space or tab after '{{refChar}}' in comment.", beginMatch, commentIdentifier);
+ reportBegin(node, "unexpectedSpaceAfter", beginMatch, commentIdentifier);
} else {
- reportBegin(node, "Unexpected space or tab after marker ({{refChar}}) in comment.", beginMatch, beginMatch[1]);
+ reportBegin(node, "unexpectedSpaceAfterMarker", beginMatch, beginMatch[1]);
}
}
if (balanced && type === "block" && endMatch) {
- reportEnd(node, "Unexpected space or tab before '*/' in comment.", endMatch);
+ reportEnd(node, "unexpectedSpaceBefore", endMatch);
}
}
}
diff --git a/tools/node_modules/eslint/lib/rules/template-curly-spacing.js b/tools/node_modules/eslint/lib/rules/template-curly-spacing.js
index 07da6a39b0e9bb..a16c0732df7b50 100644
--- a/tools/node_modules/eslint/lib/rules/template-curly-spacing.js
+++ b/tools/node_modules/eslint/lib/rules/template-curly-spacing.js
@@ -57,7 +57,7 @@ module.exports = {
* @returns {void}
*/
function checkSpacingBefore(token) {
- const prevToken = sourceCode.getTokenBefore(token);
+ const prevToken = sourceCode.getTokenBefore(token, { includeComments: true });
if (prevToken &&
CLOSE_PAREN.test(token.value) &&
@@ -86,7 +86,7 @@ module.exports = {
* @returns {void}
*/
function checkSpacingAfter(token) {
- const nextToken = sourceCode.getTokenAfter(token);
+ const nextToken = sourceCode.getTokenAfter(token, { includeComments: true });
if (nextToken &&
OPEN_PAREN.test(token.value) &&
diff --git a/tools/node_modules/eslint/lib/rules/use-isnan.js b/tools/node_modules/eslint/lib/rules/use-isnan.js
index cd9ccdbaf898ee..7b466be75f2e5e 100644
--- a/tools/node_modules/eslint/lib/rules/use-isnan.js
+++ b/tools/node_modules/eslint/lib/rules/use-isnan.js
@@ -45,7 +45,7 @@ module.exports = {
properties: {
enforceForSwitchCase: {
type: "boolean",
- default: false
+ default: true
},
enforceForIndexOf: {
type: "boolean",
@@ -66,7 +66,7 @@ module.exports = {
create(context) {
- const enforceForSwitchCase = context.options[0] && context.options[0].enforceForSwitchCase;
+ const enforceForSwitchCase = !context.options[0] || context.options[0].enforceForSwitchCase;
const enforceForIndexOf = context.options[0] && context.options[0].enforceForIndexOf;
/**
diff --git a/tools/node_modules/eslint/lib/rules/utils/ast-utils.js b/tools/node_modules/eslint/lib/rules/utils/ast-utils.js
index 01c6b47b82eefc..e10544dd61e9ca 100644
--- a/tools/node_modules/eslint/lib/rules/utils/ast-utils.js
+++ b/tools/node_modules/eslint/lib/rules/utils/ast-utils.js
@@ -865,6 +865,47 @@ module.exports = {
return isFunction(node) && module.exports.isEmptyBlock(node.body);
},
+ /**
+ * Returns the result of the string conversion applied to the evaluated value of the given expression node,
+ * if it can be determined statically.
+ *
+ * This function returns a `string` value for all `Literal` nodes and simple `TemplateLiteral` nodes only.
+ * In all other cases, this function returns `null`.
+ * @param {ASTNode} node Expression node.
+ * @returns {string|null} String value if it can be determined. Otherwise, `null`.
+ */
+ getStaticStringValue(node) {
+ switch (node.type) {
+ case "Literal":
+ if (node.value === null) {
+ if (module.exports.isNullLiteral(node)) {
+ return String(node.value); // "null"
+ }
+ if (node.regex) {
+ return `/${node.regex.pattern}/${node.regex.flags}`;
+ }
+ if (node.bigint) {
+ return node.bigint;
+ }
+
+ // Otherwise, this is an unknown literal. The function will return null.
+
+ } else {
+ return String(node.value);
+ }
+ break;
+ case "TemplateLiteral":
+ if (node.expressions.length === 0 && node.quasis.length === 1) {
+ return node.quasis[0].value.cooked;
+ }
+ break;
+
+ // no default
+ }
+
+ return null;
+ },
+
/**
* Gets the property name of a given node.
* The node can be a MemberExpression, a Property, or a MethodDefinition.
@@ -911,23 +952,12 @@ module.exports = {
// no default
}
- switch (prop && prop.type) {
- case "Literal":
- return String(prop.value);
-
- case "TemplateLiteral":
- if (prop.expressions.length === 0 && prop.quasis.length === 1) {
- return prop.quasis[0].value.cooked;
- }
- break;
-
- case "Identifier":
- if (!node.computed) {
- return prop.name;
- }
- break;
+ if (prop) {
+ if (prop.type === "Identifier" && !node.computed) {
+ return prop.name;
+ }
- // no default
+ return module.exports.getStaticStringValue(prop);
}
return null;
@@ -987,6 +1017,7 @@ module.exports = {
* 0o5 // false
* 5e0 // false
* '5' // false
+ * 5n // false
*/
isDecimalInteger(node) {
return node.type === "Literal" && typeof node.value === "number" &&
@@ -1306,6 +1337,18 @@ module.exports = {
return node.type === "Literal" && node.value === null && !node.regex && !node.bigint;
},
+ /**
+ * Check if a given node is a numeric literal or not.
+ * @param {ASTNode} node The node to check.
+ * @returns {boolean} `true` if the node is a number or bigint literal.
+ */
+ isNumericLiteral(node) {
+ return (
+ node.type === "Literal" &&
+ (typeof node.value === "number" || Boolean(node.bigint))
+ );
+ },
+
/**
* Determines whether two tokens can safely be placed next to each other without merging into a single token
* @param {Token|string} leftValue The left token. If this is a string, it will be tokenized and the last token will be used.
diff --git a/tools/node_modules/eslint/lib/rules/utils/unicode/is-combining-character.js b/tools/node_modules/eslint/lib/rules/utils/unicode/is-combining-character.js
index 0fa40ee4ae8630..0498b99a21ed45 100644
--- a/tools/node_modules/eslint/lib/rules/utils/unicode/is-combining-character.js
+++ b/tools/node_modules/eslint/lib/rules/utils/unicode/is-combining-character.js
@@ -1,13 +1,13 @@
-// THIS FILE WAS GENERATED BY 'tools/update-unicode-utils.js'
+/**
+ * @author Toru Nagashima
+ */
"use strict";
-const combiningChars = new Set([768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,1155,1156,1157,1158,1159,1160,1161,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1471,1473,1474,1476,1477,1479,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1648,1750,1751,1752,1753,1754,1755,1756,1759,1760,1761,1762,1763,1764,1767,1768,1770,1771,1772,1773,1809,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,2027,2028,2029,2030,2031,2032,2033,2034,2035,2070,2071,2072,2073,2075,2076,2077,2078,2079,2080,2081,2082,2083,2085,2086,2087,2089,2090,2091,2092,2093,2137,2138,2139,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,2304,2305,2306,2307,2362,2363,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2385,2386,2387,2388,2389,2390,2391,2402,2403,2433,2434,2435,2492,2494,2495,2496,2497,2498,2499,2500,2503,2504,2507,2508,2509,2519,2530,2531,2561,2562,2563,2620,2622,2623,2624,2625,2626,2631,2632,2635,2636,2637,2641,2672,2673,2677,2689,2690,2691,2748,2750,2751,2752,2753,2754,2755,2756,2757,2759,2760,2761,2763,2764,2765,2786,2787,2810,2811,2812,2813,2814,2815,2817,2818,2819,2876,2878,2879,2880,2881,2882,2883,2884,2887,2888,2891,2892,2893,2902,2903,2914,2915,2946,3006,3007,3008,3009,3010,3014,3015,3016,3018,3019,3020,3021,3031,3072,3073,3074,3075,3134,3135,3136,3137,3138,3139,3140,3142,3143,3144,3146,3147,3148,3149,3157,3158,3170,3171,3201,3202,3203,3260,3262,3263,3264,3265,3266,3267,3268,3270,3271,3272,3274,3275,3276,3277,3285,3286,3298,3299,3328,3329,3330,3331,3387,3388,3390,3391,3392,3393,3394,3395,3396,3398,3399,3400,3402,3403,3404,3405,3415,3426,3427,3458,3459,3530,3535,3536,3537,3538,3539,3540,3542,3544,3545,3546,3547,3548,3549,3550,3551,3570,3571,3633,3636,3637,3638,3639,3640,3641,3642,3655,3656,3657,3658,3659,3660,3661,3662,3761,3764,3765,3766,3767,3768,3769,3771,3772,3784,3785,3786,3787,3788,3789,3864,3865,3893,3895,3897,3902,3903,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3974,3975,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4038,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4182,4183,4184,4185,4190,4191,4192,4194,4195,4196,4199,4200,4201,4202,4203,4204,4205,4209,4210,4211,4212,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4239,4250,4251,4252,4253,4957,4958,4959,5906,5907,5908,5938,5939,5940,5970,5971,6002,6003,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6109,6155,6156,6157,6277,6278,6313,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,6679,6680,6681,6682,6683,6741,6742,6743,6744,6745,6746,6747,6748,6749,6750,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779,6780,6783,6832,6833,6834,6835,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6912,6913,6914,6915,6916,6964,6965,6966,6967,6968,6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,7019,7020,7021,7022,7023,7024,7025,7026,7027,7040,7041,7042,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154,7155,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7376,7377,7378,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7405,7410,7411,7412,7415,7416,7417,7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7675,7676,7677,7678,7679,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,11503,11504,11505,11647,11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755,11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,12330,12331,12332,12333,12334,12335,12441,12442,42607,42608,42609,42610,42612,42613,42614,42615,42616,42617,42618,42619,42620,42621,42654,42655,42736,42737,43010,43014,43019,43043,43044,43045,43046,43047,43136,43137,43188,43189,43190,43191,43192,43193,43194,43195,43196,43197,43198,43199,43200,43201,43202,43203,43204,43205,43232,43233,43234,43235,43236,43237,43238,43239,43240,43241,43242,43243,43244,43245,43246,43247,43248,43249,43302,43303,43304,43305,43306,43307,43308,43309,43335,43336,43337,43338,43339,43340,43341,43342,43343,43344,43345,43346,43347,43392,43393,43394,43395,43443,43444,43445,43446,43447,43448,43449,43450,43451,43452,43453,43454,43455,43456,43493,43561,43562,43563,43564,43565,43566,43567,43568,43569,43570,43571,43572,43573,43574,43587,43596,43597,43643,43644,43645,43696,43698,43699,43700,43703,43704,43710,43711,43713,43755,43756,43757,43758,43759,43765,43766,44003,44004,44005,44006,44007,44008,44009,44010,44012,44013,64286,65024,65025,65026,65027,65028,65029,65030,65031,65032,65033,65034,65035,65036,65037,65038,65039,65056,65057,65058,65059,65060,65061,65062,65063,65064,65065,65066,65067,65068,65069,65070,65071,66045,66272,66422,66423,66424,66425,66426,68097,68098,68099,68101,68102,68108,68109,68110,68111,68152,68153,68154,68159,68325,68326,69632,69633,69634,69688,69689,69690,69691,69692,69693,69694,69695,69696,69697,69698,69699,69700,69701,69702,69759,69760,69761,69762,69808,69809,69810,69811,69812,69813,69814,69815,69816,69817,69818,69888,69889,69890,69927,69928,69929,69930,69931,69932,69933,69934,69935,69936,69937,69938,69939,69940,70003,70016,70017,70018,70067,70068,70069,70070,70071,70072,70073,70074,70075,70076,70077,70078,70079,70080,70090,70091,70092,70188,70189,70190,70191,70192,70193,70194,70195,70196,70197,70198,70199,70206,70367,70368,70369,70370,70371,70372,70373,70374,70375,70376,70377,70378,70400,70401,70402,70403,70460,70462,70463,70464,70465,70466,70467,70468,70471,70472,70475,70476,70477,70487,70498,70499,70502,70503,70504,70505,70506,70507,70508,70512,70513,70514,70515,70516,70709,70710,70711,70712,70713,70714,70715,70716,70717,70718,70719,70720,70721,70722,70723,70724,70725,70726,70832,70833,70834,70835,70836,70837,70838,70839,70840,70841,70842,70843,70844,70845,70846,70847,70848,70849,70850,70851,71087,71088,71089,71090,71091,71092,71093,71096,71097,71098,71099,71100,71101,71102,71103,71104,71132,71133,71216,71217,71218,71219,71220,71221,71222,71223,71224,71225,71226,71227,71228,71229,71230,71231,71232,71339,71340,71341,71342,71343,71344,71345,71346,71347,71348,71349,71350,71351,71453,71454,71455,71456,71457,71458,71459,71460,71461,71462,71463,71464,71465,71466,71467,72193,72194,72195,72196,72197,72198,72199,72200,72201,72202,72243,72244,72245,72246,72247,72248,72249,72251,72252,72253,72254,72263,72273,72274,72275,72276,72277,72278,72279,72280,72281,72282,72283,72330,72331,72332,72333,72334,72335,72336,72337,72338,72339,72340,72341,72342,72343,72344,72345,72751,72752,72753,72754,72755,72756,72757,72758,72760,72761,72762,72763,72764,72765,72766,72767,72850,72851,72852,72853,72854,72855,72856,72857,72858,72859,72860,72861,72862,72863,72864,72865,72866,72867,72868,72869,72870,72871,72873,72874,72875,72876,72877,72878,72879,72880,72881,72882,72883,72884,72885,72886,73009,73010,73011,73012,73013,73014,73018,73020,73021,73023,73024,73025,73026,73027,73028,73029,73031,92912,92913,92914,92915,92916,92976,92977,92978,92979,92980,92981,92982,94033,94034,94035,94036,94037,94038,94039,94040,94041,94042,94043,94044,94045,94046,94047,94048,94049,94050,94051,94052,94053,94054,94055,94056,94057,94058,94059,94060,94061,94062,94063,94064,94065,94066,94067,94068,94069,94070,94071,94072,94073,94074,94075,94076,94077,94078,94095,94096,94097,94098,113821,113822,119141,119142,119143,119144,119145,119149,119150,119151,119152,119153,119154,119163,119164,119165,119166,119167,119168,119169,119170,119173,119174,119175,119176,119177,119178,119179,119210,119211,119212,119213,119362,119363,119364,121344,121345,121346,121347,121348,121349,121350,121351,121352,121353,121354,121355,121356,121357,121358,121359,121360,121361,121362,121363,121364,121365,121366,121367,121368,121369,121370,121371,121372,121373,121374,121375,121376,121377,121378,121379,121380,121381,121382,121383,121384,121385,121386,121387,121388,121389,121390,121391,121392,121393,121394,121395,121396,121397,121398,121403,121404,121405,121406,121407,121408,121409,121410,121411,121412,121413,121414,121415,121416,121417,121418,121419,121420,121421,121422,121423,121424,121425,121426,121427,121428,121429,121430,121431,121432,121433,121434,121435,121436,121437,121438,121439,121440,121441,121442,121443,121444,121445,121446,121447,121448,121449,121450,121451,121452,121461,121476,121499,121500,121501,121502,121503,121505,121506,121507,121508,121509,121510,121511,121512,121513,121514,121515,121516,121517,121518,121519,122880,122881,122882,122883,122884,122885,122886,122888,122889,122890,122891,122892,122893,122894,122895,122896,122897,122898,122899,122900,122901,122902,122903,122904,122907,122908,122909,122910,122911,122912,122913,122915,122916,122918,122919,122920,122921,122922,125136,125137,125138,125139,125140,125141,125142,125252,125253,125254,125255,125256,125257,125258,917760,917761,917762,917763,917764,917765,917766,917767,917768,917769,917770,917771,917772,917773,917774,917775,917776,917777,917778,917779,917780,917781,917782,917783,917784,917785,917786,917787,917788,917789,917790,917791,917792,917793,917794,917795,917796,917797,917798,917799,917800,917801,917802,917803,917804,917805,917806,917807,917808,917809,917810,917811,917812,917813,917814,917815,917816,917817,917818,917819,917820,917821,917822,917823,917824,917825,917826,917827,917828,917829,917830,917831,917832,917833,917834,917835,917836,917837,917838,917839,917840,917841,917842,917843,917844,917845,917846,917847,917848,917849,917850,917851,917852,917853,917854,917855,917856,917857,917858,917859,917860,917861,917862,917863,917864,917865,917866,917867,917868,917869,917870,917871,917872,917873,917874,917875,917876,917877,917878,917879,917880,917881,917882,917883,917884,917885,917886,917887,917888,917889,917890,917891,917892,917893,917894,917895,917896,917897,917898,917899,917900,917901,917902,917903,917904,917905,917906,917907,917908,917909,917910,917911,917912,917913,917914,917915,917916,917917,917918,917919,917920,917921,917922,917923,917924,917925,917926,917927,917928,917929,917930,917931,917932,917933,917934,917935,917936,917937,917938,917939,917940,917941,917942,917943,917944,917945,917946,917947,917948,917949,917950,917951,917952,917953,917954,917955,917956,917957,917958,917959,917960,917961,917962,917963,917964,917965,917966,917967,917968,917969,917970,917971,917972,917973,917974,917975,917976,917977,917978,917979,917980,917981,917982,917983,917984,917985,917986,917987,917988,917989,917990,917991,917992,917993,917994,917995,917996,917997,917998,917999])
-
/**
* Check whether a given character is a combining mark or not.
- * @param {number} c The character code to check.
- * @returns {boolean} `true` if the character belongs to the category, one of `Mc`, `Me`, and `Mn`.
+ * @param {number} codePoint The character code to check.
+ * @returns {boolean} `true` if the character belongs to the category, any of `Mc`, `Me`, and `Mn`.
*/
-module.exports = function isCombiningCharacter(c) {
- return combiningChars.has(c);
+module.exports = function isCombiningCharacter(codePoint) {
+ return /^[\p{Mc}\p{Me}\p{Mn}]$/u.test(String.fromCodePoint(codePoint));
};
diff --git a/tools/node_modules/eslint/lib/rules/wrap-iife.js b/tools/node_modules/eslint/lib/rules/wrap-iife.js
index 5e590be13e28b5..896aed63de5222 100644
--- a/tools/node_modules/eslint/lib/rules/wrap-iife.js
+++ b/tools/node_modules/eslint/lib/rules/wrap-iife.js
@@ -10,6 +10,21 @@
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
+const eslintUtils = require("eslint-utils");
+
+//----------------------------------------------------------------------
+// Helpers
+//----------------------------------------------------------------------
+
+/**
+ * Check if the given node is callee of a `NewExpression` node
+ * @param {ASTNode} node node to check
+ * @returns {boolean} True if the node is callee of a `NewExpression` node
+ * @private
+ */
+function isCalleeOfNewExpression(node) {
+ return node.parent.type === "NewExpression" && node.parent.callee === node;
+}
//------------------------------------------------------------------------------
// Rule Definition
@@ -58,15 +73,25 @@ module.exports = {
const sourceCode = context.getSourceCode();
/**
- * Check if the node is wrapped in ()
+ * Check if the node is wrapped in any (). All parens count: grouping parens and parens for constructs such as if()
* @param {ASTNode} node node to evaluate
- * @returns {boolean} True if it is wrapped
+ * @returns {boolean} True if it is wrapped in any parens
* @private
*/
- function wrapped(node) {
+ function isWrappedInAnyParens(node) {
return astUtils.isParenthesised(sourceCode, node);
}
+ /**
+ * Check if the node is wrapped in grouping (). Parens for constructs such as if() don't count
+ * @param {ASTNode} node node to evaluate
+ * @returns {boolean} True if it is wrapped in grouping parens
+ * @private
+ */
+ function isWrappedInGroupingParens(node) {
+ return eslintUtils.isParenthesized(1, node, sourceCode);
+ }
+
/**
* Get the function node from an IIFE
* @param {ASTNode} node node to evaluate
@@ -99,10 +124,10 @@ module.exports = {
return;
}
- const callExpressionWrapped = wrapped(node),
- functionExpressionWrapped = wrapped(innerNode);
+ const isCallExpressionWrapped = isWrappedInAnyParens(node),
+ isFunctionExpressionWrapped = isWrappedInAnyParens(innerNode);
- if (!callExpressionWrapped && !functionExpressionWrapped) {
+ if (!isCallExpressionWrapped && !isFunctionExpressionWrapped) {
context.report({
node,
messageId: "wrapInvocation",
@@ -112,27 +137,39 @@ module.exports = {
return fixer.replaceText(nodeToSurround, `(${sourceCode.getText(nodeToSurround)})`);
}
});
- } else if (style === "inside" && !functionExpressionWrapped) {
+ } else if (style === "inside" && !isFunctionExpressionWrapped) {
context.report({
node,
messageId: "wrapExpression",
fix(fixer) {
+ // The outer call expression will always be wrapped at this point.
+
+ if (isWrappedInGroupingParens(node) && !isCalleeOfNewExpression(node)) {
+
+ /*
+ * Parenthesize the function expression and remove unnecessary grouping parens around the call expression.
+ * Replace the range between the end of the function expression and the end of the call expression.
+ * for example, in `(function(foo) {}(bar))`, the range `(bar))` should get replaced with `)(bar)`.
+ */
+
+ const parenAfter = sourceCode.getTokenAfter(node);
+
+ return fixer.replaceTextRange(
+ [innerNode.range[1], parenAfter.range[1]],
+ `)${sourceCode.getText().slice(innerNode.range[1], parenAfter.range[0])}`
+ );
+ }
+
/*
- * The outer call expression will always be wrapped at this point.
- * Replace the range between the end of the function expression and the end of the call expression.
- * for example, in `(function(foo) {}(bar))`, the range `(bar))` should get replaced with `)(bar)`.
- * Replace the parens from the outer expression, and parenthesize the function expression.
+ * Call expression is wrapped in mandatory parens such as if(), or in necessary grouping parens.
+ * These parens cannot be removed, so just parenthesize the function expression.
*/
- const parenAfter = sourceCode.getTokenAfter(node);
- return fixer.replaceTextRange(
- [innerNode.range[1], parenAfter.range[1]],
- `)${sourceCode.getText().slice(innerNode.range[1], parenAfter.range[0])}`
- );
+ return fixer.replaceText(innerNode, `(${sourceCode.getText(innerNode)})`);
}
});
- } else if (style === "outside" && !callExpressionWrapped) {
+ } else if (style === "outside" && !isCallExpressionWrapped) {
context.report({
node,
messageId: "moveInvocation",
diff --git a/tools/node_modules/eslint/lib/rules/yoda.js b/tools/node_modules/eslint/lib/rules/yoda.js
index b00acf82c702b0..c4ff3f81938595 100644
--- a/tools/node_modules/eslint/lib/rules/yoda.js
+++ b/tools/node_modules/eslint/lib/rules/yoda.js
@@ -49,12 +49,30 @@ function isRangeTestOperator(operator) {
* @returns {boolean} True if the node is a negative number that looks like a
* real literal and should be treated as such.
*/
-function looksLikeLiteral(node) {
+function isNegativeNumericLiteral(node) {
return (node.type === "UnaryExpression" &&
node.operator === "-" &&
node.prefix &&
- node.argument.type === "Literal" &&
- typeof node.argument.value === "number");
+ astUtils.isNumericLiteral(node.argument));
+}
+
+/**
+ * Determines whether a node is a Template Literal which can be determined statically.
+ * @param {ASTNode} node Node to test
+ * @returns {boolean} True if the node is a Template Literal without expression.
+ */
+function isStaticTemplateLiteral(node) {
+ return node.type === "TemplateLiteral" && node.expressions.length === 0;
+}
+
+/**
+ * Determines whether a non-Literal node should be treated as a single Literal node.
+ * @param {ASTNode} node Node to test
+ * @returns {boolean} True if the node should be treated as a single Literal node.
+ */
+function looksLikeLiteral(node) {
+ return isNegativeNumericLiteral(node) ||
+ isStaticTemplateLiteral(node);
}
/**
@@ -66,15 +84,17 @@ function looksLikeLiteral(node) {
* 1. The original node if the node is already a Literal
* 2. A normalized Literal node with the negative number as the value if the
* node represents a negative number literal.
- * 3. The Literal node which has the `defaultValue` argument if it exists.
- * 4. Otherwise `null`.
+ * 3. A normalized Literal node with the string as the value if the node is
+ * a Template Literal without expression.
+ * 4. The Literal node which has the `defaultValue` argument if it exists.
+ * 5. Otherwise `null`.
*/
function getNormalizedLiteral(node, defaultValue) {
if (node.type === "Literal") {
return node;
}
- if (looksLikeLiteral(node)) {
+ if (isNegativeNumericLiteral(node)) {
return {
type: "Literal",
value: -node.argument.value,
@@ -82,6 +102,14 @@ function getNormalizedLiteral(node, defaultValue) {
};
}
+ if (isStaticTemplateLiteral(node)) {
+ return {
+ type: "Literal",
+ value: node.quasis[0].value.cooked,
+ raw: node.quasis[0].value.raw
+ };
+ }
+
if (defaultValue) {
return {
type: "Literal",
diff --git a/tools/node_modules/eslint/lib/shared/config-validator.js b/tools/node_modules/eslint/lib/shared/config-validator.js
index aca6e1fb274fdb..458bd2a802b95c 100644
--- a/tools/node_modules/eslint/lib/shared/config-validator.js
+++ b/tools/node_modules/eslint/lib/shared/config-validator.js
@@ -10,13 +10,12 @@
//------------------------------------------------------------------------------
const
- path = require("path"),
util = require("util"),
- lodash = require("lodash"),
configSchema = require("../../conf/config-schema"),
BuiltInEnvironments = require("../../conf/environments"),
BuiltInRules = require("../rules"),
- ConfigOps = require("./config-ops");
+ ConfigOps = require("./config-ops"),
+ { emitDeprecationWarning } = require("./deprecation-warnings");
const ajv = require("./ajv")();
const ruleValidators = new WeakMap();
@@ -26,11 +25,6 @@ const noop = Function.prototype;
// Private
//------------------------------------------------------------------------------
let validateSchema;
-
-// Defitions for deprecation warnings.
-const deprecationWarningMessages = {
- ESLINT_LEGACY_ECMAFEATURES: "The 'ecmaFeatures' config file property is deprecated, and has no effect."
-};
const severityMap = {
error: 2,
warn: 1,
@@ -196,7 +190,7 @@ function validateRules(
/**
* Validates a `globals` section of a config file
- * @param {Object} globalsConfig The `glboals` section
+ * @param {Object} globalsConfig The `globals` section
* @param {string|null} source The name of the configuration source to report in the event of an error.
* @returns {void}
*/
@@ -254,25 +248,6 @@ function formatErrors(errors) {
}).map(message => `\t- ${message}.\n`).join("");
}
-/**
- * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted
- * for each unique file path, but repeated invocations with the same file path have no effect.
- * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active.
- * @param {string} source The name of the configuration source to report the warning for.
- * @param {string} errorCode The warning message to show.
- * @returns {void}
- */
-const emitDeprecationWarning = lodash.memoize((source, errorCode) => {
- const rel = path.relative(process.cwd(), source);
- const message = deprecationWarningMessages[errorCode];
-
- process.emitWarning(
- `${message} (found in "${rel}")`,
- "DeprecationWarning",
- errorCode
- );
-});
-
/**
* Validates the top level properties of the config object.
* @param {Object} config The config object to validate.
diff --git a/tools/node_modules/eslint/lib/shared/deprecation-warnings.js b/tools/node_modules/eslint/lib/shared/deprecation-warnings.js
new file mode 100644
index 00000000000000..e1481a2e9aa0b8
--- /dev/null
+++ b/tools/node_modules/eslint/lib/shared/deprecation-warnings.js
@@ -0,0 +1,56 @@
+/**
+ * @fileoverview Provide the function that emits deprecation warnings.
+ * @author Toru Nagashima
+ */
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const path = require("path");
+const lodash = require("lodash");
+
+//------------------------------------------------------------------------------
+// Private
+//------------------------------------------------------------------------------
+
+// Defitions for deprecation warnings.
+const deprecationWarningMessages = {
+ ESLINT_LEGACY_ECMAFEATURES:
+ "The 'ecmaFeatures' config file property is deprecated and has no effect.",
+ ESLINT_PERSONAL_CONFIG_LOAD:
+ "'~/.eslintrc.*' config files have been deprecated. " +
+ "Please use a config file per project or the '--config' option.",
+ ESLINT_PERSONAL_CONFIG_SUPPRESS:
+ "'~/.eslintrc.*' config files have been deprecated. " +
+ "Please remove it or add 'root:true' to the config files in your " +
+ "projects in order to avoid loading '~/.eslintrc.*' accidentally."
+};
+
+/**
+ * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted
+ * for each unique file path, but repeated invocations with the same file path have no effect.
+ * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active.
+ * @param {string} source The name of the configuration source to report the warning for.
+ * @param {string} errorCode The warning message to show.
+ * @returns {void}
+ */
+const emitDeprecationWarning = lodash.memoize((source, errorCode) => {
+ const rel = path.relative(process.cwd(), source);
+ const message = deprecationWarningMessages[errorCode];
+
+ process.emitWarning(
+ `${message} (found in "${rel}")`,
+ "DeprecationWarning",
+ errorCode
+ );
+}, (...args) => JSON.stringify(args));
+
+//------------------------------------------------------------------------------
+// Public Interface
+//------------------------------------------------------------------------------
+
+module.exports = {
+ emitDeprecationWarning
+};
diff --git a/tools/node_modules/eslint/lib/shared/naming.js b/tools/node_modules/eslint/lib/shared/naming.js
index b99155f15cafa7..32cff94538af22 100644
--- a/tools/node_modules/eslint/lib/shared/naming.js
+++ b/tools/node_modules/eslint/lib/shared/naming.js
@@ -78,7 +78,7 @@ function getShorthandName(fullname, prefix) {
/**
* Gets the scope (namespace) of a term.
* @param {string} term The term which may have the namespace.
- * @returns {string} The namepace of the term if it has one.
+ * @returns {string} The namespace of the term if it has one.
*/
function getNamespaceFromTerm(term) {
const match = term.match(NAMESPACE_REGEX);
diff --git a/tools/node_modules/eslint/lib/shared/relative-module-resolver.js b/tools/node_modules/eslint/lib/shared/relative-module-resolver.js
index 5b25fa111214ed..fa6cca72361df5 100644
--- a/tools/node_modules/eslint/lib/shared/relative-module-resolver.js
+++ b/tools/node_modules/eslint/lib/shared/relative-module-resolver.js
@@ -6,35 +6,18 @@
"use strict";
const Module = require("module");
-const path = require("path");
-// Polyfill Node's `Module.createRequire` if not present. We only support the case where the argument is a filepath, not a URL.
-const createRequire = (
-
- // Added in v12.2.0
- Module.createRequire ||
-
- // Added in v10.12.0, but deprecated in v12.2.0.
- Module.createRequireFromPath ||
-
- // Polyfill - This is not executed on the tests on node@>=10.
- /* istanbul ignore next */
- (filename => {
- const mod = new Module(filename, null);
-
- mod.filename = filename;
- mod.paths = Module._nodeModulePaths(path.dirname(filename)); // eslint-disable-line no-underscore-dangle
- mod._compile("module.exports = require;", filename); // eslint-disable-line no-underscore-dangle
- return mod.exports;
- })
-);
+/*
+ * `Module.createRequire` is added in v12.2.0. It supports URL as well.
+ * We only support the case where the argument is a filepath, not a URL.
+ */
+const createRequire = Module.createRequire || Module.createRequireFromPath;
module.exports = {
/**
* Resolves a Node module relative to another module
* @param {string} moduleName The name of a Node module, or a path to a Node module.
- *
* @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be
* a file rather than a directory, but the file need not actually exist.
* @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath`
@@ -43,6 +26,8 @@ module.exports = {
try {
return createRequire(relativeToPath).resolve(moduleName);
} catch (error) {
+
+ // This `if` block is for older Node.js than 12.0.0. We can remove this block in the future.
if (
typeof error === "object" &&
error !== null &&
diff --git a/tools/node_modules/eslint/lib/shared/types.js b/tools/node_modules/eslint/lib/shared/types.js
index a5bd0200e2792a..f3d1a7f29f02f0 100644
--- a/tools/node_modules/eslint/lib/shared/types.js
+++ b/tools/node_modules/eslint/lib/shared/types.js
@@ -21,7 +21,7 @@ module.exports = {};
/**
* @typedef {Object} ParserOptions
* @property {EcmaFeatures} [ecmaFeatures] The optional features.
- * @property {3|5|6|7|8|9|10|2015|2016|2017|2018|2019} [ecmaVersion] The ECMAScript version (or revision number).
+ * @property {3|5|6|7|8|9|10|11|2015|2016|2017|2018|2019|2020} [ecmaVersion] The ECMAScript version (or revision number).
* @property {"script"|"module"} [sourceType] The source code type.
*/
diff --git a/tools/node_modules/eslint/lib/source-code/source-code.js b/tools/node_modules/eslint/lib/source-code/source-code.js
index 30b4e9ab5c26e3..591d5a7e454ee2 100644
--- a/tools/node_modules/eslint/lib/source-code/source-code.js
+++ b/tools/node_modules/eslint/lib/source-code/source-code.js
@@ -121,7 +121,7 @@ function isSpaceBetween(sourceCode, first, second, checkInsideOfJSXText) {
currentToken.range[1] !== nextToken.range[0] ||
/*
- * For backward compatibility, check speces in JSXText.
+ * For backward compatibility, check spaces in JSXText.
* https://github.com/eslint/eslint/issues/12614
*/
(
diff --git a/tools/node_modules/eslint/lib/source-code/token-store/utils.js b/tools/node_modules/eslint/lib/source-code/token-store/utils.js
index 444684b52f1bb0..21e1d6ff7c3b6d 100644
--- a/tools/node_modules/eslint/lib/source-code/token-store/utils.js
+++ b/tools/node_modules/eslint/lib/source-code/token-store/utils.js
@@ -1,5 +1,5 @@
/**
- * @fileoverview Define utilify functions for token store.
+ * @fileoverview Define utility functions for token store.
* @author Toru Nagashima
*/
"use strict";
diff --git a/tools/node_modules/eslint/node_modules/@babel/code-frame/lib/index.js b/tools/node_modules/eslint/node_modules/@babel/code-frame/lib/index.js
index 35176fbc0682ca..62945f7782a774 100644
--- a/tools/node_modules/eslint/node_modules/@babel/code-frame/lib/index.js
+++ b/tools/node_modules/eslint/node_modules/@babel/code-frame/lib/index.js
@@ -6,17 +6,11 @@ Object.defineProperty(exports, "__esModule", {
exports.codeFrameColumns = codeFrameColumns;
exports.default = _default;
-function _highlight() {
- const data = _interopRequireWildcard(require("@babel/highlight"));
+var _highlight = _interopRequireWildcard(require("@babel/highlight"));
- _highlight = function () {
- return data;
- };
-
- return data;
-}
+function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
let deprecationWarningShown = false;
@@ -35,7 +29,7 @@ function getMarkerLines(loc, source, opts) {
column: 0,
line: -1
}, loc.start);
- const endLoc = Object.assign({}, startLoc, loc.end);
+ const endLoc = Object.assign({}, startLoc, {}, loc.end);
const {
linesAbove = 2,
linesBelow = 3
@@ -94,8 +88,8 @@ function getMarkerLines(loc, source, opts) {
}
function codeFrameColumns(rawLines, loc, opts = {}) {
- const highlighted = (opts.highlightCode || opts.forceColor) && (0, _highlight().shouldHighlight)(opts);
- const chalk = (0, _highlight().getChalk)(opts);
+ const highlighted = (opts.highlightCode || opts.forceColor) && (0, _highlight.shouldHighlight)(opts);
+ const chalk = (0, _highlight.getChalk)(opts);
const defs = getDefs(chalk);
const maybeHighlight = (chalkFn, string) => {
@@ -110,7 +104,7 @@ function codeFrameColumns(rawLines, loc, opts = {}) {
} = getMarkerLines(loc, lines, opts);
const hasColumns = loc.start && typeof loc.start.column === "number";
const numberMaxWidth = String(end).length;
- const highlightedLines = highlighted ? (0, _highlight().default)(rawLines, opts) : rawLines;
+ const highlightedLines = highlighted ? (0, _highlight.default)(rawLines, opts) : rawLines;
let frame = highlightedLines.split(NEWLINE).slice(start, end).map((line, index) => {
const number = start + 1 + index;
const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
diff --git a/tools/node_modules/eslint/node_modules/@babel/code-frame/package.json b/tools/node_modules/eslint/node_modules/@babel/code-frame/package.json
index d619d9a8f53194..7508b5b1402c94 100644
--- a/tools/node_modules/eslint/node_modules/@babel/code-frame/package.json
+++ b/tools/node_modules/eslint/node_modules/@babel/code-frame/package.json
@@ -5,7 +5,7 @@
},
"bundleDependencies": false,
"dependencies": {
- "@babel/highlight": "^7.0.0"
+ "@babel/highlight": "^7.8.3"
},
"deprecated": false,
"description": "Generate errors that contain a code frame that point to source locations.",
@@ -13,7 +13,7 @@
"chalk": "^2.0.0",
"strip-ansi": "^4.0.0"
},
- "gitHead": "0407f034f09381b95e9cabefbf6b176c76485a43",
+ "gitHead": "a7620bd266ae1345975767bbc7abf09034437017",
"homepage": "https://babeljs.io/",
"license": "MIT",
"main": "lib/index.js",
@@ -25,5 +25,5 @@
"type": "git",
"url": "https://github.com/babel/babel/tree/master/packages/babel-code-frame"
},
- "version": "7.5.5"
+ "version": "7.8.3"
}
\ No newline at end of file
diff --git a/tools/node_modules/eslint/node_modules/@babel/highlight/lib/index.js b/tools/node_modules/eslint/node_modules/@babel/highlight/lib/index.js
index 6ac5b4a350b8e6..bf275748784b50 100644
--- a/tools/node_modules/eslint/node_modules/@babel/highlight/lib/index.js
+++ b/tools/node_modules/eslint/node_modules/@babel/highlight/lib/index.js
@@ -7,39 +7,17 @@ exports.shouldHighlight = shouldHighlight;
exports.getChalk = getChalk;
exports.default = highlight;
-function _jsTokens() {
- const data = _interopRequireWildcard(require("js-tokens"));
+var _jsTokens = _interopRequireWildcard(require("js-tokens"));
- _jsTokens = function () {
- return data;
- };
-
- return data;
-}
-
-function _esutils() {
- const data = _interopRequireDefault(require("esutils"));
+var _esutils = _interopRequireDefault(require("esutils"));
- _esutils = function () {
- return data;
- };
-
- return data;
-}
-
-function _chalk() {
- const data = _interopRequireDefault(require("chalk"));
-
- _chalk = function () {
- return data;
- };
-
- return data;
-}
+var _chalk = _interopRequireDefault(require("chalk"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
+function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
+
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function getDefs(chalk) {
return {
@@ -61,10 +39,10 @@ const BRACKET = /^[()[\]{}]$/;
function getTokenType(match) {
const [offset, text] = match.slice(-2);
- const token = (0, _jsTokens().matchToToken)(match);
+ const token = (0, _jsTokens.matchToToken)(match);
if (token.type === "name") {
- if (_esutils().default.keyword.isReservedWordES6(token.value)) {
+ if (_esutils.default.keyword.isReservedWordES6(token.value)) {
return "keyword";
}
@@ -89,7 +67,7 @@ function getTokenType(match) {
}
function highlightTokens(defs, text) {
- return text.replace(_jsTokens().default, function (...args) {
+ return text.replace(_jsTokens.default, function (...args) {
const type = getTokenType(args);
const colorize = defs[type];
@@ -102,14 +80,14 @@ function highlightTokens(defs, text) {
}
function shouldHighlight(options) {
- return _chalk().default.supportsColor || options.forceColor;
+ return _chalk.default.supportsColor || options.forceColor;
}
function getChalk(options) {
- let chalk = _chalk().default;
+ let chalk = _chalk.default;
if (options.forceColor) {
- chalk = new (_chalk().default.constructor)({
+ chalk = new _chalk.default.constructor({
enabled: true,
level: 1
});
diff --git a/tools/node_modules/eslint/node_modules/chalk/index.js b/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/index.js
similarity index 100%
rename from tools/node_modules/eslint/node_modules/chalk/index.js
rename to tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/index.js
diff --git a/tools/node_modules/eslint/node_modules/chalk/index.js.flow b/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/index.js.flow
similarity index 100%
rename from tools/node_modules/eslint/node_modules/chalk/index.js.flow
rename to tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/index.js.flow
diff --git a/tools/node_modules/eslint/node_modules/string-width/node_modules/strip-ansi/license b/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/license
similarity index 100%
rename from tools/node_modules/eslint/node_modules/string-width/node_modules/strip-ansi/license
rename to tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/license
diff --git a/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/package.json b/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/package.json
new file mode 100644
index 00000000000000..270fecdc347d42
--- /dev/null
+++ b/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/package.json
@@ -0,0 +1,80 @@
+{
+ "bugs": {
+ "url": "https://github.com/chalk/chalk/issues"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "deprecated": false,
+ "description": "Terminal string styling done right",
+ "devDependencies": {
+ "ava": "*",
+ "coveralls": "^3.0.0",
+ "execa": "^0.9.0",
+ "flow-bin": "^0.68.0",
+ "import-fresh": "^2.0.0",
+ "matcha": "^0.7.0",
+ "nyc": "^11.0.2",
+ "resolve-from": "^4.0.0",
+ "typescript": "^2.5.3",
+ "xo": "*"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "files": [
+ "index.js",
+ "templates.js",
+ "types/index.d.ts",
+ "index.js.flow"
+ ],
+ "homepage": "https://github.com/chalk/chalk#readme",
+ "keywords": [
+ "color",
+ "colour",
+ "colors",
+ "terminal",
+ "console",
+ "cli",
+ "string",
+ "str",
+ "ansi",
+ "style",
+ "styles",
+ "tty",
+ "formatting",
+ "rgb",
+ "256",
+ "shell",
+ "xterm",
+ "log",
+ "logging",
+ "command-line",
+ "text"
+ ],
+ "license": "MIT",
+ "name": "chalk",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/chalk/chalk.git"
+ },
+ "scripts": {
+ "bench": "matcha benchmark.js",
+ "coveralls": "nyc report --reporter=text-lcov | coveralls",
+ "test": "xo && tsc --project types && flow --max-warnings=0 && nyc ava"
+ },
+ "types": "types/index.d.ts",
+ "version": "2.4.2",
+ "xo": {
+ "envs": [
+ "node",
+ "mocha"
+ ],
+ "ignores": [
+ "test/_flow.js"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/readme.md b/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/readme.md
new file mode 100644
index 00000000000000..d298e2c48d64a0
--- /dev/null
+++ b/tools/node_modules/eslint/node_modules/@babel/highlight/node_modules/chalk/readme.md
@@ -0,0 +1,314 @@
+
+
+
+
+
+
+
+
+
+> Terminal string styling done right
+
+[](https://travis-ci.org/chalk/chalk) [](https://coveralls.io/github/chalk/chalk?branch=master) [](https://www.youtube.com/watch?v=9auOCbH5Ns4) [](https://github.com/xojs/xo) [](https://github.com/sindresorhus/awesome-nodejs)
+
+### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0)
+
+
+
+
+## Highlights
+
+- Expressive API
+- Highly performant
+- Ability to nest styles
+- [256/Truecolor color support](#256-and-truecolor-color-support)
+- Auto-detects color support
+- Doesn't extend `String.prototype`
+- Clean and focused
+- Actively maintained
+- [Used by ~23,000 packages](https://www.npmjs.com/browse/depended/chalk) as of December 31, 2017
+
+
+## Install
+
+```console
+$ npm install chalk
+```
+
+
+
+
+
+
+## Usage
+
+```js
+const chalk = require('chalk');
+
+console.log(chalk.blue('Hello world!'));
+```
+
+Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
+
+```js
+const chalk = require('chalk');
+const log = console.log;
+
+// Combine styled and normal strings
+log(chalk.blue('Hello') + ' World' + chalk.red('!'));
+
+// Compose multiple styles using the chainable API
+log(chalk.blue.bgRed.bold('Hello world!'));
+
+// Pass in multiple arguments
+log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'));
+
+// Nest styles
+log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));
+
+// Nest styles of the same type even (color, underline, background)
+log(chalk.green(
+ 'I am a green line ' +
+ chalk.blue.underline.bold('with a blue substring') +
+ ' that becomes green again!'
+));
+
+// ES2015 template literal
+log(`
+CPU: ${chalk.red('90%')}
+RAM: ${chalk.green('40%')}
+DISK: ${chalk.yellow('70%')}
+`);
+
+// ES2015 tagged template literal
+log(chalk`
+CPU: {red ${cpu.totalPercent}%}
+RAM: {green ${ram.used / ram.total * 100}%}
+DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%}
+`);
+
+// Use RGB colors in terminal emulators that support it.
+log(chalk.keyword('orange')('Yay for orange colored text!'));
+log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
+log(chalk.hex('#DEADED').bold('Bold gray!'));
+```
+
+Easily define your own themes:
+
+```js
+const chalk = require('chalk');
+
+const error = chalk.bold.red;
+const warning = chalk.keyword('orange');
+
+console.log(error('Error!'));
+console.log(warning('Warning!'));
+```
+
+Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args):
+
+```js
+const name = 'Sindre';
+console.log(chalk.green('Hello %s'), name);
+//=> 'Hello Sindre'
+```
+
+
+## API
+
+### chalk.` |