-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
fix: Prevent false positives with no-constant-condition #15486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -262,8 +277,6 @@ ruleTester.run("no-constant-condition", rule, { | |||
|
|||
// #5228 , typeof conditions | |||
{ code: "if(typeof x){}", errors: [{ messageId: "unexpected", type: "UnaryExpression" }] }, | |||
{ code: "if(`${typeof x}`){}", errors: [{ messageId: "unexpected", type: "TemplateLiteral" }] }, | |||
{ code: "if(`${''}${typeof x}`){}", errors: [{ messageId: "unexpected", type: "TemplateLiteral" }] }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are true errors that we won't catch any more.
@@ -358,18 +371,6 @@ ruleTester.run("no-constant-condition", rule, { | |||
code: "if(''+[]) {}", | |||
errors: [{ messageId: "unexpected", type: "BinaryExpression" }] | |||
}, | |||
{ | |||
code: "if([a]==[a]) {}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a true error that we won't catch any more, but it is equivalent to a false positive (if([a]==[b]) {}
) which used to trigger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is if([a]==[b]) {}
a false positive? Both sides are objects, so this should be comparison by reference, and thus always false
(even when the elements are same)?
[1]==[1] // false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes. Sorry, not sure what I was thinking.
That said, [a]
cannot be considered "constant" for the purposes of ==
comparison unless we also know what we are comparing it to (and thus how it will be compared), and currently the rule does not try to determine that information.
[1] == 1
true
[0] == 1
false
So, you're absolutely right that if([a]==[b]) {}
is a constant condition, but I still think it's appropriate to treat [a]
as not constant when comparing with inBooleanPosition: false
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will no-constant-binary-expression
catch these cases?
- ArrayExpression === anything
- ArrayExpression !== anything
- ArrayExpression == ArrayExpression
- ArrayExpression != ArrayExpression
I'm asking because these look like realistic mistakes that will be no longer reported by no-constant-condition
, so it might be good to special-case them to retain that behavior. But if they will be reported by another rule, then there's no need for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These would get caught by no-constnat-binary-expression
:
- ArrayExpression === anything
- ArrayExpression !== anything
These would not:
- ArrayExpression == ArrayExpression
- ArrayExpression != ArrayExpression
However, I suspect (hope!) that most people would be using some form of the eqeqeq
rule to avoid the many many pitfalls and foot-guns exposed by testing for ==
equality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These would not:
- ArrayExpression == ArrayExpression
- ArrayExpression != ArrayExpression
I've just left a question about this on the no-constant-binary-expression
PR: #15296 (comment)
errors: [{ messageId: "unexpected", type: "BinaryExpression" }] | ||
}, | ||
{ | ||
code: "if([a] - '') {}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a false positive. If a = 1
the condition is true, if a = 0
it is false.
errors: [{ messageId: "unexpected", type: "BinaryExpression" }] | ||
}, | ||
{ | ||
code: "if(+[a]) {}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a false positive. If a = 1
the condition is true, if a = 0
it is false.
bd5cc8c
to
feea6d1
Compare
Fixes eslint#15467 by defining `isConstant` with `inBooleanPosition` set to `false` as meaning: > For both string and number, if coerced to that type, the value will be constant.
feea6d1
to
0456613
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks! I'll leave this open for a few days in case anyone else wants to review it before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Fixes #15467 by defining
isConstant
withinBooleanPosition
set tofalse
as meaning:Prerequisites checklist
What is the purpose of this pull request? (put an "X" next to an item)
[x] Bug fix (template)
[x] Changes an existing rule (template)
What changes did you make? (Give an overview)
Make
no-constant-condition
more correct. See #15467 for more information.Is there anything you'd like reviewers to focus on?
Would ESLint treat this as a breaking change? It will remove some false positives, but also -- in a few rare cases -- introduce a few false negatives.