sindresorhus / eslint-plugin-unicorn

More than 100 powerful ESLint rules
MIT License
3.98k stars 360 forks source link

Wrong autofix in `explicit-length-check` #2190

Open andrmoel opened 10 months ago

andrmoel commented 10 months ago

There is a wrong autofix for the explicit-length-check rule.

My code:

if (!foo.length > 0) {
 ...

Code after autofix:

if (foo.length === 0 > 0) {
 ...

Expected replacement

if (foo.length === 0) {
 ...
dimaMachina commented 10 months ago

your code is already invalid

if length = 0 true > 0 if length > 0 false > 0

andrmoel commented 10 months ago

your code is already invalid

if length = 0 true > 0 if length > 0 false > 0

Sorry but I don't get it. My code works as expected. I might give a better example:

    const foo = [];

    if (!foo.length > 0) {
        console.log('foo is empty');
    } else {
        console.log('foo is not empty');
    }

    // Result "foo is empty"

Expected outcome after autofix:

    const foo = [];

    if (foo.length === 0) {
        console.log('foo is empty');
    } else {
        console.log('foo is not empty');
    }

    // Result "foo is empty"

You can add some items to the foo array and you will get the other console log.

andrmoel commented 10 months ago

Ok get it!

!foo.length should be transpilled to foo.length === 0

Make sense. So the > operator is unnecessary.

fregante commented 10 months ago

The autofix is correct, !length produces the same result as length === 0. As mentioned before, your code is wrong; use !foo.length OR foo.length > 0, not both.

fisker commented 10 months ago

Strictly speaking, the auto fix isn't correct,

if (foo.length === 0 > 0) ;

means

if (foo.length === (0 > 0)) ;

not

if ((foo.length === 0) > 0) ;

Update: This means the autofix also breaks cases uses operators between ! and ===

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence

Maybe we should keep this open for edge cases.

fregante commented 10 months ago

You're right, I did some tests but did not finish my boolean table

!3 > 0 🔴 false
3 === 0 > 0 🔴 false
!0 > 0 🟢 true
0 === 0 > 0 🔴 false