aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core.test/src
diff options
context:
space:
mode:
authorEvgeny Mandrikov <138671+Godin@users.noreply.github.com>2020-02-09 20:14:24 +0200
committerGitHub <noreply@github.com>2020-02-09 19:14:23 +0100
commit71f9341e088bb3347ecfea2f114e5e40bdc4326b (patch)
tree95a052f842c76f044447bceddb5f71f400253381 /org.jacoco.core.test/src
parent04fe2006c0786a96462ef7336d162e4a527759e0 (diff)
downloadjacoco-71f9341e088bb3347ecfea2f114e5e40bdc4326b.tar.gz
Update filter for suspending functions with tail call optimization (#1016)
Diffstat (limited to 'org.jacoco.core.test/src')
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java76
1 files changed, 76 insertions, 0 deletions
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java
index c8ba9eb3..4f471c3c 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java
@@ -374,4 +374,80 @@ public class KotlinCoroutineFilterTest extends FilterTestBase {
assertIgnored(range0, range1, range2);
}
+ /**
+ * <pre>
+ * suspend fun example(b: Boolean) {
+ * if (b)
+ * suspendingFunction()
+ * else
+ * suspendingFunction()
+ * }
+ * </pre>
+ */
+ @Test
+ public void should_filter_suspending_functions_with_tail_call_optimization() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "example",
+ "(ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;", null,
+ null);
+ context.classAnnotations
+ .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
+
+ final Label exit = new Label();
+
+ m.visitVarInsn(Opcodes.ILOAD, 1);
+ final Label next = new Label();
+ m.visitJumpInsn(Opcodes.IFEQ, next);
+
+ m.visitVarInsn(Opcodes.ALOAD, 0);
+ m.visitVarInsn(Opcodes.ALOAD, 2);
+ m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "", "suspendingFunction",
+ "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", false);
+ final Range range1 = new Range();
+ {
+ m.visitInsn(Opcodes.DUP);
+ range1.fromInclusive = m.instructions.getLast();
+ m.visitMethodInsn(Opcodes.INVOKESTATIC,
+ "kotlin/coroutines/intrinsics/IntrinsicsKt",
+ "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;", false);
+ final Label label = new Label();
+ m.visitJumpInsn(Opcodes.IF_ACMPNE, label);
+ m.visitInsn(Opcodes.ARETURN);
+ m.visitLabel(label);
+ m.visitInsn(Opcodes.POP);
+ range1.toInclusive = m.instructions.getLast();
+ }
+
+ m.visitJumpInsn(Opcodes.GOTO, exit);
+ m.visitLabel(next);
+
+ m.visitVarInsn(Opcodes.ALOAD, 0);
+ m.visitVarInsn(Opcodes.ALOAD, 2);
+ m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "", "suspendingFunction",
+ "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", false);
+ final Range range2 = new Range();
+ {
+ m.visitInsn(Opcodes.DUP);
+ range2.fromInclusive = m.instructions.getLast();
+ m.visitMethodInsn(Opcodes.INVOKESTATIC,
+ "kotlin/coroutines/intrinsics/IntrinsicsKt",
+ "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;", false);
+ final Label label = new Label();
+ m.visitJumpInsn(Opcodes.IF_ACMPNE, label);
+ m.visitInsn(Opcodes.ARETURN);
+ m.visitLabel(label);
+ m.visitInsn(Opcodes.POP);
+ range2.toInclusive = m.instructions.getLast();
+ }
+
+ m.visitLabel(exit);
+ m.visitFieldInsn(Opcodes.GETSTATIC, "kotlin/Unit", "INSTANCE",
+ "Lkotlin/Unit;");
+ m.visitInsn(Opcodes.ARETURN);
+
+ filter.filter(m, context, output);
+
+ assertIgnored(range1, range2);
+ }
+
}