-
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
Have RequestParamType
ignore parameter types with custom deserialization support
#426
Conversation
6e66597
to
5f70f62
Compare
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
1 similar comment
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
Looks good. All 11 mutations in this change were killed.
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
@RequestParam
@RequestParam
2cf48d9
to
5a48292
Compare
Looks good. All 11 mutations in this change were killed.
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
5a48292
to
fb04db6
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.
Rebased and added a commit. Thanks for this PR!
Suggested commit message:
Have `RequestParamType` ignore parameter types with custom deserialization support (#426)
While there, introduce and use a new `Flags` utility class; various checks'
list flags now better support empty lists.
.map(String::trim) | ||
.filter(inclusion -> !inclusion.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.
Other code where we call ErrorProneFlags#getList
doesn't trim or filter. Perhaps we should introduce support for that, but for now let's keep the burden with the caller.
Edit: added a helper method :)
? describeMatch(tree) | ||
: Description.NO_MATCH; | ||
} | ||
|
||
private static Matcher<VariableTree> createVariableTreeMatcher(ErrorProneFlags flags) { |
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.
This method name doesn't explain what the returned matcher does.
|
||
/** Instantiates a new {@link RequestParamType} instance. */ | ||
public RequestParamType() {} | ||
private final Matcher<VariableTree> hasUnsupportedRequestParams; |
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 final Matcher<VariableTree> hasUnsupportedRequestParams; | |
private final Matcher<VariableTree> hasUnsupportedRequestParam; |
Even clearer: hasUnsupportedRequestParamType
.
error-prone-contrib/src/main/java/tech/picnic/errorprone/bugpatterns/RequestParamType.java
Show resolved
Hide resolved
allOf( | ||
annotations(AT_LEAST_ONE, isType("org.springframework.web.bind.annotation.RequestParam")), | ||
anyOf(isSubtypeOf(ImmutableCollection.class), isSubtypeOf(ImmutableMap.class))); | ||
private static final String FLAG_PREFIX = "RequestParamType:"; |
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.
This can be inlined.
annotations(AT_LEAST_ONE, isType("org.springframework.web.bind.annotation.RequestParam")), | ||
anyOf(isSubtypeOf(ImmutableCollection.class), isSubtypeOf(ImmutableMap.class))); | ||
private static final String FLAG_PREFIX = "RequestParamType:"; | ||
private static final String INCLUDED_CLASS_FLAG = FLAG_PREFIX + "Includes"; |
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.
- This flag name should somehow convey that it enumerates types for which custom support in provided.
- The constant should have
s/CLASS/TYPES/
.
private static Class<?> createClass(String className) { | ||
try { | ||
return Class.forName(className); | ||
} catch (ClassNotFoundException e) { | ||
throw new IllegalArgumentException( | ||
String.format("Invalid class name '%s' in `%s`", className, INCLUDED_CLASS_FLAG), e); | ||
} | ||
} |
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 should not require the listed types to be on the classpath, as that prevents users from centrally configuring the types in a multi-module (Maven) project in which some modules don't have the listed type.
(Also, IIUC this would attempt to load the class from the annotation processor classpath rather than the compilation classpath, which is incorrect.)
private final CompilationTestHelper restrictedCompilationTestHelper = | ||
CompilationTestHelper.newInstance(RequestParamType.class, getClass()) | ||
.setArgs( | ||
ImmutableList.of( | ||
"-XepOpt:RequestParamType:Includes=com.google.common.collect.ImmutableCollection")); | ||
private final CompilationTestHelper restrictedWithSubTypeCompilationTestHelper = | ||
CompilationTestHelper.newInstance(RequestParamType.class, getClass()) | ||
.setArgs( | ||
ImmutableList.of( | ||
"-XepOpt:RequestParamType:Includes=com.google.common.collect.ImmutableSet")); | ||
private final CompilationTestHelper restrictedWithInvalidFlagCompilationTestHelper = | ||
CompilationTestHelper.newInstance(RequestParamType.class, getClass()) | ||
.setArgs(ImmutableList.of("-XepOpt:RequestParamType:Includes=")); |
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.
Given the logic involved, IIUC one case would suffice.
private final CompilationTestHelper restrictedCompilationTestHelper = | ||
CompilationTestHelper.newInstance(RequestParamType.class, getClass()) | ||
.setArgs( | ||
ImmutableList.of( |
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 can omit ImmutableList.of
here. (Yep, can also be cleaned up in other tests; I have a TODO list entry for a BugChecker
that flags such cases.)
return flags.getList(INCLUDED_CLASS_FLAG).map(ImmutableList::copyOf).orElse(ImmutableList.of()); | ||
} | ||
|
||
private static ImmutableList<Matcher<Tree>> getSupportedClasses( |
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.
This method returns matchers, not classes.
Looks good. All 11 mutations in this change were killed.
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
fb04db6
to
eace6ce
Compare
Looks good. All 11 mutations in this change were killed.
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
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.
One option we can discuss. Anyway approving the code as it looks good already!
Nice PR @chamil-prabodha 😄 !
@Stephan202 nice Flags
improvements 🚀 !
@@ -6,6 +6,10 @@ | |||
final class RequestParamTypeTest { | |||
private final CompilationTestHelper compilationTestHelper = | |||
CompilationTestHelper.newInstance(RequestParamType.class, getClass()); | |||
private final CompilationTestHelper restrictedCompilationTestHelper = |
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.
@nathankooij In Error Prone there are cases for both situations; but it can be nice to inline the restrictedCompilationTestHelper
IMO. Usually there is only one test with the restricted variant and would make it extra clear in the test method itself that we are using extra flags. Besides that, the flag would be closer to the test, which makes the intend clearer as well.
WDYT?
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.
Yes, I've pondered this a few times as well. I'm fine with that, though it sounds like we should do that in a separate PR.
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'll file a PR for that then!
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.
Filed #442.
eace6ce
to
63a1386
Compare
Looks good. All 11 mutations in this change were killed.
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
@RequestParam
RequestParamType
ignore parameter types with custom deserialization support
One would want to use classes such as
ImmutableList
with@RequestParam
given that the custom support for the underlying conversion is provided. For such occasions we can specify the classes we wish to be included on top of what is already provided (by Spring) by using the flag-XepOpt:RequestParamType:Includes=<class-name>