diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCoroutineTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCoroutineTarget.kt index 2b2c2a0fd..07e94bf53 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCoroutineTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCoroutineTarget.kt @@ -19,7 +19,8 @@ import org.jacoco.core.test.validation.targets.Stubs.nop */ object KotlinCoroutineTarget { - suspend fun suspendingFunction() { + private suspend fun suspendingFunction() { + nop() // assertFullyCovered() } @JvmStatic 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 9b70b70a1..d0bb2667b 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 @@ -82,4 +82,19 @@ public void should_filter_synthetic_method_with_suffix_default_in_non_kotlin_cla assertMethodIgnored(m); } + @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", + "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", null, + null); + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + m.visitInsn(Opcodes.NOP); + + filter.filter(m, context, output); + + assertIgnored(); + } + } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java index f1261b225..d9944bf53 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java @@ -15,6 +15,7 @@ import java.util.List; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.LdcInsnNode; @@ -26,6 +27,13 @@ */ public final class KotlinCoroutineFilter implements IFilter { + static boolean isLastArgumentContinuation(final MethodNode methodNode) { + final Type methodType = Type.getMethodType(methodNode.desc); + final int lastArgument = methodType.getArgumentTypes().length - 1; + return lastArgument >= 0 && "kotlin.coroutines.Continuation".equals( + methodType.getArgumentTypes()[lastArgument].getClassName()); + } + public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { 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 5dfeecf5e..34a66b18e 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 @@ -29,10 +29,15 @@ public void filter(final MethodNode methodNode, return; } - if (KotlinDefaultArgumentsFilter - .isDefaultArgumentsMethodName(methodNode.name) - && KotlinGeneratedFilter.isKotlinClass(context)) { - return; + if (KotlinGeneratedFilter.isKotlinClass(context)) { + if (KotlinDefaultArgumentsFilter + .isDefaultArgumentsMethodName(methodNode.name)) { + return; + } + + if (KotlinCoroutineFilter.isLastArgumentContinuation(methodNode)) { + return; + } } output.ignore(methodNode.instructions.getFirst(), diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 2614497c4..379a6b332 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -42,6 +42,9 @@

Fixed Bugs

Non-functional Changes