aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core/src
diff options
context:
space:
mode:
authorEvgeny Mandrikov <Godin@users.noreply.github.com>2018-08-18 20:07:22 +0200
committerGitHub <noreply@github.com>2018-08-18 20:07:22 +0200
commit215f7668ed71165375b2cf804ae0974647050a25 (patch)
tree83efeaf549e6999ad76ab10ecc5defbca695fa43 /org.jacoco.core/src
parent32073eafa35718ef7a95df979f2202282e1e4eb1 (diff)
downloadjacoco-215f7668ed71165375b2cf804ae0974647050a25.tar.gz
Add filter for Kotlin when-expressions that list all cases of enum (#729)
Diffstat (limited to 'org.jacoco.core/src')
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java2
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java (renamed from org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenSealedFilter.java)57
2 files changed, 55 insertions, 4 deletions
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
index a8446eac..03c85d7d 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
@@ -34,7 +34,7 @@ public final class Filters implements IFilter {
new StringSwitchJavacFilter(), new StringSwitchEcjFilter(),
new EnumEmptyConstructorFilter(), new AnnotationGeneratedFilter(),
new KotlinGeneratedFilter(), new KotlinLateinitFilter(),
- new KotlinWhenSealedFilter(), new KotlinWhenStringFilter());
+ new KotlinWhenFilter(), new KotlinWhenStringFilter());
private final IFilter[] filters;
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenSealedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java
index ae0d8455..24b90c0e 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenSealedFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java
@@ -11,18 +11,26 @@
*******************************************************************************/
package org.jacoco.core.internal.analysis.filter;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.LookupSwitchInsnNode;
import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TableSwitchInsnNode;
/**
* Filters bytecode that Kotlin compiler generates for <code>when</code>
- * expressions which list all cases of <code>sealed class</code>, i.e. which
- * don't require explicit <code>else</code>.
+ * expressions which list all cases of <code>enum</code> or
+ * <code>sealed class</code>, i.e. which don't require explicit
+ * <code>else</code>.
*/
-public final class KotlinWhenSealedFilter implements IFilter {
+public final class KotlinWhenFilter implements IFilter {
private static final String EXCEPTION = "kotlin/NoWhenBranchMatchedException";
@@ -54,9 +62,52 @@ public final class KotlinWhenSealedFilter implements IFilter {
output.ignore(i, i);
output.ignore(start, cursor);
return;
+
+ } else if (getDefaultLabel(i) == start) {
+ ignoreDefaultBranch(i, output);
+ output.ignore(start, cursor);
+ return;
+
}
}
}
}
+ private static LabelNode getDefaultLabel(final AbstractInsnNode i) {
+ switch (i.getOpcode()) {
+ case Opcodes.LOOKUPSWITCH:
+ return ((LookupSwitchInsnNode) i).dflt;
+ case Opcodes.TABLESWITCH:
+ return ((TableSwitchInsnNode) i).dflt;
+ default:
+ return null;
+ }
+ }
+
+ private static void ignoreDefaultBranch(final AbstractInsnNode switchNode,
+ final IFilterOutput output) {
+ final List<LabelNode> labels;
+ if (switchNode.getOpcode() == Opcodes.LOOKUPSWITCH) {
+ labels = ((LookupSwitchInsnNode) switchNode).labels;
+ } else {
+ labels = ((TableSwitchInsnNode) switchNode).labels;
+ }
+ final Set<AbstractInsnNode> newTargets = new HashSet<AbstractInsnNode>();
+ for (LabelNode label : labels) {
+ newTargets.add(instructionAfterLabel(label));
+ }
+ output.replaceBranches(switchNode, newTargets);
+ }
+
+ private static AbstractInsnNode instructionAfterLabel(
+ final LabelNode label) {
+ AbstractInsnNode i = label.getNext();
+ while (i.getType() == AbstractInsnNode.FRAME
+ || i.getType() == AbstractInsnNode.LABEL
+ || i.getType() == AbstractInsnNode.LINE) {
+ i = i.getNext();
+ }
+ return i;
+ }
+
}