From 219088deac4b5af5d5c7346da65042894585d5c4 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:26:40 +0200 Subject: Do not filter out synthetic constructors that contain values of default arguments in Kotlin (#888) --- .../filter/KotlinDefaultArgumentsFilter.java | 37 +++++++++++++++------- .../internal/analysis/filter/SyntheticFilter.java | 7 +++- 2 files changed, 32 insertions(+), 12 deletions(-) (limited to 'org.jacoco.core/src/org/jacoco/core/internal/analysis') diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java index 34f9562c..a7a05cf7 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java @@ -38,14 +38,28 @@ import org.objectweb.asm.tree.VarInsnNode; * * * Where maskVar is penultimate argument of synthetic method with - * suffix "$default". And its value can't be zero - invocation with all - * arguments uses original non synthetic method, thus IFEQ - * instructions should be ignored. + * suffix "$default" or of synthetic constructor with last argument + * "kotlin.jvm.internal.DefaultConstructorMarker". And its value can't be zero - + * invocation with all arguments uses original non synthetic method, thus + * IFEQ instructions should be ignored. */ public final class KotlinDefaultArgumentsFilter implements IFilter { - static boolean isDefaultArgumentsMethodName(final String methodName) { - return methodName.endsWith("$default"); + static boolean isDefaultArgumentsMethod(final MethodNode methodNode) { + return methodNode.name.endsWith("$default"); + } + + static boolean isDefaultArgumentsConstructor(final MethodNode methodNode) { + if (!"".equals(methodNode.name)) { + return false; + } + final Type[] argumentTypes = Type.getMethodType(methodNode.desc) + .getArgumentTypes(); + if (argumentTypes.length < 2) { + return false; + } + return "kotlin.jvm.internal.DefaultConstructorMarker" + .equals(argumentTypes[argumentTypes.length - 1].getClassName()); } public void filter(final MethodNode methodNode, @@ -53,19 +67,20 @@ public final class KotlinDefaultArgumentsFilter implements IFilter { if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) { return; } - if (!isDefaultArgumentsMethodName(methodNode.name)) { - return; - } if (!KotlinGeneratedFilter.isKotlinClass(context)) { return; } - new Matcher().match(methodNode, output); + if (isDefaultArgumentsMethod(methodNode)) { + new Matcher().match(methodNode, output, false); + } else if (isDefaultArgumentsConstructor(methodNode)) { + new Matcher().match(methodNode, output, true); + } } private static class Matcher extends AbstractMatcher { public void match(final MethodNode methodNode, - final IFilterOutput output) { + final IFilterOutput output, final boolean constructor) { cursor = methodNode.instructions.getFirst(); nextIs(Opcodes.IFNULL); @@ -91,7 +106,7 @@ public final class KotlinDefaultArgumentsFilter implements IFilter { final Set ignore = new HashSet(); final int maskVar = Type.getMethodType(methodNode.desc) - .getArgumentTypes().length - 2; + .getArgumentTypes().length - (constructor ? 1 : 2); while (true) { if (cursor.getOpcode() != Opcodes.ILOAD) { break; 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 69c4092a..46d4e6eb 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 @@ -31,7 +31,12 @@ public final class SyntheticFilter implements IFilter { if (KotlinGeneratedFilter.isKotlinClass(context)) { if (KotlinDefaultArgumentsFilter - .isDefaultArgumentsMethodName(methodNode.name)) { + .isDefaultArgumentsMethod(methodNode)) { + return; + } + + if (KotlinDefaultArgumentsFilter + .isDefaultArgumentsConstructor(methodNode)) { return; } -- cgit v1.2.3