-
Notifications
You must be signed in to change notification settings - Fork 1.2k
FilteringOptions
This wiki is primarily used by JaCoCo developers to analyze and design new features. For users please see the latest documentation.
The JaCoCo Analyzer should allow to hook-in filters, that filters synthetic compiler constructs or code, that should not be considered for code coverage. This page is a collection of filters that might be useful.
Filters implemented in versions starting from 0.8.0 are enabled unconditionally and take place during generation of report from exec file, therefore tools that directly read exec files and embed JaCoCo for this (such as SonarQube or Jenkins) will provide filtering functionality only after they updated to this version of JaCoCo.
For technical reasons compilers sometime create additional byte code, that seems to have no relation to the source code. Highlighting such code in coverage reports is confusing and therefore should be filtered out.
- ✅ JAVAC.SYNTHCLASS - synthetic classes - implemented in 0.8.2
- ✅ JAVAC.SYNTHMETH - synthetic methods - implemented
- JAVAC.CLASS - try/catch blocks for class literals (<= Java 1.4)
- ✅ JAVAC.SYNC - release lock code in synchronized statements - implemented in 0.8.0
- ✅ JAVAC.FINALLY - finally block emitted multiple times - implemented in 0.8.0, previous WiP
- ✅ JAVAC.ENUM - static methods and initializer generated for
enumtypes - implemented in 0.8.0 - ✅ JAVAC.ASSERT - branches created for
assertstatement - implemented in 0.8.8 - ✅ JAVAC.TRYWITH - extra exception handlers installed to close resources in try-with-resources statements
- ✅ JAVAC.STRINGSWITCH - extra branches for
Stringinswitchdue to implementation withhashCodeandequalscomparison - ✅ empty constructor without parameters in
enums - implemented in 0.8.1 -
JAVAC.NOT - branches created by the logical complement operator (
!) on boolean values - ✅ exhaustive switch-expression - implemented in 0.8.11
- ✅ records
-
toString,hashCodeandequals- implemented in 0.8.6 - accessors - implemented in 0.8.9
-
- ✅ record patterns - implemented in 0.8.11
- ToDo primitive types in patterns
- ✅ methods without line numbers, e.g.
equalsandhashCodeindata classes - implemented in 0.8.2 - KOTLIN.PROPERTIES - generated getters and setters
- ✅
lateinitinitialized checks- implemented in 0.8.2
- updated in 0.8.7 for Kotlin 1.5.0
- updated in 0.8.12 because of changes in Kotlin compiler 1.5.30 (KT-46267), 1.6.0 and 1.6.20
- ✅
whenexpressions and statements- that list all cases of
sealedtype - that list all cases of
enum- implemented in 0.8.2
- improved in 0.8.13 for nullable
- fixed for statements in Kotlin compiler 2.0.0
- that list all cases of
Boolean - with
String- implemented in 0.8.2
- improved in 0.8.7
- updated in 0.8.7 for Kotlin 1.5.0 because of change in compiler
- ToDo for Kotlin 1.6.20 because of change in compiler
- improved in 0.8.13 for nullable
- improved in 0.8.13 - handling of implicit else clause
- that list all cases of
- ✅ "unsafe" cast operator (
as)- implemented in 0.8.3
- updated in 0.8.7 for Kotlin 1.4.0 because of KT-22275
- updated in 0.8.7 for Kotlin 1.5.0
- updated in 0.8.8 for Kotlin 1.6.0 because of change in compiler
- ✅ not-null assertion operator (
!!) - implemented in 0.8.3 - ✅ default arguments
- in functions should not be filtered out - implemented in 0.8.3
- in constructors should not be filtered out - implemented in 0.8.5
- default arguments in
openfunctions - implemented in 0.8.5 - updated in 0.8.7 for Kotlin 1.5.0
- improved in 0.8.12 for methods and constructors with more than 32 parameters
-
@JvmOverloads- implemented in 0.8.13 because of regression in Kotlin compiler version 2.0 - improved in 0.8.14 for case when argument number 33 or higher has default value
- ToDo in
@Composablefunctions
- ✅
inlinefunctions- line coverage implemented in 0.8.13
- with
reifiedtype parameters - implemented in 0.8.13 - regression in Kotlin compiler version 2.0 was fixed in 2.2 - KT-74617
- ToDo branch coverage
- ✅ inlined instructions
- implemented in 0.8.3
- updated in 0.8.7 for Kotlin 1.5.0 because of KT-37704
- improved in 0.8.13
- ✅ suspending lambdas
- implemented in 0.8.3
- improved in 0.8.3
- updated in 0.8.4 for Kotlin 1.3.30 because of KT-28015
- updated in 0.8.7 for Kotlin 1.4.20
- updated in 0.8.13 for Kotlin 1.6.0 because of change in compiler
- updated in 0.8.14 for Kotlin 2.2.0 because of change in compiler
- ✅ suspending functions
- implemented in 0.8.3
- updated in 0.8.4 for Kotlin 1.3.30 because of KT-28015
- updated in 0.8.6 for Kotlin 1.3.60 because of change in compiler
- updated in 0.8.7 for Kotlin 1.5.0 because of change in compiler
- improved in 0.8.14 for suspension points that return inline value class
-
WiP for
inlinefunctions - WiP tail call optimization
- ✅ inlined invocations of
suspendCoroutineUninterceptedOrReturnintrinsic - implemented in 0.8.14 - ✅
suspendfunctions should not be filtered out - implemented in 0.8.3 - ✅ anonymous classes for callable references - KT-28453 fixed in Kotlin 1.3.30
- ✅ bridge methods not marked as synthetic - implemented in 0.8.6
- ✅ methods generated for non-overridden non-abstract methods of interfaces
- implemented in 0.8.6
- WiP improvement
- ToDo for Kotlin 1.6.0 because of change in compiler
- ToDo for Kotlin 2.2.0 because of change in compiler
- ✅
Enum.entries- implemented in 0.8.13 because of regression in Kotlin compiler version 2.0 - ✅ inline value classes
- implemented in 0.8.13
-
@JvmExposeBoxed- WiP in 0.8.15
- ✅
@Composablefunctions - implemented in 0.8.13 - ✅ safe call operator (
?.)- implemented in 0.8.13 for "optimized" and "unoptimized" chains
- improved in 0.8.14 for chains that throw exceptions
- improved in 0.8.14 for "unoptimized" chains
- when followed by elvis operator (
?:) - implemented and improved in 0.8.14
- ✅
@JvmSynthetic- functions - implemented in 0.8.13
- files - ToDo
- ✅
kotlinx.serialization.Serializable- implemented, fixed and improved in 0.8.14
- ToDo improvement for parameterized types
- ToDo
@JvmMultifileClass - ToDo
DeprecationLevel.HIDDENandDeprecationLevel.ERROR
- ✅ GROOVYC.METHODS - methods from GroovyObject
- ✅ annotation
groovy.transform.Generatedwas added in Groovy 2.5.0 - Done in 0.8.0 for methods from AST transformations-
groovy.lang.Delegate- implemented in Groovy 2.5.7 -
groovy.beans.Bindable- implemented in Groovy 2.5.7 -
groovy.beans.Vetoable- implemented in Groovy 2.5.7 -
groovy.transform.Sortable- implemented in Groovy 2.5.7 -
groovy.transform.Immutable- implemented in Groovy 2.5.7 -
groovy.transform.AutoClone- implemented in Groovy 2.5.7 -
groovy.transform.builder.Builder- implemented in Groovy 2.5.8
-
- dead code generated by Groovy compiler - GROOVY-9126
- ✅ captured arguments in closures are not annotated with
@Generated- GROOVY-9396 fixed in Groovy 3.0.1
- SCALAC.MIXIN - methods from mixin-classes
- SCALAC.CASE - synthetic methods from Scala case classes. Like mixin, these appear on the same line number as the constructor. [idea from @retronym]
- ✅ synthetic methods containing bodies of anonymous functions should not be filtered out - implemented in 0.8.5
- ToDo for Scala 3
- lazy initializers
-
matchwithString
- ✅ Methods annotated with
@lombok.Generated(generated by Lombok getters, setters, equals, hashcode, toString, etc) - implemented in 0.8.0
- ✅ Private empty constructors that do not have arguments - implemented in 0.8.0
- @originalcvk: Empty (non-constructor) methods, whether called or not
- Plain getters and setters
- Blocks that throw
AssertionErrors- Entire block should be ignored if a condition (if !assertion throw new AssertionError) - For
switchstatements which cover all values of a enum the default branch cannot be covered- Godin: wouldn't this require an analysis of an enum class file, which might be unavailable at analysis time?
Filters might parse source code to find lines with with special tags like
} catch (SomeException e) {
dohandle(e); // $COVERAGE-IGNORE$
}
In such a case all blocks overlapping with the tagged line could be ignored.
As of today JaCoCo core only works on class files, there is no source processing. This would require a major rework of the architecture and adds additional configuration hassles.
Filtering out methods and classes based on attributes much like .NET does it.
@ExcludeFromCodeCoverage
public void someMethodThatShouldNotHaveCoverage() {
...
}
- ✅ Classes and methods with annotation whose retention policy is runtime or class and whose simple name contains "Generated" are filtered out during generation of report - implemented in 0.8.2
Remark: A Generated annotation should only be used for code actually generated by compilers or tools, never for manual exclusion.
The excludes property of the report goals/tasks may interpret the # separator to exclude members:
com.sample.MyEnum#valueOf(String)
com.sample.MyEnum#valueOf(*)
com.sample.MyEnum#values()
As of today the filter parameters have inconsistent semantics. For report generation they apply on files only. See issue #34.
The following example creates an anonymous class Foo$1 when compiled with JDK 5.0, but does not with ECJ or JDK 6.0. Adding in the constructor also stops creation of the class.
public class Test {
private class Foo {
/* public Foo() {} */
public void run() {}
}
public void execute() {
new Foo().run();
}
}
Godin: what this example demonstrates? To me seems that generated class has no executable lines and also comment is incorrect - name of class is Test$1 and it is generated by all versions of JDK.
===
Constructor of anonymous classes when compiled with ECJ 3.12.3 contains reference to a first line of source code:
package org.example;
class Fun {
void fun() {
new Object() {
};
}
}
Seems that this was fixed in ECJ 3.14.0
The access flags reported by ClassReader does not include pseudo access flags that are stored in code attributes. It seems as if the correct access flags are only reported during the visit methods of ClassVisitor. To make things more interesting, you only get the right flags for inner classes after visit inner has been called (which happens after visit and visit source).
Filtering code coverage only for New and Modified lines on a specific branch can help to determine the coverage of a new feature before merging it on the "main/master/trunk" branch.
Testing that filtering doesn't cause analysis failures can be done using Command Line Interface:
find ~/.m2 -type f -name "*.jar" -exec \
java -jar jacococli.jar report --quiet --classfiles {} \;