Skip to content
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

Add prefer-array-index-of rule #920

Merged
merged 85 commits into from Jan 11, 2021
Merged

Add prefer-array-index-of rule #920

merged 85 commits into from Jan 11, 2021

Conversation

Fabrice-TIERCELIN
Copy link
Contributor

@Fabrice-TIERCELIN Fabrice-TIERCELIN commented Dec 6, 2020

Add prefer-indexof rule

I have successfully run npm test. I have successfully manually tested the lint and the fix on a project. I have run npm run integration but my node is too old.

Fixes #919

@fisker fisker changed the title Fixes #919; Add prefer-indexof rule Add prefer-indexof rule Dec 7, 2020
rules/prefer-indexof.js Outdated Show resolved Hide resolved
@Fabrice-TIERCELIN Fabrice-TIERCELIN changed the title Add prefer-indexof rule Add prefer-array-index-of rule Dec 8, 2020
@Fabrice-TIERCELIN Fabrice-TIERCELIN marked this pull request as draft December 9, 2020 06:54
@Fabrice-TIERCELIN
Copy link
Contributor Author

May node.callee.object be undefined?

@fisker
Copy link
Collaborator

fisker commented Dec 9, 2020

No, it can't

@Fabrice-TIERCELIN
Copy link
Contributor Author

Have you got common code to check extended literals like:

  • -8
  • 1 + 1
  • 'foo' + 'bar'
  • 10 * (5 - 9)
  • ...

?

@Fabrice-TIERCELIN Fabrice-TIERCELIN marked this pull request as ready for review December 9, 2020 07:50
@fisker
Copy link
Collaborator

fisker commented Dec 9, 2020

No, you are not doing right, you should not care about the searching value, you only need care about left/right is the same as element

@fisker
Copy link
Collaborator

fisker commented Dec 9, 2020

Meaning foo.findIndex(bar => bar === a.b.c) should be fixed to foo.indexOf(a.b.c) too, WDYT?

@Fabrice-TIERCELIN
Copy link
Contributor Author

I think I should only check it's an expression that doesn't change, that is to say not that for example:

foo.findIndex(bar => bar === a.getValueAndUpdateIt())

In this case, check that it's a literal is just a first objective that can be improved in the future.

@fisker
Copy link
Collaborator

fisker commented Dec 9, 2020

Yes, I considered that, you can use hasSideEffect to make sure it don't has SideEffect. So we can fix it, otherwise, I think we can use ESLint suggestion.

And I suggest still report it , because I can't image anyone really do something in findIndex call

@Fabrice-TIERCELIN
Copy link
Contributor Author

Yes, it is parsed as FunctionExpression. I thought we were using esquery 😞

Thanx for implementing the suggestion. I don't know if I have badly understood your comment or wanted not to understand it 😄

@fisker
Copy link
Collaborator

fisker commented Dec 16, 2020

I don't know if I have badly understood your comment or wanted not to understand it

Sorry for my bad English, I'm not a native speaker.

@@ -0,0 +1,29 @@
# Prefer [`Array#indexOf()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) over [`Array#findIndex()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) when looking for the index of an item
Copy link
Collaborator

@fisker fisker Dec 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We normally add links in details. and this should be the same as the one in readme.md


```js
[].findIndex(i => i === list[i]);
[].findIndex(x => x === 'foo' && isValid);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is not valid cases anymore, please fix it.

Also, please put these in separate markdown code blocks. example https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/error-message.md#fail


```js
values.findIndex(function (x) {return x !== 'foo';});
```
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't care about the callee.object, let's use const index = foo.findIndex in these examples,

please add this to "pass" section

const index = foo.indexOf('foo');

Copy link
Collaborator

@fisker fisker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@sindresorhus
Copy link
Owner

Can you fix the merge conflict?

@@ -1,6 +1,6 @@
# Prefer [`Array#indexOf()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) over [`Array#findIndex()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) when looking for the index of an item

[`Array#findIndex()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) is made for more complex criteria. If you are just looking for the index where a given object is present, then the code can be reduced. It concerns any search with a literal, a variable or any expression that hasn't any side effect. However, if the expression you are looking for has side effect, relies on element related to the function (the name of the function, its arguments...), the case is still valid.
[`Array#findIndex()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) is intended for more complex needs. If you are just looking for the index where the given item is present, then the code can be simplified. This applies to any search with a literal, a variable, or any expression that doesn't have any side effects. However, if the expression you are looking for has side effects, relies on element related to the function (the name of the function, its arguments, etc.), the case is still valid.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, if the expression you are looking for has side effects, relies on element related to the function (the name of the function, its arguments, etc.), the case is still valid.

This part seems not right, the searching value has "side effects" not valid.

const index = foo.findIndex(x => x === call());

This call has "side effects", but it will still reported without "auto-fix".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added explicit side effects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In getBinaryExpressionSelector, I want to add a criteria that avoids the existence of call(), something like:

:not(:has(*[expression.callee.name="call"][expression.type="CallExpression"]))

But I don't know how to tell to search only in the binary expression.

@Fabrice-TIERCELIN Fabrice-TIERCELIN marked this pull request as draft December 28, 2020 08:07
@Fabrice-TIERCELIN Fabrice-TIERCELIN deleted the prefer-indexof-over-findindex branch December 28, 2020 08:09
@Fabrice-TIERCELIN Fabrice-TIERCELIN restored the prefer-indexof-over-findindex branch December 28, 2020 08:34
@Fabrice-TIERCELIN Fabrice-TIERCELIN marked this pull request as ready for review December 28, 2020 08:42
@sindresorhus sindresorhus merged commit 517a782 into sindresorhus:master Jan 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rule proposal: prefer-array-index-of
3 participants