diff options
Diffstat (limited to 'tools/node_modules/eslint/lib')
5 files changed, 233 insertions, 29 deletions
diff --git a/tools/node_modules/eslint/lib/rules/camelcase.js b/tools/node_modules/eslint/lib/rules/camelcase.js index 6fb8760f10..a8341c84b6 100644 --- a/tools/node_modules/eslint/lib/rules/camelcase.js +++ b/tools/node_modules/eslint/lib/rules/camelcase.js @@ -100,14 +100,20 @@ module.exports = { * @private */ function isInsideObjectPattern(node) { - let { parent } = node; + let current = node; - while (parent) { - if (parent.type === "ObjectPattern") { + while (current) { + const parent = current.parent; + + if (parent && parent.type === "Property" && parent.computed && parent.key === current) { + return false; + } + + if (current.type === "ObjectPattern") { return true; } - parent = parent.parent; + current = parent; } return false; @@ -169,12 +175,15 @@ module.exports = { if (node.parent.parent && node.parent.parent.type === "ObjectPattern") { if (node.parent.shorthand && node.parent.value.left && nameIsUnderscored) { - report(node); } const assignmentKeyEqualsValue = node.parent.key.name === node.parent.value.name; + if (isUnderscored(name) && node.parent.computed) { + report(node); + } + // prevent checking righthand side of destructured object if (node.parent.key === node && node.parent.value !== node) { return; diff --git a/tools/node_modules/eslint/lib/rules/implicit-arrow-linebreak.js b/tools/node_modules/eslint/lib/rules/implicit-arrow-linebreak.js index a883b22647..fb7d603a35 100644 --- a/tools/node_modules/eslint/lib/rules/implicit-arrow-linebreak.js +++ b/tools/node_modules/eslint/lib/rules/implicit-arrow-linebreak.js @@ -4,6 +4,12 @@ */ "use strict"; +const { + isArrowToken, + isParenthesised, + isOpeningParenToken +} = require("../util/ast-utils"); + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -42,6 +48,142 @@ module.exports = { } /** + * Formats the comments depending on whether it's a line or block comment. + * @param {Comment[]} comments The array of comments between the arrow and body + * @param {Integer} column The column number of the first token + * @returns {string} A string of comment text joined by line breaks + */ + function formatComments(comments, column) { + const whiteSpaces = " ".repeat(column); + + return `${comments.map(comment => { + + if (comment.type === "Line") { + return `//${comment.value}`; + } + + return `/*${comment.value}*/`; + }).join(`\n${whiteSpaces}`)}\n${whiteSpaces}`; + } + + /** + * Finds the first token to prepend comments to depending on the parent type + * @param {Node} node The validated node + * @returns {Token|Node} The node to prepend comments to + */ + function findFirstToken(node) { + switch (node.parent.type) { + case "VariableDeclarator": + + // If the parent is first or only declarator, return the declaration, else, declarator + return sourceCode.getFirstToken( + node.parent.parent.declarations.length === 1 || + node.parent.parent.declarations[0].id.name === node.parent.id.name + ? node.parent.parent : node.parent + ); + case "CallExpression": + case "Property": + + // find the object key + return sourceCode.getFirstToken(node.parent); + default: + return node; + } + } + + /** + * Helper function for adding parentheses fixes for nodes containing nested arrow functions + * @param {Fixer} fixer Fixer + * @param {Token} arrow - The arrow token + * @param {ASTNode} arrowBody - The arrow function body + * @returns {Function[]} autofixer -- wraps function bodies with parentheses + */ + function addParentheses(fixer, arrow, arrowBody) { + const parenthesesFixes = []; + let closingParentheses = ""; + + let followingBody = arrowBody; + let currentArrow = arrow; + + while (currentArrow) { + if (!isParenthesised(sourceCode, followingBody)) { + parenthesesFixes.push( + fixer.insertTextAfter(currentArrow, " (") + ); + + const paramsToken = sourceCode.getTokenBefore(currentArrow, token => + isOpeningParenToken(token) || token.type === "Identifier"); + + const whiteSpaces = " ".repeat(paramsToken.loc.start.column); + + closingParentheses = `\n${whiteSpaces})${closingParentheses}`; + } + + currentArrow = sourceCode.getTokenAfter(currentArrow, isArrowToken); + + if (currentArrow) { + followingBody = sourceCode.getTokenAfter(currentArrow, token => !isOpeningParenToken(token)); + } + } + + return [...parenthesesFixes, + fixer.insertTextAfter(arrowBody, closingParentheses) + ]; + } + + /** + * Autofixes the function body to collapse onto the same line as the arrow. + * If comments exist, prepends the comments before the arrow function. + * If the function body contains arrow functions, appends the function bodies with parentheses. + * @param {Token} arrowToken The arrow token. + * @param {ASTNode} arrowBody the function body + * @param {ASTNode} node The evaluated node + * @returns {Function} autofixer -- validates the node to adhere to besides + */ + function autoFixBesides(arrowToken, arrowBody, node) { + return fixer => { + const placeBesides = fixer.replaceTextRange([arrowToken.range[1], arrowBody.range[0]], " "); + + const comments = sourceCode.getCommentsInside(node).filter(comment => + comment.loc.start.line < arrowBody.loc.start.line); + + if (comments.length) { + + // If the grandparent is not a variable declarator + if ( + arrowBody.parent && + arrowBody.parent.parent && + arrowBody.parent.parent.type !== "VariableDeclarator" + ) { + + // If any arrow functions follow, return the necessary parens fixes. + if (sourceCode.getTokenAfter(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") { + return addParentheses(fixer, arrowToken, arrowBody); + } + + // If any arrow functions precede, the necessary fixes have already been returned, so return null. + if (sourceCode.getTokenBefore(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") { + return null; + } + } + + const firstToken = findFirstToken(node); + + const commentText = formatComments(comments, firstToken.loc.start.column); + + const commentBeforeExpression = fixer.insertTextBeforeRange( + firstToken.range, + commentText + ); + + return [placeBesides, commentBeforeExpression]; + } + + return placeBesides; + }; + } + + /** * Validates the location of an arrow function body * @param {ASTNode} node The arrow function body * @returns {void} @@ -75,7 +217,7 @@ module.exports = { context.report({ node: fixerTarget, message: "Expected no linebreak before this expression.", - fix: fixer => fixer.replaceTextRange([tokenBefore.range[1], fixerTarget.range[0]], " ") + fix: autoFixBesides(tokenBefore, fixerTarget, node) }); } } diff --git a/tools/node_modules/eslint/lib/rules/indent.js b/tools/node_modules/eslint/lib/rules/indent.js index 0b87412c8f..af7e2b147a 100644 --- a/tools/node_modules/eslint/lib/rules/indent.js +++ b/tools/node_modules/eslint/lib/rules/indent.js @@ -522,25 +522,13 @@ module.exports = { }, VariableDeclarator: { oneOf: [ - { - type: "integer", - minimum: 0 - }, + ELEMENT_LIST_SCHEMA, { type: "object", properties: { - var: { - type: "integer", - minimum: 0 - }, - let: { - type: "integer", - minimum: 0 - }, - const: { - type: "integer", - minimum: 0 - } + var: ELEMENT_LIST_SCHEMA, + let: ELEMENT_LIST_SCHEMA, + const: ELEMENT_LIST_SCHEMA }, additionalProperties: false } @@ -661,7 +649,7 @@ module.exports = { if (context.options[1]) { lodash.merge(options, context.options[1]); - if (typeof options.VariableDeclarator === "number") { + if (typeof options.VariableDeclarator === "number" || options.VariableDeclarator === "first") { options.VariableDeclarator = { var: options.VariableDeclarator, let: options.VariableDeclarator, @@ -1349,10 +1337,27 @@ module.exports = { }, VariableDeclaration(node) { - const variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind) + let variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind) ? options.VariableDeclarator[node.kind] : DEFAULT_VARIABLE_INDENT; + const firstToken = sourceCode.getFirstToken(node), + lastToken = sourceCode.getLastToken(node); + + if (options.VariableDeclarator[node.kind] === "first") { + if (node.declarations.length > 1) { + addElementListIndent( + node.declarations, + firstToken, + lastToken, + "first" + ); + return; + } + + variableIndent = DEFAULT_VARIABLE_INDENT; + } + if (node.declarations[node.declarations.length - 1].loc.start.line > node.loc.start.line) { /* @@ -1374,13 +1379,10 @@ module.exports = { * on the same line as the start of the declaration, provided that there are declarators that * follow this one. */ - const firstToken = sourceCode.getFirstToken(node); - offsets.setDesiredOffsets(node.range, firstToken, variableIndent, true); } else { - offsets.setDesiredOffsets(node.range, sourceCode.getFirstToken(node), variableIndent); + offsets.setDesiredOffsets(node.range, firstToken, variableIndent); } - const lastToken = sourceCode.getLastToken(node); if (astUtils.isSemicolonToken(lastToken)) { offsets.ignoreToken(lastToken); diff --git a/tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js b/tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js index 7920ebdc56..90d1a79a1c 100644 --- a/tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js +++ b/tools/node_modules/eslint/lib/rules/no-irregular-whitespace.js @@ -30,7 +30,7 @@ module.exports = { type: "problem", docs: { - description: "disallow irregular whitespace outside of strings and comments", + description: "disallow irregular whitespace", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-irregular-whitespace" diff --git a/tools/node_modules/eslint/lib/rules/no-useless-catch.js b/tools/node_modules/eslint/lib/rules/no-useless-catch.js new file mode 100644 index 0000000000..3211ed2c73 --- /dev/null +++ b/tools/node_modules/eslint/lib/rules/no-useless-catch.js @@ -0,0 +1,51 @@ +/** + * @fileoverview Reports useless `catch` clauses that just rethrow their error. + * @author Teddy Katz + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary `catch` clauses", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-useless-catch" + }, + + schema: [] + }, + + create(context) { + return { + CatchClause(node) { + if ( + node.param.type === "Identifier" && + node.body.body.length && + node.body.body[0].type === "ThrowStatement" && + node.body.body[0].argument.type === "Identifier" && + node.body.body[0].argument.name === node.param.name + ) { + if (node.parent.finalizer) { + context.report({ + node, + message: "Unnecessary catch clause." + }); + } else { + context.report({ + node: node.parent, + message: "Unnecessary try/catch wrapper." + }); + } + } + } + }; + } +}; |