aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core/src/org
diff options
context:
space:
mode:
authorEvgeny Mandrikov <Godin@users.noreply.github.com>2018-12-30 09:17:58 +0100
committerMarc R. Hoffmann <hoffmann@mountainminds.com>2018-12-30 09:17:58 +0100
commit9c45dab3e9d9ed888481005095b30d3e5b55b338 (patch)
treeec387806eead8727a95970b017fa3bec3376679f /org.jacoco.core/src/org
parentfd90e3ee3404d4996f42fa95eef32c45464592bb (diff)
downloadjacoco-9c45dab3e9d9ed888481005095b30d3e5b55b338.tar.gz
Update filter for Kotlin suspending functions (#809)
Diffstat (limited to 'org.jacoco.core/src/org')
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java65
1 files changed, 60 insertions, 5 deletions
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 d9944bf5..51943ef9 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
@@ -41,10 +41,6 @@ public final class KotlinCoroutineFilter implements IFilter {
return;
}
- if (!"invokeSuspend".equals(methodNode.name)) {
- return;
- }
-
new Matcher().match(methodNode, output);
}
@@ -55,6 +51,16 @@ public final class KotlinCoroutineFilter implements IFilter {
cursor = methodNode.instructions.getFirst();
nextIsInvokeStatic("kotlin/coroutines/intrinsics/IntrinsicsKt",
"getCOROUTINE_SUSPENDED");
+
+ if (cursor == null) {
+ cursor = skipNonOpcodes(methodNode.instructions.getFirst());
+
+ nextIsCreateStateInstance();
+
+ nextIsInvokeStatic("kotlin/coroutines/intrinsics/IntrinsicsKt",
+ "getCOROUTINE_SUSPENDED");
+ }
+
nextIsVar(Opcodes.ASTORE, "COROUTINE_SUSPENDED");
nextIsVar(Opcodes.ALOAD, "this");
nextIs(Opcodes.GETFIELD);
@@ -78,7 +84,7 @@ public final class KotlinCoroutineFilter implements IFilter {
if (cursor == null) {
return;
}
- ignore.add(s);
+ ignore.add(methodNode.instructions.getFirst());
ignore.add(cursor);
int suspensionPoint = 1;
@@ -142,6 +148,55 @@ public final class KotlinCoroutineFilter implements IFilter {
output.ignore(ignore.get(i), ignore.get(i + 1));
}
}
+
+ private void nextIsCreateStateInstance() {
+ nextIs(Opcodes.INSTANCEOF);
+
+ nextIs(Opcodes.IFEQ);
+ if (cursor == null) {
+ return;
+ }
+ final AbstractInsnNode createStateInstance = skipNonOpcodes(
+ ((JumpInsnNode) cursor).label);
+
+ nextIs(Opcodes.ALOAD);
+ nextIs(Opcodes.CHECKCAST);
+ nextIs(Opcodes.ASTORE);
+
+ nextIs(Opcodes.ALOAD);
+ nextIs(Opcodes.GETFIELD);
+
+ nextIs(Opcodes.LDC);
+ nextIs(Opcodes.IAND);
+ nextIs(Opcodes.IFEQ);
+ if (cursor == null || skipNonOpcodes(
+ ((JumpInsnNode) cursor).label) != createStateInstance) {
+ return;
+ }
+
+ nextIs(Opcodes.ALOAD);
+ nextIs(Opcodes.DUP);
+ nextIs(Opcodes.GETFIELD);
+
+ nextIs(Opcodes.LDC);
+ nextIs(Opcodes.ISUB);
+ nextIs(Opcodes.PUTFIELD);
+
+ nextIs(Opcodes.GOTO);
+ if (cursor == null) {
+ return;
+ }
+ final AbstractInsnNode afterCoroutineStateCreated = skipNonOpcodes(
+ ((JumpInsnNode) cursor).label);
+
+ if (skipNonOpcodes(cursor.getNext()) != createStateInstance) {
+ return;
+ }
+
+ cursor = afterCoroutineStateCreated;
+ nextIs(Opcodes.GETFIELD);
+ nextIs(Opcodes.ASTORE);
+ }
}
}