aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinDefaultArgumentsTarget.kt7
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java34
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java15
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java37
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java7
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html7
6 files changed, 95 insertions, 12 deletions
diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinDefaultArgumentsTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinDefaultArgumentsTarget.kt
index c2922812..1a89eaba 100644
--- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinDefaultArgumentsTarget.kt
+++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinDefaultArgumentsTarget.kt
@@ -27,6 +27,10 @@ object KotlinDefaultArgumentsTarget {
}
}
+ class Constructor() {
+ constructor(a: Boolean, b: String = if (a) "a" else "b") : this() // assertFullyCovered(0, 2)
+ }
+
@JvmStatic
fun main(args: Array<String>) {
f(a = "a")
@@ -38,6 +42,9 @@ object KotlinDefaultArgumentsTarget {
branch(true)
Open().f()
+
+ Constructor(false)
+ Constructor(true)
}
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java
index 8e79a5a7..721abfb0 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java
@@ -150,4 +150,38 @@ public class KotlinDefaultArgumentsFilterTest extends FilterTestBase {
new Range(m.instructions.get(11), m.instructions.get(11)));
}
+ /**
+ * <pre>
+ * class C(a: Int = 42)
+ * </pre>
+ */
+ @Test
+ public void should_filter_constructors() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION,
+ Opcodes.ACC_SYNTHETIC, "<init>",
+ "(IILkotlin/jvm/internal/DefaultConstructorMarker;)V", null,
+ null);
+ context.classAnnotations
+ .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
+
+ m.visitVarInsn(Opcodes.ILOAD, 2);
+ m.visitInsn(Opcodes.ICONST_1);
+ m.visitInsn(Opcodes.IAND);
+ Label label = new Label();
+ m.visitJumpInsn(Opcodes.IFEQ, label);
+ // default argument
+ m.visitLdcInsn(Integer.valueOf(42));
+ m.visitVarInsn(Opcodes.ISTORE, 1);
+ m.visitLabel(label);
+ m.visitVarInsn(Opcodes.ALOAD, 0);
+ m.visitVarInsn(Opcodes.ILOAD, 1);
+ m.visitMethodInsn(Opcodes.INVOKESPECIAL, "Owner", "<init>", "(I)V",
+ false);
+ m.visitInsn(Opcodes.RETURN);
+
+ filter.filter(m, context, output);
+
+ assertIgnored(new Range(m.instructions.get(3), m.instructions.get(3)));
+ }
+
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java
index 5bbae983..5b0a30ba 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java
@@ -83,6 +83,21 @@ public class SyntheticFilterTest extends FilterTestBase {
}
@Test
+ public void should_not_filter_synthetic_constructor_containing_default_arguments_in_kotlin_classes() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION,
+ Opcodes.ACC_SYNTHETIC, "<init>",
+ "(IILkotlin/jvm/internal/DefaultConstructorMarker;)V", null,
+ null);
+ context.classAnnotations
+ .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter(m, context, output);
+
+ assertIgnored();
+ }
+
+ @Test
public void should_not_filter_synthetic_methods_whose_last_argument_is_kotlin_coroutine_continuation() {
final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION,
Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC, "example",
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java
index 34f9562c..a7a05cf7 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java
@@ -38,14 +38,28 @@ import org.objectweb.asm.tree.VarInsnNode;
* </pre>
*
* Where <code>maskVar</code> is penultimate argument of synthetic method with
- * suffix "$default". And its value can't be zero - invocation with all
- * arguments uses original non synthetic method, thus <code>IFEQ</code>
- * instructions should be ignored.
+ * suffix "$default" or of synthetic constructor with last argument
+ * "kotlin.jvm.internal.DefaultConstructorMarker". And its value can't be zero -
+ * invocation with all arguments uses original non synthetic method, thus
+ * <code>IFEQ</code> instructions should be ignored.
*/
public final class KotlinDefaultArgumentsFilter implements IFilter {
- static boolean isDefaultArgumentsMethodName(final String methodName) {
- return methodName.endsWith("$default");
+ static boolean isDefaultArgumentsMethod(final MethodNode methodNode) {
+ return methodNode.name.endsWith("$default");
+ }
+
+ static boolean isDefaultArgumentsConstructor(final MethodNode methodNode) {
+ if (!"<init>".equals(methodNode.name)) {
+ return false;
+ }
+ final Type[] argumentTypes = Type.getMethodType(methodNode.desc)
+ .getArgumentTypes();
+ if (argumentTypes.length < 2) {
+ return false;
+ }
+ return "kotlin.jvm.internal.DefaultConstructorMarker"
+ .equals(argumentTypes[argumentTypes.length - 1].getClassName());
}
public void filter(final MethodNode methodNode,
@@ -53,19 +67,20 @@ public final class KotlinDefaultArgumentsFilter implements IFilter {
if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) {
return;
}
- if (!isDefaultArgumentsMethodName(methodNode.name)) {
- return;
- }
if (!KotlinGeneratedFilter.isKotlinClass(context)) {
return;
}
- new Matcher().match(methodNode, output);
+ if (isDefaultArgumentsMethod(methodNode)) {
+ new Matcher().match(methodNode, output, false);
+ } else if (isDefaultArgumentsConstructor(methodNode)) {
+ new Matcher().match(methodNode, output, true);
+ }
}
private static class Matcher extends AbstractMatcher {
public void match(final MethodNode methodNode,
- final IFilterOutput output) {
+ final IFilterOutput output, final boolean constructor) {
cursor = methodNode.instructions.getFirst();
nextIs(Opcodes.IFNULL);
@@ -91,7 +106,7 @@ public final class KotlinDefaultArgumentsFilter implements IFilter {
final Set<AbstractInsnNode> ignore = new HashSet<AbstractInsnNode>();
final int maskVar = Type.getMethodType(methodNode.desc)
- .getArgumentTypes().length - 2;
+ .getArgumentTypes().length - (constructor ? 1 : 2);
while (true) {
if (cursor.getOpcode() != Opcodes.ILOAD) {
break;
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
index 69c4092a..46d4e6eb 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
@@ -31,7 +31,12 @@ public final class SyntheticFilter implements IFilter {
if (KotlinGeneratedFilter.isKotlinClass(context)) {
if (KotlinDefaultArgumentsFilter
- .isDefaultArgumentsMethodName(methodNode.name)) {
+ .isDefaultArgumentsMethod(methodNode)) {
+ return;
+ }
+
+ if (KotlinDefaultArgumentsFilter
+ .isDefaultArgumentsConstructor(methodNode)) {
return;
}
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index 252d7db7..25087b3a 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -27,6 +27,13 @@
(GitHub <a href="https://github.com/jacoco/jacoco/issues/887">#887</a>).</li>
</ul>
+<h3>Fixed bugs</h3>
+<ul>
+ <li><code>synthetic</code> constructors that contain values of default arguments
+ in Kotlin should not be ignored
+ (GitHub <a href="https://github.com/jacoco/jacoco/issues/888">#888</a>).</li>
+</ul>
+
<h2>Release 0.8.4 (2019/05/08)</h2>
<h3>New Features</h3>