From 7240156b74f46e014cdcb22331b9b83aa18feee9 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Sun, 14 Jul 2019 18:30:52 +0900 Subject: [PATCH] fix no-extra-parens rule --- lib/rules/no-extra-parens.js | 53 ++++++++++++++++++------------ package.json | 2 +- tests/lib/rules/no-extra-parens.js | 24 ++++++++++++++ 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js index 98fc49654cb..bcd619cef11 100644 --- a/lib/rules/no-extra-parens.js +++ b/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; @@ -116,6 +116,16 @@ module.exports = { return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression"; } + /** + * 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. @@ -123,12 +133,7 @@ module.exports = { * @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); } /** @@ -390,15 +395,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); } /** @@ -562,7 +561,7 @@ module.exports = { }, DoWhileStatement(node) { - if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) { + if (hasExcessParens(node.test) && !isCondAssignException(node)) { report(node.test); } }, @@ -616,11 +615,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) { @@ -693,7 +704,7 @@ module.exports = { }, SwitchStatement(node) { - if (hasDoubleExcessParens(node.discriminant)) { + if (hasExcessParens(node.discriminant)) { report(node.discriminant); } }, @@ -721,13 +732,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); } }, diff --git a/package.json b/package.json index d9961b9e63c..cb64361f97a 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", + "eslint-utils": "^1.4.0", "eslint-visitor-keys": "github:eslint/eslint-visitor-keys#add-import-expression", "espree": "github:eslint/espree#support-bigint-and-dynamic-import", "esquery": "^1.0.1", diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js index dcdf71cfc35..67b91750616 100644 --- a/tests/lib/rules/no-extra-parens.js +++ b/tests/lib/rules/no-extra-parens.js @@ -98,6 +98,7 @@ ruleTester.run("no-extra-parens", rule, { "(2 + 3) ** 4", "2 ** (2 + 3)", "new (import(source))", + "import((s,t))", // same precedence "a, b, c", @@ -1106,6 +1107,29 @@ ruleTester.run("no-extra-parens", rule, { "(let)", "Identifier", 1 + ), + + // import expressions + invalid( + "import((source))", + "import(source)", + "Identifier", + 1, + { parserOptions: { ecmaVersion: 2020 } } + ), + invalid( + "import((source = 'foo.js'))", + "import(source = 'foo.js')", + "AssignmentExpression", + 1, + { parserOptions: { ecmaVersion: 2020 } } + ), + invalid( + "import(((s,t)))", + "import((s,t))", + "SequenceExpression", + 1, + { parserOptions: { ecmaVersion: 2020 } } ) ] });