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

Add filter for methods that Kotlin compiler generates #689

Merged
merged 6 commits into from
Jun 7, 2018
Merged

Add filter for methods that Kotlin compiler generates #689

merged 6 commits into from
Jun 7, 2018

Conversation

goodwinnk
Copy link
Contributor

Filtering for Kotlin generated methods based on line numbers absence among method instructions.

Constructors are ignored for tests with debug information stripped pass.
List of class annotations descriptions and source file name are added.
@marchof
Copy link
Member

marchof commented Jun 5, 2018

@goodwinnk Are generated method already without line numbers? Or what would be the minimum required Kotlin compiler version?

@goodwinnk
Copy link
Contributor Author

Generated methods are without line numbers since Kotlin 1.0.0 till the latest one.

Copy link
Member

@marchof marchof left a comment

Choose a reason for hiding this comment

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

Hi @goodwinnk , thanks for the great idea how to implement filtering and this well-crafted pull request. I would like to propose two formal changes. We also always add an entry to changes.html.

If you don't mind I can take care of this.

import java.util.ListIterator;
import java.util.Set;

public class KotlinNoSourceLinesFilter implements IFilter {
Copy link
Member

Choose a reason for hiding this comment

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

JavaDoc missing.

Copy link
Member

Choose a reason for hiding this comment

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

In addition to a missing Javadoc - maybe also rename into KotlinGeneratedFilter by analogy with existing GroovyGeneratedFilter and LombokGeneratedFilter ?

* @param methodNode
* method to inspect
* @param output
* callback to report filtering results to
*/
void filter(String className, String superClassName, MethodNode methodNode,
void filter(String className, String superClassName,
Copy link
Member

Choose a reason for hiding this comment

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

Now we're definitely beyond the limit of extra parameters. Probably we will see even more in future. I would propose to introduce a new interface

public interface org.jacoco.core.internal.analysis.filter.IFilterContext{
    String getClassName();
    String getSuperClassName();
    Set<String> getClassAnnotations();
    String getSourceFileName();
}

For now this can be directly implemented by ClassAnalyzer.

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 thought about introducing something like IFilterContext but decided that it's a bit more structural change than this PR needs.

Copy link
Member

@Godin Godin left a comment

Choose a reason for hiding this comment

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

First of all - thank you for this nice contribution! 👍 ❤️

I added few more comments. IMO one about iteration and one about cleanup of map are worth to be addressed, others are really minor, picky as @marchof loves 😉 in order to keep our codebase healthy, clean and consistent, so feel free to leave them on his shoulders as he already requested 😜 😆

import java.util.ListIterator;
import java.util.Set;

public class KotlinNoSourceLinesFilter implements IFilter {
Copy link
Member

Choose a reason for hiding this comment

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

In addition to a missing Javadoc - maybe also rename into KotlinGeneratedFilter by analogy with existing GroovyGeneratedFilter and LombokGeneratedFilter ?

@Godin Godin added this to IN PROGRESS in Filtering Jun 5, 2018
@Godin Godin added this to IN PROGRESS in Current work items Jun 6, 2018
* Rename Filter to KotlinGeneratedFilter in analogy to other filters.
* Iterate over instructions without allocation
* Identify LineNumberNode with getType()
* Remove unnecessary clear()
* Use project source formatting (final, imports)
@marchof
Copy link
Member

marchof commented Jun 6, 2018

@Godin I tried to address your issues in first step. I will work on my findings tonight.

@marchof
Copy link
Member

marchof commented Jun 6, 2018

@goodwinnk Silly question from my side: Have you done some integration testing with a Kotlin project? Are the results as expected?

@goodwinnk
Copy link
Contributor Author

@marchof, @Godin Thank you for the review.
@marchof I didn't notice your changes and prepared some fixes, but they are probably the same (https://github.com/goodwinnk/jacoco/commits/kotlin-generated-filter-fixes).

I would still like to ask you fill changes.html in the way you prefer it.

@goodwinnk Silly question from my side: Have you done some integration testing with a Kotlin project? Are the results as expected?

I'm using the sample project https://github.com/goodwinnk/kotlin-features-coverage and have just updated readme with the results from jacoco with KotlinGeneratedFilter enabled.

All results are as expected.
Inlines are still uncovered because of the #654. Function cannot be considered generated as it written in user code.
There're also problems with coroutines feature (there're uncovered branches in coroutines), but there would be an additional investigation, because coroutines are not finalized feature in Kotlin.

@marchof
Copy link
Member

marchof commented Jun 6, 2018

@goodwinnk Thanks for the deedback! Sure, I will finalize this PR.

@marchof
Copy link
Member

marchof commented Jun 6, 2018

@Godin I tried to address all issues . Can you please re-review?

@Godin Godin added this to the 0.8.2 milestone Jun 6, 2018
Copy link
Member

@Godin Godin left a comment

Choose a reason for hiding this comment

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

@marchof perfect! 👍

As usual I also made end-to-end test - example.zip

Before this change using JaCoCo 0.8.1:
before

After this change:
after

Results are the same for Kotlin 1.0.1 and 1.2.41.

Noticed that val's in data classes require read test and vars both read and write.
This seems correct to me - don't read val = remove it, don't write var = make it val. And this seems to be consistent with Groovy. However not consistent with Lombok for which we filter out generated setters and getters 😆

@Godin Godin changed the title Kotlin generated filter Add filter for methods that Kotlin compiler generates Jun 7, 2018
@Godin Godin merged commit 281538b into jacoco:master Jun 7, 2018
@Godin Godin removed this from IN PROGRESS in Current work items Jun 7, 2018
@Godin Godin moved this from IN PROGRESS to DONE in Filtering Jun 7, 2018
@hleb-albau
Copy link

Hi, thanks !
When new release is planned?

@marchof
Copy link
Member

marchof commented Jun 8, 2018

See FAQ https://www.jacoco.org/jacoco/trunk/doc/faq.html

When will feature X be released?

JaCoCo is maintained by volunteers in their free time. Since we cannot guarantee free capacity, we do not commit to particular release dates. Typically, you can expect a couple of releases every year.

In the change log, you can see all features that have been been implemented in master branch and > will be available with the next release. And in the meantime you can test latest build of of master branch (Maven SNAPSHOT) and provide feedback to us.

@NickButcher1
Copy link

I have pointed my app at 0.8.2-SNAPSHOT. The fix is working nicely, thanks.

@hleb-albau
Copy link

@marchof I also moved to SNAPSHOT release, no issues, thanks.

PS: Sorry, I should read docs first.

charleskorn added a commit to batect/batect that referenced this pull request Jul 5, 2018
The report currently doesn't look great due to JaCoCo including
compiler-generated methods such as equals and hashCode. This will be
fixed in the next JaCoCo release (see
jacoco/jacoco#689).
@Barryrowe
Copy link

Is there a configuration option that needs to be set to take advantage of this with 0.8.2?
I have updated a project from 0.8.0 --> 0.8.2 but see no difference in my coverage and data classes still calculate coverage on generated toString()/hashCode() etc. functions.

@Godin
Copy link
Member

Godin commented Oct 8, 2018

No - all filters so far implemented in JaCoCo are enabled unconditionally and do not require any configuration.

Also by carefully reading this thread - you can find above example.zip which contains complete example for Maven and Gradle demonstrating that toString and hashCode are perfectly filtered out in data classes as shown on corresponding screenshots. This example was used as end-to-end test of unreleased version, however replacement of 0.8.2-SNAPSHOT on 0.8.2 in pom.xml and build.gradle doesn't change result.

Please also pay attention on what is stated in each release announcement starting from 0.8.0 up to 0.8.2 and in changelog:

filtering happens at a time of generation of reports, so that

Integrations developed as part of JaCoCo project by us (Ant Tasks, Maven Plugin and Command Line Interface) provide new filters.

while

Tools that directly read exec files (which is not a final report) and embed JaCoCo for generation of report will provide filtering functionality only after they updated to this version of JaCoCo.

If the above doesn't help, then please use our mailing list to provide complete example that demonstrates your problem.

@jacoco jacoco locked as resolved and limited conversation to collaborators Oct 8, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Status: Done
Filtering
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

6 participants