aboutsummaryrefslogtreecommitdiff
path: root/tools/node_modules/eslint/lib
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2019-08-25 23:54:42 -0400
committercjihrig <cjihrig@gmail.com>2019-08-28 10:17:26 -0400
commit403dacf9ce205d591b27c937141feb8321774c0b (patch)
tree2630ef172432a6b7f52a9be3debc9f8ef2822cd7 /tools/node_modules/eslint/lib
parent0259aadc5a2330dfa8b444e67114d0c0cbc9aae1 (diff)
downloadandroid-node-v8-403dacf9ce205d591b27c937141feb8321774c0b.tar.gz
android-node-v8-403dacf9ce205d591b27c937141feb8321774c0b.tar.bz2
android-node-v8-403dacf9ce205d591b27c937141feb8321774c0b.zip
tools: update ESLint to 6.2.2
Update ESLint to 6.2.2 PR-URL: https://github.com/nodejs/node/pull/29320 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Roman Reiss <me@silverwind.io>
Diffstat (limited to 'tools/node_modules/eslint/lib')
-rw-r--r--tools/node_modules/eslint/lib/cli-engine/config-array-factory.js2
-rw-r--r--tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js7
-rw-r--r--tools/node_modules/eslint/lib/cli-engine/config-array/extracted-config.js17
-rw-r--r--tools/node_modules/eslint/lib/init/npm-utils.js4
-rw-r--r--tools/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js1
-rw-r--r--tools/node_modules/eslint/lib/linter/linter.js63
-rw-r--r--tools/node_modules/eslint/lib/rules/accessor-pairs.js230
-rw-r--r--tools/node_modules/eslint/lib/rules/class-methods-use-this.js13
-rw-r--r--tools/node_modules/eslint/lib/rules/dot-notation.js8
-rw-r--r--tools/node_modules/eslint/lib/rules/func-call-spacing.js50
-rw-r--r--tools/node_modules/eslint/lib/rules/func-names.js4
-rw-r--r--tools/node_modules/eslint/lib/rules/function-call-argument-newline.js120
-rw-r--r--tools/node_modules/eslint/lib/rules/function-paren-newline.js56
-rw-r--r--tools/node_modules/eslint/lib/rules/indent.js15
-rw-r--r--tools/node_modules/eslint/lib/rules/index.js1
-rw-r--r--tools/node_modules/eslint/lib/rules/new-cap.js3
-rw-r--r--tools/node_modules/eslint/lib/rules/no-dupe-keys.js2
-rw-r--r--tools/node_modules/eslint/lib/rules/no-duplicate-case.js18
-rw-r--r--tools/node_modules/eslint/lib/rules/no-extra-bind.js1
-rw-r--r--tools/node_modules/eslint/lib/rules/no-extra-boolean-cast.js49
-rw-r--r--tools/node_modules/eslint/lib/rules/no-extra-parens.js76
-rw-r--r--tools/node_modules/eslint/lib/rules/no-mixed-operators.js61
-rw-r--r--tools/node_modules/eslint/lib/rules/no-restricted-syntax.js4
-rw-r--r--tools/node_modules/eslint/lib/rules/no-unused-vars.js2
-rw-r--r--tools/node_modules/eslint/lib/rules/prefer-template.js11
-rw-r--r--tools/node_modules/eslint/lib/rules/sort-keys.js14
-rw-r--r--tools/node_modules/eslint/lib/rules/utils/ast-utils.js21
-rw-r--r--tools/node_modules/eslint/lib/rules/yoda.js2
-rw-r--r--tools/node_modules/eslint/lib/shared/types.js2
29 files changed, 686 insertions, 171 deletions
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 95430c358d..0b2ed07b6a 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
@@ -526,6 +526,7 @@ class ConfigArrayFactory {
env,
extends: extend,
globals,
+ noInlineConfig,
parser: parserName,
parserOptions,
plugins: pluginList,
@@ -567,6 +568,7 @@ class ConfigArrayFactory {
criteria: null,
env,
globals,
+ noInlineConfig,
parser,
parserOptions,
plugins,
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 5c7aaa3340..0859868d82 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
@@ -54,6 +54,7 @@ const { ExtractedConfig } = require("./extracted-config");
* @property {InstanceType<OverrideTester>|null} criteria The tester for the `files` and `excludedFiles` of this config element.
* @property {Record<string, boolean>|undefined} env The environment settings.
* @property {Record<string, GlobalConf>|undefined} globals The global variable settings.
+ * @property {boolean|undefined} noInlineConfig The flag that disables directive comments.
* @property {DependentParser|undefined} parser The parser loader.
* @property {Object|undefined} parserOptions The parser options.
* @property {Record<string, DependentPlugin>|undefined} plugins The plugin loaders.
@@ -250,6 +251,12 @@ function createConfig(instance, indices) {
config.processor = element.processor;
}
+ // Adopt the noInlineConfig which was found at first.
+ if (config.noInlineConfig === void 0 && element.noInlineConfig !== void 0) {
+ config.noInlineConfig = element.noInlineConfig;
+ config.configNameOfNoInlineConfig = element.name;
+ }
+
// Merge others.
mergeWithoutOverwrite(config.env, element.env);
mergeWithoutOverwrite(config.globals, element.globals);
diff --git a/tools/node_modules/eslint/lib/cli-engine/config-array/extracted-config.js b/tools/node_modules/eslint/lib/cli-engine/config-array/extracted-config.js
index 377cc0fa91..53208c16e4 100644
--- a/tools/node_modules/eslint/lib/cli-engine/config-array/extracted-config.js
+++ b/tools/node_modules/eslint/lib/cli-engine/config-array/extracted-config.js
@@ -30,6 +30,12 @@ class ExtractedConfig {
constructor() {
/**
+ * The config name what `noInlineConfig` setting came from.
+ * @type {string}
+ */
+ this.configNameOfNoInlineConfig = "";
+
+ /**
* Environments.
* @type {Record<string, boolean>}
*/
@@ -42,6 +48,12 @@ class ExtractedConfig {
this.globals = {};
/**
+ * The flag that disables directive comments.
+ * @type {boolean|undefined}
+ */
+ this.noInlineConfig = void 0;
+
+ /**
* Parser definition.
* @type {DependentParser|null}
*/
@@ -84,7 +96,10 @@ class ExtractedConfig {
*/
toCompatibleObjectAsConfigFileContent() {
const {
- processor: _ignore, // eslint-disable-line no-unused-vars
+ /* eslint-disable no-unused-vars */
+ configNameOfNoInlineConfig: _ignore1,
+ processor: _ignore2,
+ /* eslint-enable no-unused-vars */
...config
} = this;
diff --git a/tools/node_modules/eslint/lib/init/npm-utils.js b/tools/node_modules/eslint/lib/init/npm-utils.js
index 26e78406fd..3a680aae92 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) {
* Check whether node modules are included in the dependencies of a project's
* package.json.
*
- * Convienience wrapper around check().
+ * Convenience wrapper around check().
*
* @param {string[]} packages Array of node modules to check.
* @param {string} rootDir The directory contianing a package.json
@@ -150,7 +150,7 @@ function checkDeps(packages, rootDir) {
* Check whether node modules are included in the devDependencies of a project's
* package.json.
*
- * Convienience wrapper around check().
+ * Convenience wrapper around check().
*
* @param {string[]} packages Array of node modules to check.
* @returns {Object} An object whose keys are the module names
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 c1f4a60045..821477aef9 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
@@ -526,6 +526,7 @@ function processCodePathToExit(analyzer, node) {
break;
case "CallExpression":
+ case "ImportExpression":
case "MemberExpression":
case "NewExpression":
state.makeFirstThrowablePathInTryBlock();
diff --git a/tools/node_modules/eslint/lib/linter/linter.js b/tools/node_modules/eslint/lib/linter/linter.js
index a49d850859..d367cef6cb 100644
--- a/tools/node_modules/eslint/lib/linter/linter.js
+++ b/tools/node_modules/eslint/lib/linter/linter.js
@@ -198,14 +198,20 @@ function createMissingRuleMessage(ruleId) {
/**
* creates a linting problem
* @param {Object} options to create linting error
- * @param {string} options.ruleId the ruleId to report
- * @param {Object} options.loc the loc to report
- * @param {string} options.message the error message to report
- * @returns {Problem} created problem, returns a missing-rule problem if only provided ruleId.
+ * @param {string} [options.ruleId] the ruleId to report
+ * @param {Object} [options.loc] the loc to report
+ * @param {string} [options.message] the error message to report
+ * @param {string} [options.severity] the error message to report
+ * @returns {LintMessage} created problem, returns a missing-rule problem if only provided ruleId.
* @private
*/
function createLintingProblem(options) {
- const { ruleId, loc = DEFAULT_ERROR_LOC, message = createMissingRuleMessage(options.ruleId) } = options;
+ const {
+ ruleId = null,
+ loc = DEFAULT_ERROR_LOC,
+ message = createMissingRuleMessage(options.ruleId),
+ severity = 2
+ } = options;
return {
ruleId,
@@ -214,7 +220,7 @@ function createLintingProblem(options) {
column: loc.start.column + 1,
endLine: loc.end.line,
endColumn: loc.end.column + 1,
- severity: 2,
+ severity,
nodeType: null
};
}
@@ -257,10 +263,11 @@ function createDisableDirectives(options) {
* @param {string} filename The file being checked.
* @param {ASTNode} ast The top node of the AST.
* @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules
+ * @param {string|null} warnInlineConfig If a string then it should warn directive comments as disabled. The string value is the config name what the setting came from.
* @returns {{configuredRules: Object, enabledGlobals: {value:string,comment:Token}[], exportedVariables: Object, problems: Problem[], disableDirectives: DisableDirective[]}}
* A collection of the directive comments that were found, along with any problems that occurred when parsing
*/
-function getDirectiveComments(filename, ast, ruleMapper) {
+function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) {
const configuredRules = {};
const enabledGlobals = Object.create(null);
const exportedVariables = {};
@@ -269,16 +276,29 @@ function getDirectiveComments(filename, ast, ruleMapper) {
ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
const trimmedCommentText = comment.value.trim();
- const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/u.exec(trimmedCommentText);
+ const match = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(trimmedCommentText);
if (!match) {
return;
}
+ const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(match[1]);
+
+ if (warnInlineConfig && (lineCommentSupported || comment.type === "Block")) {
+ const kind = comment.type === "Block" ? `/*${match[1]}*/` : `//${match[1]}`;
+
+ problems.push(createLintingProblem({
+ ruleId: null,
+ message: `'${kind}' has no effect because you have 'noInlineConfig' setting in ${warnInlineConfig}.`,
+ loc: comment.loc,
+ severity: 1
+ }));
+ return;
+ }
const directiveValue = trimmedCommentText.slice(match.index + match[1].length);
let directiveType = "";
- if (/^eslint-disable-(next-)?line$/u.test(match[1])) {
+ if (lineCommentSupported) {
if (comment.loc.start.line === comment.loc.end.line) {
directiveType = match[1].slice("eslint-".length);
} else {
@@ -441,16 +461,27 @@ function normalizeFilename(filename) {
return index === -1 ? filename : parts.slice(index).join(path.sep);
}
+// eslint-disable-next-line valid-jsdoc
/**
* Normalizes the possible options for `linter.verify` and `linter.verifyAndFix` to a
* consistent shape.
* @param {VerifyOptions} providedOptions Options
- * @returns {Required<VerifyOptions>} Normalized options
+ * @param {ConfigData} config Config.
+ * @returns {Required<VerifyOptions> & { warnInlineConfig: string|null }} Normalized options
*/
-function normalizeVerifyOptions(providedOptions) {
+function normalizeVerifyOptions(providedOptions, config) {
+ const disableInlineConfig = config.noInlineConfig === true;
+ const ignoreInlineConfig = providedOptions.allowInlineConfig === false;
+ const configNameOfNoInlineConfig = config.configNameOfNoInlineConfig
+ ? ` (${config.configNameOfNoInlineConfig})`
+ : "";
+
return {
filename: normalizeFilename(providedOptions.filename || "<input>"),
- allowInlineConfig: providedOptions.allowInlineConfig !== false,
+ allowInlineConfig: !ignoreInlineConfig,
+ warnInlineConfig: disableInlineConfig && !ignoreInlineConfig
+ ? `your config${configNameOfNoInlineConfig}`
+ : null,
reportUnusedDisableDirectives: Boolean(providedOptions.reportUnusedDisableDirectives),
disableFixes: Boolean(providedOptions.disableFixes)
};
@@ -984,7 +1015,7 @@ class Linter {
_verifyWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) {
const slots = internalSlotsMap.get(this);
const config = providedConfig || {};
- const options = normalizeVerifyOptions(providedOptions);
+ const options = normalizeVerifyOptions(providedOptions, config);
let text;
// evaluate arguments
@@ -1019,7 +1050,9 @@ class Linter {
}
// search and apply "eslint-env *".
- const envInFile = findEslintEnv(text);
+ const envInFile = options.allowInlineConfig && !options.warnInlineConfig
+ ? findEslintEnv(text)
+ : {};
const resolvedEnvConfig = Object.assign({ builtin: true }, config.env, envInFile);
const enabledEnvs = Object.keys(resolvedEnvConfig)
.filter(envName => resolvedEnvConfig[envName])
@@ -1062,7 +1095,7 @@ class Linter {
const sourceCode = slots.lastSourceCode;
const commentDirectives = options.allowInlineConfig
- ? getDirectiveComments(options.filename, sourceCode.ast, ruleId => getRule(slots, ruleId))
+ ? getDirectiveComments(options.filename, sourceCode.ast, ruleId => getRule(slots, ruleId), options.warnInlineConfig)
: { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] };
// augment global scope with declared global variables
diff --git a/tools/node_modules/eslint/lib/rules/accessor-pairs.js b/tools/node_modules/eslint/lib/rules/accessor-pairs.js
index aca2318486..9c78bdc70e 100644
--- a/tools/node_modules/eslint/lib/rules/accessor-pairs.js
+++ b/tools/node_modules/eslint/lib/rules/accessor-pairs.js
@@ -6,10 +6,87 @@
"use strict";
//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const astUtils = require("./utils/ast-utils");
+
+//------------------------------------------------------------------------------
+// Typedefs
+//------------------------------------------------------------------------------
+
+/**
+ * Property name if it can be computed statically, otherwise the list of the tokens of the key node.
+ * @typedef {string|Token[]} Key
+ */
+
+/**
+ * Accessor nodes with the same key.
+ * @typedef {Object} AccessorData
+ * @property {Key} key Accessor's key
+ * @property {ASTNode[]} getters List of getter nodes.
+ * @property {ASTNode[]} setters List of setter nodes.
+ */
+
+//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
+ * Checks whether or not the given lists represent the equal tokens in the same order.
+ * Tokens are compared by their properties, not by instance.
+ * @param {Token[]} left First list of tokens.
+ * @param {Token[]} right Second list of tokens.
+ * @returns {boolean} `true` if the lists have same tokens.
+ */
+function areEqualTokenLists(left, right) {
+ if (left.length !== right.length) {
+ return false;
+ }
+
+ for (let i = 0; i < left.length; i++) {
+ const leftToken = left[i],
+ rightToken = right[i];
+
+ if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Checks whether or not the given keys are equal.
+ * @param {Key} left First key.
+ * @param {Key} right Second key.
+ * @returns {boolean} `true` if the keys are equal.
+ */
+function areEqualKeys(left, right) {
+ if (typeof left === "string" && typeof right === "string") {
+
+ // Statically computed names.
+ return left === right;
+ }
+ if (Array.isArray(left) && Array.isArray(right)) {
+
+ // Token lists.
+ return areEqualTokenLists(left, right);
+ }
+
+ return false;
+}
+
+/**
+ * Checks whether or not a given node is of an accessor kind ('get' or 'set').
+ * @param {ASTNode} node - A node to check.
+ * @returns {boolean} `true` if the node is of an accessor kind.
+ */
+function isAccessorKind(node) {
+ return node.kind === "get" || node.kind === "set";
+}
+
+/**
* Checks whether or not a given node is an `Identifier` node which was named a given name.
* @param {ASTNode} node - A node to check.
* @param {string} name - An expected name of the node.
@@ -97,69 +174,152 @@ module.exports = {
}],
messages: {
- getter: "Getter is not present.",
- setter: "Setter is not present."
+ missingGetterInPropertyDescriptor: "Getter is not present in property descriptor.",
+ missingSetterInPropertyDescriptor: "Setter is not present in property descriptor.",
+ missingGetterInObjectLiteral: "Getter is not present for {{ name }}.",
+ missingSetterInObjectLiteral: "Setter is not present for {{ name }}."
}
},
create(context) {
const config = context.options[0] || {};
const checkGetWithoutSet = config.getWithoutSet === true;
const checkSetWithoutGet = config.setWithoutGet !== false;
+ const sourceCode = context.getSourceCode();
/**
- * Checks a object expression to see if it has setter and getter both present or none.
- * @param {ASTNode} node The node to check.
+ * Reports the given node.
+ * @param {ASTNode} node The node to report.
+ * @param {string} messageKind "missingGetter" or "missingSetter".
* @returns {void}
* @private
*/
- function checkLonelySetGet(node) {
- let isSetPresent = false;
- let isGetPresent = false;
- const isDescriptor = isPropertyDescriptor(node);
+ function report(node, messageKind) {
+ if (node.type === "Property") {
+ context.report({
+ node,
+ messageId: `${messageKind}InObjectLiteral`,
+ loc: astUtils.getFunctionHeadLoc(node.value, sourceCode),
+ data: { name: astUtils.getFunctionNameWithKind(node.value) }
+ });
+ } else {
+ context.report({
+ node,
+ messageId: `${messageKind}InPropertyDescriptor`
+ });
+ }
+ }
- for (let i = 0, end = node.properties.length; i < end; i++) {
- const property = node.properties[i];
+ /**
+ * Reports each of the nodes in the given list using the same messageId.
+ * @param {ASTNode[]} nodes Nodes to report.
+ * @param {string} messageKind "missingGetter" or "missingSetter".
+ * @returns {void}
+ * @private
+ */
+ function reportList(nodes, messageKind) {
+ for (const node of nodes) {
+ report(node, messageKind);
+ }
+ }
- let propToCheck = "";
+ /**
+ * Creates a new `AccessorData` object for the given getter or setter node.
+ * @param {ASTNode} node A getter or setter node.
+ * @returns {AccessorData} New `AccessorData` object that contains the given node.
+ * @private
+ */
+ function createAccessorData(node) {
+ const name = astUtils.getStaticPropertyName(node);
+ const key = (name !== null) ? name : sourceCode.getTokens(node.key);
- if (property.kind === "init") {
- if (isDescriptor && !property.computed) {
- propToCheck = property.key.name;
- }
- } else {
- propToCheck = property.kind;
- }
+ return {
+ key,
+ getters: node.kind === "get" ? [node] : [],
+ setters: node.kind === "set" ? [node] : []
+ };
+ }
- switch (propToCheck) {
- case "set":
- isSetPresent = true;
- break;
+ /**
+ * Merges the given `AccessorData` object into the given accessors list.
+ * @param {AccessorData[]} accessors The list to merge into.
+ * @param {AccessorData} accessorData The object to merge.
+ * @returns {AccessorData[]} The same instance with the merged object.
+ * @private
+ */
+ function mergeAccessorData(accessors, accessorData) {
+ const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key));
- case "get":
- isGetPresent = true;
- break;
+ if (equalKeyElement) {
+ equalKeyElement.getters.push(...accessorData.getters);
+ equalKeyElement.setters.push(...accessorData.setters);
+ } else {
+ accessors.push(accessorData);
+ }
- default:
+ return accessors;
+ }
- // Do nothing
- }
+ /**
+ * Checks accessor pairs in the given list of nodes.
+ * @param {ASTNode[]} nodes The list to check.
+ * @returns {void}
+ * @private
+ */
+ function checkList(nodes) {
+ const accessors = nodes
+ .filter(isAccessorKind)
+ .map(createAccessorData)
+ .reduce(mergeAccessorData, []);
- if (isSetPresent && isGetPresent) {
- break;
+ for (const { getters, setters } of accessors) {
+ if (checkSetWithoutGet && setters.length && !getters.length) {
+ reportList(setters, "missingGetter");
+ }
+ if (checkGetWithoutSet && getters.length && !setters.length) {
+ reportList(getters, "missingSetter");
}
}
+ }
- if (checkSetWithoutGet && isSetPresent && !isGetPresent) {
- context.report({ node, messageId: "getter" });
- } else if (checkGetWithoutSet && isGetPresent && !isSetPresent) {
- context.report({ node, messageId: "setter" });
+ /**
+ * Checks accessor pairs in an object literal.
+ * @param {ASTNode} node `ObjectExpression` node to check.
+ * @returns {void}
+ * @private
+ */
+ function checkObjectLiteral(node) {
+ checkList(node.properties.filter(p => p.type === "Property"));
+ }
+
+ /**
+ * Checks accessor pairs in a property descriptor.
+ * @param {ASTNode} node Property descriptor `ObjectExpression` node to check.
+ * @returns {void}
+ * @private
+ */
+ function checkPropertyDescriptor(node) {
+ const namesToCheck = node.properties
+ .filter(p => p.type === "Property" && p.kind === "init" && !p.computed)
+ .map(({ key }) => key.name);
+
+ const hasGetter = namesToCheck.includes("get");
+ const hasSetter = namesToCheck.includes("set");
+
+ if (checkSetWithoutGet && hasSetter && !hasGetter) {
+ report(node, "missingGetter");
+ }
+ if (checkGetWithoutSet && hasGetter && !hasSetter) {
+ report(node, "missingSetter");
}
}
return {
ObjectExpression(node) {
if (checkSetWithoutGet || checkGetWithoutSet) {
- checkLonelySetGet(node);
+ checkObjectLiteral(node);
+ if (isPropertyDescriptor(node)) {
+ checkPropertyDescriptor(node);
+ }
}
}
};
diff --git a/tools/node_modules/eslint/lib/rules/class-methods-use-this.js b/tools/node_modules/eslint/lib/rules/class-methods-use-this.js
index 0eb1da87f4..4bf17090ab 100644
--- a/tools/node_modules/eslint/lib/rules/class-methods-use-this.js
+++ b/tools/node_modules/eslint/lib/rules/class-methods-use-this.js
@@ -6,6 +6,12 @@
"use strict";
//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const astUtils = require("./utils/ast-utils");
+
+//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -34,7 +40,7 @@ module.exports = {
}],
messages: {
- missingThis: "Expected 'this' to be used by class method '{{name}}'."
+ missingThis: "Expected 'this' to be used by class {{name}}."
}
},
create(context) {
@@ -70,7 +76,8 @@ module.exports = {
* @private
*/
function isIncludedInstanceMethod(node) {
- return isInstanceMethod(node) && !exceptMethods.has(node.key.name);
+ return isInstanceMethod(node) &&
+ (node.computed || !exceptMethods.has(node.key.name));
}
/**
@@ -89,7 +96,7 @@ module.exports = {
node,
messageId: "missingThis",
data: {
- name: node.parent.key.name
+ name: astUtils.getFunctionNameWithKind(node)
}
});
}
diff --git a/tools/node_modules/eslint/lib/rules/dot-notation.js b/tools/node_modules/eslint/lib/rules/dot-notation.js
index 61184ddcd1..2e8fff8b90 100644
--- a/tools/node_modules/eslint/lib/rules/dot-notation.js
+++ b/tools/node_modules/eslint/lib/rules/dot-notation.js
@@ -9,13 +9,16 @@
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
+const keywords = require("./utils/keywords");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u;
-const keywords = require("./utils/keywords");
+
+// `null` literal must be handled separately.
+const literalTypesToCheck = new Set(["string", "boolean"]);
module.exports = {
meta: {
@@ -115,7 +118,8 @@ module.exports = {
MemberExpression(node) {
if (
node.computed &&
- node.property.type === "Literal"
+ node.property.type === "Literal" &&
+ (literalTypesToCheck.has(typeof node.property.value) || astUtils.isNullLiteral(node.property))
) {
checkComputedProperty(node, node.property.value);
}
diff --git a/tools/node_modules/eslint/lib/rules/func-call-spacing.js b/tools/node_modules/eslint/lib/rules/func-call-spacing.js
index f9c8e78057..e2edd4282d 100644
--- a/tools/node_modules/eslint/lib/rules/func-call-spacing.js
+++ b/tools/node_modules/eslint/lib/rules/func-call-spacing.js
@@ -78,21 +78,13 @@ module.exports = {
/**
* Check if open space is present in a function name
* @param {ASTNode} node node to evaluate
+ * @param {Token} leftToken The last token of the callee. This may be the closing parenthesis that encloses the callee.
+ * @param {Token} rightToken Tha first token of the arguments. this is the opening parenthesis that encloses the arguments.
* @returns {void}
* @private
*/
- function checkSpacing(node) {
- const lastToken = sourceCode.getLastToken(node);
- const lastCalleeToken = sourceCode.getLastToken(node.callee);
- const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken);
- const prevToken = parenToken && sourceCode.getTokenBefore(parenToken);
-
- // Parens in NewExpression are optional
- if (!(parenToken && parenToken.range[1] < node.range[1])) {
- return;
- }
-
- const textBetweenTokens = text.slice(prevToken.range[1], parenToken.range[0]).replace(/\/\*.*?\*\//gu, "");
+ function checkSpacing(node, leftToken, rightToken) {
+ const textBetweenTokens = text.slice(leftToken.range[1], rightToken.range[0]).replace(/\/\*.*?\*\//gu, "");
const hasWhitespace = /\s/u.test(textBetweenTokens);
const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens);
@@ -123,7 +115,7 @@ module.exports = {
if (never && hasWhitespace) {
context.report({
node,
- loc: lastCalleeToken.loc.start,
+ loc: leftToken.loc.start,
messageId: "unexpected",
fix(fixer) {
@@ -132,7 +124,7 @@ module.exports = {
* https://github.com/eslint/eslint/issues/7787
*/
if (!hasNewline) {
- return fixer.removeRange([prevToken.range[1], parenToken.range[0]]);
+ return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
}
return null;
@@ -141,27 +133,45 @@ module.exports = {
} else if (!never && !hasWhitespace) {
context.report({
node,
- loc: lastCalleeToken.loc.start,
+ loc: leftToken.loc.start,
messageId: "missing",
fix(fixer) {
- return fixer.insertTextBefore(parenToken, " ");
+ return fixer.insertTextBefore(rightToken, " ");
}
});
} else if (!never && !allowNewlines && hasNewline) {
context.report({
node,
- loc: lastCalleeToken.loc.start,
+ loc: leftToken.loc.start,
messageId: "unexpected",
fix(fixer) {
- return fixer.replaceTextRange([prevToken.range[1], parenToken.range[0]], " ");
+ return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ");
}
});
}
}
return {
- CallExpression: checkSpacing,
- NewExpression: checkSpacing
+ "CallExpression, NewExpression"(node) {
+ const lastToken = sourceCode.getLastToken(node);
+ const lastCalleeToken = sourceCode.getLastToken(node.callee);
+ const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken);
+ const prevToken = parenToken && sourceCode.getTokenBefore(parenToken);
+
+ // Parens in NewExpression are optional
+ if (!(parenToken && parenToken.range[1] < node.range[1])) {
+ return;
+ }
+
+ checkSpacing(node, prevToken, parenToken);
+ },
+
+ ImportExpression(node) {
+ const leftToken = sourceCode.getFirstToken(node);
+ const rightToken = sourceCode.getTokenAfter(leftToken);
+
+ checkSpacing(node, leftToken, rightToken);
+ }
};
}
diff --git a/tools/node_modules/eslint/lib/rules/func-names.js b/tools/node_modules/eslint/lib/rules/func-names.js
index 01beb9e2ed..ff3a1f4b5b 100644
--- a/tools/node_modules/eslint/lib/rules/func-names.js
+++ b/tools/node_modules/eslint/lib/rules/func-names.js
@@ -69,6 +69,8 @@ module.exports = {
create(context) {
+ const sourceCode = context.getSourceCode();
+
/**
* Returns the config option for the given node.
* @param {ASTNode} node - A node to get the config for.
@@ -130,6 +132,7 @@ module.exports = {
context.report({
node,
messageId: "unnamed",
+ loc: astUtils.getFunctionHeadLoc(node, sourceCode),
data: { name: astUtils.getFunctionNameWithKind(node) }
});
}
@@ -143,6 +146,7 @@ module.exports = {
context.report({
node,
messageId: "named",
+ loc: astUtils.getFunctionHeadLoc(node, sourceCode),
data: { name: astUtils.getFunctionNameWithKind(node) }
});
}
diff --git a/tools/node_modules/eslint/lib/rules/function-call-argument-newline.js b/tools/node_modules/eslint/lib/rules/function-call-argument-newline.js
new file mode 100644
index 0000000000..8bf31f7c71
--- /dev/null
+++ b/tools/node_modules/eslint/lib/rules/function-call-argument-newline.js
@@ -0,0 +1,120 @@
+/**
+ * @fileoverview Rule to enforce line breaks between arguments of a function call
+ * @author Alexey Gonchar <https://github.com/finico>
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ type: "layout",
+
+ docs: {
+ description: "enforce line breaks between arguments of a function call",
+ category: "Stylistic Issues",
+ recommended: false,
+ url: "https://eslint.org/docs/rules/function-call-argument-newline"
+ },
+
+ fixable: "whitespace",
+
+ schema: [
+ {
+ enum: ["always", "never", "consistent"]
+ }
+ ],
+
+ messages: {
+ unexpectedLineBreak: "There should be no line break here.",
+ missingLineBreak: "There should be a line break after this argument."
+ }
+ },
+
+ create(context) {
+ const sourceCode = context.getSourceCode();
+
+ const checkers = {
+ unexpected: {
+ messageId: "unexpectedLineBreak",
+ check: (prevToken, currentToken) => prevToken.loc.start.line !== currentToken.loc.start.line,
+ createFix: (token, tokenBefore) => fixer =>
+ fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ")
+ },
+ missing: {
+ messageId: "missingLineBreak",
+ check: (prevToken, currentToken) => prevToken.loc.start.line === currentToken.loc.start.line,
+ createFix: (token, tokenBefore) => fixer =>
+ fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n")
+ }
+ };
+
+ /**
+ * Check all arguments for line breaks in the CallExpression
+ * @param {CallExpression} node node to evaluate
+ * @param {{ messageId: string, check: Function }} checker selected checker
+ * @returns {void}
+ * @private
+ */
+ function checkArguments(node, checker) {
+ for (let i = 1; i < node.arguments.length; i++) {
+ const prevArgToken = sourceCode.getFirstToken(node.arguments[i - 1]);
+ const currentArgToken = sourceCode.getFirstToken(node.arguments[i]);
+
+ if (checker.check(prevArgToken, currentArgToken)) {
+ const tokenBefore = sourceCode.getTokenBefore(
+ currentArgToken,
+ { includeComments: true }
+ );
+
+ context.report({
+ node,
+ loc: {
+ start: tokenBefore.loc.end,
+ end: currentArgToken.loc.start
+ },
+ messageId: checker.messageId,
+ fix: checker.createFix(currentArgToken, tokenBefore)
+ });
+ }
+ }
+ }
+
+ /**
+ * Check if open space is present in a function name
+ * @param {CallExpression} node node to evaluate
+ * @returns {void}
+ * @private
+ */
+ function check(node) {
+ if (node.arguments.length < 2) {
+ return;
+ }
+
+ const option = context.options[0] || "always";
+
+ if (option === "never") {
+ checkArguments(node, checkers.unexpected);
+ } else if (option === "always") {
+ checkArguments(node, checkers.missing);
+ } else if (option === "consistent") {
+ const firstArgToken = sourceCode.getFirstToken(node.arguments[0]);
+ const secondArgToken = sourceCode.getFirstToken(node.arguments[1]);
+
+ if (firstArgToken.loc.start.line === secondArgToken.loc.start.line) {
+ checkArguments(node, checkers.unexpected);
+ } else {
+ checkArguments(node, checkers.missing);
+ }
+ }
+ }
+
+ return {
+ CallExpression: check,
+ NewExpression: check
+ };
+ }
+};
diff --git a/tools/node_modules/eslint/lib/rules/function-paren-newline.js b/tools/node_modules/eslint/lib/rules/function-paren-newline.js
index 0a0b57a372..c9f09fdefa 100644
--- a/tools/node_modules/eslint/lib/rules/function-paren-newline.js
+++ b/tools/node_modules/eslint/lib/rules/function-paren-newline.js
@@ -232,25 +232,15 @@ module.exports = {
};
}
- default:
- throw new TypeError(`unexpected node with type ${node.type}`);
- }
- }
-
- /**
- * Validates the parentheses for a node
- * @param {ASTNode} node The node with parens
- * @returns {void}
- */
- function validateNode(node) {
- const parens = getParenTokens(node);
-
- if (parens) {
- validateParens(parens, astUtils.isFunction(node) ? node.params : node.arguments);
+ case "ImportExpression": {
+ const leftParen = sourceCode.getFirstToken(node, 1);
+ const rightParen = sourceCode.getLastToken(node);
- if (multilineArgumentsOption) {
- validateArguments(parens, astUtils.isFunction(node) ? node.params : node.arguments);
+ return { leftParen, rightParen };
}
+
+ default:
+ throw new TypeError(`unexpected node with type ${node.type}`);
}
}
@@ -259,11 +249,33 @@ module.exports = {
//----------------------------------------------------------------------
return {
- ArrowFunctionExpression: validateNode,
- CallExpression: validateNode,
- FunctionDeclaration: validateNode,
- FunctionExpression: validateNode,
- NewExpression: validateNode
+ [[
+ "ArrowFunctionExpression",
+ "CallExpression",
+ "FunctionDeclaration",
+ "FunctionExpression",
+ "ImportExpression",
+ "NewExpression"
+ ]](node) {
+ const parens = getParenTokens(node);
+ let params;
+
+ if (node.type === "ImportExpression") {
+ params = [node.source];
+ } else if (astUtils.isFunction(node)) {
+ params = node.params;
+ } else {
+ params = node.arguments;
+ }
+
+ if (parens) {
+ validateParens(parens, params);
+
+ if (multilineArgumentsOption) {
+ validateArguments(parens, params);
+ }
+ }
+ }
};
}
};
diff --git a/tools/node_modules/eslint/lib/rules/indent.js b/tools/node_modules/eslint/lib/rules/indent.js
index 345c69e81c..79b1063137 100644
--- a/tools/node_modules/eslint/lib/rules/indent.js
+++ b/tools/node_modules/eslint/lib/rules/indent.js
@@ -99,7 +99,8 @@ const KNOWN_NODES = new Set([
"ImportDeclaration",
"ImportSpecifier",
"ImportDefaultSpecifier",
- "ImportNamespaceSpecifier"
+ "ImportNamespaceSpecifier",
+ "ImportExpression"
]);
/*
@@ -1109,7 +1110,6 @@ module.exports = {
CallExpression: addFunctionCallIndent,
-
"ClassDeclaration[superClass], ClassExpression[superClass]"(node) {
const classToken = sourceCode.getFirstToken(node);
const extendsToken = sourceCode.getTokenBefore(node.superClass, astUtils.isNotOpeningParenToken);
@@ -1236,6 +1236,17 @@ module.exports = {
}
},
+ ImportExpression(node) {
+ const openingParen = sourceCode.getFirstToken(node, 1);
+ const closingParen = sourceCode.getLastToken(node);
+
+ parameterParens.add(openingParen);
+ parameterParens.add(closingParen);
+ offsets.setDesiredOffset(openingParen, sourceCode.getTokenBefore(openingParen), 0);
+
+ addElementListIndent([node.source], openingParen, closingParen, options.CallExpression.arguments);
+ },
+
"MemberExpression, JSXMemberExpression, MetaProperty"(node) {
const object = node.type === "MetaProperty" ? node.meta : node.object;
const firstNonObjectToken = sourceCode.getFirstTokenBetween(object, node.property, astUtils.isNotClosingParenToken);
diff --git a/tools/node_modules/eslint/lib/rules/index.js b/tools/node_modules/eslint/lib/rules/index.js
index 45045904bb..c42ae41d6c 100644
--- a/tools/node_modules/eslint/lib/rules/index.js
+++ b/tools/node_modules/eslint/lib/rules/index.js
@@ -46,6 +46,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
"func-name-matching": () => require("./func-name-matching"),
"func-names": () => require("./func-names"),
"func-style": () => require("./func-style"),
+ "function-call-argument-newline": () => require("./function-call-argument-newline"),
"function-paren-newline": () => require("./function-paren-newline"),
"generator-star-spacing": () => require("./generator-star-spacing"),
"getter-return": () => require("./getter-return"),
diff --git a/tools/node_modules/eslint/lib/rules/new-cap.js b/tools/node_modules/eslint/lib/rules/new-cap.js
index dcae238d9b..cee979310e 100644
--- a/tools/node_modules/eslint/lib/rules/new-cap.js
+++ b/tools/node_modules/eslint/lib/rules/new-cap.js
@@ -23,7 +23,8 @@ const CAPS_ALLOWED = [
"Object",
"RegExp",
"String",
- "Symbol"
+ "Symbol",
+ "BigInt"
];
/**
diff --git a/tools/node_modules/eslint/lib/rules/no-dupe-keys.js b/tools/node_modules/eslint/lib/rules/no-dupe-keys.js
index d0751b4a2d..1b7f69cfac 100644
--- a/tools/node_modules/eslint/lib/rules/no-dupe-keys.js
+++ b/tools/node_modules/eslint/lib/rules/no-dupe-keys.js
@@ -120,7 +120,7 @@ module.exports = {
}
// Skip if the name is not static.
- if (!name) {
+ if (name === null) {
return;
}
diff --git a/tools/node_modules/eslint/lib/rules/no-duplicate-case.js b/tools/node_modules/eslint/lib/rules/no-duplicate-case.js
index 93c8548f91..c8a0fa9da3 100644
--- a/tools/node_modules/eslint/lib/rules/no-duplicate-case.js
+++ b/tools/node_modules/eslint/lib/rules/no-duplicate-case.js
@@ -33,17 +33,19 @@ module.exports = {
return {
SwitchStatement(node) {
- const mapping = {};
+ const previousKeys = new Set();
- node.cases.forEach(switchCase => {
- const key = sourceCode.getText(switchCase.test);
+ for (const switchCase of node.cases) {
+ if (switchCase.test) {
+ const key = sourceCode.getText(switchCase.test);
- if (mapping[key]) {
- context.report({ node: switchCase, messageId: "unexpected" });
- } else {
- mapping[key] = switchCase;
+ if (previousKeys.has(key)) {
+ context.report({ node: switchCase, messageId: "unexpected" });
+ } else {
+ previousKeys.add(key);
+ }
}
- });
+ }
}
};
}
diff --git a/tools/node_modules/eslint/lib/rules/no-extra-bind.js b/tools/node_modules/eslint/lib/rules/no-extra-bind.js
index 5380cf217f..cc0b1f8437 100644
--- a/tools/node_modules/eslint/lib/rules/no-extra-bind.js
+++ b/tools/node_modules/eslint/lib/rules/no-extra-bind.js
@@ -98,6 +98,7 @@ module.exports = {
grandparent.type === "CallExpression" &&
grandparent.callee === parent &&
grandparent.arguments.length === 1 &&
+ grandparent.arguments[0].type !== "SpreadElement" &&
parent.type === "MemberExpression" &&
parent.object === node &&
astUtils.getStaticPropertyName(parent) === "bind"
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 8dd526477d..9ae9b5be61 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
@@ -50,8 +50,8 @@ module.exports = {
/**
* Check if a node is in a context where its value would be coerced to a boolean at runtime.
*
- * @param {Object} node The node
- * @param {Object} parent Its parent
+ * @param {ASTNode} node The node
+ * @param {ASTNode} parent Its parent
* @returns {boolean} If it is in a boolean context
*/
function isInBooleanContext(node, parent) {
@@ -65,6 +65,15 @@ module.exports = {
);
}
+ /**
+ * Check if a node has comments inside.
+ *
+ * @param {ASTNode} node The node to check.
+ * @returns {boolean} `true` if it has comments inside.
+ */
+ function hasCommentsInside(node) {
+ return Boolean(sourceCode.getCommentsInside(node).length);
+ }
return {
UnaryExpression(node) {
@@ -89,7 +98,12 @@ module.exports = {
context.report({
node,
messageId: "unexpectedNegation",
- fix: fixer => fixer.replaceText(parent, sourceCode.getText(node.argument))
+ fix: fixer => {
+ if (hasCommentsInside(parent)) {
+ return null;
+ }
+ return fixer.replaceText(parent, sourceCode.getText(node.argument));
+ }
});
}
},
@@ -106,10 +120,35 @@ module.exports = {
messageId: "unexpectedCall",
fix: fixer => {
if (!node.arguments.length) {
- return fixer.replaceText(parent, "true");
+ if (parent.type === "UnaryExpression" && parent.operator === "!") {
+
+ // !Boolean() -> true
+
+ if (hasCommentsInside(parent)) {
+ return null;
+ }
+
+ const replacement = "true";
+ let prefix = "";
+ const tokenBefore = sourceCode.getTokenBefore(parent);
+
+ if (tokenBefore && tokenBefore.range[1] === parent.range[0] &&
+ !astUtils.canTokensBeAdjacent(tokenBefore, replacement)) {
+ prefix = " ";
+ }
+
+ return fixer.replaceText(parent, prefix + replacement);
+ }
+
+ // Boolean() -> false
+ if (hasCommentsInside(node)) {
+ return null;
+ }
+ return fixer.replaceText(node, "false");
}
- if (node.arguments.length > 1 || node.arguments[0].type === "SpreadElement") {
+ if (node.arguments.length > 1 || node.arguments[0].type === "SpreadElement" ||
+ hasCommentsInside(node)) {
return null;
}
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 6c3198b5f0..aa455c6a25 100644
--- a/tools/node_modules/eslint/lib/rules/no-extra-parens.js
+++ b/tools/node_modules/eslint/lib/rules/no-extra-parens.js
@@ -8,6 +8,7 @@
// Rule Definition
//------------------------------------------------------------------------------
+const { isParenthesized: isParenthesizedRaw } = require("eslint-utils");
const astUtils = require("./utils/ast-utils.js");
module.exports = {
@@ -68,7 +69,6 @@ module.exports = {
const sourceCode = context.getSourceCode();
const tokensToIgnore = new WeakSet();
- const isParenthesised = astUtils.isParenthesised.bind(astUtils, sourceCode);
const precedence = astUtils.getPrecedence;
const ALL_NODES = context.options[0] !== "functions";
const EXCEPT_COND_ASSIGN = ALL_NODES && context.options[1] && context.options[1].conditionalAssign === false;
@@ -119,18 +119,23 @@ module.exports = {
}
/**
+ * Determines if a node is surrounded by parentheses.
+ * @param {ASTNode} node - The node to be checked.
+ * @returns {boolean} True if the node is parenthesised.
+ * @private
+ */
+ function isParenthesised(node) {
+ return isParenthesizedRaw(1, node, sourceCode);
+ }
+
+ /**
* Determines if a node is surrounded by parentheses twice.
* @param {ASTNode} node - The node to be checked.
* @returns {boolean} True if the node is doubly parenthesised.
* @private
*/
function isParenthesisedTwice(node) {
- const previousToken = sourceCode.getTokenBefore(node, 1),
- nextToken = sourceCode.getTokenAfter(node, 1);
-
- return isParenthesised(node) && previousToken && nextToken &&
- astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] &&
- astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1];
+ return isParenthesizedRaw(2, node, sourceCode);
}
/**
@@ -406,15 +411,9 @@ module.exports = {
report(node.callee);
}
}
- if (node.arguments.length === 1) {
- if (hasDoubleExcessParens(node.arguments[0]) && precedence(node.arguments[0]) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
- report(node.arguments[0]);
- }
- } else {
- node.arguments
- .filter(arg => hasExcessParens(arg) && precedence(arg) >= PRECEDENCE_OF_ASSIGNMENT_EXPR)
- .forEach(report);
- }
+ node.arguments
+ .filter(arg => hasExcessParens(arg) && precedence(arg) >= PRECEDENCE_OF_ASSIGNMENT_EXPR)
+ .forEach(report);
}
/**
@@ -686,6 +685,13 @@ module.exports = {
CallExpression: checkCallNew,
+ ClassBody(node) {
+ node.body
+ .filter(member => member.type === "MethodDefinition" && member.computed &&
+ member.key && hasExcessParens(member.key) && precedence(member.key) >= PRECEDENCE_OF_ASSIGNMENT_EXPR)
+ .forEach(member => report(member.key));
+ },
+
ConditionalExpression(node) {
if (isReturnAssignException(node)) {
return;
@@ -705,7 +711,7 @@ module.exports = {
},
DoWhileStatement(node) {
- if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) {
+ if (hasExcessParens(node.test) && !isCondAssignException(node)) {
report(node.test);
}
},
@@ -830,11 +836,23 @@ module.exports = {
},
IfStatement(node) {
- if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) {
+ if (hasExcessParens(node.test) && !isCondAssignException(node)) {
report(node.test);
}
},
+ ImportExpression(node) {
+ const { source } = node;
+
+ if (source.type === "SequenceExpression") {
+ if (hasDoubleExcessParens(source)) {
+ report(source);
+ }
+ } else if (hasExcessParens(source)) {
+ report(source);
+ }
+ },
+
LogicalExpression: checkBinaryLogical,
MemberExpression(node) {
@@ -917,7 +935,7 @@ module.exports = {
},
SwitchStatement(node) {
- if (hasDoubleExcessParens(node.discriminant)) {
+ if (hasExcessParens(node.discriminant)) {
report(node.discriminant);
}
},
@@ -945,13 +963,13 @@ module.exports = {
},
WhileStatement(node) {
- if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) {
+ if (hasExcessParens(node.test) && !isCondAssignException(node)) {
report(node.test);
}
},
WithStatement(node) {
- if (hasDoubleExcessParens(node.object)) {
+ if (hasExcessParens(node.object)) {
report(node.object);
}
},
@@ -973,7 +991,21 @@ module.exports = {
SpreadElement: checkSpreadOperator,
SpreadProperty: checkSpreadOperator,
- ExperimentalSpreadProperty: checkSpreadOperator
+ ExperimentalSpreadProperty: checkSpreadOperator,
+
+ TemplateLiteral(node) {
+ node.expressions
+ .filter(e => e && hasExcessParens(e))
+ .forEach(report);
+ },
+
+ AssignmentPattern(node) {
+ const { right } = node;
+
+ if (right && hasExcessParens(right) && precedence(right) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
+ report(right);
+ }
+ }
};
}
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 21e1d95c68..8d1c7a6af4 100644
--- a/tools/node_modules/eslint/lib/rules/no-mixed-operators.js
+++ b/tools/node_modules/eslint/lib/rules/no-mixed-operators.js
@@ -20,12 +20,14 @@ const BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"];
const COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="];
const LOGICAL_OPERATORS = ["&&", "||"];
const RELATIONAL_OPERATORS = ["in", "instanceof"];
+const TERNARY_OPERATOR = ["?:"];
const ALL_OPERATORS = [].concat(
ARITHMETIC_OPERATORS,
BITWISE_OPERATORS,
COMPARISON_OPERATORS,
LOGICAL_OPERATORS,
- RELATIONAL_OPERATORS
+ RELATIONAL_OPERATORS,
+ TERNARY_OPERATOR
);
const DEFAULT_GROUPS = [
ARITHMETIC_OPERATORS,
@@ -34,7 +36,7 @@ const DEFAULT_GROUPS = [
LOGICAL_OPERATORS,
RELATIONAL_OPERATORS
];
-const TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/u;
+const TARGET_NODE_TYPE = /^(?:Binary|Logical|Conditional)Expression$/u;
/**
* Normalizes options.
@@ -65,6 +67,18 @@ function includesBothInAGroup(groups, left, right) {
return groups.some(group => group.indexOf(left) !== -1 && group.indexOf(right) !== -1);
}
+/**
+ * Checks whether the given node is a conditional expression and returns the test node else the left node.
+ *
+ * @param {ASTNode} node - A node which can be a BinaryExpression or a LogicalExpression node.
+ * This parent node can be BinaryExpression, LogicalExpression
+ * , or a ConditionalExpression node
+ * @returns {ASTNode} node the appropriate node(left or test).
+ */
+function getChildNode(node) {
+ return node.type === "ConditionalExpression" ? node.test : node.left;
+}
+
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@@ -121,7 +135,7 @@ module.exports = {
const b = node.parent;
return (
- !includesBothInAGroup(options.groups, a.operator, b.operator) ||
+ !includesBothInAGroup(options.groups, a.operator, b.type === "ConditionalExpression" ? "?:" : b.operator) ||
(
options.allowSamePrecedence &&
astUtils.getPrecedence(a) === astUtils.getPrecedence(b)
@@ -139,6 +153,7 @@ module.exports = {
* @returns {boolean} `true` if the node was mixed.
*/
function isMixedWithParent(node) {
+
return (
node.operator !== node.parent.operator &&
!astUtils.isParenthesised(sourceCode, node)
@@ -146,6 +161,18 @@ module.exports = {
}
/**
+ * Checks whether the operator of a given node is mixed with a
+ * conditional expression.
+ *
+ * @param {ASTNode} node - A node to check. This is a conditional
+ * expression node
+ * @returns {boolean} `true` if the node was mixed.
+ */
+ function isMixedWithConditionalParent(node) {
+ return !astUtils.isParenthesised(sourceCode, node) && !astUtils.isParenthesised(sourceCode, node.test);
+ }
+
+ /**
* Gets the operator token of a given node.
*
* @param {ASTNode} node - A node to check. This is a BinaryExpression
@@ -153,7 +180,7 @@ module.exports = {
* @returns {Token} The operator token of the node.
*/
function getOperatorToken(node) {
- return sourceCode.getTokenAfter(node.left, astUtils.isNotClosingParenToken);
+ return sourceCode.getTokenAfter(getChildNode(node), astUtils.isNotClosingParenToken);
}
/**
@@ -167,13 +194,13 @@ module.exports = {
*/
function reportBothOperators(node) {
const parent = node.parent;
- const left = (parent.left === node) ? node : parent;
- const right = (parent.left !== node) ? 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
+ leftOperator: left.operator || "?:",
+ rightOperator: right.operator || "?:"
};
context.report({
@@ -198,17 +225,25 @@ module.exports = {
* @returns {void}
*/
function check(node) {
- if (TARGET_NODE_TYPE.test(node.parent.type) &&
- isMixedWithParent(node) &&
- !shouldIgnore(node)
- ) {
- reportBothOperators(node);
+ if (TARGET_NODE_TYPE.test(node.parent.type)) {
+ if (node.parent.type === "ConditionalExpression" && !shouldIgnore(node) && isMixedWithConditionalParent(node.parent)) {
+ reportBothOperators(node);
+ } else {
+ if (TARGET_NODE_TYPE.test(node.parent.type) &&
+ isMixedWithParent(node) &&
+ !shouldIgnore(node)
+ ) {
+ reportBothOperators(node);
+ }
+ }
}
+
}
return {
BinaryExpression: check,
LogicalExpression: check
+
};
}
};
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 74eea14789..41aa9fa390 100644
--- a/tools/node_modules/eslint/lib/rules/no-restricted-syntax.js
+++ b/tools/node_modules/eslint/lib/rules/no-restricted-syntax.js
@@ -21,7 +21,7 @@ module.exports = {
schema: {
type: "array",
- items: [{
+ items: {
oneOf: [
{
type: "string"
@@ -36,7 +36,7 @@ module.exports = {
additionalProperties: false
}
]
- }],
+ },
uniqueItems: true,
minItems: 0
}
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 48df3aa3cc..8094de57c7 100644
--- a/tools/node_modules/eslint/lib/rules/no-unused-vars.js
+++ b/tools/node_modules/eslint/lib/rules/no-unused-vars.js
@@ -507,7 +507,7 @@ module.exports = {
const childScopes = scope.childScopes;
let i, l;
- if (scope.type !== "TDZ" && (scope.type !== "global" || config.vars === "all")) {
+ if (scope.type !== "global" || config.vars === "all") {
for (i = 0, l = variables.length; i < l; ++i) {
const variable = variables[i];
diff --git a/tools/node_modules/eslint/lib/rules/prefer-template.js b/tools/node_modules/eslint/lib/rules/prefer-template.js
index f73ac34f83..a2507d452c 100644
--- a/tools/node_modules/eslint/lib/rules/prefer-template.js
+++ b/tools/node_modules/eslint/lib/rules/prefer-template.js
@@ -52,16 +52,7 @@ function isOctalEscapeSequence(node) {
return false;
}
- const match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-7]{1,3})/u);
-
- if (match) {
-
- // \0 is actually not considered an octal
- if (match[2] !== "0" || typeof match[3] !== "undefined") {
- return true;
- }
- }
- return false;
+ return astUtils.hasOctalEscapeSequence(node.raw);
}
/**
diff --git a/tools/node_modules/eslint/lib/rules/sort-keys.js b/tools/node_modules/eslint/lib/rules/sort-keys.js
index beda42f1e3..c314d4a636 100644
--- a/tools/node_modules/eslint/lib/rules/sort-keys.js
+++ b/tools/node_modules/eslint/lib/rules/sort-keys.js
@@ -29,7 +29,13 @@ const astUtils = require("./utils/ast-utils"),
* @private
*/
function getPropertyName(node) {
- return astUtils.getStaticPropertyName(node) || node.key.name || null;
+ const staticName = astUtils.getStaticPropertyName(node);
+
+ if (staticName !== null) {
+ return staticName;
+ }
+
+ return node.key.name || null;
}
/**
@@ -151,9 +157,11 @@ module.exports = {
const numKeys = stack.numKeys;
const thisName = getPropertyName(node);
- stack.prevName = thisName || prevName;
+ if (thisName !== null) {
+ stack.prevName = thisName;
+ }
- if (!prevName || !thisName || numKeys < minKeys) {
+ if (prevName === null || thisName === null || numKeys < minKeys) {
return;
}
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 78ae7bc015..f0b926e329 100644
--- a/tools/node_modules/eslint/lib/rules/utils/ast-utils.js
+++ b/tools/node_modules/eslint/lib/rules/utils/ast-utils.js
@@ -38,6 +38,7 @@ const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
const DECIMAL_INTEGER_PATTERN = /^(0|[1-9]\d*)$/u;
+const OCTAL_ESCAPE_PATTERN = /^(?:[^\\]|\\[^0-7]|\\0(?![0-9]))*\\(?:[1-7]|0[0-9])/u;
/**
* Checks reference if is non initializer and writable.
@@ -847,6 +848,7 @@ module.exports = {
return 17;
case "CallExpression":
+ case "ImportExpression":
return 18;
case "NewExpression":
@@ -1101,7 +1103,7 @@ module.exports = {
} else {
const name = module.exports.getStaticPropertyName(parent);
- if (name) {
+ if (name !== null) {
tokens.push(`'${name}'`);
}
}
@@ -1301,7 +1303,7 @@ module.exports = {
* set `node.value` to a unicode regex. To make sure a literal is actually `null`, check
* `node.regex` instead. Also see: https://github.com/eslint/eslint/issues/8020
*/
- return node.type === "Literal" && node.value === null && !node.regex;
+ return node.type === "Literal" && node.value === null && !node.regex && !node.bigint;
},
/**
@@ -1373,5 +1375,20 @@ module.exports = {
"/*".length +
(match ? match.index + 1 : 0)
);
+ },
+
+ /**
+ * Determines whether the given raw string contains an octal escape sequence.
+ *
+ * "\1", "\2" ... "\7"
+ * "\00", "\01" ... "\09"
+ *
+ * "\0", when not followed by a digit, is not an octal escape sequence.
+ *
+ * @param {string} rawString A string in its raw representation.
+ * @returns {boolean} `true` if the string contains at least one octal escape sequence.
+ */
+ hasOctalEscapeSequence(rawString) {
+ return OCTAL_ESCAPE_PATTERN.test(rawString);
}
};
diff --git a/tools/node_modules/eslint/lib/rules/yoda.js b/tools/node_modules/eslint/lib/rules/yoda.js
index 43783c193b..89c4a8afd1 100644
--- a/tools/node_modules/eslint/lib/rules/yoda.js
+++ b/tools/node_modules/eslint/lib/rules/yoda.js
@@ -119,7 +119,7 @@ function same(a, b) {
const nameA = astUtils.getStaticPropertyName(a);
// x.y = x["y"]
- if (nameA) {
+ if (nameA !== null) {
return (
same(a.object, b.object) &&
nameA === astUtils.getStaticPropertyName(b)
diff --git a/tools/node_modules/eslint/lib/shared/types.js b/tools/node_modules/eslint/lib/shared/types.js
index d835779994..8a889d21db 100644
--- a/tools/node_modules/eslint/lib/shared/types.js
+++ b/tools/node_modules/eslint/lib/shared/types.js
@@ -30,6 +30,7 @@ module.exports = {};
* @property {Record<string, boolean>} [env] The environment settings.
* @property {string | string[]} [extends] The path to other config files or the package name of shareable configs.
* @property {Record<string, GlobalConf>} [globals] The global variable settings.
+ * @property {boolean} [noInlineConfig] The flag that disables directive comments.
* @property {OverrideConfigData[]} [overrides] The override settings per kind of files.
* @property {string} [parser] The path to a parser or the package name of a parser.
* @property {ParserOptions} [parserOptions] The parser options.
@@ -47,6 +48,7 @@ module.exports = {};
* @property {string | string[]} [extends] The path to other config files or the package name of shareable configs.
* @property {string | string[]} files The glob pattarns for target files.
* @property {Record<string, GlobalConf>} [globals] The global variable settings.
+ * @property {boolean} [noInlineConfig] The flag that disables directive comments.
* @property {OverrideConfigData[]} [overrides] The override settings per kind of files.
* @property {string} [parser] The path to a parser or the package name of a parser.
* @property {ParserOptions} [parserOptions] The parser options.