From b9b879481444386405abbd058e919bb67079e55f Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 18 May 2023 18:43:54 +0800 Subject: [PATCH] `explicit-length-check`: Ignore `.length || number` (#1977) --- rules/explicit-length-check.js | 19 +++++++++++++++++-- test/explicit-length-check.mjs | 13 +++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/rules/explicit-length-check.js b/rules/explicit-length-check.js index 67872bd8c2..86a6cc7aea 100644 --- a/rules/explicit-length-check.js +++ b/rules/explicit-length-check.js @@ -4,7 +4,7 @@ const {checkVueTemplate} = require('./utils/rule.js'); const isLogicalExpression = require('./utils/is-logical-expression.js'); const {isBooleanNode, getBooleanAncestor} = require('./utils/boolean.js'); const {fixSpaceAroundKeyword} = require('./fix/index.js'); -const {isLiteral, isMemberExpression} = require('./ast/index.js'); +const {isLiteral, isMemberExpression, isNumberLiteral} = require('./ast/index.js'); const TYPE_NON_ZERO = 'non-zero'; const TYPE_ZERO = 'zero'; @@ -90,6 +90,15 @@ function getLengthCheckNode(node) { return {}; } +function isNodeValueNumber(node, context) { + if (isNumberLiteral(node)) { + return true; + } + + const staticValue = getStaticValue(node, context.sourceCode.getScope(node)); + return staticValue && typeof staticValue.value === 'number'; +} + function create(context) { const options = { 'non-zero': 'greater-than', @@ -171,7 +180,13 @@ function create(context) { if (isBooleanNode(ancestor)) { isZeroLengthCheck = isNegative; node = ancestor; - } else if (isLogicalExpression(lengthNode.parent)) { + } else if ( + isLogicalExpression(lengthNode.parent) + && !( + lengthNode.parent.operator === '||' + && isNodeValueNumber(lengthNode.parent.right, context) + ) + ) { isZeroLengthCheck = isNegative; node = lengthNode; autoFix = false; diff --git a/test/explicit-length-check.mjs b/test/explicit-length-check.mjs index b5cea72cae..f923935aa1 100644 --- a/test/explicit-length-check.mjs +++ b/test/explicit-length-check.mjs @@ -103,6 +103,9 @@ test({ 'const foo = { length: 1.5 }; if (foo.length) {}', // Array lengths must be integers 'const foo = { length: NaN }; if (foo.length) {}', // Array lengths cannot be NaN 'const foo = { length: Infinity }; if (foo.length) {}', // Array lengths cannot be Infinity + // Logical OR + 'const x = foo.length || 2', + 'const A_NUMBER = 2; const x = foo.length || A_NUMBER', ], invalid: [ suggestionCase({ @@ -110,6 +113,16 @@ test({ output: 'const x = foo.length > 0 || bar()', desc: 'Replace `.length` with `.length > 0`.', }), + suggestionCase({ + code: 'const x = foo.length || unknown', + output: 'const x = foo.length > 0 || unknown', + desc: 'Replace `.length` with `.length > 0`.', + }), + suggestionCase({ + code: 'const NON_NUMBER = "2"; const x = foo.length || NON_NUMBER', + output: 'const NON_NUMBER = "2"; const x = foo.length > 0 || NON_NUMBER', + desc: 'Replace `.length` with `.length > 0`.', + }), suggestionCase({ code: 'const x = foo.length || bar()', output: 'const x = foo.length !== 0 || bar()',