diff --git a/tools/node_modules/eslint/README.md b/tools/node_modules/eslint/README.md index 73a30990e50974..624ad9e3adb868 100644 --- a/tools/node_modules/eslint/README.md +++ b/tools/node_modules/eslint/README.md @@ -35,10 +35,11 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J 6. [Releases](#releases) 7. [Security Policy](#security-policy) 8. [Semantic Versioning Policy](#semantic-versioning-policy) -9. [License](#license) -10. [Team](#team) -11. [Sponsors](#sponsors) -12. [Technology Sponsors](#technology-sponsors) +9. [Stylistic Rule Updates](#stylistic-rule-updates) +10. [License](#license) +11. [Team](#team) +12. [Sponsors](#sponsors) +13. [Technology Sponsors](#technology-sponsors) ## Installation and Usage @@ -136,6 +137,16 @@ Once a language feature has been adopted into the ECMAScript standard (stage 4 a Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://eslint.org/chat). +### Why doesn't ESLint lock dependency versions? + +Lock files like `package-lock.json` are helpful for deployed applications. They ensure that dependencies are consistent between environments and across deployments. + +Packages like `eslint` that get published to the npm registry do not include lock files. `npm install eslint` as a user will respect version constraints in ESLint's `package.json`. ESLint and its dependencies will be included in the user's lock file if one exists, but ESLint's own lock file would not be used. + +We intentionally don't lock dependency versions so that we have the latest compatible dependency versions in development and CI that our users get when installing ESLint in a project. + +The Twilio blog has a [deeper dive](https://www.twilio.com/blog/lockfiles-nodejs) to learn more. + ## Releases We have scheduled releases every two weeks on Friday or Saturday. You can follow a [release issue](https://github.com/eslint/eslint/issues?q=is%3Aopen+is%3Aissue+label%3Arelease) for updates about the scheduling of any particular release. @@ -177,6 +188,15 @@ ESLint follows [semantic versioning](https://semver.org). However, due to the na According to our policy, any minor update may report more linting errors than the previous release (ex: from a bug fix). As such, we recommend using the tilde (`~`) in `package.json` e.g. `"eslint": "~3.1.0"` to guarantee the results of your builds. +## Stylistic Rule Updates + +Stylistic rules are frozen according to [our policy](https://eslint.org/blog/2020/05/changes-to-rules-policies) on how we evaluate new rules and rule changes. +This means: + +* **Bug fixes**: We will still fix bugs in stylistic rules. +* **New ECMAScript features**: We will also make sure stylistic rules are compatible with new ECMAScript features. +* **New options**: We will **not** add any new options to stylistic rules unless an option is the only way to fix a bug or support a newly-added ECMAScript feature. + ## License [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Feslint%2Feslint.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Feslint%2Feslint?ref=badge_large) @@ -261,8 +281,8 @@ The following companies, organizations, and individuals support ESLint's ongoing

Platinum Sponsors

Automattic

Gold Sponsors

-

Chrome's Web Framework & Tools Performance Fund Shopify Salesforce Airbnb Microsoft FOSS Fund Sponsorships

Silver Sponsors

-

Liftoff AMP Project

Bronze Sponsors

+

Chrome's Web Framework & Tools Performance Fund Shopify Salesforce Airbnb Microsoft FOSS Fund Sponsorships

Silver Sponsors

+

Retool Liftoff AMP Project

Bronze Sponsors

Streamat The Standard Daily Writers Per Hour February 2021 calendar Buy.Fineproxy.Org Anagram Solver Bugsnag Stability Monitoring Mixpanel VPS Server Icons8: free icons, photos, illustrations, and music Discord ThemeIsle Fire Stick Tricks

diff --git a/tools/node_modules/eslint/lib/rules/indent.js b/tools/node_modules/eslint/lib/rules/indent.js index 1c0dccc5c9891f..8f4079d31f91d9 100644 --- a/tools/node_modules/eslint/lib/rules/indent.js +++ b/tools/node_modules/eslint/lib/rules/indent.js @@ -1178,6 +1178,7 @@ module.exports = { offsets.setDesiredOffset(colonToken, firstToken, 1); offsets.setDesiredOffset(firstConsequentToken, firstToken, + firstConsequentToken.type === "Punctuator" && options.offsetTernaryExpressions ? 2 : 1); /* 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 19c6fced79d4ff..307e340c958d88 100644 --- a/tools/node_modules/eslint/lib/rules/no-extra-parens.js +++ b/tools/node_modules/eslint/lib/rules/no-extra-parens.js @@ -844,45 +844,49 @@ module.exports = { ExportDefaultDeclaration: node => checkExpressionOrExportStatement(node.declaration), ExpressionStatement: node => checkExpressionOrExportStatement(node.expression), - "ForInStatement, ForOfStatement"(node) { - if (node.left.type !== "VariableDeclarator") { + ForInStatement(node) { + if (node.left.type !== "VariableDeclaration") { const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken); if ( - firstLeftToken.value === "let" && ( - - /* - * If `let` is the only thing on the left side of the loop, it's the loop variable: `for ((let) of foo);` - * Removing it will cause a syntax error, because it will be parsed as the start of a VariableDeclarator. - */ - (firstLeftToken.range[1] === node.left.range[1] || /* - * If `let` is followed by a `[` token, it's a property access on the `let` value: `for ((let[foo]) of bar);` - * Removing it will cause the property access to be parsed as a destructuring declaration of `foo` instead. - */ - astUtils.isOpeningBracketToken( - sourceCode.getTokenAfter(firstLeftToken, astUtils.isNotClosingParenToken) - )) + firstLeftToken.value === "let" && + astUtils.isOpeningBracketToken( + sourceCode.getTokenAfter(firstLeftToken, astUtils.isNotClosingParenToken) ) ) { + + // ForInStatement#left expression cannot start with `let[`. tokensToIgnore.add(firstLeftToken); } } - if (node.type === "ForOfStatement") { - const hasExtraParens = node.right.type === "SequenceExpression" - ? hasDoubleExcessParens(node.right) - : hasExcessParens(node.right); + if (hasExcessParens(node.left)) { + report(node.left); + } - if (hasExtraParens) { - report(node.right); - } - } else if (hasExcessParens(node.right)) { + if (hasExcessParens(node.right)) { report(node.right); } + }, + + ForOfStatement(node) { + if (node.left.type !== "VariableDeclaration") { + const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken); + + if (firstLeftToken.value === "let") { + + // ForOfStatement#left expression cannot start with `let`. + tokensToIgnore.add(firstLeftToken); + } + } if (hasExcessParens(node.left)) { report(node.left); } + + if (hasExcessParensWithPrecedence(node.right, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.right); + } }, ForStatement(node) { 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 6136ebb9e0be11..94ad5ba6d5c23d 100644 --- a/tools/node_modules/eslint/lib/rules/no-invalid-regexp.js +++ b/tools/node_modules/eslint/lib/rules/no-invalid-regexp.js @@ -69,6 +69,28 @@ module.exports = { return node && node.type === "Literal" && typeof node.value === "string"; } + /** + * Gets flags of a regular expression created by the given `RegExp()` or `new RegExp()` call + * Examples: + * new RegExp(".") // => "" + * new RegExp(".", "gu") // => "gu" + * new RegExp(".", flags) // => null + * @param {ASTNode} node `CallExpression` or `NewExpression` node + * @returns {string|null} flags if they can be determined, `null` otherwise + * @private + */ + function getFlags(node) { + if (node.arguments.length < 2) { + return ""; + } + + if (isString(node.arguments[1])) { + return node.arguments[1].value; + } + + return null; + } + /** * Check syntax error in a given pattern. * @param {string} pattern The RegExp pattern to validate. @@ -104,18 +126,23 @@ module.exports = { return; } const pattern = node.arguments[0].value; - let flags = isString(node.arguments[1]) ? node.arguments[1].value : ""; + let flags = getFlags(node); - if (allowedFlags) { + if (flags && allowedFlags) { flags = flags.replace(allowedFlags, ""); } - // If flags are unknown, check both are errored or not. - const message = validateRegExpFlags(flags) || ( - flags - ? validateRegExpPattern(pattern, flags.indexOf("u") !== -1) - : validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false) - ); + const message = + ( + flags && validateRegExpFlags(flags) + ) || + ( + + // If flags are unknown, report the regex only if its pattern is invalid both with and without the "u" flag + flags === null + ? validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false) + : validateRegExpPattern(pattern, flags.includes("u")) + ); if (message) { context.report({ diff --git a/tools/node_modules/eslint/lib/rules/no-shadow.js b/tools/node_modules/eslint/lib/rules/no-shadow.js index 1be8590e47abcb..a0b1db50c0b5f2 100644 --- a/tools/node_modules/eslint/lib/rules/no-shadow.js +++ b/tools/node_modules/eslint/lib/rules/no-shadow.js @@ -44,7 +44,8 @@ module.exports = { ], messages: { - noShadow: "'{{name}}' is already declared in the upper scope." + noShadow: "'{{name}}' is already declared in the upper scope on line {{shadowedLine}} column {{shadowedColumn}}.", + noShadowGlobal: "'{{name}}' is already a global variable." } }, @@ -117,6 +118,29 @@ module.exports = { return def && def.name.range; } + /** + * Get declared line and column of a variable. + * @param {eslint-scope.Variable} variable The variable to get. + * @returns {Object} The declared line and column of the variable. + */ + function getDeclaredLocation(variable) { + const identifier = variable.identifiers[0]; + let obj; + + if (identifier) { + obj = { + global: false, + line: identifier.loc.start.line, + column: identifier.loc.start.column + 1 + }; + } else { + obj = { + global: true + }; + } + return obj; + } + /** * Checks if a variable is in TDZ of scopeVar. * @param {Object} variable The variable to check. @@ -165,10 +189,18 @@ module.exports = { !isOnInitializer(variable, shadowed) && !(options.hoist !== "all" && isInTdz(variable, shadowed)) ) { + const location = getDeclaredLocation(shadowed); + const messageId = location.global ? "noShadowGlobal" : "noShadow"; + const data = { name: variable.name }; + + if (!location.global) { + data.shadowedLine = location.line; + data.shadowedColumn = location.column; + } context.report({ node: variable.identifiers[0], - messageId: "noShadow", - data: variable + messageId, + data }); } } 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 fa88f37f50b79c..a7cec025da7e70 100644 --- a/tools/node_modules/eslint/lib/rules/no-useless-rename.js +++ b/tools/node_modules/eslint/lib/rules/no-useless-rename.js @@ -5,6 +5,12 @@ "use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("./utils/ast-utils"); + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -54,11 +60,10 @@ module.exports = { * Reports error for unnecessarily renamed assignments * @param {ASTNode} node node to report * @param {ASTNode} initial node with initial name value - * @param {ASTNode} result node with new name value * @param {string} type the type of the offending node * @returns {void} */ - function reportError(node, initial, result, type) { + function reportError(node, initial, type) { const name = initial.type === "Identifier" ? initial.name : initial.value; return context.report({ @@ -69,18 +74,21 @@ module.exports = { type }, fix(fixer) { - if (sourceCode.commentsExistBetween(initial, result)) { + const replacementNode = node.type === "Property" ? node.value : node.local; + + if (sourceCode.getCommentsInside(node).length > sourceCode.getCommentsInside(replacementNode).length) { return null; } - const replacementText = result.type === "AssignmentPattern" - ? sourceCode.getText(result) - : name; + // Don't autofix code such as `({foo: (foo) = a} = obj);`, parens are not allowed in shorthand properties. + if ( + replacementNode.type === "AssignmentPattern" && + astUtils.isParenthesised(sourceCode, replacementNode.left) + ) { + return null; + } - return fixer.replaceTextRange([ - initial.range[0], - result.range[1] - ], replacementText); + return fixer.replaceText(node, sourceCode.getText(replacementNode)); } }); } @@ -97,19 +105,11 @@ module.exports = { for (const property of node.properties) { - /* - * TODO: Remove after babel-eslint removes ExperimentalRestProperty - * https://github.com/eslint/eslint/issues/12335 - */ - if (property.type === "ExperimentalRestProperty") { - continue; - } - /** * Properties using shorthand syntax and rest elements can not be renamed. * If the property is computed, we have no idea if a rename is useless or not. */ - if (property.shorthand || property.type === "RestElement" || property.computed) { + if (property.type !== "Property" || property.shorthand || property.computed) { continue; } @@ -117,7 +117,7 @@ module.exports = { const renamedKey = property.value.type === "AssignmentPattern" ? property.value.left.name : property.value.name; if (key === renamedKey) { - reportError(property, property.key, property.value, "Destructuring assignment"); + reportError(property, property.key, "Destructuring assignment"); } } } @@ -134,7 +134,7 @@ module.exports = { if (node.imported.name === node.local.name && node.imported.range[0] !== node.local.range[0]) { - reportError(node, node.imported, node.local, "Import"); + reportError(node, node.imported, "Import"); } } @@ -150,7 +150,7 @@ module.exports = { if (node.local.name === node.exported.name && node.local.range[0] !== node.exported.range[0]) { - reportError(node, node.local, node.exported, "Export"); + reportError(node, node.local, "Export"); } } diff --git a/tools/node_modules/eslint/lib/rules/prefer-const.js b/tools/node_modules/eslint/lib/rules/prefer-const.js index 439a4db3c963f6..f6e79e71c3e975 100644 --- a/tools/node_modules/eslint/lib/rules/prefer-const.js +++ b/tools/node_modules/eslint/lib/rules/prefer-const.js @@ -5,6 +5,11 @@ "use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const FixTracker = require("./utils/fix-tracker"); const astUtils = require("./utils/ast-utils"); //------------------------------------------------------------------------------ @@ -451,10 +456,18 @@ module.exports = { messageId: "useConst", data: node, fix: shouldFix - ? fixer => fixer.replaceText( - sourceCode.getFirstToken(varDeclParent, t => t.value === varDeclParent.kind), - "const" - ) + ? fixer => { + const letKeywordToken = sourceCode.getFirstToken(varDeclParent, t => t.value === varDeclParent.kind); + + /** + * Extend the replacement range to the whole declaration, + * in order to prevent other fixes in the same pass + * https://github.com/eslint/eslint/issues/13899 + */ + return new FixTracker(fixer, sourceCode) + .retainRange(varDeclParent.range) + .replaceTextRange(letKeywordToken.range, "const"); + } : null }); }); 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 471c22210eb613..3c550984fc6252 100644 --- a/tools/node_modules/eslint/lib/rules/space-infix-ops.js +++ b/tools/node_modules/eslint/lib/rules/space-infix-ops.js @@ -132,7 +132,9 @@ module.exports = { if (nonSpacedConsequentNode) { report(node, nonSpacedConsequentNode); - } else if (nonSpacedAlternateNode) { + } + + if (nonSpacedAlternateNode) { report(node, nonSpacedAlternateNode); } } diff --git a/tools/node_modules/eslint/node_modules/esprima/package.json b/tools/node_modules/eslint/node_modules/esprima/package.json index 03d154ee722a3c..4dfb4a142e7aa5 100644 --- a/tools/node_modules/eslint/node_modules/esprima/package.json +++ b/tools/node_modules/eslint/node_modules/esprima/package.json @@ -4,8 +4,8 @@ "email": "ariya.hidayat@gmail.com" }, "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "esparse": "./bin/esparse.js", + "esvalidate": "./bin/esvalidate.js" }, "bugs": { "url": "https://github.com/jquery/esprima/issues" diff --git a/tools/node_modules/eslint/node_modules/flatted/package.json b/tools/node_modules/eslint/node_modules/flatted/package.json index 1834f209fa8a22..41a5b5defc6d20 100644 --- a/tools/node_modules/eslint/node_modules/flatted/package.json +++ b/tools/node_modules/eslint/node_modules/flatted/package.json @@ -57,5 +57,5 @@ "type": "module", "types": "types.d.ts", "unpkg": "min.js", - "version": "3.1.0" + "version": "3.1.1" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/which/package.json b/tools/node_modules/eslint/node_modules/which/package.json index 32eaa57575d680..9620a99a29e14c 100644 --- a/tools/node_modules/eslint/node_modules/which/package.json +++ b/tools/node_modules/eslint/node_modules/which/package.json @@ -5,7 +5,7 @@ "url": "http://blog.izs.me" }, "bin": { - "node-which": "bin/node-which" + "node-which": "./bin/node-which" }, "bugs": { "url": "https://github.com/isaacs/node-which/issues" diff --git a/tools/node_modules/eslint/package.json b/tools/node_modules/eslint/package.json index dda9992ee81177..24c8bc57f61b9f 100644 --- a/tools/node_modules/eslint/package.json +++ b/tools/node_modules/eslint/package.json @@ -154,5 +154,5 @@ "test:cli": "mocha", "webpack": "node Makefile.js webpack" }, - "version": "7.18.0" + "version": "7.19.0" } \ No newline at end of file