aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/dependabot.yml2
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--org.jacoco.build/pom.xml45
-rw-r--r--org.jacoco.core.test.validation.kotlin/pom.xml2
-rw-r--r--org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineClassTest.java27
-rw-r--r--org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineClassTarget.kt75
-rw-r--r--org.jacoco.core.test.validation/pom.xml4
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilterTest.java98
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java1
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilter.java89
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html3
11 files changed, 344 insertions, 6 deletions
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 2983a7be..0cdb0983 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -23,6 +23,6 @@ updates:
labels:
- "dependencies"
- "component: test"
- - "language: kotlin"
+ - "language: Kotlin"
allow:
- dependency-name: "org.jetbrains.kotlin:*"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 911151c7..1f005398 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,7 +15,7 @@ jobs:
name: JDK ${{ matrix.jdk }}
runs-on: ubuntu-20.04
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
with:
distribution: 'zulu'
@@ -49,7 +49,7 @@ jobs:
Windows:
runs-on: windows-2022
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
with:
distribution: 'zulu'
diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml
index 1a0e8448..053edfe7 100644
--- a/org.jacoco.build/pom.xml
+++ b/org.jacoco.build/pom.xml
@@ -762,6 +762,27 @@
</properties>
</profile>
+ <profile>
+ <id>maven-jdk23</id>
+ <activation>
+ <jdk>[23,)</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <additionalOptions>
+ <!-- https://bugs.openjdk.org/browse/JDK-8324774 -->
+ <option>--no-fonts</option>
+ </additionalOptions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
<!--
Following profile is automatically activated in IntelliJ IDEA
and used to set the correct Java language level in it
@@ -1035,6 +1056,30 @@
</properties>
</profile>
+ <profile>
+ <id>jdk23</id>
+ <activation>
+ <property>
+ <name>jdk.version</name>
+ <value>23</value>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <additionalOptions>
+ <!-- https://bugs.openjdk.org/browse/JDK-8324774 -->
+ <option>--no-fonts</option>
+ </additionalOptions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
<!-- This profile enables generation of JARs with sources and javadocs -->
<profile>
<id>sources</id>
diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml
index 00f7845a..4d6143ec 100644
--- a/org.jacoco.core.test.validation.kotlin/pom.xml
+++ b/org.jacoco.core.test.validation.kotlin/pom.xml
@@ -25,7 +25,7 @@
<name>JaCoCo :: Test :: Core :: Validation Kotlin</name>
<properties>
- <kotlin.version>1.9.23</kotlin.version>
+ <kotlin.version>1.9.24</kotlin.version>
</properties>
<dependencies>
diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineClassTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineClassTest.java
new file mode 100644
index 00000000..908ad782
--- /dev/null
+++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineClassTest.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2024 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * 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.KotlinInlineClassTarget;
+
+/**
+ * Test of code coverage in {@link KotlinInlineClassTarget}.
+ */
+public class KotlinInlineClassTest extends ValidationTestBase {
+
+ public KotlinInlineClassTest() {
+ super(KotlinInlineClassTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineClassTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineClassTarget.kt
new file mode 100644
index 00000000..079fa6d9
--- /dev/null
+++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineClassTarget.kt
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2024 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.test.validation.kotlin.targets
+
+import org.jacoco.core.test.validation.targets.Stubs.nop
+
+/**
+ * Test target for `inline class`.
+ */
+object KotlinInlineClassTarget {
+
+ interface Base {
+ fun base()
+ }
+
+ @JvmInline
+ value class I1(val value: String) : Base { // assertEmpty()
+
+ init { // assertEmpty()
+ nop() // assertFullyCovered()
+ } // assertEmpty()
+
+ constructor() : this("") { // assertFullyCovered()
+ nop() // assertFullyCovered()
+ } // assertEmpty()
+
+ val length: Int // assertEmpty()
+ get() = value.length // assertFullyCovered()
+
+ fun f(p: String) { // assertEmpty()
+ nop(p) // assertFullyCovered()
+ } // assertFullyCovered()
+
+ fun f(p: I1) { // assertEmpty()
+ nop(p) // assertFullyCovered()
+ } // assertFullyCovered()
+
+ override fun base() { // assertEmpty()
+ nop() // assertFullyCovered()
+ } // assertFullyCovered()
+
+ } // assertEmpty()
+
+ @JvmInline
+ value class I2(val value: String) { // assertEmpty()
+
+ override fun toString(): String { // assertEmpty()
+ return "Value: $value" // assertNotCovered()
+ } // assertEmpty()
+
+ } // assertEmpty()
+
+ @JvmStatic
+ fun main(args: Array<String>) {
+ val i = I1()
+ i.value
+ i.length
+ i.f("")
+ i.f(i)
+ i.base()
+
+ I2("")
+ }
+
+}
diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml
index c6526019..5f1b6b45 100644
--- a/org.jacoco.core.test.validation/pom.xml
+++ b/org.jacoco.core.test.validation/pom.xml
@@ -476,7 +476,7 @@
</property>
</activation>
<properties>
- <!-- Kotlin 1.9.23 doesn't support compilation into 22 -->
+ <!-- Kotlin 1.9.24 doesn't support compilation into 22 -->
<kotlin.compiler.jvmTarget>21</kotlin.compiler.jvmTarget>
<!-- Groovy 3.0.20 does not support compilation into 22 -->
<groovy.targetBytecode>16</groovy.targetBytecode>
@@ -507,7 +507,7 @@
</property>
</activation>
<properties>
- <!-- Kotlin 1.9.23 doesn't support compilation into 23 -->
+ <!-- Kotlin 1.9.24 doesn't support compilation into 23 -->
<kotlin.compiler.jvmTarget>21</kotlin.compiler.jvmTarget>
<!-- Groovy 3.0.20 does not support compilation into 23 -->
<groovy.targetBytecode>16</groovy.targetBytecode>
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilterTest.java
new file mode 100644
index 00000000..8fd77a0a
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilterTest.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2024 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Unit tests for {@link KotlinInlineClassFilter}.
+ */
+public class KotlinInlineClassFilterTest extends FilterTestBase {
+
+ private final IFilter filter = new KotlinInlineClassFilter();
+
+ /**
+ * <pre>
+ * &#064;kotlin.jvm.JvmInline
+ * value class Example(val value: String)
+ * </pre>
+ */
+ @Test
+ public void should_filter() {
+ context.classAnnotations
+ .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
+ context.classAnnotations.add("Lkotlin/jvm/JvmInline;");
+ final MethodNode m = new MethodNode(0, "getValue",
+ "()Ljava/lang/String;", null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter(m, context, output);
+
+ assertMethodIgnored(m);
+ }
+
+ /**
+ * <pre>
+ * &#064;kotlin.jvm.JvmInline
+ * value class Example(val value: String) {
+ * fun f() { ... }
+ * }
+ * </pre>
+ */
+ @Test
+ public void should_not_filter_static() {
+ context.classAnnotations
+ .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
+ context.classAnnotations.add("Lkotlin/jvm/JvmInline;");
+ final MethodNode m = new MethodNode(Opcodes.ACC_STATIC, "f-impl", "()V",
+ null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter(m, context, output);
+
+ assertIgnored();
+ }
+
+ /**
+ * <pre>
+ * data class Example(val value: String)
+ * </pre>
+ */
+ @Test
+ public void should_not_filter_when_no_JvmInline_annotation() {
+ context.classAnnotations
+ .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
+ final MethodNode m = new MethodNode(0, "getValue",
+ "()Ljava/lang/String;", null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter(m, context, output);
+
+ assertIgnored();
+ }
+
+ @Test
+ public void should_not_filter_when_not_kotlin() {
+ context.classAnnotations.add("Lkotlin/jvm/JvmInline;");
+ final MethodNode m = new MethodNode(0, "getValue",
+ "()Ljava/lang/String;", null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter(m, context, output);
+
+ assertIgnored();
+ }
+
+}
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 07268c41..c644d9f8 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
@@ -47,6 +47,7 @@ public final class Filters implements IFilter {
new KotlinWhenStringFilter(),
new KotlinUnsafeCastOperatorFilter(),
new KotlinNotNullOperatorFilter(),
+ new KotlinInlineClassFilter(),
new KotlinDefaultArgumentsFilter(), new KotlinInlineFilter(),
new KotlinCoroutineFilter(), new KotlinDefaultMethodsFilter(),
new KotlinComposeFilter());
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilter.java
new file mode 100644
index 00000000..0279e047
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2024 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Filters methods that Kotlin compiler generates for inline classes.
+ *
+ * For
+ *
+ * <pre>
+ * &#064;kotlin.jvm.JvmInline
+ * value class Example(val value: String) : Base {
+ * fun f(p: String) { ... }
+ * fun f(p: Example) { ... }
+ * override fun base() { ... }
+ * }
+ * </pre>
+ *
+ * Kotlin compiler produces
+ *
+ * <pre>
+ * &#064;kotlin.jvm.JvmInline
+ * class Example implements Base {
+ * private final String value;
+ * public String getValue() { return value; }
+ *
+ * private synthetic Example(String value) { this.value = value; }
+ *
+ * public static String constructor-impl(String value) { ... }
+ *
+ * public static void f-impl(String value, String p) { ... }
+ *
+ * public static void f-ulP-heY(String value, String p) { ... }
+ *
+ * public void base() { base-impl(value); }
+ * public static void base-impl(String value) { ... }
+ *
+ * public String toString() { return toString-impl(value); }
+ * public static String toString-impl(String value) { ... }
+ *
+ * public boolean equals(Object other) { return equals-impl(value, other); }
+ * public static boolean equals-impl(String value, Object other) { ... }
+ *
+ * public int hashCode() { return hashCode-impl(value); }
+ * public static int hashCode-impl(String value) { ... }
+ *
+ * public final synthetic String unbox-impl() { return value; }
+ * public static synthetic Example box-impl(String value) { return new Example(value); }
+ *
+ * public static equals-impl0(String value1, String value2) { ... }
+ * }
+ * </pre>
+ *
+ * Except getter all non-synthetic non-static methods delegate to corresponding
+ * static methods. Non-static methods are provided for interoperability with
+ * Java and can not be invoked from Kotlin without reflection and so should be
+ * filtered out.
+ */
+final class KotlinInlineClassFilter implements IFilter {
+
+ public void filter(final MethodNode methodNode,
+ final IFilterContext context, final IFilterOutput output) {
+ if (!KotlinGeneratedFilter.isKotlinClass(context)) {
+ return;
+ }
+ if (!context.getClassAnnotations().contains("Lkotlin/jvm/JvmInline;")) {
+ return;
+ }
+ if ((methodNode.access & Opcodes.ACC_STATIC) != 0) {
+ return;
+ }
+ output.ignore(methodNode.instructions.getFirst(),
+ methodNode.instructions.getLast());
+ }
+
+}
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index e5a53ba9..f958060c 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -25,6 +25,9 @@
<li>Part of bytecode generated by the Kotlin Compose compiler plugin is
filtered out during generation of report
(GitHub <a href="https://github.com/jacoco/jacoco/issues/1616">#1616</a>).</li>
+ <li>Part of bytecode generated by the Kotlin compiler for inline value classes is
+ filtered out during generation of report
+ (GitHub <a href="https://github.com/jacoco/jacoco/issues/1475">#1475</a>).</li>
</ul>
<h2>Release 0.8.12 (2024/03/31)</h2>