diff options
author | Evgeny Mandrikov <Godin@users.noreply.github.com> | 2018-08-18 20:07:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-18 20:07:22 +0200 |
commit | 215f7668ed71165375b2cf804ae0974647050a25 (patch) | |
tree | 83efeaf549e6999ad76ab10ecc5defbca695fa43 /org.jacoco.core/src | |
parent | 32073eafa35718ef7a95df979f2202282e1e4eb1 (diff) | |
download | jacoco-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.java | 2 | ||||
-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; + } + } |