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 1a89eaba36..210cc8e917 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 @@ -19,6 +19,9 @@ object KotlinDefaultArgumentsTarget { private fun f(a: String = "a", b: String = "b") { // assertFullyCovered(0, 0) } + private fun longParameter(x: Long = 0) { // assertFullyCovered() + } + private fun branch(a: Boolean, b: String = if (a) "a" else "b") { // assertFullyCovered(0, 2) } @@ -38,6 +41,9 @@ object KotlinDefaultArgumentsTarget { /* next invocation doesn't use synthetic method: */ f("a", "b") + longParameter() + longParameter(1) + branch(false) branch(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 721abfb029..d649e8e072 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 @@ -184,4 +184,38 @@ public void should_filter_constructors() { assertIgnored(new Range(m.instructions.get(3), m.instructions.get(3))); } + /** + *
+	 * data class C(val x: Long = 42)
+	 * 
+ */ + @Test + public void should_filter_methods_with_parameters_that_consume_two_slots() { + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_SYNTHETIC, "", + "(JILkotlin/jvm/internal/DefaultConstructorMarker;)V", null, + null); + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + + m.visitVarInsn(Opcodes.ILOAD, 3); + m.visitInsn(Opcodes.ICONST_1); + m.visitInsn(Opcodes.IAND); + final 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", "", "(J)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/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java index a7a05cf75b..6627ffe5a3 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 @@ -105,8 +105,7 @@ public void match(final MethodNode methodNode, } final Set ignore = new HashSet(); - final int maskVar = Type.getMethodType(methodNode.desc) - .getArgumentTypes().length - (constructor ? 1 : 2); + final int maskVar = maskVar(methodNode.desc, constructor); while (true) { if (cursor.getOpcode() != Opcodes.ILOAD) { break; @@ -129,6 +128,22 @@ public void match(final MethodNode methodNode, output.ignore(i, i); } } + + private static int maskVar(final String desc, + final boolean constructor) { + int slot = 0; + if (constructor) { + // one slot for reference to current object + slot++; + } + final Type[] argumentTypes = Type.getMethodType(desc) + .getArgumentTypes(); + final int penultimateArgument = argumentTypes.length - 2; + for (int i = 0; i < penultimateArgument; i++) { + slot += argumentTypes[i].getSize(); + } + return slot; + } } } diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 9211acd2ac..a8e69ce135 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -36,6 +36,10 @@

Fixed bugs

(GitHub #888).
  • Instrumentation should update indexes of local variables in annotations (GitHub #894).
  • +
  • Branches added by the Kotlin compiler for functions with default arguments + and containing arguments of type long or double + should be filtered out during generation of report + (GitHub #908).
  • Release 0.8.4 (2019/05/08)