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

Introduce CollectorMutability check #135

Merged
merged 8 commits into from
Jun 20, 2022
Merged

Introduce CollectorMutability check #135

merged 8 commits into from
Jun 20, 2022

Conversation

oxkitsune
Copy link
Contributor

Implement BugPattern to flag collect(to{List,Map,Set}()) and suggest to either use an Immutable variant or a clear mutable variant, in order to emphasise the (im)mutability of the resulting collection.

Example:

- Flux.just(1).collect(toList());
+ Flux.just(1).collect(toImmutableList());
OR
+ Flux.just(1).collect(toCollection(ArrayList::new));

- Flux.just("foo").collect(toMap(String::getBytes, String::length));
+ Flux.just("foo").collect(toImmutableMap(String::getBytes, String::length));
OR
+ Flux.just("foo").collect(toMap(String::getBytes, String::length, (a, b) -> a, HashMap::new));

- Flux.just(1).collect(toSet());
+ Flux.just(1).collect(toImmutableSet());
OR
+ Flux.just(1).collect(toCollection(HashSet::new));

Suggested commit message:

Add BugPattern to flag `collect(to{List,Map,Set}())` to emphasize (im)mutability (#135)

@oxkitsune oxkitsune requested a review from rickie June 16, 2022 09:49
@oxkitsune oxkitsune force-pushed the gdejong/PSM-1336 branch 2 times, most recently from ead1bdc to 32c976c Compare June 16, 2022 10:05
Copy link
Member

@rickie rickie left a comment

Choose a reason for hiding this comment

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

Have training right now, so already flushing the comments I have so far. PTAL :).

@oxkitsune oxkitsune requested a review from rickie June 16, 2022 14:16
Copy link
Member

@rickie rickie left a comment

Choose a reason for hiding this comment

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

Adding some suggestions and ideas. Let me know what you think :).

Nice work already, seeing these tests makes me happy. It'll have some nice impact downstream! 🚀

linkType = NONE,
severity = ERROR,
tags = LIKELY_ERROR)
public final class CollectorMutabilityCheck extends BugChecker
Copy link
Member

Choose a reason for hiding this comment

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

I'm thinking about the name of the checker. Not too strong of an opinion yet but; we could also name it CollectorImmutabilty`, because we prefer it being immutable. However, AFAIK the current name doesn't mention that we prefer either one of the two. What are your thoughts 😄?

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 feel like the name is fine like this, as we want emphasis on the (im)mutability of the resulting collection.

Copy link
Member

@Stephan202 Stephan202 left a comment

Choose a reason for hiding this comment

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

Rebased and added a commit. Tnx for picking this up!

Alternative suggested commit message:

Introduce `CollectorMutability` check (#135)

This check flags `Collectors.to{List,Map,Set}` usages, suggesting that they be
replaced with expressions that clearly indicate the (im)mutability of the 
resultant collection.

Refaster templates that violated the new check are simplified by removing the
relevant expressions; they were too contrived to be updated some other way.

ExpressionTree valueMapper = tree.getArguments().get(1);

return buildDescription(tree)
.addFix(SuggestedFixes.renameMethodInvocation(tree, "toImmutableMap", state))
Copy link
Member

Choose a reason for hiding this comment

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

Here and above: IIUC we may also need to introduce a (static) import.

private Description buildSimpleDescription(
MethodInvocationTree tree, VisitorState state, String immutable, String mutable) {
return buildDescription(tree)
.addFix(SuggestedFixes.renameMethodInvocation(tree, immutable, state))
Copy link
Member

Choose a reason for hiding this comment

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

Here and below: this breaks if the original code didn't statically import to{List,Map,Set}. (Will add a test case.)

staticMethod().onClass("java.util.stream.Collectors").namedAnyOf("toList", "toSet"),
allOf(
staticMethod().onClass("java.util.stream.Collectors").named("toMap"),
argumentCount(2))));
Copy link
Member

Choose a reason for hiding this comment

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

We can also convert the three-argument case.

name = "CollectorMutability",
summary = "`#collect(to{List,Map,Set}())` doesn't emphasize (im)mutability",
linkType = NONE,
severity = ERROR,
Copy link
Member

Choose a reason for hiding this comment

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

I guess WARNING is more appropriate. (Within the Picnic context this doesn't matter, as we build with -Werror.)

summary = "`#collect(to{List,Map,Set}())` doesn't emphasize (im)mutability",
linkType = NONE,
severity = ERROR,
tags = LIKELY_ERROR)
Copy link
Member

Choose a reason for hiding this comment

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

Or FRAGILE_CODE? 🤔

Comment on lines 31 to 27
/**
* A {@link BugChecker} which flags {@link Collector} usages that don't clearly express
* (im)mutability.
*/
Copy link
Member

Choose a reason for hiding this comment

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

We also have a few violations of this checker in the current repo; will add a commit to resolve those. (In this case IMHO simply dropping the relevant Refaster templates seems appropriate.)

@Stephan202 Stephan202 added this to the 0.1.0 milestone Jun 19, 2022
@Stephan202
Copy link
Member

(Also verified that the code now has 100% mutation coverage.)

Copy link
Member

@rickie rickie left a comment

Choose a reason for hiding this comment

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

Nice feedback @Stephan202.

The code LGTM!

Pushed some changes, we could further cleanup some of the tests.

@Stephan202
Copy link
Member

Tnx for the extra cleanup @rickie! Feel free to merge if no further changes are planned.

@rickie rickie changed the title Add BugPattern to flag collect(to{List,Map,Set}()) to emphasize (im)mutability Introduce CollectorMutability check Jun 20, 2022
@rickie rickie merged commit 0bdc171 into master Jun 20, 2022
@rickie rickie deleted the gdejong/PSM-1336 branch June 20, 2022 09:08
collectingAndThen(null, null),
naturalOrder(),
toList());
Arrays.class, Collections.class, Comparator.class, Streams.class, naturalOrder());
Copy link
Member

Choose a reason for hiding this comment

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

@rickie another thought I had (and this one will be tricky to implement, I suspect, so not high on the list): we should also be able to automatically validate that elidedTypesAndStaticImports is minimal. (And perhaps sorted?)

Copy link
Member

Choose a reason for hiding this comment

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

Nice, will write it down.

Copy link
Member

Choose a reason for hiding this comment

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

😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants