diff --git a/tools/node_modules/eslint/README.md b/tools/node_modules/eslint/README.md
index 43bcdaa3f29778..90eac6469998a5 100644
--- a/tools/node_modules/eslint/README.md
+++ b/tools/node_modules/eslint/README.md
@@ -242,7 +242,7 @@ Toru Nagashima
-薛定谔的猫
+唯然
|
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 aae71607d2c89a..e3647018d26fa3 100644
--- a/tools/node_modules/eslint/lib/cli-engine/cli-engine.js
+++ b/tools/node_modules/eslint/lib/cli-engine/cli-engine.js
@@ -570,8 +570,10 @@ class CLIEngine {
/**
* Creates a new instance of the core CLI engine.
* @param {CLIEngineOptions} providedOptions The options for this instance.
+ * @param {Object} [additionalData] Additional settings that are not CLIEngineOptions.
+ * @param {Record|null} [additionalData.preloadedPlugins] Preloaded plugins.
*/
- constructor(providedOptions) {
+ constructor(providedOptions, { preloadedPlugins } = {}) {
const options = Object.assign(
Object.create(null),
defaultOptions,
@@ -584,6 +586,13 @@ class CLIEngine {
}
const additionalPluginPool = new Map();
+
+ if (preloadedPlugins) {
+ for (const [id, plugin] of Object.entries(preloadedPlugins)) {
+ additionalPluginPool.set(id, plugin);
+ }
+ }
+
const cacheFilePath = getCacheFile(
options.cacheLocation || options.cacheFile,
options.cwd
@@ -698,26 +707,6 @@ class CLIEngine {
});
}
-
- /**
- * Add a plugin by passing its configuration
- * @param {string} name Name of the plugin.
- * @param {Plugin} pluginObject Plugin configuration object.
- * @returns {void}
- */
- addPlugin(name, pluginObject) {
- const {
- additionalPluginPool,
- configArrayFactory,
- lastConfigArrays
- } = internalSlotsMap.get(this);
-
- additionalPluginPool.set(name, pluginObject);
- configArrayFactory.clearCache();
- lastConfigArrays.length = 1;
- lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile();
- }
-
/**
* Resolves the patterns passed into executeOnFiles() into glob-based patterns
* for easier handling.
diff --git a/tools/node_modules/eslint/lib/eslint/eslint.js b/tools/node_modules/eslint/lib/eslint/eslint.js
index b4a1d028db9d15..8886d45ab43480 100644
--- a/tools/node_modules/eslint/lib/eslint/eslint.js
+++ b/tools/node_modules/eslint/lib/eslint/eslint.js
@@ -54,7 +54,7 @@ const { version } = require("../../package.json");
* @property {string} [ignorePath] The ignore file to use instead of .eslintignore.
* @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance
* @property {string} [overrideConfigFile] The configuration file to use.
- * @property {Record} [plugins] An array of plugin implementations.
+ * @property {Record|null} [plugins] Preloaded plugins. This is a map-like object, keys are plugin IDs and each value is implementation.
* @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives.
* @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD.
* @property {string[]} [rulePaths] An array of directories to load custom rules from.
@@ -433,26 +433,13 @@ class ESLint {
*/
constructor(options = {}) {
const processedOptions = processOptions(options);
- const cliEngine = new CLIEngine(processedOptions);
+ const cliEngine = new CLIEngine(processedOptions, { preloadedPlugins: options.plugins });
const {
- additionalPluginPool,
configArrayFactory,
lastConfigArrays
} = getCLIEngineInternalSlots(cliEngine);
let updated = false;
- /*
- * Address `plugins` to add plugin implementations.
- * Operate the `additionalPluginPool` internal slot directly to avoid
- * using `addPlugin(id, plugin)` method that resets cache everytime.
- */
- if (options.plugins) {
- for (const [id, plugin] of Object.entries(options.plugins)) {
- additionalPluginPool.set(id, plugin);
- updated = true;
- }
- }
-
/*
* Address `overrideConfig` to set override config.
* Operate the `configArrayFactory` internal slot directly because this
diff --git a/tools/node_modules/eslint/lib/linter/config-comment-parser.js b/tools/node_modules/eslint/lib/linter/config-comment-parser.js
index 34675a76b55987..b88c5e6c850929 100644
--- a/tools/node_modules/eslint/lib/linter/config-comment-parser.js
+++ b/tools/node_modules/eslint/lib/linter/config-comment-parser.js
@@ -15,7 +15,7 @@ const levn = require("levn"),
Legacy: {
ConfigOps
}
- } = require("@eslint/eslintrc/universal"); // eslint-disable-line node/no-missing-require -- false positive
+ } = require("@eslint/eslintrc/universal");
const debug = require("debug")("eslint:config-comment-parser");
diff --git a/tools/node_modules/eslint/lib/linter/linter.js b/tools/node_modules/eslint/lib/linter/linter.js
index fab6c26113f4e4..410c07fee519e9 100644
--- a/tools/node_modules/eslint/lib/linter/linter.js
+++ b/tools/node_modules/eslint/lib/linter/linter.js
@@ -24,7 +24,7 @@ const
ConfigValidator,
environments: BuiltInEnvironments
}
- } = require("@eslint/eslintrc/universal"), // eslint-disable-line node/no-missing-require -- false positive
+ } = require("@eslint/eslintrc/universal"),
Traverser = require("../shared/traverser"),
{ SourceCode } = require("../source-code"),
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
diff --git a/tools/node_modules/eslint/lib/linter/node-event-generator.js b/tools/node_modules/eslint/lib/linter/node-event-generator.js
index 89ebd281048ffd..d56bef2fa9defd 100644
--- a/tools/node_modules/eslint/lib/linter/node-event-generator.js
+++ b/tools/node_modules/eslint/lib/linter/node-event-generator.js
@@ -98,6 +98,13 @@ function getPossibleTypes(parsedSelector) {
case "adjacent":
return getPossibleTypes(parsedSelector.right);
+ case "class":
+ if (parsedSelector.name === "function") {
+ return ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"];
+ }
+
+ return null;
+
default:
return null;
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 324af7b2caea32..7f590a5ea70995 100644
--- a/tools/node_modules/eslint/lib/rule-tester/rule-tester.js
+++ b/tools/node_modules/eslint/lib/rule-tester/rule-tester.js
@@ -67,6 +67,7 @@ const { SourceCode } = require("../source-code");
/**
* A test case that is expected to pass lint.
* @typedef {Object} ValidTestCase
+ * @property {string} [name] Name for the test case.
* @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.
@@ -81,6 +82,7 @@ const { SourceCode } = require("../source-code");
/**
* A test case that is expected to fail lint.
* @typedef {Object} InvalidTestCase
+ * @property {string} [name] Name for the test case.
* @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.
@@ -124,6 +126,7 @@ let defaultConfig = { rules: {} };
* configuration
*/
const RuleTesterParameters = [
+ "name",
"code",
"filename",
"options",
@@ -964,7 +967,7 @@ class RuleTester {
RuleTester.describe("valid", () => {
test.valid.forEach(valid => {
RuleTester[valid.only ? "itOnly" : "it"](
- sanitize(typeof valid === "object" ? valid.code : valid),
+ sanitize(typeof valid === "object" ? valid.name || valid.code : valid),
() => {
testValidTemplate(valid);
}
@@ -975,7 +978,7 @@ class RuleTester {
RuleTester.describe("invalid", () => {
test.invalid.forEach(invalid => {
RuleTester[invalid.only ? "itOnly" : "it"](
- sanitize(invalid.code),
+ sanitize(invalid.name || invalid.code),
() => {
testInvalidTemplate(invalid);
}
diff --git a/tools/node_modules/eslint/lib/rules/index.js b/tools/node_modules/eslint/lib/rules/index.js
index c88febd85b9f22..ed322a4120af13 100644
--- a/tools/node_modules/eslint/lib/rules/index.js
+++ b/tools/node_modules/eslint/lib/rules/index.js
@@ -221,6 +221,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
"no-unsafe-optional-chaining": () => require("./no-unsafe-optional-chaining"),
"no-unused-expressions": () => require("./no-unused-expressions"),
"no-unused-labels": () => require("./no-unused-labels"),
+ "no-unused-private-class-members": () => require("./no-unused-private-class-members"),
"no-unused-vars": () => require("./no-unused-vars"),
"no-use-before-define": () => require("./no-use-before-define"),
"no-useless-backreference": () => require("./no-useless-backreference"),
diff --git a/tools/node_modules/eslint/lib/rules/keyword-spacing.js b/tools/node_modules/eslint/lib/rules/keyword-spacing.js
index e9441ad1708fda..d860ae0f04bbeb 100644
--- a/tools/node_modules/eslint/lib/rules/keyword-spacing.js
+++ b/tools/node_modules/eslint/lib/rules/keyword-spacing.js
@@ -109,6 +109,8 @@ module.exports = {
create(context) {
const sourceCode = context.getSourceCode();
+ const tokensToIgnore = new WeakSet();
+
/**
* Reports a given token if there are not space(s) before the token.
* @param {Token} token A token to report.
@@ -121,6 +123,7 @@ module.exports = {
if (prevToken &&
(CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) &&
!isOpenParenOfTemplate(prevToken) &&
+ !tokensToIgnore.has(prevToken) &&
astUtils.isTokenOnSameLine(prevToken, token) &&
!sourceCode.isSpaceBetweenTokens(prevToken, token)
) {
@@ -147,6 +150,7 @@ module.exports = {
if (prevToken &&
(CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) &&
!isOpenParenOfTemplate(prevToken) &&
+ !tokensToIgnore.has(prevToken) &&
astUtils.isTokenOnSameLine(prevToken, token) &&
sourceCode.isSpaceBetweenTokens(prevToken, token)
) {
@@ -173,6 +177,7 @@ module.exports = {
if (nextToken &&
(CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) &&
!isCloseParenOfTemplate(nextToken) &&
+ !tokensToIgnore.has(nextToken) &&
astUtils.isTokenOnSameLine(token, nextToken) &&
!sourceCode.isSpaceBetweenTokens(token, nextToken)
) {
@@ -199,6 +204,7 @@ module.exports = {
if (nextToken &&
(CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) &&
!isCloseParenOfTemplate(nextToken) &&
+ !tokensToIgnore.has(nextToken) &&
astUtils.isTokenOnSameLine(token, nextToken) &&
sourceCode.isSpaceBetweenTokens(token, nextToken)
) {
@@ -584,7 +590,14 @@ module.exports = {
ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier,
MethodDefinition: checkSpacingForProperty,
PropertyDefinition: checkSpacingForProperty,
- Property: checkSpacingForProperty
+ Property: checkSpacingForProperty,
+
+ // To avoid conflicts with `space-infix-ops`, e.g. `a > this.b`
+ "BinaryExpression[operator='>']"(node) {
+ const operatorToken = sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken);
+
+ tokensToIgnore.add(operatorToken);
+ }
};
}
};
diff --git a/tools/node_modules/eslint/lib/rules/no-unused-private-class-members.js b/tools/node_modules/eslint/lib/rules/no-unused-private-class-members.js
new file mode 100644
index 00000000000000..74cf6ab694a460
--- /dev/null
+++ b/tools/node_modules/eslint/lib/rules/no-unused-private-class-members.js
@@ -0,0 +1,194 @@
+/**
+ * @fileoverview Rule to flag declared but unused private class members
+ * @author Tim van der Lippe
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ type: "problem",
+
+ docs: {
+ description: "disallow unused private class members",
+ recommended: false,
+ url: "https://eslint.org/docs/rules/no-unused-private-class-members"
+ },
+
+ schema: [],
+
+ messages: {
+ unusedPrivateClassMember: "'{{classMemberName}}' is defined but never used."
+ }
+ },
+
+ create(context) {
+ const trackedClasses = [];
+
+ /**
+ * Check whether the current node is in a write only assignment.
+ * @param {ASTNode} privateIdentifierNode Node referring to a private identifier
+ * @returns {boolean} Whether the node is in a write only assignment
+ * @private
+ */
+ function isWriteOnlyAssignment(privateIdentifierNode) {
+ const parentStatement = privateIdentifierNode.parent.parent;
+ const isAssignmentExpression = parentStatement.type === "AssignmentExpression";
+
+ if (!isAssignmentExpression &&
+ parentStatement.type !== "ForInStatement" &&
+ parentStatement.type !== "ForOfStatement" &&
+ parentStatement.type !== "AssignmentPattern") {
+ return false;
+ }
+
+ // It is a write-only usage, since we still allow usages on the right for reads
+ if (parentStatement.left !== privateIdentifierNode.parent) {
+ return false;
+ }
+
+ // For any other operator (such as '+=') we still consider it a read operation
+ if (isAssignmentExpression && parentStatement.operator !== "=") {
+
+ /*
+ * However, if the read operation is "discarded" in an empty statement, then
+ * we consider it write only.
+ */
+ return parentStatement.parent.type === "ExpressionStatement";
+ }
+
+ return true;
+ }
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ return {
+
+ // Collect all declared members up front and assume they are all unused
+ ClassBody(classBodyNode) {
+ const privateMembers = new Map();
+
+ trackedClasses.unshift(privateMembers);
+ for (const bodyMember of classBodyNode.body) {
+ if (bodyMember.type === "PropertyDefinition" || bodyMember.type === "MethodDefinition") {
+ if (bodyMember.key.type === "PrivateIdentifier") {
+ privateMembers.set(bodyMember.key.name, {
+ declaredNode: bodyMember,
+ isAccessor: bodyMember.type === "MethodDefinition" &&
+ (bodyMember.kind === "set" || bodyMember.kind === "get")
+ });
+ }
+ }
+ }
+ },
+
+ /*
+ * Process all usages of the private identifier and remove a member from
+ * `declaredAndUnusedPrivateMembers` if we deem it used.
+ */
+ PrivateIdentifier(privateIdentifierNode) {
+ const classBody = trackedClasses.find(classProperties => classProperties.has(privateIdentifierNode.name));
+
+ // Can't happen, as it is a parser to have a missing class body, but let's code defensively here.
+ if (!classBody) {
+ return;
+ }
+
+ // In case any other usage was already detected, we can short circuit the logic here.
+ const memberDefinition = classBody.get(privateIdentifierNode.name);
+
+ if (memberDefinition.isUsed) {
+ return;
+ }
+
+ // The definition of the class member itself
+ if (privateIdentifierNode.parent.type === "PropertyDefinition" ||
+ privateIdentifierNode.parent.type === "MethodDefinition") {
+ return;
+ }
+
+ /*
+ * Any usage of an accessor is considered a read, as the getter/setter can have
+ * side-effects in its definition.
+ */
+ if (memberDefinition.isAccessor) {
+ memberDefinition.isUsed = true;
+ return;
+ }
+
+ // Any assignments to this member, except for assignments that also read
+ if (isWriteOnlyAssignment(privateIdentifierNode)) {
+ return;
+ }
+
+ const wrappingExpressionType = privateIdentifierNode.parent.parent.type;
+ const parentOfWrappingExpressionType = privateIdentifierNode.parent.parent.parent.type;
+
+ // A statement which only increments (`this.#x++;`)
+ if (wrappingExpressionType === "UpdateExpression" &&
+ parentOfWrappingExpressionType === "ExpressionStatement") {
+ return;
+ }
+
+ /*
+ * ({ x: this.#usedInDestructuring } = bar);
+ *
+ * But should treat the following as a read:
+ * ({ [this.#x]: a } = foo);
+ */
+ if (wrappingExpressionType === "Property" &&
+ parentOfWrappingExpressionType === "ObjectPattern" &&
+ privateIdentifierNode.parent.parent.value === privateIdentifierNode.parent) {
+ return;
+ }
+
+ // [...this.#unusedInRestPattern] = bar;
+ if (wrappingExpressionType === "RestElement") {
+ return;
+ }
+
+ // [this.#unusedInAssignmentPattern] = bar;
+ if (wrappingExpressionType === "ArrayPattern") {
+ return;
+ }
+
+ /*
+ * We can't delete the memberDefinition, as we need to keep track of which member we are marking as used.
+ * In the case of nested classes, we only mark the first member we encounter as used. If you were to delete
+ * the member, then any subsequent usage could incorrectly mark the member of an encapsulating parent class
+ * as used, which is incorrect.
+ */
+ memberDefinition.isUsed = true;
+ },
+
+ /*
+ * Post-process the class members and report any remaining members.
+ * Since private members can only be accessed in the current class context,
+ * we can safely assume that all usages are within the current class body.
+ */
+ "ClassBody:exit"() {
+ const unusedPrivateMembers = trackedClasses.shift();
+
+ for (const [classMemberName, { declaredNode, isUsed }] of unusedPrivateMembers.entries()) {
+ if (isUsed) {
+ continue;
+ }
+ context.report({
+ node: declaredNode,
+ loc: declaredNode.key.loc,
+ messageId: "unusedPrivateClassMember",
+ data: {
+ classMemberName: `#${classMemberName}`
+ }
+ });
+ }
+ }
+ };
+ }
+};
diff --git a/tools/node_modules/eslint/lib/shared/types.js b/tools/node_modules/eslint/lib/shared/types.js
index bbfd2ed9a99a98..c497f783be5c46 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|11|12|2015|2016|2017|2018|2019|2020|2021} [ecmaVersion] The ECMAScript version (or revision number).
+ * @property {3|5|6|7|8|9|10|11|12|13|2015|2016|2017|2018|2019|2020|2021|2022} [ecmaVersion] The ECMAScript version (or revision number).
* @property {"script"|"module"} [sourceType] The source code type.
*/
diff --git a/tools/node_modules/eslint/node_modules/@eslint/eslintrc/package.json b/tools/node_modules/eslint/node_modules/@eslint/eslintrc/package.json
index 593e8aeb1db413..ae56ceeac196a3 100644
--- a/tools/node_modules/eslint/node_modules/@eslint/eslintrc/package.json
+++ b/tools/node_modules/eslint/node_modules/@eslint/eslintrc/package.json
@@ -1,6 +1,6 @@
{
"name": "@eslint/eslintrc",
- "version": "1.0.2",
+ "version": "1.0.3",
"description": "The legacy ESLintRC config file format for ESLint",
"type": "module",
"main": "./dist/eslintrc.cjs",
@@ -19,7 +19,8 @@
"lib",
"conf",
"LICENSE",
- "dist"
+ "dist",
+ "universal.js"
],
"publishConfig": {
"access": "public"
diff --git a/tools/node_modules/eslint/node_modules/@eslint/eslintrc/universal.js b/tools/node_modules/eslint/node_modules/@eslint/eslintrc/universal.js
new file mode 100644
index 00000000000000..4e1846ee6e0106
--- /dev/null
+++ b/tools/node_modules/eslint/node_modules/@eslint/eslintrc/universal.js
@@ -0,0 +1,9 @@
+// Jest (and probably some other runtimes with custom implementations of
+// `require`) doesn't support `exports` in `package.json`, so this file is here
+// to help them load this module. Note that it is also `.js` and not `.cjs` for
+// the same reason - `cjs` files requires to be loaded with an extension, but
+// since Jest doesn't respect `module` outside of ESM mode it still works in
+// this case (and the `require` in _this_ file does specify the extension).
+
+// eslint-disable-next-line no-undef
+module.exports = require("./dist/eslintrc-universal.cjs");
diff --git a/tools/node_modules/eslint/package.json b/tools/node_modules/eslint/package.json
index 89b02acd4cba1b..f214112c74cc63 100644
--- a/tools/node_modules/eslint/package.json
+++ b/tools/node_modules/eslint/package.json
@@ -1,6 +1,6 @@
{
"name": "eslint",
- "version": "8.0.0",
+ "version": "8.1.0",
"author": "Nicholas C. Zakas ",
"description": "An AST-based pattern checker for JavaScript.",
"bin": {
@@ -47,7 +47,7 @@
"homepage": "https://eslint.org",
"bugs": "https://github.com/eslint/eslint/issues/",
"dependencies": {
- "@eslint/eslintrc": "^1.0.2",
+ "@eslint/eslintrc": "^1.0.3",
"@humanwhocodes/config-array": "^0.6.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
@@ -99,7 +99,7 @@
"eslint": "file:.",
"eslint-config-eslint": "file:packages/eslint-config-eslint",
"eslint-plugin-eslint-comments": "^3.2.0",
- "eslint-plugin-eslint-plugin": "^3.5.3",
+ "eslint-plugin-eslint-plugin": "^4.0.1",
"eslint-plugin-internal-rules": "file:tools/internal-rules",
"eslint-plugin-jsdoc": "^36.0.6",
"eslint-plugin-node": "^11.1.0",