-
Notifications
You must be signed in to change notification settings - Fork 39
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
Extend CollectionIsEmpty
Refaster rule
#1027
Conversation
Looks good. No mutations were possible for these changes. |
ce8f078
to
35fb0f7
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.
Right, so we generally prefer findFirst()
over findAny()
(because in the vast majority of cases the former better expresses semantics), but when followed by isEmpty()
/isPresent()
we prefer the latter. This is a bit of a quirk in our setup; usually we try to avoid those "contextual preferences", as it can cause a combinatorial explosion of cases to consider.
So a second option would be to change the other rules to unconditionally prefer findFirst()
. But in this case I think a suppression may be nicer. I rebased and pushed a proposal :)
Suggested commit message:
Extend `CollectionIsEmpty` Refaster rule (#1027)
collection.stream().findAny().isEmpty(), | ||
collection.stream().findFirst().isEmpty()); |
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.
So OptionalFirstCollectionElement
and StreamIsEmpty
prefer different variants. But our Refaster integration prefers writing the longest expression matched, so this one will win.
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.
Understood, I was wondering indeed what happens when an expression is matched by multiple rules. It makes sense that the longest one wins 👍
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.
Yeah; implemented here :)
Looks good. No mutations were possible for these changes. |
Thank you @Stephan202, indeed the need for suppression comes from the fact that we're "inconsistent" over the preference of |
35fb0f7
to
4cd8e25
Compare
Looks good. No mutations were possible for these changes. |
4cd8e25
to
0d226df
Compare
Looks good. No mutations were possible for these changes. |
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.
🚀
0d226df
to
095e3f1
Compare
Looks good. No mutations were possible for these changes. |
Quality Gate passedIssues Measures |
Add the following expression to
CollectionIsEmpty
:collection.stream().findAny().isEmpty()
.Clashing issue
Currently, this rule clashes with the rule
OptionalFirstCollectionElement
, which is matchingcollection.stream().findAny()
, rewriting it tocollection.stream().findFirst()
. Not sure what's the best way to solve this issue, both use cases seem valid 🤔collection.stream().findAny().isEmpty()
tocollection.stream().findFirst().isEmpty()
leads to a loop sincestream().findFirst().isEmpty()
is rewritten tostream().findAny().isEmpty()
Benefits
This acts as a useful partner to
StreamIsEmpty
: expressions that match the one introduced in this PR can result as a consequence of applying theStreamIsEmpty
rule: this allows for refactors like the following to be applied in multiple steps: