diff options
author | Evgeny Mandrikov <138671+Godin@users.noreply.github.com> | 2019-01-08 20:47:27 +0100 |
---|---|---|
committer | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2019-01-08 20:47:27 +0100 |
commit | 45efe1ec7a8f182e5d80a89ce306f8958b047140 (patch) | |
tree | fb53f1b023f56cb97b072f2f94cc84efb63fe4f5 | |
parent | 2458e8a4e467a5afc376b56a4e487ac54de0158e (diff) | |
download | platform_external_jacoco-45efe1ec7a8f182e5d80a89ce306f8958b047140.tar.gz platform_external_jacoco-45efe1ec7a8f182e5d80a89ce306f8958b047140.tar.bz2 platform_external_jacoco-45efe1ec7a8f182e5d80a89ce306f8958b047140.zip |
Add filter for Kotlin not-null assertion operator (#815)
6 files changed, 169 insertions, 0 deletions
diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinNotNullOperatorTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinNotNullOperatorTest.java new file mode 100644 index 00000000..d2fb7162 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinNotNullOperatorTest.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation.kotlin; + +import org.jacoco.core.test.validation.ValidationTestBase; +import org.jacoco.core.test.validation.kotlin.targets.KotlinNotNullOperatorTarget; + +/** + * Test of not-null assertion operator. + */ +public class KotlinNotNullOperatorTest extends ValidationTestBase { + + public KotlinNotNullOperatorTest() { + super(KotlinNotNullOperatorTarget.class); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinNotNullOperatorTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinNotNullOperatorTarget.kt new file mode 100644 index 00000000..23681de4 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinNotNullOperatorTarget.kt @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation.kotlin.targets + +/** + * Test target for not-null assertion operator. + */ +object KotlinNotNullOperatorTarget { + + private fun example(x: String?): Int { + return x!!.length // assertFullyCovered() + } + + @JvmStatic + fun main(args: Array<String>) { + example("") + try { + example(null) + } catch (e: NullPointerException) { + } + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilterTest.java new file mode 100644 index 00000000..4e40caed --- /dev/null +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilterTest.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis.filter; + +import org.jacoco.core.internal.instr.InstrSupport; +import org.junit.Test; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.MethodNode; + +/** + * Unit tests for {@link KotlinNotNullOperatorFilter}. + */ +public class KotlinNotNullOperatorFilterTest extends FilterTestBase { + + private final KotlinNotNullOperatorFilter filter = new KotlinNotNullOperatorFilter(); + + private final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "example", "()V", null, null); + + /** + * <pre> + * return x!!.length + * </pre> + */ + @Test + public void should_filter() { + m.visitVarInsn(Opcodes.ALOAD, 1); + m.visitInsn(Opcodes.DUP); + + final Range range = new Range(); + final Label label = new Label(); + m.visitJumpInsn(Opcodes.IFNONNULL, label); + range.fromInclusive = m.instructions.getLast(); + // no line number here and hence no probe + m.visitMethodInsn(Opcodes.INVOKESTATIC, + "kotlin/jvm/internal/Intrinsics", "throwNpe", "()V", false); + range.toInclusive = m.instructions.getLast(); + + m.visitLabel(label); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "length", + "()I", false); + m.visitInsn(Opcodes.IRETURN); + + filter.filter(m, context, output); + + assertIgnored(range); + } + +} 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 a1116548..2f071942 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 @@ -42,6 +42,7 @@ public final class Filters implements IFilter { new KotlinLateinitFilter(), new KotlinWhenFilter(), new KotlinWhenStringFilter(), new KotlinUnsafeCastOperatorFilter(), + new KotlinNotNullOperatorFilter(), new KotlinDefaultArgumentsFilter(), new KotlinInlineFilter(), new KotlinCoroutineFilter()); } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilter.java new file mode 100644 index 00000000..2a96bfb9 --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilter.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis.filter; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.MethodNode; + +/** + * Filters branch in bytecode that Kotlin compiler generates for not-null + * assertion operator. + */ +public final class KotlinNotNullOperatorFilter implements IFilter { + + public void filter(final MethodNode methodNode, + final IFilterContext context, final IFilterOutput output) { + final Matcher matcher = new Matcher(); + for (AbstractInsnNode i = methodNode.instructions + .getFirst(); i != null; i = i.getNext()) { + matcher.match(i, output); + } + } + + private static class Matcher extends AbstractMatcher { + public void match(final AbstractInsnNode start, + final IFilterOutput output) { + if (Opcodes.IFNONNULL != start.getOpcode()) { + return; + } + cursor = start; + nextIsInvokeStatic("kotlin/jvm/internal/Intrinsics", "throwNpe"); + if (cursor == null) { + return; + } + output.ignore(start, cursor); + } + } + +} diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 58d87c84..cc483851 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -27,6 +27,9 @@ <li>Branch added by the Kotlin compiler for "unsafe" cast operator is filtered out during generation of report (GitHub <a href="https://github.com/jacoco/jacoco/issues/761">#761</a>).</li> + <li>Branch added by the Kotlin compiler for not-null assertion operator is + filtered out during generation of report + (GitHub <a href="https://github.com/jacoco/jacoco/issues/815">#815</a>).</li> <li>Instructions inlined by Kotlin compiler are filtered out during generation of report (GitHub <a href="https://github.com/jacoco/jacoco/issues/764">#764</a>).</li> |