-
Notifications
You must be signed in to change notification settings - Fork 37
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 validation for Ordering.explicit()
to contain all enum values
#14
Conversation
668b0b5
to
b2a75cc
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.
Very nice. Rebased and added a commit. Suggested commit message:
Flag `Ordering#explicit` invocations listing a subset of an enum's values (#14)
Will merge if you're okay with my changes :)
.map(Name::toString) | ||
.collect(toImmutableSet()); | ||
|
||
LinkedHashSet<String> enumValues = |
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.
LinkedHashSet<String> enumValues = | |
Set<String> enumValues = |
if (not(staticMethod().onClass(Ordering.class.getName()).named("explicit")) | ||
.matches(tree, state)) { |
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 (not(staticMethod().onClass(Ordering.class.getName()).named("explicit")) | |
.matches(tree, state)) { | |
if (!staticMethod().onClass(Ordering.class.getName()).named("explicit") | |
.matches(tree, state)) { |
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.
Also: we should move the matcher construction to a static field, so that this isn't repeated for every method invocation.
} | ||
|
||
private static boolean isNotEnumType(List<? extends ExpressionTree> arguments) { | ||
return arguments.stream().anyMatch(Predicate.not(arg -> ASTHelpers.getSymbol(arg).isEnum())); |
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.
return arguments.stream().anyMatch(Predicate.not(arg -> ASTHelpers.getSymbol(arg).isEnum())); | |
return arguments.stream().anyMatch(arg -> !ASTHelpers.getSymbol(arg).isEnum()); |
.build(); | ||
} | ||
|
||
private static boolean isNotEnumType(List<? extends ExpressionTree> arguments) { |
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.
private static boolean isNotEnumType(List<? extends ExpressionTree> arguments) { | |
private static boolean containsNonEnumValue(List<? extends ExpressionTree> arguments) { |
.collect(toImmutableSet()); | ||
|
||
LinkedHashSet<String> enumValues = | ||
getTypeSymbolStream(arguments).map(ASTHelpers::enumValues).findFirst().orElseThrow(); |
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.
Making clearer that only one map will be performed:
getTypeSymbolStream(arguments).map(ASTHelpers::enumValues).findFirst().orElseThrow(); | |
getTypeSymbolStream(arguments).findFirst().map(ASTHelpers::enumValues).orElseThrow(); |
Though then we can just do:
getTypeSymbolStream(arguments).map(ASTHelpers::enumValues).findFirst().orElseThrow(); | |
ASTHelpers.enumValues(getTypeSymbolStream(arguments).findFirst().orElseThrow()); |
"import java.util.Comparator;", | ||
"", | ||
"enum A {", | ||
" ONE, TWO, THREE", |
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.
We're using non-AOSP style here, so two space indent :)
"", | ||
"class B {", | ||
" // BUG: Diagnostic contains: Method should include all values from A enum", | ||
" Comparator<A> explicit = Ordering.explicit(A.TWO, A.ONE);", |
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.
Let's also test with statically imported enum values.
linkType = BugPattern.LinkType.NONE, | ||
severity = BugPattern.SeverityLevel.WARNING, | ||
tags = BugPattern.StandardTags.FRAGILE_CODE) |
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.
Like in the other classes:
linkType = BugPattern.LinkType.NONE, | |
severity = BugPattern.SeverityLevel.WARNING, | |
tags = BugPattern.StandardTags.FRAGILE_CODE) | |
linkType = LinkType.NONE, | |
severity = SeverityLevel.WARNING, | |
tags = StandardTags.FRAGILE_CODE) |
/** | ||
* A {@link BugChecker} which flags that {@link com.google.common.collect.Ordering#explicit(Object, | ||
* Object[])}} for enums does not contain all it's values. | ||
*/ |
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.
/** | |
* A {@link BugChecker} which flags that {@link com.google.common.collect.Ordering#explicit(Object, | |
* Object[])}} for enums does not contain all it's values. | |
*/ | |
/** | |
* A {@link BugChecker} which flags {@link Ordering#explicit(Object, Object[])}} invocations listing | |
* a subset of an enum type's values. | |
*/ |
*/ | ||
@AutoService(BugChecker.class) | ||
@BugPattern( | ||
name = "OrderingExplicitMethod", |
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.
How about:
name = "OrderingExplicitMethod", | |
name = "ExplicitEnumOrdering", |
Build failure is unrelated to this PR; will fix |
b2a75cc
to
0543be9
Compare
According to the
Ordering.explicit()
documentation it can throwClassCastException
when it receives an input parameter that isn't among the provided values.So in case when we had such method in a codebase with enum values and after time someone adds new values to that enum we need to make sure that the logic where
Ordering.explicit()
is used works as expected and include a new value there aswell.