-
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 StreamRules
Refaster rule collection
#593
Extend StreamRules
Refaster rule collection
#593
Conversation
Looks good. No mutations were possible for these changes. |
@@ -90,7 +91,8 @@ ImmutableSet<Boolean> testStreamIsNotEmpty() { | |||
ImmutableSet<Optional<String>> testStreamMin() { | |||
return ImmutableSet.of( | |||
Stream.of("foo").max(comparingInt(String::length).reversed()), | |||
Stream.of("bar").sorted(comparingInt(String::length)).findFirst()); | |||
Stream.of("bar").sorted(comparingInt(String::length)).findFirst(), | |||
Stream.of("baz").collect(java.util.stream.Collectors.minBy(comparingInt(String::length)))); |
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.
Not sure about this...
For some reason, test output expcts to have the same imports are input test 😕.
While running fmt:format
removes the expected imported packages.
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.
Yep, that's why we have that funny elidedTypesAndStaticImports
method at the top :).
@BeforeTemplate | ||
long before( | ||
Stream<T> stream, | ||
@Matches(IsLambdaExpressionOrMethodReference.class) ToIntFunction<T> mapper) { |
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.
I could not Generalise Function<? super T, Integer> mapper
from StreamMapToIntSum
....
Ditto StreamMapToDoubleSum
& StreamMapToLongSum
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, so what we usually do here is to combine the @BeforeTemplate
s, even though some will have a parameter type that doesn't match the @AfterTemplate
. In this case that's already true for the existing rule, so we can add the extra @BeforeTemplate
to it. Two things to note:
- None of the new rules should have
@Matches(IsLambdaExpressionOrMethodReference.class)
. That matcher is only present on the existing rules precisely because the parameter type mismatch :) - The compiler may want about a potential ambiguity between the two
before
methods; this we can avoid using a rename.
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.
Thank you so much for the clarification. 🚀
One question though
should'nt
....Function<? super T, Integer> mapper) {
return stream.collect(summingInt(t -> mapper.apply(t).intValue()));
}
be equal to
....ToIntFunction<T> mapper) {
return stream.collect(summingInt(mapper));
}
The tests fail but the compiler aint complaining 😓 ...
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.
Explained offline 😄
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.
Thanks @mohamedsamehsalah! I added a commit.
We have some unwritten fuzzy rule about the order in which we place Refaster rules inside the enclosing class, based on which some of these new rules should perhaps be moved up. But since eventually we'll likely sort the rules lexicographically (or according to some other more objective algorithm), I'm fine with merging this as-is.
Suggested commit message:
Add additional Refaster rules to `StreamRules` (#593)
All changes suggested by SonarCloud's java:S4266 rule are now covered.
See https://sonarcloud.io/organizations/picnic-technologies/rules?open=java%3AS4266&rule_key=java%3AS4266
Fixes #578.
@BeforeTemplate | ||
long before( | ||
Stream<T> stream, | ||
@Matches(IsLambdaExpressionOrMethodReference.class) ToIntFunction<T> mapper) { |
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, so what we usually do here is to combine the @BeforeTemplate
s, even though some will have a parameter type that doesn't match the @AfterTemplate
. In this case that's already true for the existing rule, so we can add the extra @BeforeTemplate
to it. Two things to note:
- None of the new rules should have
@Matches(IsLambdaExpressionOrMethodReference.class)
. That matcher is only present on the existing rules precisely because the parameter type mismatch :) - The compiler may want about a potential ambiguity between the two
before
methods; this we can avoid using a rename.
static final class StreamReduce<T> { | ||
@BeforeTemplate | ||
T before(Stream<T> stream, T identity, BinaryOperator<T> accumulator) { | ||
return stream.collect(reducing(identity, accumulator)); | ||
} | ||
|
||
@AfterTemplate | ||
T after(Stream<T> stream, T identity, BinaryOperator<T> accumulator) { | ||
return stream.reduce(identity, accumulator); | ||
} | ||
} | ||
|
||
static final class StreamReduceOptional<T> { | ||
@BeforeTemplate | ||
Optional<T> before(Stream<T> stream, BinaryOperator<T> accumulator) { | ||
return stream.collect(reducing(accumulator)); | ||
} | ||
|
||
@AfterTemplate | ||
Optional<T> after(Stream<T> stream, BinaryOperator<T> accumulator) { | ||
return stream.reduce(accumulator); | ||
} | ||
} |
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.
I think that so far we used the shorter/simpler rule name for the shorter/simpler code. That would change the names of these rules to StreamReduceAccumulator
and StreamReduceWithIdentity
, respectively.
@@ -90,7 +91,8 @@ ImmutableSet<Boolean> testStreamIsNotEmpty() { | |||
ImmutableSet<Optional<String>> testStreamMin() { | |||
return ImmutableSet.of( | |||
Stream.of("foo").max(comparingInt(String::length).reversed()), | |||
Stream.of("bar").sorted(comparingInt(String::length)).findFirst()); | |||
Stream.of("bar").sorted(comparingInt(String::length)).findFirst(), | |||
Stream.of("baz").collect(java.util.stream.Collectors.minBy(comparingInt(String::length)))); |
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.
Yep, that's why we have that funny elidedTypesAndStaticImports
method at the top :).
Stream<T> stream, | ||
@Matches(IsLambdaExpressionOrMethodReference.class) Function<? super T, ? extends U> mapper, | ||
Collector<? super U, A, R> collector) { | ||
return stream.collect(mapping(mapper, collector)); |
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.
While missing from SonarCloud's overview, we can add similar rules for filtering
, flatMapping
and summarizing*
.
} | ||
} | ||
|
||
static final class StreamMap<T, U, A, R> { |
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.
Our naming strategy would call for StreamMapCollect
.
Looks good. No mutations were possible for these changes. |
78e60cf
to
b8b6adc
Compare
StreamRules
Rebased and resolved trivial conflicts. |
Looks good. No mutations were possible for these changes. |
^ New SonarCloud violations. I'll have a look. |
b8b6adc
to
653403b
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.
Added two commits. @rickie I think this one is ready for your eyes :)
@@ -263,9 +280,12 @@ boolean after(Stream<T> stream) { | |||
|
|||
static final class StreamMin<T> { | |||
@BeforeTemplate | |||
@SuppressWarnings("java:S1155" /* This violation will be rewritten. */) |
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.
Here and below: we could introduce a separate method to further reduce this suppression's scope, but not sure that this is worth it.
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.
Don't think that is worth it indeed.
Looks good. No mutations were possible for these changes. |
1 similar comment
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.
Some questions and considerations :).
In general, looks good! Curious to see the impact 😄.
@@ -263,9 +280,12 @@ boolean after(Stream<T> stream) { | |||
|
|||
static final class StreamMin<T> { | |||
@BeforeTemplate | |||
@SuppressWarnings("java:S1155" /* This violation will be rewritten. */) |
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.
Don't think that is worth it indeed.
@@ -428,4 +469,130 @@ long after(Stream<T> stream, ToLongFunction<T> mapper) { | |||
return stream.mapToLong(mapper).sum(); | |||
} | |||
} | |||
|
|||
static final class StreamMapToIntSummaryStatistics<T> { |
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.
I'd suspect *SummaryStatistics
rules to be at the end as they are not directly on Stream
🤔.
So the ordering is not lexicographical but also not based on the order of Stream
itself 🤔. filter
, map
and flatMap
things are first in that class.
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.
If you want to reorder things based on a formula that we can eventually automate/auto-enforce: go for it 😄
} | ||
} | ||
|
||
static final class StreamFlatMapCollect<T, U, R> { |
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.
As Stream#collect
and Stream#reduce
both have two (or three) overloads, we could consider to add an extra type suffix, but we can also defer till at some point we have the name generator 😋.
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.
Up to you 🙃
Well, okay let's leave it for now. Just wanted to make sure we are aware of the choice we were implicitly making 😄. |
Pinged @werli on Slack and I made some suggestions to the commit message from the PR description. |
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.
Nothing to add from my side after @Stephan202 & @rickie's suggestions. 👍
Thx @mohamedsamehsalah 💪
…om input tests for java.util.stream.Collectors while the mvn fmt:format does not :passive-aggressive-smile:
9b6a0e6
to
c826335
Compare
Rebased, will merge once 🟢 . |
Looks good. No mutations were possible for these changes. |
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
StreamRules
StreamRules
Refaster rule collection
#578
stream#collect
calls.Suggested commit message:
stream.collect(minBy(comparator))
->stream.min(comparator)
stream.collect(maxBy(comparator))
->stream.max(comparator)
stream.collect(summingInt(mapper))
->stream.mapToInt(mapper).sum()
stream.collect(summingDouble(mapper))
->stream.mapToDouble(mapper).sum()
stream.collect(summingLong(mapper))
->stream.mapToLong(mapper).sum()
stream.collect(counting())
->stream.count()
stream.collect(reducing(identity, accumulator))
->stream.reduce(identity, accumulator)
stream.collect(reducing(accumulator))
->stream.reduce(accumulator)
stream.collect(mapping(mapper, collector))
->stream.map(mapper).collect(collector)
Fun fact: Most of this list was suggested by co-pilot 🧠 :