-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Exclude from a report private empty constructors that do not have arguments #529
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
Conversation
331d669 to
44e5b8d
Compare
marchof
left a comment
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.
@Godin This filter is definitely a quick win! I have two minor comments to improve the matcher API.
| if (m != null && superClassName.equals(m.owner) | ||
| && "<init>".equals(m.name) && ("()V").equals(m.desc)) { | ||
| nextIs(Opcodes.RETURN); | ||
| return cursor != null; |
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 nextIs() would have an boolean return value, we could write this as:
return nextIs(Opcodes.Return)
Could also be used in other existing filters.
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.
@marchof then there will be temptation to use it with && everywhere, but that is exactly what we were trying to avoid.
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.
@Godin It's internal API, I would try to keep the filter as readable as possible.
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.
@marchof Then in case of preceding if statement containing return of a boolean, IDE start to suggest to combine them, making code unreadable. Also even if I don't see this in IntelliJ, static analyzers might warn about unused return value in other places.
|
|
||
| private boolean match(final MethodNode methodNode, | ||
| final String superClassName) { | ||
| vars.put("this", THIS); |
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.
The trick with ASTORE is to define a named argument. This looks surprising as there is no ASTORE involved in private empty constructors.
For better documentation I would therefore prefer to encapsulate this within AbstractMatcher and provide a method for this:
void defineLocal(int idx, String name)
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.
@marchof I removed usage of nextIsVar - it does not work for a first instruction in absence of preceding label.
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.
@Godin Ok, I see. I would still prefer to implement semantical matching premitives in AbstractMatcher, so we can write e.g.
private boolean match(final MethodNode methodNode,
final String superClassName) {
cursor = methodNode.instructions.getFirst();
skipNonOpcodes();
nextIsVar(Opcodes.ALOAD, 0);
nextIsMethod(Opcodes.INVOKESPECIAL, superClassName, "<init>",
"()V");
return nextIs(Opcodes.RETURN);
}
[Updated]
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.
@marchof I added skipNonOpcodes, but nextIsVar anyway can't be used for a very first instruction, because after skipNonOpcodes we need to check current instruction, while semantic of next... methods is to move to a next instruction. Change of semantic to check of current instruction - first of all will affect a lot of existing code relying on it, but anyway will lead to the same problem, a kind of, but at the end of method. IMO the only way - is to insert an artificial label at the beginning of all methods, but IMO this is an overkill compared just to a condition in if here, which is IMO perfectly readable.
Replacement of another if on method nextIsMethod in abstract class IMO also an overkill, because its only usage will be here, and there won't be code-sharing with other places where we already check MethodInsnNode (see references on it in TryWithResourcesJavacFilter and TryWithResourcesEcjFilter), and again IMO condition is perfectly readable.
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.
@Godin Thanks for the explations. This would require to keep a state in AbstractMatcher and replace the direct access to cursor with simething like start(AbstractInsnNode).
But I agree that refactoring the matcher API soes not provide enough value for now.
| private static class PrivateDefault { // $line-privateDefault$ | ||
| } | ||
|
|
||
| private static class PrivateEmptyNoArg { |
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.
@Godin I wonder whether we should add another negative test for the case where the private non-arg constructor is not empty in source code:
private static class PrivateNonEmptyNoArg {
private PrivateNonEmptyNoArg() {
nop(); // $line-privateNonEmptyNoArg$
}
}
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.
Done
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.
@Godin Thx! 👍
4c8aa24 to
d0b42ad
Compare
marchof
left a comment
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.
@Godin From my point of view this can be merged. Please do so if you don't have any open issues.
|
Do you have an estimate about when this could be released? |
|
@MonsieurBon Hopefully this year. You can use our snapshot builds in the meantime and help us testing! |
|
Snapshot build is fine with me, but I can't seem to test this.
what am I doing wrong? |
After reflecting for some time, I believe that we can unconditionally safely ignore private empty constructors that do not have arguments. Even despite the fact that they relate to a source code and not generated by compiler. Note that this will completely exclude from report unused classes that have only such constructor, but anyway revealing of those is not a job of code coverage tool.
This will also improve report for JaCoCo itself.