From 0f110613cb0df3004947f34c58eeb99b2492ef76 Mon Sep 17 00:00:00 2001 From: Sean Gray Date: Mon, 23 Sep 2019 18:03:55 -0500 Subject: [PATCH 1/4] Fix: no-constant-condition doesn't introspect arrays (fixes #12225) --- lib/rules/no-constant-condition.js | 16 ++++++++++++++- tests/lib/rules/no-constant-condition.js | 26 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js index d6d04174298..06c35f6aab4 100644 --- a/lib/rules/no-constant-condition.js +++ b/lib/rules/no-constant-condition.js @@ -90,14 +90,28 @@ module.exports = { * @private */ function isConstant(node, inBooleanPosition) { + + /* + * Bug in espree (#425) causes [,] to return children of null + * so we need to check for existance until that is fixed + */ + if (!node) { + return true; + } switch (node.type) { case "Literal": case "ArrowFunctionExpression": case "FunctionExpression": case "ObjectExpression": - case "ArrayExpression": return true; + case "ArrayExpression": { + if (inBooleanPosition) { + return true; + } + return node.elements.every(element => isConstant(element, false)); + } + case "UnaryExpression": if (node.operator === "void") { return true; diff --git a/tests/lib/rules/no-constant-condition.js b/tests/lib/rules/no-constant-condition.js index a5ede35cc8e..cfc2134eb4b 100644 --- a/tests/lib/rules/no-constant-condition.js +++ b/tests/lib/rules/no-constant-condition.js @@ -73,6 +73,14 @@ ruleTester.run("no-constant-condition", rule, { "if ((key || 'k') in obj) {}", "if ((foo || {}) instanceof obj) {}", + // #12225 + "if ('' + [y] === '' + [ty]) {}", + "if ('a' === '' + [ty]) {}", + "if ('' + [y, m, d] === 'a') {}", + "if ('' + [y, 'm'] === '' + [ty, 'tm']) {}", + "if ('' + [y, 'm'] === '' + ['ty']) {}", + "if ([,] in\n\n($2))\n ;\nelse\n ;", + // { checkLoops: false } { code: "while(true);", options: [{ checkLoops: false }] }, { code: "for(;true;);", options: [{ checkLoops: false }] }, @@ -183,6 +191,24 @@ ruleTester.run("no-constant-condition", rule, { { code: "function* foo() { for (let foo = 1 + 2 + 3 + (yield); true; baz) {}}", errors: [{ messageId: "unexpected", type: "Literal" }] + }, + + // #12225 + { + code: "if([a]) {}", + errors: [{ messageId: "unexpected", type: "ArrayExpression" }] + }, + { + code: "if([]) {}", + errors: [{ messageId: "unexpected", type: "ArrayExpression" }] + }, + { + code: "if(''+['a']) {}", + errors: [{ messageId: "unexpected", type: "BinaryExpression" }] + }, + { + code: "if(''+[]) {}", + errors: [{ messageId: "unexpected", type: "BinaryExpression" }] } ] }); From 8fb1bdb4afb473eeb3ceeb032e621d29e2fb8e5d Mon Sep 17 00:00:00 2001 From: Sean Gray Date: Mon, 7 Oct 2019 17:36:57 -0500 Subject: [PATCH 2/4] Update: no-constant-condition allows for narrower scope of varriable arrays --- lib/rules/no-constant-condition.js | 7 ++----- tests/lib/rules/no-constant-condition.js | 4 ++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js index 06c35f6aab4..744b8c6245f 100644 --- a/lib/rules/no-constant-condition.js +++ b/lib/rules/no-constant-condition.js @@ -91,10 +91,7 @@ module.exports = { */ function isConstant(node, inBooleanPosition) { - /* - * Bug in espree (#425) causes [,] to return children of null - * so we need to check for existance until that is fixed - */ + // node.elements can return null values in the case of sparse arrays ex. [,] if (!node) { return true; } @@ -106,7 +103,7 @@ module.exports = { return true; case "ArrayExpression": { - if (inBooleanPosition) { + if (!(node.parent.operator === "+")) { return true; } return node.elements.every(element => isConstant(element, false)); diff --git a/tests/lib/rules/no-constant-condition.js b/tests/lib/rules/no-constant-condition.js index cfc2134eb4b..84dd1976c0d 100644 --- a/tests/lib/rules/no-constant-condition.js +++ b/tests/lib/rules/no-constant-condition.js @@ -209,6 +209,10 @@ ruleTester.run("no-constant-condition", rule, { { code: "if(''+[]) {}", errors: [{ messageId: "unexpected", type: "BinaryExpression" }] + }, + { + code: "if([a]==[a]) {}", + errors: [{ messageId: "unexpected", type: "BinaryExpression" }] } ] }); From 3bf864de2cfa1ce601ebf06aa90aacd9f8421f7c Mon Sep 17 00:00:00 2001 From: Sean Gray Date: Mon, 23 Dec 2019 21:44:08 -0800 Subject: [PATCH 3/4] Update: no-constant condition now requires direct parent to be binary expression --- lib/rules/no-constant-condition.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js index 744b8c6245f..58691b6da6d 100644 --- a/lib/rules/no-constant-condition.js +++ b/lib/rules/no-constant-condition.js @@ -103,10 +103,10 @@ module.exports = { return true; case "ArrayExpression": { - if (!(node.parent.operator === "+")) { - return true; + if (node.parent.operator === "+" && node.parent.type === "BinaryExpression") { + return node.elements.every(element => isConstant(element, false)); } - return node.elements.every(element => isConstant(element, false)); + return true; } case "UnaryExpression": From 2cc4659d75684a2f96efb443ad21af293d691196 Mon Sep 17 00:00:00 2001 From: Sean Gray Date: Sat, 28 Dec 2019 09:50:07 -0800 Subject: [PATCH 4/4] Update: no-contant-contidtion now checks parent type before operator, unit tests include more paths --- lib/rules/no-constant-condition.js | 2 +- tests/lib/rules/no-constant-condition.js | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js index 58691b6da6d..a88fefeadba 100644 --- a/lib/rules/no-constant-condition.js +++ b/lib/rules/no-constant-condition.js @@ -103,7 +103,7 @@ module.exports = { return true; case "ArrayExpression": { - if (node.parent.operator === "+" && node.parent.type === "BinaryExpression") { + if (node.parent.type === "BinaryExpression" && node.parent.operator === "+") { return node.elements.every(element => isConstant(element, false)); } return true; diff --git a/tests/lib/rules/no-constant-condition.js b/tests/lib/rules/no-constant-condition.js index 84dd1976c0d..2315853735d 100644 --- a/tests/lib/rules/no-constant-condition.js +++ b/tests/lib/rules/no-constant-condition.js @@ -80,6 +80,7 @@ ruleTester.run("no-constant-condition", rule, { "if ('' + [y, 'm'] === '' + [ty, 'tm']) {}", "if ('' + [y, 'm'] === '' + ['ty']) {}", "if ([,] in\n\n($2))\n ;\nelse\n ;", + "if ([...x]+'' === 'y'){}", // { checkLoops: false } { code: "while(true);", options: [{ checkLoops: false }] }, @@ -213,6 +214,18 @@ ruleTester.run("no-constant-condition", rule, { { code: "if([a]==[a]) {}", errors: [{ messageId: "unexpected", type: "BinaryExpression" }] + }, + { + code: "if([a] - '') {}", + errors: [{ messageId: "unexpected", type: "BinaryExpression" }] + }, + { + code: "if(+1) {}", + errors: [{ messageId: "unexpected", type: "UnaryExpression" }] + }, + { + code: "if ([,] + ''){}", + errors: [{ messageId: "unexpected", type: "BinaryExpression" }] } ] });