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
Coverage of default methods #905
Comments
In case of
which delegates to default implementation (
and which contains line number ( So @realdadfish could you please report this to developers of Kotlin compiler in their issue tracker with cross-reference to/from this ticket? |
@realdadfish @sellmair have you reported this to the developers of Kotlin compiler in their issue tracker? |
@Godin No, but I actually asked about a year ago on the JetBrains (and Google) bugtracker to find some common ground for improving Kotlin support in Jacoco, without getting feedback (https://youtrack.jetbrains.com/issue/KT-29180). Last week on KotlinConf I stepped up and specifically asked Andrey again if there are any plans to get more in touch and he denied ("except bugfixes"), however I think even those are not very high priority for them sadly. For example in recent Android Studio versions (up until recent 4.0 canaries) the inline display of Jacoco coverage results is broken / works unreliably, while the built-in coverage tool shows no issues (but is also of course far away from what Jacoco can provide). After that event I'm frankly a bit disenchanted about the whole thing. |
@qwwdfsad I suppose that the answer will be the same as #1002 (comment) , but anyway should ask: |
Surprisingly, it won't be the same :) The problem, in general, can be rephrased as "How can we distinguish auto-generated methods (that do not carry any new semantic or cognitive load) from the user-defined ones?" This is a problem worth addressing, though it is not clear how exactly we are going to do it. We definitely want to add line numbers to all auto-generated methods (so stracktraces are always navigable), but in return, we will indicate that methods are compiler-generated. Two options here:
We'll start discussing it, but it's unlikely to be implemented until the autumn and, unfortunately, I cannot make a commitment here. As a temporary Kotlin-specific filter, it's probably worth attempting to match the byte-code against |
@qwwdfsad thank you for looking into this and for the response! ❤️
Agree.
I would say that not As a note: if here or in other places Kotlin compiler will be adding annotation with There also might be other options, e.g. maybe SMAPs (JSR-045).
This confirms my guesses, so draft of implementation was done already - see #1012 😉 At the same time, you probably know - "there is nothing more permanent than temporary" 😉 so thanks a lot for triggering discussions 👍 is there any ticket in Kotlin tracker about this which can be followed? |
I seem to have run into a problem with this, although I'm not sure entirely sure whether it's a bug or a feature/limitation. I'm leaning towards the latter, as this looks very tricky to solve without further support from the Kotlin team. Currently, it looks like the filter as implemented will only filter out DefaultImpl functions without any parameters. It checks if the first instructions are ALOAD0 followed by an immediate INVOKESTATIC. However, any default function with actual function parameters will have to put these parameters on the stack before the INVOKESTATIC call, and will thus have ALOAD1/2/... calls in between ALOAD0 and INVOKESTATIC. Furthermore, these will not necessarily be the first instructions in the function, as Kotlin injects a checkNotNullParameter call for each non-nullable function parameter at the start of the function. In my codebase I have an interface with several functions with default implementations, some without parameters, others with parameters. Those without parameters are correctly excluded from the report of any implementing classes. However, those that have parameters and are unused in the implementing class are reported as having 0% coverage. I don't know if this is currently solvable. A quick and dirty test seems to indicate that any overridden implementation of foo(...) which contains a super.foo(...) call somewhere in it, will end up containing the same block of bytecode for an INVOKESTATIC call to the $DefaultImpls as the bytecode generated for a non-overridden function, so I personally don't see a way to distinguish between the two. However, the release notes of 0.8.6 state that this problem is fixed in general, which appears to not be the case. |
@bguns you're right - unfortunately methods with parameters were overlooked during implementation of #1012 in And you're right that
as long as compiler produces the same bytecode for generated method in However both are distinguishable from Hope one day implementation of https://youtrack.jetbrains.com/issue/KT-41906 or similar will make |
Unfortunately, we are still not sure if we are going to implement this at all (I'll post the rationale in KT ticket as soon as it will be complete). Meanwhile, you already can distinguish auto-generated methods from handwritten using You can read all the methods and method
Also, we have a repository with examples https://github.com/udalov/kotlinx-metadata-examples that read metadata from |
@qwwdfsad thank you for the information, we are already aware of |
Okay, good to know. You probably still can use it only on Kotlin-related code paths (or even only in Kotlin-specific filters) because Kotlin itself is compatible with Java 6 and above. Then only Kotlin-specific part of JaCoCo will require Java 6 |
@Godin This coverage issue is recurring for the Kotlin version 1.6.10 |
@pexa-asekar yes we know - ticket #1137 is still open as you can see by yourself |
Steps to reproduce
JaCoCo version: 0.8.3
Operating system: macOS
Tool integration: Gradle
Expected behaviour
I'd like to see that Jacoco reports 100% coverage, because all methods in
CallbackImpl
are in fact covered and the default method implementations might technically be part of the class, but serve no purpose.Actual behaviour
For a test of
CallbackImpl
, Jacoco will tell me that 66% of the class' methods are not covered (and one instruction per missed method as well).One could argue that one could test to call the other methods to check if they lead to no behaviour change, but being default implementations from some base class with no actual implementation in this class I don't see why I should unit-test them here.
The text was updated successfully, but these errors were encountered: