From 337c80f7c01ce699b1a8eb7916f03aa74c02eaed Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Sun, 31 Mar 2024 22:09:29 +0200 Subject: [PATCH 001/163] Prepare for next development iteration --- jacoco-maven-plugin.test/pom.xml | 2 +- jacoco-maven-plugin/pom.xml | 2 +- jacoco/pom.xml | 2 +- org.jacoco.agent.rt.test/pom.xml | 2 +- org.jacoco.agent.rt/pom.xml | 2 +- org.jacoco.agent.test/pom.xml | 2 +- org.jacoco.agent/pom.xml | 2 +- org.jacoco.ant.test/pom.xml | 2 +- org.jacoco.ant/pom.xml | 2 +- org.jacoco.build/pom.xml | 2 +- org.jacoco.cli.test/pom.xml | 2 +- org.jacoco.cli/pom.xml | 2 +- org.jacoco.core.test.validation.groovy/pom.xml | 2 +- org.jacoco.core.test.validation.java14/pom.xml | 2 +- org.jacoco.core.test.validation.java16/pom.xml | 2 +- org.jacoco.core.test.validation.java21/pom.xml | 2 +- org.jacoco.core.test.validation.java5/pom.xml | 2 +- org.jacoco.core.test.validation.java7/pom.xml | 2 +- org.jacoco.core.test.validation.java8/pom.xml | 2 +- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- org.jacoco.core.test.validation.scala/pom.xml | 2 +- org.jacoco.core.test.validation/pom.xml | 2 +- org.jacoco.core.test/pom.xml | 2 +- org.jacoco.core/pom.xml | 2 +- org.jacoco.doc/docroot/doc/changes.html | 2 ++ org.jacoco.doc/pom.xml | 2 +- org.jacoco.examples.test/pom.xml | 2 +- org.jacoco.examples/pom.xml | 2 +- org.jacoco.report.test/pom.xml | 2 +- org.jacoco.report/pom.xml | 2 +- org.jacoco.tests/pom.xml | 2 +- pom.xml | 2 +- 32 files changed, 33 insertions(+), 31 deletions(-) diff --git a/jacoco-maven-plugin.test/pom.xml b/jacoco-maven-plugin.test/pom.xml index b469b2f8bb..ffca23e99c 100644 --- a/jacoco-maven-plugin.test/pom.xml +++ b/jacoco-maven-plugin.test/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/jacoco-maven-plugin/pom.xml b/jacoco-maven-plugin/pom.xml index e40e225fac..6eb088957c 100644 --- a/jacoco-maven-plugin/pom.xml +++ b/jacoco-maven-plugin/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/jacoco/pom.xml b/jacoco/pom.xml index ce63e89882..7d919d08c4 100644 --- a/jacoco/pom.xml +++ b/jacoco/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.agent.rt.test/pom.xml b/org.jacoco.agent.rt.test/pom.xml index 5e56469027..9fbc61edd5 100644 --- a/org.jacoco.agent.rt.test/pom.xml +++ b/org.jacoco.agent.rt.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/org.jacoco.agent.rt/pom.xml b/org.jacoco.agent.rt/pom.xml index 91bdc54cfa..9a42d840b6 100644 --- a/org.jacoco.agent.rt/pom.xml +++ b/org.jacoco.agent.rt/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.agent.test/pom.xml b/org.jacoco.agent.test/pom.xml index 233a959b29..42da9c26b6 100644 --- a/org.jacoco.agent.test/pom.xml +++ b/org.jacoco.agent.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/org.jacoco.agent/pom.xml b/org.jacoco.agent/pom.xml index b98e2b1ae7..89b5c15754 100644 --- a/org.jacoco.agent/pom.xml +++ b/org.jacoco.agent/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.ant.test/pom.xml b/org.jacoco.ant.test/pom.xml index 72056946f1..0decb5008b 100644 --- a/org.jacoco.ant.test/pom.xml +++ b/org.jacoco.ant.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/org.jacoco.ant/pom.xml b/org.jacoco.ant/pom.xml index 40b3ea51a8..8809fddd1c 100644 --- a/org.jacoco.ant/pom.xml +++ b/org.jacoco.ant/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index fef442fdc7..1ea398c344 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -15,7 +15,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT pom JaCoCo diff --git a/org.jacoco.cli.test/pom.xml b/org.jacoco.cli.test/pom.xml index 28bdfc1cdd..1d532934e3 100644 --- a/org.jacoco.cli.test/pom.xml +++ b/org.jacoco.cli.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/org.jacoco.cli/pom.xml b/org.jacoco.cli/pom.xml index 2aad3c2039..358c2808f4 100644 --- a/org.jacoco.cli/pom.xml +++ b/org.jacoco.cli/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.core.test.validation.groovy/pom.xml b/org.jacoco.core.test.validation.groovy/pom.xml index cfb53753cf..6732b7c5fa 100644 --- a/org.jacoco.core.test.validation.groovy/pom.xml +++ b/org.jacoco.core.test.validation.groovy/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java14/pom.xml b/org.jacoco.core.test.validation.java14/pom.xml index 5553e6b3b7..8d64ec96ec 100644 --- a/org.jacoco.core.test.validation.java14/pom.xml +++ b/org.jacoco.core.test.validation.java14/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java16/pom.xml b/org.jacoco.core.test.validation.java16/pom.xml index 713c2b556c..9e5f095a66 100644 --- a/org.jacoco.core.test.validation.java16/pom.xml +++ b/org.jacoco.core.test.validation.java16/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java21/pom.xml b/org.jacoco.core.test.validation.java21/pom.xml index 0d02516aa7..ccef737085 100644 --- a/org.jacoco.core.test.validation.java21/pom.xml +++ b/org.jacoco.core.test.validation.java21/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java5/pom.xml b/org.jacoco.core.test.validation.java5/pom.xml index 67db528cb3..28822239d0 100644 --- a/org.jacoco.core.test.validation.java5/pom.xml +++ b/org.jacoco.core.test.validation.java5/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java7/pom.xml b/org.jacoco.core.test.validation.java7/pom.xml index 1f8965352f..4877157585 100644 --- a/org.jacoco.core.test.validation.java7/pom.xml +++ b/org.jacoco.core.test.validation.java7/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java8/pom.xml b/org.jacoco.core.test.validation.java8/pom.xml index c060e95edc..4a151e1155 100644 --- a/org.jacoco.core.test.validation.java8/pom.xml +++ b/org.jacoco.core.test.validation.java8/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index e7dfae9ee6..0cebf67846 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.scala/pom.xml b/org.jacoco.core.test.validation.scala/pom.xml index 43e606550e..296202b368 100644 --- a/org.jacoco.core.test.validation.scala/pom.xml +++ b/org.jacoco.core.test.validation.scala/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index eae91b61d4..ad96138fd6 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/org.jacoco.core.test/pom.xml b/org.jacoco.core.test/pom.xml index 0124bf70f3..45a40d90e5 100644 --- a/org.jacoco.core.test/pom.xml +++ b/org.jacoco.core.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/org.jacoco.core/pom.xml b/org.jacoco.core/pom.xml index 76504a1dbd..6857f13c43 100644 --- a/org.jacoco.core/pom.xml +++ b/org.jacoco.core/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index e3a567d5e2..48b2ac196e 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -18,6 +18,8 @@

Change History

+

Snapshot Build @qualified.bundle.version@ (@build.date@)

+

Release 0.8.12 (2024/03/31)

New Features

diff --git a/org.jacoco.doc/pom.xml b/org.jacoco.doc/pom.xml index c18ae75de6..6176308713 100644 --- a/org.jacoco.doc/pom.xml +++ b/org.jacoco.doc/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.examples.test/pom.xml b/org.jacoco.examples.test/pom.xml index 8b927e04ef..45b0b9ffe6 100644 --- a/org.jacoco.examples.test/pom.xml +++ b/org.jacoco.examples.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/org.jacoco.examples/pom.xml b/org.jacoco.examples/pom.xml index eee4d67011..5dbd27cab3 100644 --- a/org.jacoco.examples/pom.xml +++ b/org.jacoco.examples/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.report.test/pom.xml b/org.jacoco.report.test/pom.xml index 2dcac9b32e..40705b1e6d 100644 --- a/org.jacoco.report.test/pom.xml +++ b/org.jacoco.report.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.tests diff --git a/org.jacoco.report/pom.xml b/org.jacoco.report/pom.xml index 6542442bfb..03d0e91820 100644 --- a/org.jacoco.report/pom.xml +++ b/org.jacoco.report/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/org.jacoco.tests/pom.xml b/org.jacoco.tests/pom.xml index 36fac96925..dc6b07372c 100644 --- a/org.jacoco.tests/pom.xml +++ b/org.jacoco.tests/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.build - 0.8.12 + 0.8.13-SNAPSHOT ../org.jacoco.build diff --git a/pom.xml b/pom.xml index 12c371ca79..dc71687067 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.jacoco root - 0.8.12 + 0.8.13-SNAPSHOT pom From 2f7f84172f4127d74b33bd333a9da60c33cc176d Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 9 Apr 2024 11:37:54 +0200 Subject: [PATCH 002/163] Fix build with JDK >= 20 when option `-Dbytecode.version` is not provided (#1605) --- org.jacoco.build/pom.xml | 29 ++++++++++++++++++- org.jacoco.core.test.validation.java7/pom.xml | 18 +++++++++--- org.jacoco.doc/docroot/doc/build.html | 6 ++-- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 1ea398c344..1a0e8448c0 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -744,13 +744,40 @@ maven-jdk12 - [12,) + [12,20) 7 + + + maven-jdk20 + + [20,) + + + 8 + + + + + + intellij + + + idea.maven.embedder.version + + + + 5 + + + integration-tests diff --git a/org.jacoco.core.test.validation.java7/pom.xml b/org.jacoco.core.test.validation.java7/pom.xml index 4877157585..3f7d34dad9 100644 --- a/org.jacoco.core.test.validation.java7/pom.xml +++ b/org.jacoco.core.test.validation.java7/pom.xml @@ -24,14 +24,24 @@ JaCoCo :: Test :: Core :: Validation Java 7 - - 7 - - ${project.groupId} org.jacoco.core.test + + + + intellij + + + idea.maven.embedder.version + + + + 7 + + + diff --git a/org.jacoco.doc/docroot/doc/build.html b/org.jacoco.doc/docroot/doc/build.html index 8cca1348e6..46600cdd1a 100644 --- a/org.jacoco.doc/docroot/doc/build.html +++ b/org.jacoco.doc/docroot/doc/build.html @@ -287,9 +287,9 @@

Compilation and testing with different JDKs

7 7 7 - 7 - 7 - 7 + 8 + 8 + 8 From 92edc21fd80c8080d1ee141a33ef7c7e381197e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 10:30:23 +0200 Subject: [PATCH 003/163] Bump actions/upload-artifact from 4.3.1 to 4.3.3 (#1611) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.1 to 4.3.3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/5d5d22a31266ced268874388b861e4b58bb5c2f3...65462800fd760344b1a7b4382951275a0abb4808) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 980990658f..8d0f929bda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,7 +82,7 @@ jobs: mvn -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 id: artifact-upload-step with: name: jacoco From 230937dc3854055bac57ad600fd585a563397a26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 08:55:45 +0000 Subject: [PATCH 004/163] Bump actions/checkout from 4.1.1 to 4.1.4 (#1613) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/b4ffde65f46336ab88eb53be808477a3936bae11...0ad4b8fadaa221de15dcec353f45205ec38ea70b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d0f929bda..911151c74b 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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - 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@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 with: distribution: 'zulu' From 1ad4a155973702f3714034c9b9ab29788b670c02 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 1 May 2024 07:08:09 +0200 Subject: [PATCH 005/163] Upgrade Kotlin to 1.9.23 (#1567) --- .../pom.xml | 4 +-- .../targets/KotlinWhenExpressionTarget.kt | 3 +- org.jacoco.core.test.validation/pom.xml | 34 +++++++------------ org.jacoco.doc/docroot/doc/build.html | 34 +++++++++---------- 4 files changed, 33 insertions(+), 42 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index 0cebf67846..00f7845aad 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -25,7 +25,7 @@ JaCoCo :: Test :: Core :: Validation Kotlin - 1.5.0 + 1.9.23 @@ -41,7 +41,7 @@ org.jetbrains.kotlinx kotlinx-coroutines-core - 1.0.1 + 1.8.0 diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt index f38b10d4ae..ccf98244bb 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt @@ -63,8 +63,9 @@ object KotlinWhenExpressionTarget { /** * Unlike [whenString] * in this example first case is the only case with biggest hashCode value. + * FIXME https://github.com/jacoco/jacoco/issues/1295 */ - private fun whenStringBiggestHashCodeFirst(p: String): Int = when (p) { // assertFullyCovered(0, 6) + private fun whenStringBiggestHashCodeFirst(p: String): Int = when (p) { // assertPartlyCovered(3, 11) "c" -> 1 // assertFullyCovered() "b" -> 2 // assertFullyCovered() "\u0000b" -> 3 // assertFullyCovered() diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index ad96138fd6..c652601969 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -34,7 +34,6 @@ true - 1.6 1.8 @@ -68,10 +67,8 @@ - 1.6 - ../org.jacoco.core.test.validation.kotlin
@@ -84,7 +81,6 @@ - ../org.jacoco.core.test.validation.kotlin @@ -97,11 +93,8 @@ - - 1.6 - ../org.jacoco.core.test.validation.kotlin ../org.jacoco.core.test.validation.java7 @@ -115,7 +108,6 @@ - ../org.jacoco.core.test.validation.kotlin ../org.jacoco.core.test.validation.java7 @@ -125,6 +117,9 @@ true + + 1.8 + ../org.jacoco.core.test.validation.kotlin ../org.jacoco.core.test.validation.java7 @@ -346,8 +341,7 @@ - - 16 + 17 17 17 @@ -373,8 +367,7 @@ - - 16 + 18 16 @@ -401,8 +394,7 @@ - - 16 + 19 16 @@ -429,8 +421,7 @@ - - 16 + 20 16 @@ -457,8 +448,7 @@ - - 16 + 21 16 @@ -486,8 +476,8 @@ - - 16 + + 21 16 @@ -517,8 +507,8 @@ - - 16 + + 21 16 diff --git a/org.jacoco.doc/docroot/doc/build.html b/org.jacoco.doc/docroot/doc/build.html index 46600cdd1a..06217bce87 100644 --- a/org.jacoco.doc/docroot/doc/build.html +++ b/org.jacoco.doc/docroot/doc/build.html @@ -231,23 +231,23 @@

Compilation and testing with different JDKs

org.jacoco.core.test.validation.kotlin - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 6 + + + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 org.jacoco.core.test.validation.scala From 726dcdf88ca022f1cead486cc4ca239b669c80ea Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 2 May 2024 19:55:24 +0200 Subject: [PATCH 006/163] Starting from JDK 20 compilation into bytecode version 7 not supported (#1615) --- org.jacoco.doc/docroot/doc/build.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/org.jacoco.doc/docroot/doc/build.html b/org.jacoco.doc/docroot/doc/build.html index 06217bce87..89ed086914 100644 --- a/org.jacoco.doc/docroot/doc/build.html +++ b/org.jacoco.doc/docroot/doc/build.html @@ -203,9 +203,9 @@

Compilation and testing with different JDKs

7 7 7 - 7 - 7 - 7 + 8 + 8 + 8 org.jacoco.core.test.validation.groovy From 7ab41d16f2abefb80b6d7788bde2cc4114b38a0e Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sat, 4 May 2024 12:16:59 +0200 Subject: [PATCH 007/163] Add filter for bytecode generated by Compose Kotlin compiler plugin (#1616) --- .../filter/KotlinComposeFilterTest.java | 255 ++++++++++++++++++ .../internal/analysis/filter/Filters.java | 3 +- .../analysis/filter/KotlinComposeFilter.java | 83 ++++++ org.jacoco.doc/docroot/doc/changes.html | 7 + 4 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilterTest.java create mode 100644 org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilterTest.java new file mode 100644 index 0000000000..a6564f15cc --- /dev/null +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilterTest.java @@ -0,0 +1,255 @@ +/******************************************************************************* + * 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 static org.objectweb.asm.Opcodes.*; + +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 KotlinComposeFilter}. + */ +public class KotlinComposeFilterTest extends FilterTestBase { + + private final IFilter filter = new KotlinComposeFilter(); + + /** + *
+	 * @androidx.compose.runtime.Composable
+	 * fun example(x: Int) {
+	 *   if (x < 0)
+	 *     return
+	 *   example(x - 1)
+	 * }
+	 * 
+ * + * transformed by Compose + * Kotlin compiler plugin version 2.0.0 into + * + *
+	 * fun example(x: Int, $composer: Composer?, $changed: Int) {
+	 *   $composer = $composer.startRestartGroup(...)
+	 *   sourceInformation($composer, ...)
+	 *   val $dirty = $changed
+	 *   if ($changed and 0b0110 == 0) {
+	 *     $dirty = $dirty or if ($composer.changed(x)) 0b0100 else 0b0010
+	 *   }
+	 *   if ($dirty and 0b0011 != 0b0010 || !$composer.skipping) {
+	 *     if (isTraceInProgress()) {
+	 *       traceEventStart(...)
+	 *     }
+	 *
+	 *     if (x < 0) {
+	 *       if (isTraceInProgress()) {
+	 *         traceEventEnd()
+	 *       }
+	 *       $composer.endRestartGroup()?.updateScope { ... }
+	 *       return
+	 *     }
+	 *
+	 *     example(x, $composer, 0)
+	 *
+	 *     if (isTraceInProgress()) {
+	 *       traceEventEnd()
+	 *     }
+	 *   } else {
+	 *     $composer.skipToGroupEnd()
+	 *   }
+	 *   $composer.endRestartGroup()?.updateScope { ... }
+	 * }
+	 * 
+ */ + @Test + public void should_filter() { + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "f", "(Landroidx/compose/runtime/Composer;I)V", null, null); + m.visitAnnotation("Landroidx/compose/runtime/Composable;", false); + + final Range range1 = new Range(); + final Range range2 = new Range(); + final Range range3 = new Range(); + final Range range4 = new Range(); + final Range range5 = new Range(); + final Range range6 = new Range(); + final Range range7 = new Range(); + + m.visitVarInsn(ALOAD, 1); + range1.fromInclusive = m.instructions.getLast(); + m.visitLdcInsn(Integer.valueOf(-974630231)); + m.visitMethodInsn(INVOKEINTERFACE, "androidx/compose/runtime/Composer", + "startRestartGroup", "(I)Landroidx/compose/runtime/Composer;", + true); + m.visitVarInsn(ASTORE, 1); + m.visitVarInsn(ILOAD, 2); + m.visitVarInsn(ISTORE, 3); + Label label1 = new Label(); + m.visitLabel(label1); + m.visitVarInsn(ILOAD, 2); + m.visitIntInsn(BIPUSH, 14); + m.visitInsn(IAND); + Label label2 = new Label(); + m.visitJumpInsn(IFNE, label2); + m.visitVarInsn(ILOAD, 3); + m.visitVarInsn(ALOAD, 1); + m.visitVarInsn(ILOAD, 0); + m.visitMethodInsn(INVOKEINTERFACE, "androidx/compose/runtime/Composer", + "changed", "(I)Z", true); + Label label3 = new Label(); + m.visitJumpInsn(IFEQ, label3); + m.visitInsn(ICONST_4); + Label label4 = new Label(); + m.visitJumpInsn(GOTO, label4); + m.visitLabel(label3); + m.visitInsn(ICONST_2); + m.visitLabel(label4); + m.visitInsn(IOR); + m.visitVarInsn(ISTORE, 3); + m.visitLabel(label2); + m.visitVarInsn(ILOAD, 3); + m.visitIntInsn(BIPUSH, 11); + m.visitInsn(IAND); + m.visitInsn(ICONST_2); + Label label5 = new Label(); + m.visitJumpInsn(IF_ICMPNE, label5); + m.visitVarInsn(ALOAD, 1); + m.visitMethodInsn(INVOKEINTERFACE, "androidx/compose/runtime/Composer", + "getSkipping", "()Z", true); + Label label6 = new Label(); + m.visitJumpInsn(IFNE, label6); + range1.toInclusive = m.instructions.getLast(); + + m.visitLabel(label5); + m.visitMethodInsn(INVOKESTATIC, "androidx/compose/runtime/ComposerKt", + "isTraceInProgress", "()Z", false); + Label label7 = new Label(); + m.visitJumpInsn(IFEQ, label7); + range3.fromInclusive = m.instructions.getLast(); + m.visitLdcInsn(Integer.valueOf(-974630231)); + m.visitVarInsn(ILOAD, 3); + m.visitInsn(ICONST_M1); + m.visitLdcInsn("org.example.example (Example.kt:19)"); + m.visitMethodInsn(INVOKESTATIC, "androidx/compose/runtime/ComposerKt", + "traceEventStart", "(IIILjava/lang/String;)V", false); + m.visitLabel(label7); + range3.toInclusive = m.instructions.getLast(); + + m.visitVarInsn(ILOAD, 0); + Label label8 = new Label(); + m.visitJumpInsn(IFGE, label8); + m.visitMethodInsn(INVOKESTATIC, "androidx/compose/runtime/ComposerKt", + "isTraceInProgress", "()Z", false); + Label label9 = new Label(); + m.visitJumpInsn(IFEQ, label9); + range4.fromInclusive = m.instructions.getLast(); + m.visitMethodInsn(INVOKESTATIC, "androidx/compose/runtime/ComposerKt", + "traceEventEnd", "()V", false); + m.visitLabel(label9); + range4.toInclusive = m.instructions.getLast(); + + m.visitVarInsn(ALOAD, 1); + m.visitMethodInsn(INVOKEINTERFACE, "androidx/compose/runtime/Composer", + "endRestartGroup", + "()Landroidx/compose/runtime/ScopeUpdateScope;", true); + m.visitInsn(DUP); + Label label10 = new Label(); + m.visitJumpInsn(IFNULL, label10); + range5.fromInclusive = m.instructions.getLast(); + m.visitTypeInsn(NEW, "org/example/ExampleKt$example$4"); + m.visitInsn(DUP); + m.visitVarInsn(ILOAD, 0); + m.visitVarInsn(ILOAD, 2); + m.visitMethodInsn(INVOKESPECIAL, "org/example/ExampleKt$example$4", + "", "(II)V", false); + m.visitTypeInsn(CHECKCAST, "kotlin/jvm/functions/Function2"); + m.visitMethodInsn(INVOKEINTERFACE, + "androidx/compose/runtime/ScopeUpdateScope", "updateScope", + "(Lkotlin/jvm/functions/Function2;)V", true); + Label label11 = new Label(); + m.visitJumpInsn(GOTO, label11); + m.visitLabel(label10); + m.visitFrame(Opcodes.F_SAME1, 0, null, 1, + new Object[] { "androidx/compose/runtime/ScopeUpdateScope" }); + m.visitInsn(POP); + range5.toInclusive = m.instructions.getLast(); + + m.visitLabel(label11); + m.visitInsn(Opcodes.RETURN); + + m.visitLabel(label8); + m.visitVarInsn(ILOAD, 0); + m.visitInsn(ICONST_1); + m.visitInsn(ISUB); + m.visitVarInsn(ALOAD, 1); + m.visitInsn(ICONST_0); + m.visitMethodInsn(INVOKESTATIC, "org/example/ExampleKt", "example", + "(ILandroidx/compose/runtime/Composer;I)V", false); + + m.visitMethodInsn(INVOKESTATIC, "androidx/compose/runtime/ComposerKt", + "isTraceInProgress", "()Z", false); + Label label12 = new Label(); + m.visitJumpInsn(IFEQ, label12); + range6.fromInclusive = m.instructions.getLast(); + m.visitMethodInsn(INVOKESTATIC, "androidx/compose/runtime/ComposerKt", + "traceEventEnd", "()V", false); + m.visitJumpInsn(GOTO, label12); + m.visitLabel(label6); + range2.fromInclusive = m.instructions.getLast(); + m.visitVarInsn(ALOAD, 1); + m.visitMethodInsn(INVOKEINTERFACE, "androidx/compose/runtime/Composer", + "skipToGroupEnd", "()V", true); + m.visitLabel(label12); + range6.toInclusive = m.instructions.getLast(); + + m.visitVarInsn(ALOAD, 1); + m.visitMethodInsn(INVOKEINTERFACE, "androidx/compose/runtime/Composer", + "endRestartGroup", + "()Landroidx/compose/runtime/ScopeUpdateScope;", true); + m.visitInsn(DUP); + Label label13 = new Label(); + m.visitJumpInsn(IFNULL, label13); + range7.fromInclusive = m.instructions.getLast(); + m.visitTypeInsn(NEW, "org/example/ExampleKt$example$5"); + m.visitInsn(DUP); + m.visitVarInsn(ILOAD, 0); + m.visitVarInsn(ILOAD, 2); + m.visitMethodInsn(INVOKESPECIAL, "org/example/ExampleKt$example$5", + "", "(II)V", false); + m.visitTypeInsn(CHECKCAST, "kotlin/jvm/functions/Function2"); + m.visitMethodInsn(INVOKEINTERFACE, + "androidx/compose/runtime/ScopeUpdateScope", "updateScope", + "(Lkotlin/jvm/functions/Function2;)V", true); + Label label14 = new Label(); + m.visitJumpInsn(GOTO, label14); + m.visitLabel(label13); + m.visitFrame(Opcodes.F_SAME1, 0, null, 1, + new Object[] { "androidx/compose/runtime/ScopeUpdateScope" }); + m.visitInsn(POP); + range7.toInclusive = m.instructions.getLast(); + + m.visitLabel(label14); + m.visitInsn(RETURN); + range2.toInclusive = m.instructions.getLast(); + + filter.filter(m, context, output); + + assertIgnored(range1, range2, range3, range4, range5, range6, range7); + } + +} 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 70bb751ec0..07268c4121 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 @@ -48,7 +48,8 @@ public static IFilter all() { new KotlinUnsafeCastOperatorFilter(), new KotlinNotNullOperatorFilter(), new KotlinDefaultArgumentsFilter(), new KotlinInlineFilter(), - new KotlinCoroutineFilter(), new KotlinDefaultMethodsFilter()); + new KotlinCoroutineFilter(), new KotlinDefaultMethodsFilter(), + new KotlinComposeFilter()); } private Filters(final IFilter... filters) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java new file mode 100644 index 0000000000..48a1fbd565 --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * 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.AbstractInsnNode; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.JumpInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +/** + * Filters bytecode generated by Compose Kotlin compiler plugin. + */ +final class KotlinComposeFilter implements IFilter { + + public void filter(final MethodNode methodNode, + final IFilterContext context, final IFilterOutput output) { + if (!KotlinGeneratedFilter.isKotlinClass(context)) { + return; + } + if (!isComposable(methodNode)) { + return; + } + for (final AbstractInsnNode i : methodNode.instructions) { + if (i.getType() != AbstractInsnNode.METHOD_INSN) { + continue; + } + final MethodInsnNode mi = (MethodInsnNode) i; + if ("androidx/compose/runtime/Composer".equals(mi.owner) + && "getSkipping".equals(mi.name) && "()Z".equals(mi.desc) + && mi.getNext().getOpcode() == Opcodes.IFNE) { + // https://github.com/JetBrains/kotlin/blob/v2.0.0-RC2/plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt#L361-L384 + final JumpInsnNode ji = (JumpInsnNode) mi.getNext(); + output.ignore(methodNode.instructions.getFirst(), ji); + output.ignore(ji.label, methodNode.instructions.getLast()); + } else if ("androidx/compose/runtime/Composer".equals(mi.owner) + && "endRestartGroup".equals(mi.name) + && "()Landroidx/compose/runtime/ScopeUpdateScope;" + .equals(mi.desc) + && mi.getNext().getOpcode() == Opcodes.DUP + && mi.getNext().getNext().getOpcode() == Opcodes.IFNULL) { + // https://github.com/JetBrains/kotlin/blob/v2.0.0-RC2/plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt#L430-L450 + final JumpInsnNode ji = (JumpInsnNode) mi.getNext().getNext(); + final AbstractInsnNode jumpTarget = AbstractMatcher + .skipNonOpcodes(ji.label); + if (jumpTarget.getOpcode() == Opcodes.POP) { + output.ignore(ji, jumpTarget); + } + } else if ("androidx/compose/runtime/ComposerKt".equals(mi.owner) + && "isTraceInProgress".equals(mi.name) + && "()Z".equals(mi.desc) + && mi.getNext().getOpcode() == Opcodes.IFEQ) { + // https://github.com/JetBrains/kotlin/blob/v2.0.0-RC2/plugins/compose/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt#L2123-L2163 + final JumpInsnNode ji = (JumpInsnNode) mi.getNext(); + output.ignore(ji, ji.label); + } + } + } + + private static boolean isComposable(final MethodNode methodNode) { + if (methodNode.invisibleAnnotations == null) { + return false; + } + for (final AnnotationNode a : methodNode.invisibleAnnotations) { + if ("Landroidx/compose/runtime/Composable;".equals(a.desc)) { + return true; + } + } + return false; + } + +} diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 48b2ac196e..e5a53ba9a0 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -20,6 +20,13 @@

Change History

Snapshot Build @qualified.bundle.version@ (@build.date@)

+

New Features

+
    +
  • Part of bytecode generated by the Kotlin Compose compiler plugin is + filtered out during generation of report + (GitHub #1616).
  • +
+

Release 0.8.12 (2024/03/31)

New Features

From 4d23aae2859e4010da0a3d5c3ff74e3e9c427548 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 8 May 2024 05:41:28 +0200 Subject: [PATCH 008/163] Add configuration for Dependabot to simplify updates of Kotlin (#1618) --- .github/dependabot.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 51d2ae7554..2983a7be26 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -16,3 +16,13 @@ updates: - "component: core" allow: - dependency-name: "org.ow2.asm:*" + - package-ecosystem: "maven" + directory: "/org.jacoco.core.test.validation.kotlin" + schedule: + interval: "weekly" + labels: + - "dependencies" + - "component: test" + - "language: kotlin" + allow: + - dependency-name: "org.jetbrains.kotlin:*" From 3bba375e0cb6416efa1a3e3682a7d83cc75a3da8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 22:33:58 +0200 Subject: [PATCH 009/163] Upgrade Kotlin to 1.9.24 Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evgeny Mandrikov --- .github/dependabot.yml | 2 +- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- org.jacoco.core.test.validation/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2983a7be26..0cdb098373 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/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index 00f7845aad..4d6143ece8 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -25,7 +25,7 @@ JaCoCo :: Test :: Core :: Validation Kotlin - 1.9.23 + 1.9.24 diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index c652601969..5f1b6b45a7 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -476,7 +476,7 @@ - + 21 16 @@ -507,7 +507,7 @@ - + 21 16 From adf9595df74ad37f0c9c00c9a54942e326e875df Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sun, 12 May 2024 18:45:47 +0200 Subject: [PATCH 010/163] Add filter for Kotlin inline value classes (#1475) --- .../kotlin/KotlinInlineClassTest.java | 27 +++++ .../kotlin/targets/KotlinInlineClassTarget.kt | 75 ++++++++++++++ .../filter/KotlinInlineClassFilterTest.java | 98 +++++++++++++++++++ .../internal/analysis/filter/Filters.java | 1 + .../filter/KotlinInlineClassFilter.java | 89 +++++++++++++++++ org.jacoco.doc/docroot/doc/changes.html | 3 + 6 files changed, 293 insertions(+) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineClassTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineClassTarget.kt create mode 100644 org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilterTest.java create mode 100644 org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineClassFilter.java 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 0000000000..908ad78260 --- /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 0000000000..079fa6d9ab --- /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) { + val i = I1() + i.value + i.length + i.f("") + i.f(i) + i.base() + + I2("") + } + +} 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 0000000000..8fd77a0a4e --- /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(); + + /** + *
+	 * @kotlin.jvm.JvmInline
+	 * value class Example(val value: String)
+	 * 
+ */ + @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); + } + + /** + *
+	 * @kotlin.jvm.JvmInline
+	 * value class Example(val value: String) {
+	 *   fun f() { ... }
+	 * }
+	 * 
+ */ + @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(); + } + + /** + *
+	 * data class Example(val value: String)
+	 * 
+ */ + @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 07268c4121..c644d9f8af 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 static IFilter all() { 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 0000000000..0279e04786 --- /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 + * + *
+ * @kotlin.jvm.JvmInline
+ * value class Example(val value: String) : Base {
+ *   fun f(p: String) { ... }
+ *   fun f(p: Example) { ... }
+ *   override fun base() { ... }
+ * }
+ * 
+ * + * Kotlin compiler produces + * + *
+ * @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) { ... }
+ * }
+ * 
+ * + * 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 e5a53ba9a0..f958060ced 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -25,6 +25,9 @@

New Features

  • Part of bytecode generated by the Kotlin Compose compiler plugin is filtered out during generation of report (GitHub #1616).
  • +
  • Part of bytecode generated by the Kotlin compiler for inline value classes is + filtered out during generation of report + (GitHub #1475).
  • Release 0.8.12 (2024/03/31)

    From e1e6af6142f30a0210644be7585ad24424a86060 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 09:07:34 +0000 Subject: [PATCH 011/163] Bump actions/checkout from 4.1.4 to 4.1.6 (#1621) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.4 to 4.1.6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/44c2b7a8a4ea60a981eaca3cf939b5f4305c123b...a5ac7e51b41094c92402da3b24376905380afc29) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 911151c74b..1f005398a7 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' From 583ee10ce516b49ca69c15d969ee2df34e8f3853 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sun, 26 May 2024 01:32:14 +0200 Subject: [PATCH 012/163] Fix build with JDK 23 EA (#1620) --- org.jacoco.build/pom.xml | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 1a0e8448c0..053edfe778 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -762,6 +762,27 @@
    + + maven-jdk23 + + [23,) + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + + + + + + + + + + + + + + sources From c98f7bd01efb3cfe838bee2d65e994b1fd0f287c Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 30 May 2024 23:53:38 +0200 Subject: [PATCH 013/163] Upgrade Kotlin to 2.0.0 (#1624) --- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- .../test/validation/kotlin/KotlinWhenExpressionTest.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index 4d6143ece8..b3984fc546 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -25,7 +25,7 @@ JaCoCo :: Test :: Core :: Validation Kotlin - 1.9.24 + 2.0.0 diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenExpressionTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenExpressionTest.java index 5bfe46d5d5..4f0cd0b54b 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenExpressionTest.java +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenExpressionTest.java @@ -24,4 +24,9 @@ public KotlinWhenExpressionTest() { super(KotlinWhenExpressionTarget.class); } + @Override + public void all_missed_instructions_should_have_line_number() { + // https://github.com/jacoco/jacoco/issues/1557 + } + } From a6337c2f5c0f16a98a4e496a96267fb48d2f6c52 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 10 Jun 2024 10:40:02 +0200 Subject: [PATCH 014/163] Kotlin 2.0.0 supports compilation into Java 22 bytecode (#1632) --- org.jacoco.core.test.validation/pom.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index 5f1b6b45a7..3b2a3f2359 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -476,8 +476,7 @@ - - 21 + 22 16 @@ -507,8 +506,8 @@ - - 21 + + 22 16 From 859da1c9b23a71de257718fa4bbb2c7e2d518614 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 11 Jun 2024 09:56:50 +0200 Subject: [PATCH 015/163] Add experimental support for Java 24 class files (#1631) --- .azure-pipelines/azure-pipelines.yml | 2 ++ org.jacoco.build/pom.xml | 14 +++++++++ org.jacoco.core.test.validation/pom.xml | 31 +++++++++++++++++++ .../jacoco/core/analysis/AnalyzerTest.java | 10 +++--- .../jacoco/core/instr/InstrumenterTest.java | 10 +++--- .../core/internal/instr/InstrSupportTest.java | 15 ++++----- .../core/internal/instr/InstrSupport.java | 4 +-- org.jacoco.doc/docroot/doc/changes.html | 2 ++ 8 files changed, 69 insertions(+), 19 deletions(-) diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 893ec71b69..2726d645ce 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -49,6 +49,8 @@ jobs: JDK_VERSION: 22 JDK 23: JDK_VERSION: 23 + JDK 24: + JDK_VERSION: 24 pool: vmImage: 'ubuntu-20.04' steps: diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 053edfe778..5c994baf78 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -928,6 +928,20 @@ + + java24-bytecode + + + bytecode.version + 24 + + + + 17 + 17 + + + ecj diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index 3b2a3f2359..957bbb2704 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -528,6 +528,37 @@
    + + java24-bytecode + + + bytecode.version + 24 + + + + + 22 + + 16 + + 24 + 24 + + + ../org.jacoco.core.test.validation.kotlin + ../org.jacoco.core.test.validation.java7 + ../org.jacoco.core.test.validation.java8 + ../org.jacoco.core.test.validation.java14 + ../org.jacoco.core.test.validation.java16 + ../org.jacoco.core.test.validation.java21 + + ../org.jacoco.core.test.validation.scala + + + diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java index 0e249f5228..b4ac0c865b 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java @@ -109,7 +109,7 @@ public void should_ignore_synthetic_classes() throws Exception { @Test public void should_not_modify_class_bytes_to_support_next_version() throws Exception { - final byte[] originalBytes = createClass(Opcodes.V22 + 1); + final byte[] originalBytes = createClass(Opcodes.V23 + 1); final byte[] bytes = new byte[originalBytes.length]; System.arraycopy(originalBytes, 0, bytes, 0, originalBytes.length); final long expectedClassId = CRC64.classId(bytes); @@ -132,13 +132,13 @@ private static byte[] createClass(final int version) { */ @Test public void analyzeClass_should_throw_exception_for_unsupported_class_file_version() { - final byte[] bytes = createClass(Opcodes.V22 + 2); + final byte[] bytes = createClass(Opcodes.V23 + 2); try { analyzer.analyzeClass(bytes, "UnsupportedVersion"); fail("exception expected"); } catch (IOException e) { assertExceptionMessage("UnsupportedVersion", e); - assertEquals("Unsupported class file major version 68", + assertEquals("Unsupported class file major version 69", e.getCause().getMessage()); } } @@ -218,14 +218,14 @@ public void testAnalyzeClass_BrokenStream() throws IOException { */ @Test public void analyzeAll_should_throw_exception_for_unsupported_class_file_version() { - final byte[] bytes = createClass(Opcodes.V22 + 2); + final byte[] bytes = createClass(Opcodes.V23 + 2); try { analyzer.analyzeAll(new ByteArrayInputStream(bytes), "UnsupportedVersion"); fail("exception expected"); } catch (IOException e) { assertExceptionMessage("UnsupportedVersion", e); - assertEquals("Unsupported class file major version 68", + assertEquals("Unsupported class file major version 69", e.getCause().getMessage()); } } diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java index 4eee4b189f..04a0ba972f 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java @@ -100,7 +100,7 @@ public void setup() throws Exception { @Test public void should_not_modify_class_bytes_to_support_next_version() throws Exception { - final byte[] originalBytes = createClass(Opcodes.V22 + 1); + final byte[] originalBytes = createClass(Opcodes.V23 + 1); final byte[] bytes = new byte[originalBytes.length]; System.arraycopy(originalBytes, 0, bytes, 0, originalBytes.length); final long expectedClassId = CRC64.classId(bytes); @@ -123,13 +123,13 @@ private static byte[] createClass(final int version) { */ @Test public void instrument_should_throw_exception_for_unsupported_class_file_version() { - final byte[] bytes = createClass(Opcodes.V22 + 2); + final byte[] bytes = createClass(Opcodes.V23 + 2); try { instrumenter.instrument(bytes, "UnsupportedVersion"); fail("exception expected"); } catch (final IOException e) { assertExceptionMessage("UnsupportedVersion", e); - assertEquals("Unsupported class file major version 68", + assertEquals("Unsupported class file major version 69", e.getCause().getMessage()); } } @@ -221,14 +221,14 @@ public void testSerialization() throws Exception { */ @Test public void instrumentAll_should_throw_exception_for_unsupported_class_file_version() { - final byte[] bytes = createClass(Opcodes.V22 + 2); + final byte[] bytes = createClass(Opcodes.V23 + 2); try { instrumenter.instrumentAll(new ByteArrayInputStream(bytes), new ByteArrayOutputStream(), "UnsupportedVersion"); fail("exception expected"); } catch (final IOException e) { assertExceptionMessage("UnsupportedVersion", e); - assertEquals("Unsupported class file major version 68", + assertEquals("Unsupported class file major version 69", e.getCause().getMessage()); } } diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java index d629bd717e..1ee2e7d74a 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java @@ -43,8 +43,8 @@ public void setup() { } @Test - public void classReaderFor_should_read_java_23_class() { - final byte[] bytes = createJava23Class(); + public void classReaderFor_should_read_java_24_class() { + final byte[] bytes = createJava24Class(); final ClassReader classReader = InstrSupport.classReaderFor(bytes); @@ -53,16 +53,16 @@ public void classReaderFor_should_read_java_23_class() { public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { - assertEquals(Opcodes.V22 + 1, version); + assertEquals(Opcodes.V23 + 1, version); } }, 0); - assertArrayEquals(createJava23Class(), bytes); + assertArrayEquals(createJava24Class(), bytes); } - private static byte[] createJava23Class() { + private static byte[] createJava24Class() { final ClassWriter cw = new ClassWriter(0); - cw.visit(Opcodes.V22 + 1, 0, "Foo", null, "java/lang/Object", null); + cw.visit(Opcodes.V23 + 1, 0, "Foo", null, "java/lang/Object", null); cw.visitEnd(); return cw.toByteArray(); } @@ -134,7 +134,8 @@ public void needFrames_should_return_true_for_versions_greater_than_or_equal_to_ assertTrue(InstrSupport.needsFrames(Opcodes.V20)); assertTrue(InstrSupport.needsFrames(Opcodes.V21)); assertTrue(InstrSupport.needsFrames(Opcodes.V22)); - assertTrue(InstrSupport.needsFrames(Opcodes.V22 + 1)); + assertTrue(InstrSupport.needsFrames(Opcodes.V23)); + assertTrue(InstrSupport.needsFrames(Opcodes.V23 + 1)); assertTrue(InstrSupport.needsFrames(0x0100)); } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java index b9e21d1c66..858f290f4b 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java @@ -273,9 +273,9 @@ public static void push(final MethodVisitor mv, final int value) { */ public static ClassReader classReaderFor(final byte[] b) { final int originalVersion = getMajorVersion(b); - if (originalVersion == Opcodes.V22 + 1) { + if (originalVersion == Opcodes.V23 + 1) { // temporarily downgrade version to bypass check in ASM - setMajorVersion(Opcodes.V22, b); + setMajorVersion(Opcodes.V23, b); } final ClassReader classReader = new ClassReader(b); setMajorVersion(originalVersion, b); diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index f958060ced..7f5e774d96 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -22,6 +22,8 @@

    Snapshot Build @qualified.bundle.version@ (@build.date@)

    New Features

    Release 0.8.12 (2024/03/31)

    From ebad1872760568d5c6cc60f65c0a2034dcb66691 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 20:43:17 +0000 Subject: [PATCH 019/163] Bump actions/upload-artifact from 4.3.3 to 4.3.4 (#1645) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.3 to 4.3.4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/65462800fd760344b1a7b4382951275a0abb4808...0b2256b8c012f0828dc542b3febcab082c67f72b) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7eedcb7c5b..60fddb7341 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,7 +82,7 @@ jobs: mvn -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 id: artifact-upload-step with: name: jacoco From 68325881fd3119a1f7952b9d8466208d61aa14fa Mon Sep 17 00:00:00 2001 From: Marharyta Date: Tue, 9 Jul 2024 23:14:56 +0200 Subject: [PATCH 020/163] Version of sonar-maven-plugin should be specified explicitly --- org.jacoco.build/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 5c994baf78..19d75bb81b 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -451,6 +451,11 @@ spotless-maven-plugin 2.41.1 + + org.sonarsource.scanner.maven + sonar-maven-plugin + 4.0.0.4121 + From 7589f79f3a7329b77c605a11a6825aed8b812f0f Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 11 Jul 2024 16:26:42 +0200 Subject: [PATCH 021/163] Fix typo (#1647) --- org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java b/org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java index 50ca901675..ca398e9596 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java @@ -18,7 +18,7 @@ */ public interface ISourceNode extends ICoverageNode { - /** Place holder for unknown lines (no debug information) */ + /** Placeholder for unknown lines (no debug information) */ int UNKNOWN_LINE = -1; /** From 77d2af5ec31faf04419d945e1a0c34da49f8a702 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 12 Jul 2024 23:32:45 +0200 Subject: [PATCH 022/163] `mvn -Decj=false` should not activate the use of ECJ (#1648) --- org.jacoco.build/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 19d75bb81b..8476939e33 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -953,6 +953,7 @@ ecj + true From fce2e5b6ef1cd48c0cb3e436d2454389fceeb637 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sat, 13 Jul 2024 23:17:09 +0200 Subject: [PATCH 023/163] Update KotlinCoroutineFilter for Kotlin 1.6 (#1283) --- .../kotlin/targets/KotlinCoroutineTarget.kt | 7 +++ .../filter/KotlinCoroutineFilterTest.java | 63 +++++++++++++++++++ .../filter/KotlinCoroutineFilter.java | 33 +++++++--- org.jacoco.doc/docroot/doc/changes.html | 3 + 4 files changed, 99 insertions(+), 7 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCoroutineTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCoroutineTarget.kt index 7a5def6d7d..0c5d7ce030 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCoroutineTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCoroutineTarget.kt @@ -34,6 +34,12 @@ object KotlinCoroutineTarget { nop() // assertFullyCovered() } + private fun suspendingLambdaWithoutSuspensionPoints() { + runBlocking { // assertFullyCovered() + nop() // assertFullyCovered() + } // assertFullyCovered() + } + @JvmStatic fun main(args: Array) { @@ -45,6 +51,7 @@ object KotlinCoroutineTarget { suspendingFunctionWithTailCallOptimization() } // assertFullyCovered() + suspendingLambdaWithoutSuspensionPoints() } } diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java index 19209ebd66..12a22369d1 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilterTest.java @@ -448,4 +448,67 @@ public void should_filter_suspending_functions_with_tail_call_optimization() { assertIgnored(range1, range2); } + /** + *
    +	 *     runBlocking {
    +	 *         // suspending lambda without suspension points,
    +	 *         // i.e. without invocations of suspending functions/lambdas
    +	 *     }
    +	 * 
    + * + * https://github.com/JetBrains/kotlin/commit/f4a1e27124f77b2ffca576f7393218373c6ae085 + * + * @see #should_filter_suspending_lambdas() + */ + @Test + public void should_filter_Kotlin_1_6_suspending_lambda_without_suspension_points() { + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "invokeSuspend", + "(Ljava/lang/Object;)Ljava/lang/Object;", null, null); + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + + m.visitMethodInsn(Opcodes.INVOKESTATIC, + "kotlin/coroutines/intrinsics/IntrinsicsKt", + "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;", false); + final Range range1 = new Range(); + range1.fromInclusive = m.instructions.getLast(); + m.visitInsn(Opcodes.POP); + + m.visitVarInsn(Opcodes.ALOAD, 0); + m.visitFieldInsn(Opcodes.GETFIELD, "ExampleKt$example$1", "label", "I"); + + final Label dflt = new Label(); + final Label state0 = new Label(); + m.visitTableSwitchInsn(0, 0, dflt, state0); + + m.visitLabel(state0); + { + m.visitVarInsn(Opcodes.ALOAD, 1); + m.visitMethodInsn(Opcodes.INVOKESTATIC, "kotlin/ResultKt", + "throwOnFailure", "(Ljava/lang/Object;)V", false); + } + range1.toInclusive = m.instructions.getLast(); + + m.visitFieldInsn(Opcodes.GETSTATIC, "kotlin/Unit", "INSTANCE", + "Lkotlin/Unit;"); + m.visitInsn(Opcodes.ARETURN); + + m.visitLabel(dflt); + final Range range0 = new Range(); + range0.fromInclusive = m.instructions.getLast(); + m.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException"); + m.visitInsn(Opcodes.DUP); + m.visitLdcInsn("call to 'resume' before 'invoke' with coroutine"); + m.visitMethodInsn(Opcodes.INVOKESPECIAL, + "java/lang/IllegalStateException", "", + "(Ljava/lang/String;)V", false); + m.visitInsn(Opcodes.ATHROW); + range0.toInclusive = m.instructions.getLast(); + + filter.filter(m, context, output); + + assertIgnored(range0, range1); + } + } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java index 0fc360cb10..6dd47fd413 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java @@ -94,14 +94,23 @@ private void match(final MethodNode methodNode, "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;"); } - nextIsVar(Opcodes.ASTORE, "COROUTINE_SUSPENDED"); - nextIsVar(Opcodes.ALOAD, "this"); - nextIs(Opcodes.GETFIELD); - nextIs(Opcodes.TABLESWITCH); - if (cursor == null) { - return; + final TableSwitchInsnNode s; + if (cursor != null + && Opcodes.POP == skipNonOpcodes(cursor.getNext()) + .getOpcode()) { + // suspending lambda without suspension points + nextIs(Opcodes.POP); + s = nextIsStateSwitch(); + if (s == null || s.labels.size() != 1) { + return; + } + } else { + nextIsVar(Opcodes.ASTORE, "COROUTINE_SUSPENDED"); + s = nextIsStateSwitch(); + if (s == null) { + return; + } } - final TableSwitchInsnNode s = (TableSwitchInsnNode) cursor; final List ignore = new ArrayList( s.labels.size() * 2); @@ -174,6 +183,16 @@ private void match(final MethodNode methodNode, } } + private TableSwitchInsnNode nextIsStateSwitch() { + nextIsVar(Opcodes.ALOAD, "this"); + nextIs(Opcodes.GETFIELD); + nextIs(Opcodes.TABLESWITCH); + if (cursor == null) { + return null; + } + return (TableSwitchInsnNode) cursor; + } + private void nextIsThrowOnFailure() { final AbstractInsnNode c = cursor; nextIsInvoke(Opcodes.INVOKESTATIC, "kotlin/ResultKt", diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 7f8347b791..2dec020d62 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -30,6 +30,9 @@

    New Features

  • Part of bytecode generated by the Kotlin compiler for inline value classes is filtered out during generation of report (GitHub #1475).
  • +
  • Part of bytecode generated by the Kotlin compiler for suspending lambdas + without suspension points is filtered out during generation of report + (GitHub #1283).
  • Method getEntries generated by the Kotlin compiler for enum classes is filtered out during generation of report (GitHub #1625).
  • From 5fdd9e6e4ac5db18b89433d13e7c34a144ef7a7c Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sun, 14 Jul 2024 18:52:04 +0200 Subject: [PATCH 024/163] Add builds with ECJ to GitHub Actions (#1649) --- .github/workflows/ci.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60fddb7341..098418b581 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,10 +9,18 @@ jobs: matrix: include: - jdk: 8 + - jdk: 8 + ecj: true + - jdk: 11 - jdk: 11 + ecj: true - jdk: 17 + - jdk: 17 + ecj: true + - jdk: 21 - jdk: 21 - name: JDK ${{ matrix.jdk }} + ecj: true + name: JDK ${{ matrix.jdk }}${{ matrix.ecj && ' with ECJ' || ''}} runs-on: ubuntu-20.04 steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 @@ -45,6 +53,7 @@ jobs: run: | mvn -V -B -e --no-transfer-progress \ verify -Djdk.version=${{ matrix.jdk }} -Dbytecode.version=${{ matrix.jdk }} \ + ${{ matrix.ecj && '-Decj' || ''}} \ --toolchains=toolchains.xml Windows: runs-on: windows-2022 From 4f851cae6822289c55aff539786405d2bf473584 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sat, 20 Jul 2024 07:12:09 +0200 Subject: [PATCH 025/163] Reduce code duplication (#1652) --- .../agent/rt/internal/ClassFileDumperTest.java | 10 +++------- .../agent/rt/internal/CoverageTransformerTest.java | 11 +++-------- .../src/org/jacoco/core/test/TargetLoader.java | 12 ++++-------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ClassFileDumperTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ClassFileDumperTest.java index c493d3416e..f8cae15ec2 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ClassFileDumperTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ClassFileDumperTest.java @@ -14,12 +14,12 @@ import static org.junit.Assert.assertArrayEquals; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import org.jacoco.core.internal.InputStreams; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -66,13 +66,9 @@ public void testNoDumps() throws IOException { private void assertContents(File location, String filename) throws IOException { InputStream in = new FileInputStream(new File(location, filename)); - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - int b; - while ((b = in.read()) != -1) { - buffer.write(b); - } + final byte[] bytes = InputStreams.readFully(in); in.close(); - assertArrayEquals(contents, buffer.toByteArray()); + assertArrayEquals(contents, bytes); } } diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/CoverageTransformerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/CoverageTransformerTest.java index d53e190570..63eba1a6f0 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/CoverageTransformerTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/CoverageTransformerTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.instrument.IllegalClassFormatException; @@ -27,6 +26,7 @@ import java.security.cert.Certificate; import org.jacoco.core.JaCoCo; +import org.jacoco.core.internal.InputStreams; import org.jacoco.core.runtime.AbstractRuntime; import org.jacoco.core.runtime.AgentOptions; import org.junit.After; @@ -245,14 +245,9 @@ private static byte[] getClassData(Class clazz) throws IOException { final String resource = "/" + clazz.getName().replace('.', '/') + ".class"; final InputStream in = clazz.getResourceAsStream(resource); - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] buffer = new byte[0x100]; - int len; - while ((len = in.read(buffer)) != -1) { - out.write(buffer, 0, len); - } + final byte[] bytes = InputStreams.readFully(in); in.close(); - return out.toByteArray(); + return bytes; } private static class StubRuntime extends AbstractRuntime { diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java b/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java index 431516b5a9..84daacb3e8 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java @@ -12,12 +12,13 @@ *******************************************************************************/ package org.jacoco.core.test; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import org.jacoco.core.internal.InputStreams; + /** * Loads given classes from a byte arrays. */ @@ -68,14 +69,9 @@ public static byte[] getClassDataAsBytes(Class clazz) } private static byte[] readBytes(InputStream in) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] buffer = new byte[0x100]; - int len; - while ((len = in.read(buffer)) != -1) { - out.write(buffer, 0, len); - } + final byte[] bytes = InputStreams.readFully(in); in.close(); - return out.toByteArray(); + return bytes; } @Override From eda47f1a223d387accedeaed7a3d4f9096fbe5ba Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:13:36 +0300 Subject: [PATCH 026/163] Remove unused field (#1657) --- .../internal/analysis/filter/KotlinLateinitFilterTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilterTest.java index c9b8dc87d7..5672d35260 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilterTest.java @@ -12,7 +12,6 @@ *******************************************************************************/ 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; @@ -26,9 +25,6 @@ public class KotlinLateinitFilterTest extends FilterTestBase { private final KotlinLateinitFilter filter = new KotlinLateinitFilter(); - private final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, - "name", "()V", null, null); - @Test public void should_filter_Kotlin_1_2() { final MethodNode m = new MethodNode(0, "read", "()Ljava/lang/String;", From 7222848bef6a43a15a0809596f024544ecf38397 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:40:56 +0300 Subject: [PATCH 027/163] Add missing `Test` annotation to method in `FileOutputTest` (#1658) This was overlooked in aa16a7c25cfc119ba3486bb114d3d54dc1bcca6c --- .../src/org/jacoco/agent/rt/internal/output/FileOutputTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/FileOutputTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/FileOutputTest.java index ccfc2b2375..9422020e42 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/FileOutputTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/output/FileOutputTest.java @@ -108,6 +108,7 @@ public void startup_should_throw_OverlappingFileLockException_when_execfile_is_p } } + @Test public void startup_should_throw_InterruptedIOException_when_execfile_is_locked_and_thread_is_interrupted() throws Exception { if (JavaVersion.current().isBefore("1.6")) { From ad12d46652db64975a2fb6718a941c3ada2ea6be Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:55:32 +0200 Subject: [PATCH 028/163] Fix typo: replace two consecutive dots in javadoc by one (#1659) --- .../jacoco/report/internal/html/page/PackageSourcePage.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/PackageSourcePage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/PackageSourcePage.java index fc1f24b4f0..7e4b0cc48d 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/PackageSourcePage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/PackageSourcePage.java @@ -70,8 +70,7 @@ public void render() throws IOException { /** * Returns the link to the source file page of the source file with the - * given name. If no source file was located, null is - * returned.. + * given name. If no source file was located, null is returned. */ ILinkable getSourceFilePage(final String name) { return sourceFilePages.get(name); From 1ba265ee1cd5bc354ee11ac1ca7a2ce8e71d3a98 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 31 Jul 2024 00:11:48 +0200 Subject: [PATCH 029/163] Fix interpretation of Kotlin SMAP (#1525) --- .../kotlin/KotlinCrossinlineTest.java | 32 ++++ .../kotlin/targets/KotlinCrossinlineTarget.kt | 37 +++++ .../filter/KotlinInlineFilterTest.java | 150 +++++++++++++++--- .../analysis/filter/KotlinInlineFilter.java | 18 +-- org.jacoco.doc/docroot/doc/changes.html | 6 + 5 files changed, 209 insertions(+), 34 deletions(-) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinCrossinlineTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCrossinlineTarget.kt diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinCrossinlineTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinCrossinlineTest.java new file mode 100644 index 0000000000..ce1f317372 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinCrossinlineTest.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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.KotlinCrossinlineTarget; + +/** + * Test of code coverage in {@link KotlinCrossinlineTarget}. + */ +public class KotlinCrossinlineTest extends ValidationTestBase { + + public KotlinCrossinlineTest() { + super(KotlinCrossinlineTarget.class); + } + + @Override + public void all_missed_instructions_should_have_line_number() { + // missed instructions without line number in inline function + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCrossinlineTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCrossinlineTarget.kt new file mode 100644 index 0000000000..f0a58015de --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCrossinlineTarget.kt @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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 `crossinline`. + */ +object KotlinCrossinlineTarget { + + inline fun example(crossinline lambda: () -> Unit): () -> Unit { // assertEmpty() + return { // assertNotCovered() + lambda() // assertEmpty() + } // assertEmpty() + } // assertEmpty() + + @JvmStatic + fun main(args: Array) { + + example { // assertFullyCovered() + nop() // assertEmpty() + }() // assertEmpty() + + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java index 2e7d1622c8..73b77a097e 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java @@ -22,6 +22,7 @@ import org.junit.Test; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.MethodNode; /** @@ -36,6 +37,7 @@ public class KotlinInlineFilterTest extends FilterTestBase { @Test public void should_filter() { + context.className = "CallsiteKt"; context.sourceFileName = "callsite.kt"; context.sourceDebugExtension = "" // + "SMAP\n" // @@ -113,6 +115,7 @@ public void should_filter() { */ @Test public void should_filter_when_in_same_file() { + context.className = "Callsite"; context.sourceFileName = "example.kt"; context.sourceDebugExtension = "" // + "SMAP\n" // @@ -173,6 +176,7 @@ public void should_filter_when_in_same_file() { */ @Test public void should_filter_without_parsing_KotlinDebug_stratum() { + context.className = "ExampleKt"; context.sourceFileName = "Example.kt"; context.sourceDebugExtension = "" // + "SMAP\n" // @@ -204,6 +208,127 @@ public void should_filter_without_parsing_KotlinDebug_stratum() { assertIgnored(expectedRanges.toArray(new Range[0])); } + /** + *
    +	 * package a;
    +	 *
    +	 * inline fun testInline() {} // line 7
    +	 * 
    + * + *
    +	 * import a.testInline
    +	 *
    +	 * fun main() {
    +	 *   testInline() // line 4
    +	 * }
    +	 * 
    + */ + @Test + public void should_filter_when_inlined_with_same_file_name_and_line_number() { + context.className = "ExampleKt"; + context.sourceFileName = "Example.kt"; + context.sourceDebugExtension = "" // + + "SMAP\n" // + + "Example.kt\n" // OutputFileName=Example.kt + + "Kotlin\n" // DefaultStratumId=Kotlin + + "*S Kotlin\n" // StratumID=Kotlin + + "*F\n" // FileSection + + "+ 1 Example.kt\n" // FileID=1,FileName=Example.kt + + "ExampleKt\n" // + + "+ 2 Example.kt\n" // FileID=2,FileName=Example.kt + + "a/ExampleKt\n" // + + "*L\n" // LineSection + + "1#1,6:1\n" // InputStartLine=1,LineFileID=1,RepeatCount=6,OutputStartLine=1 + + "7#2:7\n" // InputStartLine=7,LineFileID=2,OutputStartLine=7 + + "*S KotlinDebug"; // StratumID=KotlinDebug + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + + Label label0 = new Label(); + m.visitLabel(label0); + m.visitLineNumber(4, label0); + m.visitInsn(Opcodes.ICONST_0); + m.visitVarInsn(Opcodes.ISTORE, 0); + Label label1 = new Label(); + m.visitLabel(label1); + m.visitLineNumber(7, label1); + shouldIgnorePrevious(m); + m.visitInsn(Opcodes.NOP); + shouldIgnorePrevious(m); + Label label2 = new Label(); + m.visitLabel(label2); + shouldIgnorePrevious(m); + m.visitLineNumber(5, label2); + m.visitInsn(Opcodes.RETURN); + + filter.filter(m, context, output); + + assertIgnored(expectedRanges.toArray(new Range[0])); + } + + /** + *
    +	 * inline fun example(crossinline lambda: () -> Unit): () -> Unit {
    +	 *   return {
    +	 *     lambda()
    +	 *   }
    +	 * }
    +	 *
    +	 * fun callsite() {
    +	 *   example {
    +	 *   }()
    +	 * }
    +	 * 
    + */ + @Test + public void should_filter_all_lines() { + context.className = "ExampleKt$callsite$$inlined$example$1"; + context.sourceFileName = "Example.kt"; + context.sourceDebugExtension = "" // + + "SMAP\n" // + + "Example.kt\n" // OutputFileName=Example.kt + + "Kotlin\n" // DefaultStratumId=Kotlin + + "*S Kotlin\n" // StratumID=Kotlin + + "*F\n" // FileSection + + "+ 1 Example.kt\n" // FileID=1 + + "ExampleKt$example$1\n" // + + "+ 2 Example.kt\n" // FileID=2 + + "ExampleKt\n" // + + "*L\n" // LineSection + + "1#1,11:1\n" // InputStartLine=1,LineFileID=1,RepeatCount=11,OutputStartLine=1 + + "9#2:12\n" // InputStartLine=9,LineFileID=2,OutputStartLine=12 + + "*E\n"; // EndSection + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + + Label label0 = new Label(); + m.visitLabel(label0); + m.visitLineNumber(3, label0); + m.visitInsn(Opcodes.ICONST_0); + m.visitVarInsn(Opcodes.ISTORE, 1); + Label label1 = new Label(); + m.visitLabel(label1); + m.visitLineNumber(12, label1); + m.visitInsn(Opcodes.NOP); + Label label2 = new Label(); + m.visitLabel(label2); + m.visitLineNumber(3, label2); + m.visitInsn(Opcodes.NOP); + Label label3 = new Label(); + m.visitLabel(label3); + m.visitLineNumber(4, label3); + m.visitInsn(Opcodes.RETURN); + + for (AbstractInsnNode i = m.instructions.getFirst() + .getNext(); i != null; i = i.getNext()) { + expectedRanges.add(new Range(i, i)); + } + + filter.filter(m, context, output); + + assertIgnored(expectedRanges.toArray(new Range[0])); + } + @Test public void should_not_parse_SourceDebugExtension_attribute_when_no_kotlin_metadata_annotation() { context.sourceDebugExtension = "SMAP"; @@ -265,32 +390,9 @@ public void should_throw_exception_when_unexpected_FileInfo() { } } - @Test - public void should_throw_exception_when_no_SourceFileId_for_SourceFile() { - context.sourceFileName = "example.kt"; - context.classAnnotations - .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); - context.sourceDebugExtension = "" // - + "SMAP\n" // - + "example.kt\n" // - + "Kotlin\n" // - + "*S Kotlin\n" // - + "*F\n" // - + "+ 1 another.kt\n" // - + "AnotherKt\n" // - + "*L\n" // - + "*E\n"; - - try { - filter.filter(m, context, output); - fail("exception expected"); - } catch (final IllegalStateException e) { - assertEquals("Unexpected SMAP FileSection", e.getMessage()); - } - } - @Test public void should_throw_exception_when_unexpected_LineInfo() { + context.className = "Callsite"; context.sourceFileName = "callsite.kt"; context.sourceDebugExtension = "" // + "SMAP\n" // diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java index 60fa490e01..43e328e977 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java @@ -42,7 +42,7 @@ public void filter(final MethodNode methodNode, if (firstGeneratedLineNumber == -1) { firstGeneratedLineNumber = getFirstGeneratedLineNumber( - context.getSourceFileName(), + context.getClassName(), context.getSourceFileName(), context.getSourceDebugExtension()); } @@ -57,7 +57,8 @@ public void filter(final MethodNode methodNode, } } - private static int getFirstGeneratedLineNumber(final String sourceFileName, + private static int getFirstGeneratedLineNumber( + final String currentClassName, final String sourceFileName, final String smap) { try { final BufferedReader br = new BufferedReader( @@ -74,22 +75,19 @@ private static int getFirstGeneratedLineNumber(final String sourceFileName, final BitSet sourceFileIds = new BitSet(); String line; while (!"*L".equals(line = br.readLine())) { - // AbsoluteFileName - br.readLine(); - final Matcher m = FILE_INFO_PATTERN.matcher(line); if (!m.matches()) { throw new IllegalStateException( "Unexpected SMAP line: " + line); } - final String fileName = m.group(2); - if (fileName.equals(sourceFileName)) { + // See + // https://github.com/JetBrains/kotlin/blob/2.0.0/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt#L120-L121 + // https://github.com/JetBrains/kotlin/blob/2.0.0/compiler/backend/src/org/jetbrains/kotlin/codegen/SourceInfo.kt#L38-L41 + final String className = br.readLine(); + if (currentClassName.equals(className)) { sourceFileIds.set(Integer.parseInt(m.group(1))); } } - if (sourceFileIds.isEmpty()) { - throw new IllegalStateException("Unexpected SMAP FileSection"); - } // LineSection int min = Integer.MAX_VALUE; while (true) { diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 2dec020d62..2dd5dcb1b5 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -38,6 +38,12 @@

    New Features

    (GitHub #1625). +

    Fixed bugs

    +
      +
    • Fixed interpretation of Kotlin SMAP + (GitHub #1525).
    • +
    +

    Release 0.8.12 (2024/03/31)

    New Features

    From c4cae9087f657945291f15813f4b8566275fb9ba Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 31 Jul 2024 09:27:41 +0200 Subject: [PATCH 030/163] Fix javadoc (#1661) Incorrect since creation in commit 2f5a2fc86a1148674bd1d661111c621cfa912a6b in JaCoCo version 0.1.0 --- .../src/org/jacoco/report/internal/ReportOutputFolder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.jacoco.report/src/org/jacoco/report/internal/ReportOutputFolder.java b/org.jacoco.report/src/org/jacoco/report/internal/ReportOutputFolder.java index 8fed4bf306..d98023ddc3 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/ReportOutputFolder.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/ReportOutputFolder.java @@ -83,8 +83,8 @@ public ReportOutputFolder subFolder(final String name) { * Creates a new file in this folder with the given local name. * * @param name - * name of the sub-folder - * @return handle for output into the sub-folder + * name of the file + * @return stream for output into the file * @throws IOException * if the file creation fails */ From b8197762cfa2adb7ebddcc9ea5c3f5849f1ebf0a Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sat, 3 Aug 2024 23:18:47 +0200 Subject: [PATCH 031/163] Extract SMAP parser from KotlinInlineFilter (#1663) --- .../filter/KotlinInlineFilterTest.java | 106 --------- .../analysis/filter/KotlinSMAPTest.java | 209 ++++++++++++++++++ .../analysis/filter/KotlinInlineFilter.java | 94 +------- .../internal/analysis/filter/KotlinSMAP.java | 182 +++++++++++++++ 4 files changed, 401 insertions(+), 190 deletions(-) create mode 100644 org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSMAPTest.java create mode 100644 org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java index 73b77a097e..161faea31f 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java @@ -12,9 +12,6 @@ *******************************************************************************/ package org.jacoco.core.internal.analysis.filter; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - import java.util.ArrayList; import java.util.List; @@ -166,48 +163,6 @@ public void should_filter_when_in_same_file() { assertIgnored(expectedRanges.toArray(new Range[0])); } - /** - * See KT-37704 - * - *
    -	 * inline fun f() {}
    -	 * fun g() = f()
    -	 * 
    - */ - @Test - public void should_filter_without_parsing_KotlinDebug_stratum() { - context.className = "ExampleKt"; - context.sourceFileName = "Example.kt"; - context.sourceDebugExtension = "" // - + "SMAP\n" // - + "Example.kt\n" // OutputFileName=Example.kt - + "Kotlin\n" // DefaultStratumId=Kotlin - + "*S Kotlin\n" // StratumID=Kotlin - + "*F\n" // FileSection - + "+ 1 Example.kt\n" // FileID=1,FileName=Example.kt - + "ExampleKt\n" // - + "*L\n" // LineSection - + "1#1,3:1\n" // InputStartLine=1,LineFileID=1,RepeatCount=3,OutputStartLine=1 - + "1#1:4\n" // InputStartLine=1,LineFileID=1,OutputStartLine=4 - + "*S KotlinDebug\n"; // StratumID=KotlinDebug - context.classAnnotations - .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); - - m.visitLineNumber(2, new Label()); - m.visitInsn(Opcodes.ICONST_0); - m.visitVarInsn(Opcodes.ISTORE, 0); - m.visitLineNumber(4, new Label()); - shouldIgnorePrevious(m); - m.visitInsn(Opcodes.NOP); - shouldIgnorePrevious(m); - m.visitLineNumber(3, new Label()); - m.visitInsn(Opcodes.RETURN); - - filter.filter(m, context, output); - - assertIgnored(expectedRanges.toArray(new Range[0])); - } - /** *
     	 * package a;
    @@ -354,67 +309,6 @@ public void should_not_filter_when_no_SourceDebugExtension_attribute() {
     		assertIgnored();
     	}
     
    -	@Test
    -	public void should_throw_exception_when_SMAP_incomplete() {
    -		context.sourceDebugExtension = "" //
    -				+ "SMAP\n";
    -		context.classAnnotations
    -				.add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
    -
    -		try {
    -			filter.filter(m, context, output);
    -			fail("exception expected");
    -		} catch (final IllegalStateException e) {
    -			assertEquals("Unexpected SMAP line: null", e.getMessage());
    -		}
    -	}
    -
    -	@Test
    -	public void should_throw_exception_when_unexpected_FileInfo() {
    -		context.sourceFileName = "callsite.kt";
    -		context.sourceDebugExtension = "" //
    -				+ "SMAP\n" //
    -				+ "callsite.kt\n" //
    -				+ "Kotlin\n" //
    -				+ "*S Kotlin\n" //
    -				+ "*F\n" //
    -				+ "xxx";
    -		context.classAnnotations
    -				.add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
    -
    -		try {
    -			filter.filter(m, context, output);
    -			fail("exception expected");
    -		} catch (final IllegalStateException e) {
    -			assertEquals("Unexpected SMAP line: xxx", e.getMessage());
    -		}
    -	}
    -
    -	@Test
    -	public void should_throw_exception_when_unexpected_LineInfo() {
    -		context.className = "Callsite";
    -		context.sourceFileName = "callsite.kt";
    -		context.sourceDebugExtension = "" //
    -				+ "SMAP\n" //
    -				+ "callsite.kt\n" //
    -				+ "Kotlin\n" //
    -				+ "*S Kotlin\n" //
    -				+ "*F\n" //
    -				+ "+ 1 callsite.kt\n" //
    -				+ "Callsite\n" //
    -				+ "*L\n" //
    -				+ "xxx";
    -		context.classAnnotations
    -				.add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
    -
    -		try {
    -			filter.filter(m, context, output);
    -			fail("exception expected");
    -		} catch (final IllegalStateException e) {
    -			assertEquals("Unexpected SMAP line: xxx", e.getMessage());
    -		}
    -	}
    -
     	private final List expectedRanges = new ArrayList();
     
     	private void shouldIgnorePrevious(final MethodNode m) {
    diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSMAPTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSMAPTest.java
    new file mode 100644
    index 0000000000..f6a00115da
    --- /dev/null
    +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSMAPTest.java
    @@ -0,0 +1,209 @@
    +/*******************************************************************************
    + * 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 static org.junit.Assert.assertEquals;
    +import static org.junit.Assert.fail;
    +
    +import org.junit.Test;
    +
    +/**
    + * Unit test for {@link KotlinSMAP}.
    + */
    +public class KotlinSMAPTest {
    +
    +	/**
    +	 * 
    +	 * // A.kt
    +	 * package a
    +	 * inline fun f() {} // line 3
    +	 * 
    + * + *
    +	 * // B.kt
    +	 * package b
    +	 * fun callsite() = f() // line 3
    +	 * 
    + */ + @Test + public void should_parse() { + final KotlinSMAP smap = new KotlinSMAP("B.kt", "SMAP\n" // + + "B.kt\n" // OutputFileName=B.kt + + "Kotlin\n" // DefaultStratumId=Kotlin + + "*S Kotlin\n" // StratumID=Kotlin + + "*F\n" // FileSection + + "+ 1 B.kt\n" // FileID=1,FileName=B.kt + + "b/BKt\n" // ClassName=b/BKt + + "+ 2 A.kt\n" // FileID=2,FileName=A.kt + + "a/AKt\n" // ClassName=a/AKt + + "*L\n" // LineSection + + "1#1,4:1\n" // InputStartLine=1,LineFileID=1,RepeatCount=4,OutputStartLine=1 + + "3#2:5\n" // InputStartLine=3,LineFileID=2,RepeatCount=,OutputStartLine=5 + + "*E\n"); // EndSection + assertEquals(2, smap.mappings().size()); + KotlinSMAP.Mapping mapping = smap.mappings().get(0); + assertEquals("b/BKt", mapping.inputClassName()); + assertEquals(1, mapping.inputStartLine()); + assertEquals(4, mapping.repeatCount()); + assertEquals(1, mapping.outputStartLine()); + mapping = smap.mappings().get(1); + assertEquals("a/AKt", mapping.inputClassName()); + assertEquals(3, mapping.inputStartLine()); + assertEquals(1, mapping.repeatCount()); + assertEquals(5, mapping.outputStartLine()); + } + + /** + * See KT-37704 + * + *
    +	 * inline fun f() {}
    +	 * fun g() = f()
    +	 * 
    + */ + @Test + public void should_stop_parsing_at_KotlinDebug_stratum() { + final KotlinSMAP smap = new KotlinSMAP("Example.kt", "SMAP\n" // + + "Example.kt\n" // OutputFileName=Example.kt + + "Kotlin\n" // DefaultStratumId=Kotlin + + "*S Kotlin\n" // StratumID=Kotlin + + "*F\n" // FileSection + + "+ 1 Example.kt\n" // FileID=1,FileName=Example.kt + + "ExampleKt\n" // + + "*L\n" // LineSection + + "1#1,3:1\n" // InputStartLine=1,LineFileID=1,RepeatCount=3,OutputStartLine=1 + + "1#1:4\n" // InputStartLine=1,LineFileID=1,OutputStartLine=4 + + "*S KotlinDebug\n" // StratumID=KotlinDebug + + "xxx"); + assertEquals(2, smap.mappings().size()); + KotlinSMAP.Mapping mapping = smap.mappings().get(0); + assertEquals("ExampleKt", mapping.inputClassName()); + assertEquals(1, mapping.inputStartLine()); + assertEquals(3, mapping.repeatCount()); + assertEquals(1, mapping.outputStartLine()); + mapping = smap.mappings().get(1); + assertEquals("ExampleKt", mapping.inputClassName()); + assertEquals(1, mapping.inputStartLine()); + assertEquals(1, mapping.repeatCount()); + assertEquals(4, mapping.outputStartLine()); + } + + @Test + public void should_throw_exception_when_not_an_SMAP_Header() { + try { + new KotlinSMAP("", "xxx"); + fail("exception expected"); + } catch (final IllegalStateException e) { + assertEquals("Unexpected SMAP line: xxx", e.getMessage()); + } + } + + @Test + public void should_throw_exception_when_OutputFileName_does_not_match_SourceFileName() { + try { + new KotlinSMAP("", "SMAP\n" // + + "Example.kt\n"); + fail("exception expected"); + } catch (final IllegalStateException e) { + assertEquals("Unexpected SMAP line: Example.kt", e.getMessage()); + } + } + + @Test + public void should_throw_exception_when_DefaultStratumId_is_not_Kotlin() { + try { + new KotlinSMAP("Servlet.java", "SMAP\n" // + + "Servlet.java\n" // OutputFileName=Servlet.java + + "JSP\n"); // DefaultStratumId=JSP + fail("exception expected"); + } catch (final IllegalStateException e) { + assertEquals("Unexpected SMAP line: JSP", e.getMessage()); + } + } + + @Test + public void should_throw_exception_when_first_StratumId_is_not_Kotlin() { + try { + new KotlinSMAP("Example.kt", "SMAP\n" // + + "Example.kt\n" // OutputFileName=Example.kt + + "Kotlin\n" // DefaultStratumId=Kotlin + + "*S KotlinDebug\n"); // StratumID=KotlinDebug + fail("exception expected"); + } catch (final IllegalStateException e) { + assertEquals("Unexpected SMAP line: *S KotlinDebug", + e.getMessage()); + } + } + + @Test + public void should_throw_exception_when_StratumSection_does_not_start_with_FileSection() { + try { + new KotlinSMAP("Example.kt", "SMAP\n" // + + "Example.kt\n" // + + "Kotlin\n" // + + "*S Kotlin\n" // + + "xxx"); // + fail("exception expected"); + } catch (final IllegalStateException e) { + assertEquals("Unexpected SMAP line: xxx", e.getMessage()); + } + } + + @Test + public void should_throw_exception_when_FileSection_contains_unexpected_FileInfo() { + try { + new KotlinSMAP("Example.kt", "SMAP\n" // + + "Example.kt\n" // + + "Kotlin\n" // + + "*S Kotlin\n" // + + "*F\n" // + + "xxx"); // + fail("exception expected"); + } catch (final IllegalStateException e) { + assertEquals("Unexpected SMAP line: xxx", e.getMessage()); + } + } + + @Test + public void should_throw_exception_when_LineSection_contains_unexpected_LineInfo() { + try { + new KotlinSMAP("Example.kt", "SMAP\n" // + + "Example.kt\n" // + + "Kotlin\n" // + + "*S Kotlin\n" // + + "*F\n" // + + "*L\n" // + + "xxx"); // + fail("exception expected"); + } catch (final IllegalStateException e) { + assertEquals("Unexpected SMAP line: xxx", e.getMessage()); + } + } + + @Test + public void should_throw_exception_when_LineInfo_does_not_have_FileID() { + try { + new KotlinSMAP("Example.kt", "SMAP\n" // + + "Example.kt\n" // + + "Kotlin\n" // + + "*S Kotlin\n" // + + "*F\n" // + + "*L\n" // + + "1:1\n"); // InputStartLine=1,OutputStartLine=1 + fail("exception expected"); + } catch (final NullPointerException e) { + // expected + } + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java index 43e328e977..55c2d77fbf 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java @@ -12,13 +12,6 @@ *******************************************************************************/ package org.jacoco.core.internal.analysis.filter; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.util.BitSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.LineNumberNode; import org.objectweb.asm.tree.MethodNode; @@ -57,85 +50,18 @@ public void filter(final MethodNode methodNode, } } - private static int getFirstGeneratedLineNumber( - final String currentClassName, final String sourceFileName, - final String smap) { - try { - final BufferedReader br = new BufferedReader( - new StringReader(smap)); - expectLine(br, "SMAP"); - // OutputFileName - expectLine(br, sourceFileName); - // DefaultStratumId - expectLine(br, "Kotlin"); - // StratumSection - expectLine(br, "*S Kotlin"); - // FileSection - expectLine(br, "*F"); - final BitSet sourceFileIds = new BitSet(); - String line; - while (!"*L".equals(line = br.readLine())) { - final Matcher m = FILE_INFO_PATTERN.matcher(line); - if (!m.matches()) { - throw new IllegalStateException( - "Unexpected SMAP line: " + line); - } - // See - // https://github.com/JetBrains/kotlin/blob/2.0.0/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt#L120-L121 - // https://github.com/JetBrains/kotlin/blob/2.0.0/compiler/backend/src/org/jetbrains/kotlin/codegen/SourceInfo.kt#L38-L41 - final String className = br.readLine(); - if (currentClassName.equals(className)) { - sourceFileIds.set(Integer.parseInt(m.group(1))); - } - } - // LineSection - int min = Integer.MAX_VALUE; - while (true) { - line = br.readLine(); - if (line.equals("*E") || line.equals("*S KotlinDebug")) { - break; - } - final Matcher m = LINE_INFO_PATTERN.matcher(line); - if (!m.matches()) { - throw new IllegalStateException( - "Unexpected SMAP line: " + line); - } - final int inputStartLine = Integer.parseInt(m.group(1)); - final int lineFileID = Integer - .parseInt(m.group(2).substring(1)); - final int outputStartLine = Integer.parseInt(m.group(4)); - if (sourceFileIds.get(lineFileID) - && inputStartLine == outputStartLine) { - continue; - } - min = Math.min(outputStartLine, min); + private static int getFirstGeneratedLineNumber(final String className, + final String sourceFileName, final String smap) { + int min = Integer.MAX_VALUE; + for (KotlinSMAP.Mapping mapping : new KotlinSMAP(sourceFileName, smap) + .mappings()) { + if (className.equals(mapping.inputClassName()) + && mapping.inputStartLine() == mapping.outputStartLine()) { + continue; } - return min; - } catch (final IOException e) { - // Must not happen with StringReader - throw new AssertionError(e); + min = Math.min(mapping.outputStartLine(), min); } + return min; } - private static void expectLine(final BufferedReader br, - final String expected) throws IOException { - final String line = br.readLine(); - if (!expected.equals(line)) { - throw new IllegalStateException("Unexpected SMAP line: " + line); - } - } - - private static final Pattern LINE_INFO_PATTERN = Pattern.compile("" // - + "([0-9]++)" // InputStartLine - + "(#[0-9]++)?+" // LineFileID - + "(,[0-9]++)?+" // RepeatCount - + ":([0-9]++)" // OutputStartLine - + "(,[0-9]++)?+" // OutputLineIncrement - ); - - private static final Pattern FILE_INFO_PATTERN = Pattern.compile("" // - + "\\+ ([0-9]++)" // FileID - + " (.++)" // FileName - ); - } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java new file mode 100644 index 0000000000..8062199ae4 --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * 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 java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Parsed representation of SourceDebugExtension attribute. + */ +final class KotlinSMAP { + + public static final class Mapping { + private final String inputClassName; + private final int inputStartLine; + private final int repeatCount; + private final int outputStartLine; + + /** + * Creates a new mapping. + * + * @param inputClassName + * name of input class + * @param inputStartLine + * starting line in input + * @param repeatCount + * number of mapped lines + * @param outputStartLine + * starting line in output + */ + Mapping(final String inputClassName, final int inputStartLine, + final int repeatCount, final int outputStartLine) { + this.inputClassName = inputClassName; + this.inputStartLine = inputStartLine; + this.repeatCount = repeatCount; + this.outputStartLine = outputStartLine; + } + + /** + * @return name of input class + */ + public String inputClassName() { + return inputClassName; + } + + /** + * @return starting line in input + */ + public int inputStartLine() { + return inputStartLine; + } + + /** + * @return number of mapped lines + */ + public int repeatCount() { + return repeatCount; + } + + /** + * @return starting line in output + */ + public int outputStartLine() { + return outputStartLine; + } + } + + private final ArrayList mappings = new ArrayList(); + + /** + * Returns list of mappings. + * + * @return list of mappings + */ + public List mappings() { + return mappings; + } + + /** + * Creates parsed representation of provided SourceDebugExtension attribute. + * + * @param sourceFileName + * the name of the source file from which the class with SMAP was + * compiled + * @param smap + * value of SourceDebugExtension attribute to parse + */ + public KotlinSMAP(final String sourceFileName, final String smap) { + try { + final BufferedReader br = new BufferedReader( + new StringReader(smap)); + // Header + expectLine(br, "SMAP"); + // OutputFileName + expectLine(br, sourceFileName); + // DefaultStratumId + expectLine(br, "Kotlin"); + // StratumSection + expectLine(br, "*S Kotlin"); + // FileSection + expectLine(br, "*F"); + final HashMap inputClassNames = new HashMap(); + String line; + while (!"*L".equals(line = br.readLine())) { + final Matcher m = FILE_INFO_PATTERN.matcher(line); + if (!m.matches()) { + throw new IllegalStateException( + "Unexpected SMAP line: " + line); + } + final int id = Integer.parseInt(m.group(1)); + // See + // https://github.com/JetBrains/kotlin/blob/2.0.0/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt#L120-L121 + // https://github.com/JetBrains/kotlin/blob/2.0.0/compiler/backend/src/org/jetbrains/kotlin/codegen/SourceInfo.kt#L38-L41 + final String className = br.readLine(); + inputClassNames.put(id, className); + } + // LineSection + while (true) { + line = br.readLine(); + if (line.equals("*E") || line.equals("*S KotlinDebug")) { + break; + } + final Matcher m = LINE_INFO_PATTERN.matcher(line); + if (!m.matches()) { + throw new IllegalStateException( + "Unexpected SMAP line: " + line); + } + final int inputStartLine = Integer.parseInt(m.group(1)); + final int lineFileID = Integer + .parseInt(m.group(2).substring(1)); + final String repeatCountOptional = m.group(3); + final int repeatCount = repeatCountOptional != null + ? Integer.parseInt(repeatCountOptional.substring(1)) + : 1; + final int outputStartLine = Integer.parseInt(m.group(4)); + mappings.add(new Mapping(inputClassNames.get(lineFileID), + inputStartLine, repeatCount, outputStartLine)); + } + } catch (final IOException e) { + // Must not happen with StringReader + throw new AssertionError(e); + } + } + + private static void expectLine(final BufferedReader br, + final String expected) throws IOException { + final String line = br.readLine(); + if (!expected.equals(line)) { + throw new IllegalStateException("Unexpected SMAP line: " + line); + } + } + + private static final Pattern LINE_INFO_PATTERN = Pattern.compile("" // + + "([0-9]++)" // InputStartLine + + "(#[0-9]++)?+" // LineFileID + + "(,[0-9]++)?+" // RepeatCount + + ":([0-9]++)" // OutputStartLine + + "(,[0-9]++)?+" // OutputLineIncrement + ); + + private static final Pattern FILE_INFO_PATTERN = Pattern.compile("" // + + "\\+ ([0-9]++)" // FileID + + " (.++)" // FileName + ); + +} From 3935957ba891cca5e0a88d8639becad05689154c Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sun, 4 Aug 2024 22:05:04 +0200 Subject: [PATCH 032/163] Remove unused import (#1666) --- .../jacoco/core/test/validation/kotlin/KotlinSafeCastTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSafeCastTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSafeCastTest.java index 6eb1d5760d..95745918a5 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSafeCastTest.java +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSafeCastTest.java @@ -13,7 +13,6 @@ package org.jacoco.core.test.validation.kotlin; import org.jacoco.core.test.validation.ValidationTestBase; -import org.jacoco.core.test.validation.kotlin.targets.KotlinElvisOperatorTarget; import org.jacoco.core.test.validation.kotlin.targets.KotlinSafeCastTarget; /** From c2d805a8c73615c35d0eea5a7887f7eff412fef4 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sun, 4 Aug 2024 22:50:25 +0200 Subject: [PATCH 033/163] Add missing test (#1667) It was forgotten in commit 281538bc74d9f09f5b0d83250a4435b5c2732e21 --- .../jacoco/core/internal/analysis/ClassAnalyzerTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java index 84bb3ba21a..ee01b9ac04 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java @@ -60,6 +60,13 @@ public void testMethodFilter_Empty() { assertEquals(0, coverage.getMethods().size()); } + @Test + public void should_collect_annotations() { + assertTrue(analyzer.getClassAnnotations().isEmpty()); + analyzer.visitAnnotation("Lpkg/Annotation;", true); + assertTrue(analyzer.getClassAnnotations().contains("Lpkg/Annotation;")); + } + @Test public void should_collect_attributes() { assertTrue(analyzer.getClassAttributes().isEmpty()); From 6492b4035fcd44c9fd4553d30b8576c2cb42c278 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 09:59:30 +0200 Subject: [PATCH 034/163] Bump actions/upload-artifact from 4.3.4 to 4.3.5 (#1673) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.4 to 4.3.5. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/0b2256b8c012f0828dc542b3febcab082c67f72b...89ef406dd8d7e03cfd12d9e0a4a378f454709029) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 098418b581..7f8a681f15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: mvn -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + - uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5 id: artifact-upload-step with: name: jacoco From 2940177428cdad9d669cec32dc3459fd857438a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:46:54 +0200 Subject: [PATCH 035/163] Bump actions/setup-java from 4.2.1 to 4.2.2 (#1672) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4.2.1 to 4.2.2. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/99b8673ff64fbf99d8d325f52d9a5bdedb8483e9...6a0805fcefea3d4657a47ac4c165951e33482018) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f8a681f15..67b3a08b9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 with: distribution: 'zulu' java-version: | @@ -59,7 +59,7 @@ jobs: runs-on: windows-2022 steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 with: distribution: 'zulu' java-version: | From e4ab395b8c37e19dc73b4396a259281384122297 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:44:54 +0200 Subject: [PATCH 036/163] Upgrade Kotlin to 2.0.10 (#1674) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evgeny Mandrikov --- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- org.jacoco.core.test.validation/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index b3984fc546..a420a3e6fb 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -25,7 +25,7 @@ JaCoCo :: Test :: Core :: Validation Kotlin - 2.0.0 + 2.0.10 diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index 0dae8d4d8c..6060229c79 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -504,7 +504,7 @@ - + 22 16 @@ -535,7 +535,7 @@ - + 22 16 From a4f2b16c23b1bfba0419edc1697cb13775c043a9 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 12 Aug 2024 08:08:18 +0200 Subject: [PATCH 037/163] Add missing javadoc (#1677) It was forgotten in commit 36b4e9c7103441d556a1667b4485960f5bdfeff8 --- .../core/internal/instr/CondyProbeArrayStrategyTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/CondyProbeArrayStrategyTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/CondyProbeArrayStrategyTest.java index 13bca2efc6..e618e245bd 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/CondyProbeArrayStrategyTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/CondyProbeArrayStrategyTest.java @@ -27,6 +27,9 @@ import org.objectweb.asm.tree.TypeInsnNode; import org.objectweb.asm.tree.VarInsnNode; +/** + * Unit test for {@link CondyProbeArrayStrategy}. + */ public class CondyProbeArrayStrategyTest { private CondyProbeArrayStrategy strategy; From a06b277e824d2b1667fab85e03cb58153c474741 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 12 Aug 2024 08:44:37 +0200 Subject: [PATCH 038/163] Upgrade Groovy to 3.0.22 (#1678) --- org.jacoco.core.test.validation.groovy/pom.xml | 2 +- org.jacoco.core.test.validation/pom.xml | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/org.jacoco.core.test.validation.groovy/pom.xml b/org.jacoco.core.test.validation.groovy/pom.xml index a06c0d3518..0db9822cae 100644 --- a/org.jacoco.core.test.validation.groovy/pom.xml +++ b/org.jacoco.core.test.validation.groovy/pom.xml @@ -27,7 +27,7 @@ 3.0.0 - 3.0.21 + 3.0.22 diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index 6060229c79..c9b4001d9a 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -368,7 +368,7 @@ 18 - + 16 18 @@ -395,7 +395,7 @@ 19 - + 16 19 @@ -422,7 +422,7 @@ 20 - + 16 20 @@ -449,7 +449,7 @@ 21 - + 16 21 @@ -477,7 +477,7 @@ 22 - + 16 22 @@ -506,7 +506,7 @@ 22 - + 16 23 @@ -519,9 +519,7 @@ ../org.jacoco.core.test.validation.java14 ../org.jacoco.core.test.validation.java16 ../org.jacoco.core.test.validation.java21 - ../org.jacoco.core.test.validation.scala @@ -537,7 +535,7 @@ 22 - + 16 24 @@ -550,7 +548,7 @@ ../org.jacoco.core.test.validation.java14 ../org.jacoco.core.test.validation.java16 ../org.jacoco.core.test.validation.java21 - ../org.jacoco.core.test.validation.scala From 52e6e50d8490fca597092127d519947f48dca733 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 12 Aug 2024 09:10:15 +0200 Subject: [PATCH 039/163] Require at least Maven 3.6.3 for build (#1681) --- org.jacoco.build/pom.xml | 2 +- org.jacoco.doc/docroot/doc/build.html | 2 +- org.jacoco.doc/docroot/doc/changes.html | 6 ++++++ org.jacoco.doc/docroot/doc/environment.html | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 8476939e33..3e07eeb632 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -520,7 +520,7 @@ - [3.5.4,3.8.2),(3.8.2,) + [3.6.3,3.8.2),(3.8.2,) The rules for repo1.maven.org are that pom.xml files should not include repository definitions. diff --git a/org.jacoco.doc/docroot/doc/build.html b/org.jacoco.doc/docroot/doc/build.html index 89ed086914..efab7c1556 100644 --- a/org.jacoco.doc/docroot/doc/build.html +++ b/org.jacoco.doc/docroot/doc/build.html @@ -24,7 +24,7 @@

    Build

    The JaCoCo build is based on Maven and can be locally executed on every machine with a proper environment setup. In particular you need at - least Maven 3.5.4 and JDK 17 + least Maven 3.6.3 and JDK 17 installations. Developers are encouraged to run the build before every commit to ensure consistency of the source tree.

    diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 2dd5dcb1b5..4bddc1488a 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -44,6 +44,12 @@

    Fixed bugs

    (GitHub #1525). +

    Non-functional Changes

    +
      +
    • JaCoCo build now requires at least Maven 3.6.3 + (GitHub #1681).
    • +
    +

    Release 0.8.12 (2024/03/31)

    New Features

    diff --git a/org.jacoco.doc/docroot/doc/environment.html b/org.jacoco.doc/docroot/doc/environment.html index cc787d2405..1d827fe4f6 100644 --- a/org.jacoco.doc/docroot/doc/environment.html +++ b/org.jacoco.doc/docroot/doc/environment.html @@ -76,7 +76,7 @@

    Build

    The JaCoCo build is based on Maven - and requires at least Maven 3.5.4 and JDK 17. + and requires at least Maven 3.6.3 and JDK 17. See the build description for details.

    From 137173919422f5e7fe81ace22bc9f0ae47e8cd54 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 12 Aug 2024 11:53:49 +0200 Subject: [PATCH 040/163] Fix ClassAnalyzerTest (#1668) This was overlooked in commit 4d4d02e6dbfb17f454bf4579ee13209e9f035154 --- .../internal/analysis/ClassAnalyzerTest.java | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java index ee01b9ac04..44186568a6 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java @@ -21,6 +21,7 @@ import org.junit.Test; import org.objectweb.asm.Attribute; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.MethodNode; /** * Unit tests for {@link ClassAnalyzer}. @@ -39,27 +40,48 @@ public void setup() { } @Test(expected = IllegalStateException.class) - public void testAnalyzeInstrumentedClass1() { + public void should_throw_IllegalStateException_when_class_is_instrumented_with_data_field() { analyzer.visitField(InstrSupport.DATAFIELD_ACC, InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC, null, null); } @Test(expected = IllegalStateException.class) - public void testAnalyzeInstrumentedClass2() { + public void should_throw_IllegalStateException_when_class_is_instrumented_with_init_method() { analyzer.visitMethod(InstrSupport.INITMETHOD_ACC, InstrSupport.INITMETHOD_NAME, InstrSupport.INITMETHOD_DESC, null, null); } + /** + * @see #should_add_non_empty_methods() + */ @Test - public void testMethodFilter_Empty() { - final MethodProbesVisitor mv = analyzer.visitMethod(0, "foo", "()V", - null, null); - mv.visitEnd(); + public void should_not_add_empty_methods() { + final MethodNode m = new MethodNode(0, "foo", "()V", null, null); + + final MethodProbesVisitor mv = analyzer.visitMethod(m.access, m.name, + m.desc, m.signature, m.exceptions.toArray(new String[0])); + mv.accept(m, mv); + assertEquals(0, coverage.getMethods().size()); } + /** + * @see #should_not_add_empty_methods() + */ + @Test + public void should_add_non_empty_methods() { + final MethodNode m = new MethodNode(0, "foo", "()V", null, null); + m.visitInsn(Opcodes.RETURN); + + final MethodProbesVisitor mv = analyzer.visitMethod(m.access, m.name, + m.desc, m.signature, m.exceptions.toArray(new String[0])); + mv.accept(m, mv); + + assertEquals(1, coverage.getMethods().size()); + } + @Test public void should_collect_annotations() { assertTrue(analyzer.getClassAnnotations().isEmpty()); From d867bbcfab8edaba0b41b2ca233f52e4dffaee82 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:41:10 +0200 Subject: [PATCH 041/163] NormalizedFileNames should add prefix instead of suffix (#1660) Otherwise it changes file extensions. --- org.jacoco.doc/docroot/doc/changes.html | 3 +++ .../internal/NormalizedFileNamesTest.java | 24 +++++++++---------- .../report/internal/NormalizedFileNames.java | 4 ++-- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 4bddc1488a..27af4034e4 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -42,6 +42,9 @@

    Fixed bugs

    • Fixed interpretation of Kotlin SMAP (GitHub #1525).
    • +
    • File extensions are preserved in HTML report in case of clashes of normalized + file names + (GitHub #1660).

    Non-functional Changes

    diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/NormalizedFileNamesTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/NormalizedFileNamesTest.java index f63fe8c99d..837d81a3c5 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/NormalizedFileNamesTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/NormalizedFileNamesTest.java @@ -52,26 +52,26 @@ public void testSameInstance() { @Test public void testReplaceIllegalCharactersNonUnique() { - assertEquals("F__", nfn.getFileName("F__")); - assertEquals("F__~1", nfn.getFileName("F**")); - assertEquals("F__~2", nfn.getFileName("F??")); + assertEquals("F__.html", nfn.getFileName("F__.html")); + assertEquals("1~F__.html", nfn.getFileName("F**.html")); + assertEquals("2~F__.html", nfn.getFileName("F??.html")); // Mapping must be reproducible - assertEquals("F__", nfn.getFileName("F__")); - assertEquals("F__~1", nfn.getFileName("F**")); - assertEquals("F__~2", nfn.getFileName("F??")); + assertEquals("F__.html", nfn.getFileName("F__.html")); + assertEquals("1~F__.html", nfn.getFileName("F**.html")); + assertEquals("2~F__.html", nfn.getFileName("F??.html")); } @Test public void testCaseAware() { - assertEquals("Hello", nfn.getFileName("Hello")); - assertEquals("HELLO~1", nfn.getFileName("HELLO")); - assertEquals("HeLLo~2", nfn.getFileName("HeLLo")); + assertEquals("Hello.html", nfn.getFileName("Hello.html")); + assertEquals("1~HELLO.html", nfn.getFileName("HELLO.html")); + assertEquals("2~HeLLo.html", nfn.getFileName("HeLLo.html")); // Mapping must be reproducible - assertEquals("Hello", nfn.getFileName("Hello")); - assertEquals("HELLO~1", nfn.getFileName("HELLO")); - assertEquals("HeLLo~2", nfn.getFileName("HeLLo")); + assertEquals("Hello.html", nfn.getFileName("Hello.html")); + assertEquals("1~HELLO.html", nfn.getFileName("HELLO.html")); + assertEquals("2~HeLLo.html", nfn.getFileName("HeLLo.html")); } } diff --git a/org.jacoco.report/src/org/jacoco/report/internal/NormalizedFileNames.java b/org.jacoco.report/src/org/jacoco/report/internal/NormalizedFileNames.java index f820f10d10..192ca90972 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/NormalizedFileNames.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/NormalizedFileNames.java @@ -31,7 +31,7 @@ *
  • File names are case aware, i.e. the same file name but with different * upper/lower case characters is not possible.
  • *
  • If unique filenames can't directly created from the ids, additional - * suffixes are appended.
  • + * prefixes are prepended. * */ class NormalizedFileNames { @@ -81,7 +81,7 @@ private String ensureUniqueness(final String s) { String lower = unique.toLowerCase(Locale.ENGLISH); int idx = 1; while (usedNames.contains(lower)) { - unique = s + '~' + idx++; + unique = (idx++) + "~" + s; lower = unique.toLowerCase(Locale.ENGLISH); } usedNames.add(lower); From 36896b919e97cda9f96938c3eafd56c4b808b592 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 11:38:45 +0200 Subject: [PATCH 042/163] Bump actions/upload-artifact from 4.3.5 to 4.3.6 (#1682) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.5 to 4.3.6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/89ef406dd8d7e03cfd12d9e0a4a378f454709029...834a144ee995460fba8ed112a2fc961b36a5ec5a) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67b3a08b9b..366d04eb93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: mvn -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - - uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5 + - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 id: artifact-upload-step with: name: jacoco From 7d01bcad9e7ce19dc5b7c8ba316abdb8d530dc8a Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 15 Aug 2024 18:55:47 +0200 Subject: [PATCH 043/163] Upgrade JUnit to 4.13.2 (#1687) --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 3e07eeb632..fe18735220 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -142,7 +142,7 @@ 9.7 1.9.16 2.0.28 - 4.13.1 + 4.13.2 20100721 From 55c03b848279ba492d8645f1febe2133ed6d11d7 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 15 Aug 2024 19:22:22 +0200 Subject: [PATCH 044/163] Upgrade AntUnit to 1.4.1 (#1686) --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index fe18735220..c28ccd159f 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -237,7 +237,7 @@ org.apache.ant ant-antunit - 1.4 + 1.4.1 args4j From 7d9b69e003da6ba5d5e8cc87e85cca2b03c3b66e Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 22 Aug 2024 22:13:57 +0200 Subject: [PATCH 045/163] Generate HTML reports for validation tests (#1690) --- org.jacoco.core.test/pom.xml | 2 +- .../test/validation/ValidationTestBase.java | 31 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/org.jacoco.core.test/pom.xml b/org.jacoco.core.test/pom.xml index 45a40d90e5..0f2a666e6a 100644 --- a/org.jacoco.core.test/pom.xml +++ b/org.jacoco.core.test/pom.xml @@ -31,7 +31,7 @@ ${project.groupId} - org.jacoco.core + org.jacoco.report org.ow2.asm diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java index c160e809c1..89423ee1fa 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java @@ -15,22 +15,31 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import org.jacoco.core.analysis.Analyzer; import org.jacoco.core.analysis.CoverageBuilder; +import org.jacoco.core.analysis.IBundleCoverage; import org.jacoco.core.analysis.ICounter; import org.jacoco.core.analysis.ILine; import org.jacoco.core.data.ExecutionData; import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.SessionInfo; import org.jacoco.core.internal.analysis.CounterImpl; import org.jacoco.core.test.InstrumentingLoader; import org.jacoco.core.test.TargetLoader; import org.jacoco.core.test.validation.Source.Line; import org.jacoco.core.test.validation.targets.Stubs; +import org.jacoco.report.DirectorySourceFileLocator; +import org.jacoco.report.FileMultiReportOutput; +import org.jacoco.report.IReportVisitor; +import org.jacoco.report.ISourceFileLocator; +import org.jacoco.report.html.HTMLFormatter; import org.junit.Before; import org.junit.Test; import org.junit.runners.model.MultipleFailureException; @@ -56,6 +65,8 @@ public abstract class ValidationTestBase { private Source source; + private IBundleCoverage bundle; + private InstrumentingLoader loader; protected ValidationTestBase(final Class target) { @@ -86,7 +97,9 @@ private void analyze(final ExecutionDataStore store) throws IOException { for (ExecutionData data : store.getContents()) { analyze(analyzer, data); } - source = Source.load(target, builder.getBundle("Test")); + final String testClassSimpleName = getClass().getSimpleName(); + bundle = builder.getBundle(testClassSimpleName); + source = Source.load(target, bundle); } private void analyze(final Analyzer analyzer, final ExecutionData data) @@ -96,6 +109,22 @@ private void analyze(final Analyzer analyzer, final ExecutionData data) analyzer.analyzeClass(bytes, data.getName()); } + /** + * Generates HTML report. + */ + @Test + public final void generate_html_report() throws IOException { + final File destination = new File("target/reports/" + bundle.getName()); + final IReportVisitor visitor = new HTMLFormatter() + .createVisitor(new FileMultiReportOutput(destination)); + visitor.visitInfo(Collections. emptyList(), + Collections. emptyList()); + final ISourceFileLocator sourceFileLocator = new DirectorySourceFileLocator( + new File("src"), "UTF-8", 4); + visitor.visitBundle(bundle, sourceFileLocator); + visitor.visitEnd(); + } + /** * All single line comments are interpreted as statements in the following * format: From 517ecddb6eb3e69d33834ae4f12b78dc0f33583f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:34:05 +0200 Subject: [PATCH 046/163] Upgrade Kotlin to 2.0.20 (#1693) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evgeny Mandrikov --- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- org.jacoco.core.test.validation/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index a420a3e6fb..42e1af9c00 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -25,7 +25,7 @@ JaCoCo :: Test :: Core :: Validation Kotlin - 2.0.10 + 2.0.20 diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index c9b4001d9a..2dbd7861fd 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -504,7 +504,7 @@ - + 22 16 @@ -533,7 +533,7 @@ - + 22 16 From 5dda5f4ea92f8538dcc5bd302ead377ef8c4d400 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:18:07 +0200 Subject: [PATCH 047/163] Bump actions/upload-artifact from 4.3.6 to 4.4.0 (#1695) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.6 to 4.4.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/834a144ee995460fba8ed112a2fc961b36a5ec5a...50769540e7f4bd5e21e526ee35c689e35e0d6874) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 366d04eb93..2f388c40cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: mvn -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 id: artifact-upload-step with: name: jacoco From 831ecd609e17a3a5f8e114134fa0ce1d2071c6bd Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 5 Sep 2024 00:08:08 +0200 Subject: [PATCH 048/163] Calculate line coverage for Kotlin inline functions (#1670) --- .../kotlin/KotlinCrossinlineTest.java | 5 - .../kotlin/KotlinDefaultMethodsTest.java | 6 - .../validation/kotlin/KotlinInlineTest.java | 5 - .../kotlin/targets/KotlinCrossinlineTarget.kt | 12 +- .../kotlin/targets/KotlinInlineTarget.kt | 12 +- .../core/analysis/CoverageBuilderTest.java | 30 +++++ .../internal/analysis/ClassAnalyzerTest.java | 103 ++++++++++++++++++ .../analysis/ClassCoverageImplTest.java | 50 +++++++++ .../analysis/MethodCoverageImplTest.java | 55 ++++++++++ .../internal/analysis/SourceNodeImplTest.java | 26 +++++ .../filter/KotlinGeneratedFilterTest.java | 27 +++++ .../test/validation/ValidationTestBase.java | 4 +- .../jacoco/core/analysis/CoverageBuilder.java | 40 +++++-- .../core/internal/analysis/ClassAnalyzer.java | 58 +++++++++- .../internal/analysis/ClassCoverageImpl.java | 42 +++++++ .../internal/analysis/MethodCoverageImpl.java | 12 ++ .../internal/analysis/SourceNodeImpl.java | 35 ++++++ .../filter/KotlinGeneratedFilter.java | 8 +- .../internal/analysis/filter/KotlinSMAP.java | 2 +- org.jacoco.doc/docroot/doc/changes.html | 2 + 20 files changed, 494 insertions(+), 40 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinCrossinlineTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinCrossinlineTest.java index ce1f317372..c4c442d126 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinCrossinlineTest.java +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinCrossinlineTest.java @@ -24,9 +24,4 @@ public KotlinCrossinlineTest() { super(KotlinCrossinlineTarget.class); } - @Override - public void all_missed_instructions_should_have_line_number() { - // missed instructions without line number in inline function - } - } diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinDefaultMethodsTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinDefaultMethodsTest.java index 3ec1480182..8c92ad2d16 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinDefaultMethodsTest.java +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinDefaultMethodsTest.java @@ -24,10 +24,4 @@ public KotlinDefaultMethodsTest() { super(KotlinDefaultMethodsTarget.class); } - @Override - public void all_missed_instructions_should_have_line_number() { - // instructions without line numbers - // corresponding to non-executed default implementations - } - } diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineTest.java index 43d9e57b58..6a66b25b08 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineTest.java +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineTest.java @@ -24,9 +24,4 @@ public KotlinInlineTest() { super(KotlinInlineTargetKt.class); } - @Override - public void all_missed_instructions_should_have_line_number() { - // missed instructions without line number in inline function - } - } diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCrossinlineTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCrossinlineTarget.kt index f0a58015de..5454236f4b 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCrossinlineTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinCrossinlineTarget.kt @@ -20,17 +20,19 @@ import org.jacoco.core.test.validation.targets.Stubs.nop object KotlinCrossinlineTarget { inline fun example(crossinline lambda: () -> Unit): () -> Unit { // assertEmpty() - return { // assertNotCovered() - lambda() // assertEmpty() - } // assertEmpty() + return { // assertFullyCovered() + requireCrossinline { lambda() } // assertFullyCovered() + } // assertFullyCovered() } // assertEmpty() + fun requireCrossinline(lambda: () -> Unit) = lambda() + @JvmStatic fun main(args: Array) { example { // assertFullyCovered() - nop() // assertEmpty() - }() // assertEmpty() + nop() // assertFullyCovered() + }() // assertFullyCovered() } diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineTarget.kt index b98e6dc56d..ed21d20b92 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineTarget.kt @@ -22,15 +22,15 @@ fun main(args: Array) { KotlinInlineTarget.main(args) } -inline fun inlined_top_level() { - nop() // assertNotCovered() -} +inline fun inlined_top_level() { // assertEmpty() + nop() // assertFullyCovered() +} // assertFullyCovered() object KotlinInlineTarget { - inline fun inlined() { - nop() // assertNotCovered() - } + inline fun inlined() { // assertEmpty() + nop() // assertFullyCovered() + } // assertFullyCovered() @JvmStatic fun main(args: Array) { diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java index fcd862f2f9..03b9bb7e96 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java @@ -26,6 +26,7 @@ import org.jacoco.core.internal.analysis.ClassCoverageImpl; import org.jacoco.core.internal.analysis.CounterImpl; import org.jacoco.core.internal.analysis.MethodCoverageImpl; +import org.jacoco.core.internal.analysis.SourceNodeImpl; import org.junit.Before; import org.junit.Test; @@ -244,6 +245,35 @@ public void testGetNoMatchClasses() { assertEquals(expected, actual); } + @Test + public void testApplyFragment() { + coverageBuilder.visitCoverage(new ClassCoverageImpl("FooKt", 0, false) { + { + setSourceFileName("Foo.kt"); + addMethod(new MethodCoverageImpl("foo", "()V", null) { + { + increment(CounterImpl.COUNTER_1_0, + CounterImpl.COUNTER_0_0, 42); + } + }); + setFragments(Collections. singletonList( + new SourceNodeImpl(null, "FooKt") { + { + increment(CounterImpl.COUNTER_0_1, + CounterImpl.COUNTER_0_0, 42); + } + })); + } + }); + + final IClassCoverage c = coverageBuilder.getClasses().iterator().next(); + assertEquals(1, c.getClassCounter().getCoveredCount()); + + final ISourceFileCoverage s = coverageBuilder.getSourceFiles() + .iterator().next(); + assertEquals(1, s.getClassCounter().getCoveredCount()); + } + private Set getNames(Collection nodes) { Set result = new HashSet(); for (ICoverageNode n : nodes) { diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java index 44186568a6..018bf0fbe7 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java @@ -14,12 +14,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.jacoco.core.internal.flow.MethodProbesVisitor; import org.jacoco.core.internal.instr.InstrSupport; import org.junit.Before; import org.junit.Test; import org.objectweb.asm.Attribute; +import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.MethodNode; @@ -97,4 +99,105 @@ public void should_collect_attributes() { assertTrue(analyzer.getClassAttributes().contains("foo")); } + /** + *
    +	 * class Foo {
    +	 *   inline fun f() {}
    +	 *   fun g() = f()
    +	 * }
    +	 * 
    + */ + @Test + public void testCalculateFragments() { + analyzer.visitSource("Foo.kt", "SMAP\n" // + + "Foo.kt\n" // + + "Kotlin\n" // + + "*S Kotlin\n" // + + "*F\n" // + + "+ 1 Foo.kt\n" // + + "Foo\n" // + + "*L\n" // + + "1#1,4:1\n" // + + "2#1:6\n" // + + "*E\n"); + analyzer.visitAnnotation("Lkotlin/Metadata;", false); + MethodNode mn = new MethodNode(InstrSupport.ASM_API_VERSION, 0, "foo", + "()V", null, null) { + { + final Label label = new Label(); + visitLabel(label); + visitLineNumber(2, label); + visitInsn(Opcodes.RETURN); + } + }; + MethodProbesVisitor mv = analyzer.visitMethod(mn.access, mn.name, + mn.desc, mn.signature, mn.exceptions.toArray(new String[0])); + mv.accept(mn, mv); + mn = new MethodNode(InstrSupport.ASM_API_VERSION, 0, "bar", "()V", null, + null) { + { + final Label label = new Label(); + visitLabel(label); + visitLineNumber(6, label); + visitInsn(Opcodes.RETURN); + } + }; + mv = analyzer.visitMethod(mn.access, mn.name, mn.desc, mn.signature, + mn.exceptions.toArray(new String[0])); + mv.accept(mn, mv); + analyzer.visitEnd(); + + final SourceNodeImpl fragment = coverage.getFragments().iterator() + .next(); + assertEquals(fragment.getName(), "Foo"); + assertEquals(CounterImpl.COUNTER_1_0, + fragment.getLine(2).getInstructionCounter()); + } + + /** + * @see #should_not_parse_absent_SourceDebugExtension_attribute_when_kotlin() + * @see #should_parse_SourceDebugExtension_attribute_when_Kotlin() + */ + @Test + public void should_not_parse_SourceDebugExtension_attribute_when_not_Kotlin() { + analyzer.visitSource("Foo.kt", "SMAP\n"); + final MethodNode mn = new MethodNode(0, "foo", "()V", null, null); + final MethodProbesVisitor mv = analyzer.visitMethod(mn.access, mn.name, + mn.desc, mn.signature, mn.exceptions.toArray(new String[0])); + mv.accept(mn, mv); + } + + /** + * @see #should_not_parse_SourceDebugExtension_attribute_when_not_Kotlin() + * @see #should_parse_SourceDebugExtension_attribute_when_Kotlin() + */ + @Test + public void should_not_parse_absent_SourceDebugExtension_attribute_when_kotlin() { + analyzer.visitSource("Foo.kt", null); + analyzer.visitAnnotation("Lkotlin/Metadata;", false); + final MethodNode mn = new MethodNode(0, "foo", "()V", null, null); + final MethodProbesVisitor mv = analyzer.visitMethod(mn.access, mn.name, + mn.desc, mn.signature, mn.exceptions.toArray(new String[0])); + mv.accept(mn, mv); + } + + /** + * @see #should_not_parse_SourceDebugExtension_attribute_when_not_Kotlin() + * @see #should_not_parse_absent_SourceDebugExtension_attribute_when_kotlin() + */ + @Test + public void should_parse_SourceDebugExtension_attribute_when_Kotlin() { + analyzer.visitSource("Foo.kt", "SMAP\n"); + analyzer.visitAnnotation("Lkotlin/Metadata;", false); + final MethodNode mn = new MethodNode(0, "foo", "()V", null, null); + final MethodProbesVisitor mv = analyzer.visitMethod(mn.access, mn.name, + mn.desc, mn.signature, mn.exceptions.toArray(new String[0])); + try { + mv.accept(mn, mv); + fail("exception expected"); + } catch (Exception e) { + // expected + } + } + } diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java index 7ae5c82fab..43a4cc39c4 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java @@ -15,8 +15,10 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import java.util.Collection; import java.util.Collections; import org.jacoco.core.analysis.ICoverageNode; @@ -43,6 +45,7 @@ public void testDefaults() { assertEquals(12345, node.getId()); assertFalse(node.isNoMatch()); assertEquals(Collections.emptyList(), node.getMethods()); + assertSame(Collections.emptyList(), node.getFragments()); } @Test @@ -113,6 +116,53 @@ public void testAddMethodCovered() { assertEquals(CounterImpl.COUNTER_0_1, node.getClassCounter()); } + /** + * {@link ClassCoverageImpl#setFragments(Collection)} + * {@link ClassCoverageImpl#getFragments()} + */ + @Test + public void testSetFragments() { + final Collection fragments = Collections + .singletonList(new SourceNodeImpl(null, "fragment")); + node.setFragments(fragments); + assertSame(fragments, node.getFragments()); + } + + /** + * {@link ClassCoverageImpl#applyFragment(SourceNodeImpl)} + */ + @Test + public void testApplyFragment() { + // uncovered + final MethodCoverageImpl m = new MethodCoverageImpl("foo", "()V", null); + m.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 42); + m.incrementMethodCounter(); + node.addMethod(m); + // covered + final SourceNodeImpl fragment = new SourceNodeImpl(null, "Sample"); + fragment.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, + 42); + node.applyFragment(fragment); + + assertEquals(CounterImpl.COUNTER_0_1, node.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getLineCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getBranchCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getComplexityCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getMethodCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getClassCounter()); + LineImpl line = node.getLine(42); + assertEquals(CounterImpl.COUNTER_0_1, line.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, line.getBranchCounter()); + + assertEquals(CounterImpl.COUNTER_0_1, m.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_1, m.getLineCounter()); + assertEquals(CounterImpl.COUNTER_0_0, m.getBranchCounter()); + assertEquals(CounterImpl.COUNTER_0_1, m.getMethodCounter()); + line = m.getLine(42); + assertEquals(CounterImpl.COUNTER_0_1, line.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, line.getBranchCounter()); + } + private MethodCoverageImpl createMethod(boolean covered) { final MethodCoverageImpl m = new MethodCoverageImpl("sample", "()V", null); diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageImplTest.java index 2ac2b2d998..cb80ef8b2a 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageImplTest.java @@ -13,6 +13,8 @@ package org.jacoco.core.internal.analysis; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.jacoco.core.analysis.ICoverageNode; import org.junit.Test; @@ -136,4 +138,57 @@ public void testIncrementComplexity8() { assertEquals(CounterImpl.getInstance(0, 2), node.getComplexityCounter()); } + + /** + * {@link MethodCoverageImpl#applyFragment(SourceNodeImpl)} + */ + @Test + public void testApplyFragment() { + // uncovered + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 42); + node.incrementMethodCounter(); + // covered + final SourceNodeImpl fragment = new SourceNodeImpl(null, "fragment"); + fragment.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, + 42); + assertTrue(node.applyFragment(fragment)); + + assertEquals(CounterImpl.COUNTER_0_1, node.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getLineCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getBranchCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getComplexityCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getMethodCounter()); + final LineImpl line = node.getLine(42); + assertEquals(CounterImpl.COUNTER_0_1, line.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, line.getBranchCounter()); + } + + /** + * {@link MethodCoverageImpl#applyFragment(SourceNodeImpl)} + */ + @Test + public void testApplyFragment2() { + // uncovered + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_1_0, CounterImpl.getInstance(2, 0), + 42); + node.incrementMethodCounter(); + // covered unrelated + final SourceNodeImpl fragment = new SourceNodeImpl(null, "fragment"); + fragment.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, + 13); + assertFalse(node.applyFragment(fragment)); + // should not change + assertEquals(CounterImpl.COUNTER_1_0, node.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_1_0, node.getLineCounter()); + assertEquals(CounterImpl.getInstance(2, 0), node.getBranchCounter()); + assertEquals(CounterImpl.getInstance(2, 0), + node.getComplexityCounter()); + assertEquals(CounterImpl.COUNTER_1_0, node.getMethodCounter()); + final LineImpl line = node.getLine(42); + assertEquals(CounterImpl.COUNTER_1_0, line.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(2, 0), line.getBranchCounter()); + } + } diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceNodeImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceNodeImplTest.java index 9f82bf6f29..d530ccf897 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceNodeImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceNodeImplTest.java @@ -13,6 +13,7 @@ package org.jacoco.core.internal.analysis; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.jacoco.core.analysis.ICoverageNode.ElementType; import org.jacoco.core.analysis.ISourceNode; @@ -223,4 +224,29 @@ public void testIncrementChildWithLines() { assertEquals(CounterImpl.getInstance(0, 1), node.getLineCounter()); } + /** + * {@link SourceNodeImpl#applyFragment(SourceNodeImpl)} + */ + @Test + public void testApplyFragment() { + // uncovered + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, + "Foo"); + node.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_1_0, 42); + // covered + final SourceNodeImpl fragment = new SourceNodeImpl(null, "fragment"); + fragment.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, + 42); + + assertTrue(node.applyFragment(fragment)); + + assertEquals(CounterImpl.COUNTER_0_1, node.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getLineCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getBranchCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getComplexityCounter()); + final LineImpl line = node.getLine(42); + assertEquals(CounterImpl.COUNTER_0_1, line.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, line.getBranchCounter()); + } + } diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilterTest.java index 33ecf84d62..f0b01765de 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilterTest.java @@ -98,4 +98,31 @@ public void testWithLinesForKotlinNoDebug() { assertIgnored(); } + /** + *
    +	 * inline fun f() {
    +	 * }
    +	 * 
    + */ + @Test + public void should_filter_instructions_without_line_numbers() { + context.sourceFileName = "Example.kt"; + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "f", "()V", null, null); + m.visitInsn(Opcodes.ICONST_0); + final Range range1 = new Range(m.instructions.getLast(), + m.instructions.getLast()); + m.visitVarInsn(Opcodes.ISTORE, 1); + final Range range2 = new Range(m.instructions.getLast(), + m.instructions.getLast()); + m.visitLineNumber(1, new Label()); + m.visitInsn(Opcodes.RETURN); + + filter.filter(m, context, output); + + assertIgnored(range1, range2); + } + } diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java index 89423ee1fa..50ccd23e15 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java @@ -171,7 +171,7 @@ public void last_line_in_coverage_data_should_be_less_or_equal_to_number_of_line } @Test - public void all_missed_instructions_should_have_line_number() { + public final void all_missed_instructions_should_have_line_number() { CounterImpl c = CounterImpl.COUNTER_0_0; for (Line line : source.getLines()) { c = c.increment(line.getCoverage().getInstructionCounter()); @@ -183,7 +183,7 @@ public void all_missed_instructions_should_have_line_number() { } @Test - public void all_branches_should_have_line_number() { + public final void all_branches_should_have_line_number() { CounterImpl c = CounterImpl.COUNTER_0_0; for (Line line : source.getLines()) { c = c.increment(line.getCoverage().getBranchCounter()); diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java b/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java index 4f9a9050d9..cfd6a13c88 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java @@ -19,7 +19,9 @@ import java.util.Map; import org.jacoco.core.internal.analysis.BundleCoverageImpl; +import org.jacoco.core.internal.analysis.ClassCoverageImpl; import org.jacoco.core.internal.analysis.SourceFileCoverageImpl; +import org.jacoco.core.internal.analysis.SourceNodeImpl; /** * Builder for hierarchical {@link ICoverageNode} structures from single @@ -39,7 +41,7 @@ public class CoverageBuilder implements ICoverageVisitor { private final Map classes; - private final Map sourcefiles; + private Map sourcefiles; /** * Create a new builder. @@ -56,6 +58,7 @@ public CoverageBuilder() { * @return all class nodes */ public Collection getClasses() { + build(); return Collections.unmodifiableCollection(classes.values()); } @@ -65,6 +68,7 @@ public Collection getClasses() { * @return all source file nodes */ public Collection getSourceFiles() { + build(); return Collections.unmodifiableCollection(sourcefiles.values()); } @@ -76,6 +80,7 @@ public Collection getSourceFiles() { * @return bundle containing all classes and source files */ public IBundleCoverage getBundle(final String name) { + build(); return new BundleCoverageImpl(name, classes.values(), sourcefiles.values()); } @@ -96,9 +101,35 @@ public Collection getNoMatchClasses() { return result; } + private void build() { + if (sourcefiles != null) { + return; + } + this.sourcefiles = new HashMap(); + for (final IClassCoverage c : classes.values()) { + for (final SourceNodeImpl fragment : ((ClassCoverageImpl) c) + .getFragments()) { + final SourceNodeImpl classCoverage = (SourceNodeImpl) classes + .get(fragment.getName()); + if (classCoverage != null) { + classCoverage.applyFragment(fragment); + } + } + } + for (final IClassCoverage coverage : classes.values()) { + final String source = coverage.getSourceFileName(); + if (source != null) { + final SourceFileCoverageImpl sourceFile = getSourceFile(source, + coverage.getPackageName()); + sourceFile.increment(coverage); + } + } + } + // === ICoverageVisitor === public void visitCoverage(final IClassCoverage coverage) { + sourcefiles = null; final String name = coverage.getName(); final IClassCoverage dup = classes.put(name, coverage); if (dup != null) { @@ -106,13 +137,6 @@ public void visitCoverage(final IClassCoverage coverage) { throw new IllegalStateException( "Can't add different class with same name: " + name); } - } else { - final String source = coverage.getSourceFileName(); - if (source != null) { - final SourceFileCoverageImpl sourceFile = getSourceFile(source, - coverage.getPackageName()); - sourceFile.increment(coverage); - } } } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java index 0ca43a9bf7..d2268c5507 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java @@ -12,12 +12,17 @@ *******************************************************************************/ package org.jacoco.core.internal.analysis; +import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import org.jacoco.core.internal.analysis.filter.Filters; import org.jacoco.core.internal.analysis.filter.IFilter; import org.jacoco.core.internal.analysis.filter.IFilterContext; +import org.jacoco.core.internal.analysis.filter.KotlinGeneratedFilter; +import org.jacoco.core.internal.analysis.filter.KotlinSMAP; import org.jacoco.core.internal.flow.ClassProbesVisitor; import org.jacoco.core.internal.flow.MethodProbesVisitor; import org.jacoco.core.internal.instr.InstrSupport; @@ -25,6 +30,7 @@ import org.objectweb.asm.Attribute; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.MethodNode; /** @@ -42,6 +48,8 @@ public class ClassAnalyzer extends ClassProbesVisitor private final Set classAttributes = new HashSet(); private String sourceDebugExtension; + private KotlinSMAP smap; + private final HashMap fragments = new HashMap(); private final IFilter filter; @@ -114,8 +122,13 @@ public void accept(final MethodNode methodNode, private void addMethodCoverage(final String name, final String desc, final String signature, final InstructionsBuilder icc, final MethodNode methodNode) { + + final Map instructions = icc + .getInstructions(); + calculateFragments(instructions); + final MethodCoverageCalculator mcc = new MethodCoverageCalculator( - icc.getInstructions()); + instructions); filter.filter(methodNode, this, mcc); final MethodCoverageImpl mc = new MethodCoverageImpl(name, desc, @@ -129,6 +142,41 @@ private void addMethodCoverage(final String name, final String desc, } + private void calculateFragments( + final Map instructions) { + if (sourceDebugExtension == null + || !KotlinGeneratedFilter.isKotlinClass(this)) { + return; + } + if (smap == null) { + // Note that visitSource is invoked before visitAnnotation, + // that's why parsing is done here + smap = new KotlinSMAP(getSourceFileName(), sourceDebugExtension); + } + for (final KotlinSMAP.Mapping mapping : smap.mappings()) { + if (coverage.getName().equals(mapping.inputClassName()) + && mapping.inputStartLine() == mapping.outputStartLine()) { + continue; + } + SourceNodeImpl fragment = fragments.get(mapping.inputClassName()); + if (fragment == null) { + fragment = new SourceNodeImpl(null, mapping.inputClassName()); + fragments.put(mapping.inputClassName(), fragment); + } + final int mappingOutputEndLine = mapping.outputStartLine() + + mapping.repeatCount() - 1; + for (Instruction instruction : instructions.values()) { + if (mapping.outputStartLine() <= instruction.getLine() + && instruction.getLine() <= mappingOutputEndLine) { + final int originalLine = mapping.inputStartLine() + + instruction.getLine() - mapping.outputStartLine(); + fragment.increment(instruction.getInstructionCounter(), + CounterImpl.COUNTER_0_0, originalLine); + } + } + } + } + @Override public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) { @@ -141,6 +189,14 @@ public void visitTotalProbeCount(final int count) { // nothing to do } + @Override + public void visitEnd() { + if (!fragments.isEmpty()) { + coverage.setFragments(Arrays + .asList(fragments.values().toArray(new SourceNodeImpl[0]))); + } + } + // IFilterContext implementation public String getClassName() { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java index be90d9b674..f4dc7e8870 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import org.jacoco.core.analysis.IClassCoverage; import org.jacoco.core.analysis.IMethodCoverage; @@ -32,6 +33,8 @@ public class ClassCoverageImpl extends SourceNodeImpl private String[] interfaces; private String sourceFileName; + private Collection fragments = Collections.emptyList(); + /** * Creates a class coverage data object with the given parameters. * @@ -109,6 +112,45 @@ public void setSourceFileName(final String sourceFileName) { this.sourceFileName = sourceFileName; } + /** + * @return fragments stored in this class + */ + public Collection getFragments() { + return fragments; + } + + public void setFragments(final Collection fragments) { + this.fragments = fragments; + } + + @Override + public boolean applyFragment(final SourceNodeImpl fragment) { + super.applyFragment(fragment); + for (final IMethodCoverage methodCoverage : methods) { + final int mm = methodCoverage.getMethodCounter().getMissedCount(); + final int cm = methodCoverage.getMethodCounter().getCoveredCount(); + final int mc = methodCoverage.getComplexityCounter() + .getMissedCount(); + final int cc = methodCoverage.getComplexityCounter() + .getCoveredCount(); + if (((MethodCoverageImpl) methodCoverage).applyFragment(fragment)) { + methodCounter = methodCounter.increment( + methodCoverage.getMethodCounter().getMissedCount() - mm, + methodCoverage.getMethodCounter().getCoveredCount() + - cm); + complexityCounter = complexityCounter.increment( + methodCoverage.getComplexityCounter().getMissedCount() + - mc, + methodCoverage.getComplexityCounter().getCoveredCount() + - cc); + } + } + classCounter = methodCounter.getCoveredCount() > 0 + ? CounterImpl.COUNTER_0_1 + : CounterImpl.COUNTER_1_0; + return true; + } + // === IClassCoverage implementation === public long getId() { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageImpl.java index e6ee3283cf..25c7da1835 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageImpl.java @@ -66,6 +66,18 @@ public void incrementMethodCounter() { this.complexityCounter = this.complexityCounter.increment(base); } + @Override + public boolean applyFragment(final SourceNodeImpl fragment) { + final boolean applied = super.applyFragment(fragment); + if (applied) { + methodCounter = instructionCounter.getCoveredCount() == 0 + ? CounterImpl.COUNTER_1_0 + : CounterImpl.COUNTER_0_1; + complexityCounter = methodCounter; + } + return applied; + } + // === IMethodCoverage implementation === public String getDesc() { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java index 48fd48bd96..bab8b9edfd 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java @@ -41,6 +41,41 @@ public SourceNodeImpl(final ElementType elementType, final String name) { offset = UNKNOWN_LINE; } + /** + * @return true if fragment contains lines of this node + */ + public boolean applyFragment(final SourceNodeImpl fragment) { + boolean applied = false; + for (int line = getFirstLine(); line <= getLastLine(); line++) { + final ILine fragmentLine = fragment.getLine(line); + if (fragmentLine.equals(LineImpl.EMPTY)) { + continue; + } + final LineImpl l = getLine(line); + final CounterImpl counter; + if (l.getInstructionCounter().getCoveredCount() > 0 || fragmentLine + .getInstructionCounter().getCoveredCount() > 0) { + counter = CounterImpl.COUNTER_0_1; + } else { + counter = CounterImpl.COUNTER_1_0; + } + lines[line - offset] = LineImpl.EMPTY; + if (l.instructions.covered > 0) { + lineCounter = lineCounter.increment(0, -1); + } else if (l.instructions.missed > 0) { + lineCounter = lineCounter.increment(-1, 0); + } + incrementLine(counter, CounterImpl.COUNTER_0_0, line); + instructionCounter = instructionCounter.increment( + counter.missed - l.instructions.missed, + counter.covered - l.instructions.covered); + branchCounter = branchCounter.increment(-l.branches.missed, + -l.branches.covered); + applied = true; + } + return applied; + } + /** * Make sure that the internal buffer can keep lines from first to last. * While the buffer is also incremented automatically, this method allows diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java index ed3063f566..2bc32b1a21 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java @@ -24,7 +24,7 @@ public class KotlinGeneratedFilter implements IFilter { static final String KOTLIN_METADATA_DESC = "Lkotlin/Metadata;"; - static boolean isKotlinClass(final IFilterContext context) { + public static boolean isKotlinClass(final IFilterContext context) { return context.getClassAnnotations().contains(KOTLIN_METADATA_DESC); } @@ -42,6 +42,12 @@ public void filter(final MethodNode methodNode, } if (hasLineNumber(methodNode)) { + for (final AbstractInsnNode i : methodNode.instructions) { + if (AbstractInsnNode.LINE == i.getType()) { + break; + } + output.ignore(i, i); + } return; } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java index 8062199ae4..aa7a8d7b12 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java @@ -24,7 +24,7 @@ /** * Parsed representation of SourceDebugExtension attribute. */ -final class KotlinSMAP { +public final class KotlinSMAP { public static final class Mapping { private final String inputClassName; diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 27af4034e4..4a2ec80bd1 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -22,6 +22,8 @@

    Snapshot Build @qualified.bundle.version@ (@build.date@)

    New Features

      +
    • Calculation of line coverage for Kotlin inline functions + (GitHub #1670).
    • Experimental support for Java 24 class files (GitHub #1631).
    • Part of bytecode generated by the Kotlin Compose compiler plugin is From 1988ec3c808b0d9e616741bba87846c867f2fa63 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sat, 7 Sep 2024 00:33:24 +0200 Subject: [PATCH 049/163] Add validation test for synthetic accessor methods in Kotlin (#1675) --- .../kotlin/KotlinSyntheticAccessorsTest.java | 54 +++++++++++++++++++ .../targets/KotlinSyntheticAccessorsTarget.kt | 45 ++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSyntheticAccessorsTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSyntheticAccessorsTarget.kt diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSyntheticAccessorsTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSyntheticAccessorsTest.java new file mode 100644 index 0000000000..01543fb23d --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSyntheticAccessorsTest.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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 static org.junit.Assert.assertEquals; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; + +import org.jacoco.core.test.validation.ValidationTestBase; +import org.jacoco.core.test.validation.kotlin.targets.KotlinSyntheticAccessorsTarget; +import org.junit.Test; + +/** + * Test of code coverage in {@link KotlinSyntheticAccessorsTarget}. + */ +public class KotlinSyntheticAccessorsTest extends ValidationTestBase { + + public KotlinSyntheticAccessorsTest() { + super(KotlinSyntheticAccessorsTarget.class); + } + + @Test + public void compiler_should_generate_synthetic_accessors() { + final HashSet names = new HashSet(); + for (final Method method : KotlinSyntheticAccessorsTarget.Outer.class + .getDeclaredMethods()) { + if (method.isSynthetic()) { + names.add(method.getName()); + } + } + + assertEquals(new HashSet( + Arrays.asList("access$getX", "access$getX$p", "access$setX$p")), + names); + } + + @Test + public void test_method_count() { + assertMethodCount(/* main + 2 in Outer + 2 in Inner */ 5); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSyntheticAccessorsTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSyntheticAccessorsTarget.kt new file mode 100644 index 0000000000..36a418ace3 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSyntheticAccessorsTarget.kt @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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 + +/** + * Test target with synthetic accessor methods. + */ +object KotlinSyntheticAccessorsTarget { + + class Outer { // assertFullyCovered() + private var x = 42 + + private fun getX(): Int { + return x + } + + inner class Inner { // assertFullyCovered() + /** + * Access to private field and function of outer class causes creation of synthetic methods in it. + * Those methods refer to the line of outer class definition. + */ + @Suppress("unused") + fun accessOuter() { + x += 1 // assertNotCovered() + getX() + } + } + } + + @JvmStatic + fun main(args: Array) { + Outer().Inner() + } + +} From 44b4e5aeb3aabd370e9632074c2a426455aeb482 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:50:31 +0200 Subject: [PATCH 050/163] Nested classes should be static when they do not use reference to outer (#1688) --- jacoco-maven-plugin/src/org/jacoco/maven/ReportSupport.java | 4 ++-- org.jacoco.ant/src/org/jacoco/ant/ReportTask.java | 2 +- .../analysis/filter/TryWithResourcesJavac11Filter.java | 2 +- .../org/jacoco/report/internal/html/page/ClassPageTest.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jacoco-maven-plugin/src/org/jacoco/maven/ReportSupport.java b/jacoco-maven-plugin/src/org/jacoco/maven/ReportSupport.java index 46d09c99ac..bb42efa2fc 100644 --- a/jacoco-maven-plugin/src/org/jacoco/maven/ReportSupport.java +++ b/jacoco-maven-plugin/src/org/jacoco/maven/ReportSupport.java @@ -195,7 +195,7 @@ private void logBundleInfo(final IBundleCoverage bundle, } } - private class NoSourceLocator implements ISourceFileLocator { + private static class NoSourceLocator implements ISourceFileLocator { public Reader getSourceFile(final String packageName, final String fileName) { @@ -207,7 +207,7 @@ public int getTabWidth() { } } - private class SourceFileCollection implements ISourceFileLocator { + private static class SourceFileCollection implements ISourceFileLocator { private final List sourceRoots; private final String encoding; diff --git a/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java b/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java index cbcc685810..24051ce7af 100644 --- a/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java +++ b/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java @@ -152,7 +152,7 @@ public SourceFilesElement createSourcefiles() { /** * Interface for child elements that define formatters. */ - private abstract class FormatterElement { + private abstract static class FormatterElement { abstract IReportVisitor createVisitor() throws IOException; diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java index 120c964289..ddd24c2a3b 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java @@ -60,7 +60,7 @@ public void filter(final MethodNode methodNode, * null check for resource is omitted when it is initialized * using new */ - private class Matcher extends AbstractMatcher { + private static class Matcher extends AbstractMatcher { private boolean withNullCheck; private String expectedOwner; diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java index af4e6be015..6aee733203 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java @@ -148,7 +148,7 @@ public void should_generate_message_when_class_id_mismatch() support.findStr(doc, "/html/body/p[1]")); } - private class SourceLink implements ILinkable { + private static class SourceLink implements ILinkable { public String getLink(final ReportOutputFolder base) { return "Source.java.html"; From 58b3e65efd4237607361f1643cd485945a508262 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 10 Sep 2024 22:50:27 +0200 Subject: [PATCH 051/163] SyntheticFilter should filter out only synthetic accessors in Kotlin classes (#1700) --- .../kotlin/KotlinInlineReifiedTest.java | 52 ++++++++++++++++++ .../kotlin/KotlinJvmSyntheticTest.java | 52 ++++++++++++++++++ .../targets/KotlinInlineReifiedTarget.kt | 32 +++++++++++ .../targets/KotlinJvmSyntheticTarget.kt | 32 +++++++++++ .../analysis/filter/SyntheticFilterTest.java | 53 +++++++++++++++++++ .../filter/KotlinCoroutineFilter.java | 12 ----- .../filter/KotlinDefaultArgumentsFilter.java | 6 ++- .../analysis/filter/SyntheticFilter.java | 13 +---- org.jacoco.doc/docroot/doc/changes.html | 8 ++- 9 files changed, 233 insertions(+), 27 deletions(-) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineReifiedTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinJvmSyntheticTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineReifiedTarget.kt create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinJvmSyntheticTarget.kt diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineReifiedTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineReifiedTest.java new file mode 100644 index 0000000000..b84bb480d2 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinInlineReifiedTest.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 static org.junit.Assert.assertEquals; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashSet; + +import org.jacoco.core.test.validation.ValidationTestBase; +import org.jacoco.core.test.validation.kotlin.targets.KotlinInlineReifiedTarget; +import org.junit.Test; + +/** + * Test of code coverage in {@link KotlinInlineReifiedTarget}. + */ +public class KotlinInlineReifiedTest extends ValidationTestBase { + + public KotlinInlineReifiedTest() { + super(KotlinInlineReifiedTarget.class); + } + + @Test + public void compiler_should_generate_synthetic_method() { + final HashSet names = new HashSet(); + for (final Method method : KotlinInlineReifiedTarget.class + .getDeclaredMethods()) { + if (method.isSynthetic()) { + names.add(method.getName()); + } + } + + assertEquals(Collections.singleton("example"), names); + } + + @Test + public void test_method_count() { + assertMethodCount(2); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinJvmSyntheticTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinJvmSyntheticTest.java new file mode 100644 index 0000000000..4847d6a614 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinJvmSyntheticTest.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 static org.junit.Assert.assertEquals; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashSet; + +import org.jacoco.core.test.validation.ValidationTestBase; +import org.jacoco.core.test.validation.kotlin.targets.KotlinJvmSyntheticTarget; +import org.junit.Test; + +/** + * Test of code coverage in {@link KotlinJvmSyntheticTarget}. + */ +public class KotlinJvmSyntheticTest extends ValidationTestBase { + + public KotlinJvmSyntheticTest() { + super(KotlinJvmSyntheticTarget.class); + } + + @Test + public void compiler_should_generate_synthetic_method() { + final HashSet names = new HashSet(); + for (final Method method : KotlinJvmSyntheticTarget.class + .getDeclaredMethods()) { + if (method.isSynthetic()) { + names.add(method.getName()); + } + } + + assertEquals(Collections.singleton("example"), names); + } + + @Test + public void test_method_count() { + assertMethodCount(2); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineReifiedTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineReifiedTarget.kt new file mode 100644 index 0000000000..3ca4a2899b --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinInlineReifiedTarget.kt @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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 containing `inline` function with + * [`reified` type parameter](https://kotlinlang.org/docs/inline-functions.html#reified-type-parameters). + */ +object KotlinInlineReifiedTarget { + + private inline fun example() { // assertEmpty() + nop(T::class) // assertFullyCovered() + } // assertFullyCovered() + + @JvmStatic + fun main(args: Array) { + example() + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinJvmSyntheticTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinJvmSyntheticTarget.kt new file mode 100644 index 0000000000..4f434a2eb5 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinJvmSyntheticTarget.kt @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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 containing [JvmSynthetic] function. + */ +object KotlinJvmSyntheticTarget { + + @JvmSynthetic + private fun example() { // assertEmpty() + nop() // assertFullyCovered() + } // assertFullyCovered() + + @JvmStatic + fun main(args: Array) { + example() + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java index 81942aa480..d0cd63f417 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java @@ -57,6 +57,59 @@ public void testLambda() { assertIgnored(); } + /** + *
      +	 * @JvmSynthetic
      +	 * fun example() {
      +	 * }
      +	 * 
      + * + * @see #should_filter_synthetic_accessor_methods_in_Kotlin_classes() + */ + @Test + public void should_not_filter_synthetic_non_accessor_methods_in_Kotlin_classes() { + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_SYNTHETIC, "example", "()V", null, null); + m.visitInsn(Opcodes.RETURN); + + filter.filter(m, context, output); + + assertIgnored(); + } + + /** + *
      +	 * class Outer {
      +	 *   private var x = 42
      +	 *
      +	 *   inner class Inner {
      +	 *     fun example() {
      +	 *       x += 1
      +	 *     }
      +	 *   }
      +	 * }
      +	 * 
      + * + * @see #should_not_filter_synthetic_non_accessor_methods_in_Kotlin_classes() + */ + @Test + public void should_filter_synthetic_accessor_methods_in_Kotlin_classes() { + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_SYNTHETIC, "access$getX$p", "(Outer;)I", null, + null); + m.visitVarInsn(Opcodes.ALOAD, 0); + m.visitFieldInsn(Opcodes.GETFIELD, "Outer", "x", "I"); + m.visitInsn(Opcodes.IRETURN); + + filter.filter(m, context, output); + + assertMethodIgnored(m); + } + @Test public void should_filter_synthetic_method_with_prefix_anonfun_in_non_Scala_classes() { final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java index 6dd47fd413..64a2016175 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java @@ -16,7 +16,6 @@ import java.util.List; import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.LdcInsnNode; @@ -29,17 +28,6 @@ */ public final class KotlinCoroutineFilter implements IFilter { - static boolean isImplementationOfSuspendFunction( - final MethodNode methodNode) { - if (methodNode.name.startsWith("access$")) { - return false; - } - final Type methodType = Type.getMethodType(methodNode.desc); - final int lastArgument = methodType.getArgumentTypes().length - 1; - return lastArgument >= 0 && "kotlin.coroutines.Continuation".equals( - methodType.getArgumentTypes()[lastArgument].getClassName()); - } - public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { 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 8ea1603b0a..978dd29750 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 @@ -52,11 +52,13 @@ */ public final class KotlinDefaultArgumentsFilter implements IFilter { - static boolean isDefaultArgumentsMethod(final MethodNode methodNode) { + private static boolean isDefaultArgumentsMethod( + final MethodNode methodNode) { return methodNode.name.endsWith("$default"); } - static boolean isDefaultArgumentsConstructor(final MethodNode methodNode) { + private static boolean isDefaultArgumentsConstructor( + final MethodNode methodNode) { if (!"".equals(methodNode.name)) { return false; } 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 8a2dfd4890..55e35a621c 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 @@ -42,18 +42,7 @@ public void filter(final MethodNode methodNode, } if (KotlinGeneratedFilter.isKotlinClass(context)) { - if (KotlinDefaultArgumentsFilter - .isDefaultArgumentsMethod(methodNode)) { - return; - } - - if (KotlinDefaultArgumentsFilter - .isDefaultArgumentsConstructor(methodNode)) { - return; - } - - if (KotlinCoroutineFilter - .isImplementationOfSuspendFunction(methodNode)) { + if (!methodNode.name.startsWith("access$")) { return; } } diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 4a2ec80bd1..faf85507f1 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -22,8 +22,14 @@

      Snapshot Build @qualified.bundle.version@ (@build.date@)

      New Features

        -
      • Calculation of line coverage for Kotlin inline functions +
      • Calculation of line coverage for Kotlin inline functions (GitHub #1670).
      • +
      • Calculation of line coverage for Kotlin inline functions + with reified type parameter + (GitHub #1670, + #1700).
      • +
      • Calculation of coverage for Kotlin JvmSynthetic functions + (GitHub #1700).
      • Experimental support for Java 24 class files (GitHub #1631).
      • Part of bytecode generated by the Kotlin Compose compiler plugin is From 357a11dfce01095c8369bcdafec7d9a1251cf9fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:07:52 +0000 Subject: [PATCH 052/163] Bump actions/setup-java from 4.2.2 to 4.3.0 (#1702) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4.2.2 to 4.3.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/6a0805fcefea3d4657a47ac4c165951e33482018...2dfa2011c5b2a0f1489bf9e433881c92c1631f88) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2f388c40cf..85d617e54e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 + - uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4.3.0 with: distribution: 'zulu' java-version: | @@ -59,7 +59,7 @@ jobs: runs-on: windows-2022 steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2 + - uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88 # v4.3.0 with: distribution: 'zulu' java-version: | From 517d8e5dd523a43c73e42bc06b99de76290056c5 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 16 Sep 2024 10:21:26 +0200 Subject: [PATCH 053/163] Use Maven Wrapper (#1707) --- .azure-pipelines/azure-pipelines.yml | 12 +- .github/workflows/ci.yml | 4 +- .mvn/wrapper/maven-wrapper.properties | 19 ++ mvnw | 259 ++++++++++++++++++++++++++ mvnw.cmd | 149 +++++++++++++++ 5 files changed, 432 insertions(+), 11 deletions(-) create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100755 mvnw create mode 100644 mvnw.cmd diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 2726d645ce..485fbb31e9 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -77,12 +77,6 @@ jobs: " > toolchains.xml displayName: Setup JDK - - bash: | - set -e - mkdir .maven - curl -L "https://archive.apache.org/dist/maven/maven-3/3.8.3/binaries/apache-maven-3.8.3-bin.tar.gz" -o .maven/maven.tar.gz - tar -xzf .maven/maven.tar.gz -C .maven --strip-components 1 - displayName: Setup Maven - bash: | if [[ "$JDK_VERSION" -ge "17" ]]; then export JAVA_HOME=$PWD/.jdk @@ -90,17 +84,17 @@ jobs: export JAVA_HOME=$JAVA_HOME_17_X64 fi if [[ "$BUILD_SOURCEBRANCH" == "refs/heads/master" && "$JDK_VERSION" == "5" ]]; then - .maven/bin/mvn -V -B -e --no-transfer-progress -f org.jacoco.build \ + ./mvnw -V -B -e --no-transfer-progress -f org.jacoco.build \ verify -Djdk.version=$JDK_VERSION -Dbytecode.version=$JDK_VERSION \ deploy:deploy -DdeployAtEnd \ --toolchains=toolchains.xml --settings=.azure-pipelines/maven-settings.xml elif [[ "$BUILD_SOURCEBRANCH" == "refs/heads/master" && "$JDK_VERSION" == "11" ]]; then - .maven/bin/mvn -V -B -e --no-transfer-progress -f org.jacoco.build \ + ./mvnw -V -B -e --no-transfer-progress -f org.jacoco.build \ verify -Djdk.version=$JDK_VERSION -Dbytecode.version=$JDK_VERSION \ sonar:sonar \ --toolchains=toolchains.xml --settings=.azure-pipelines/maven-settings.xml else - .maven/bin/mvn -V -B -e --no-transfer-progress \ + ./mvnw -V -B -e --no-transfer-progress \ verify -Djdk.version=$JDK_VERSION -Dbytecode.version=$JDK_VERSION -Decj=${ECJ:-} \ --toolchains=toolchains.xml fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85d617e54e..f08ad9abec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: " > toolchains.xml - name: 'Build' run: | - mvn -V -B -e --no-transfer-progress \ + ./mvnw -V -B -e --no-transfer-progress \ verify -Djdk.version=${{ matrix.jdk }} -Dbytecode.version=${{ matrix.jdk }} \ ${{ matrix.ecj && '-Decj' || ''}} \ --toolchains=toolchains.xml @@ -88,7 +88,7 @@ jobs: - name: 'Build' shell: bash run: | - mvn -V -B -e --no-transfer-progress \ + ./mvnw -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..4cb0f7a85a --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip diff --git a/mvnw b/mvnw new file mode 100755 index 0000000000..19529ddf8c --- /dev/null +++ b/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000000..b150b91ed5 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" From 49ee4db49a3a0c4fdb0f376d729c064292fdc642 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 17 Sep 2024 06:47:44 +0200 Subject: [PATCH 054/163] Require at least Maven 3.9.9 for build (#1708) --- .mvn/wrapper/maven-wrapper.properties | 2 +- org.jacoco.build/pom.xml | 3 +- org.jacoco.doc/docroot/doc/build.html | 62 ++++++++++----------- org.jacoco.doc/docroot/doc/changes.html | 6 +- org.jacoco.doc/docroot/doc/environment.html | 2 +- 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 4cb0f7a85a..d58dfb70ba 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -16,4 +16,4 @@ # under the License. wrapperVersion=3.3.2 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index c28ccd159f..6a24dc0a69 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -519,8 +519,7 @@ 17 - - [3.6.3,3.8.2),(3.8.2,) + 3.9.9 The rules for repo1.maven.org are that pom.xml files should not include repository definitions. diff --git a/org.jacoco.doc/docroot/doc/build.html b/org.jacoco.doc/docroot/doc/build.html index efab7c1556..f524bdbce4 100644 --- a/org.jacoco.doc/docroot/doc/build.html +++ b/org.jacoco.doc/docroot/doc/build.html @@ -23,9 +23,8 @@

        Build

        The JaCoCo build is based on Maven and can be locally executed on every machine with a proper - environment setup. In particular you need at - least Maven 3.6.3 and JDK 17 - installations. Developers are encouraged to run the build before every commit + environment setup. In particular you need JDK 17 + installation. Developers are encouraged to run the build before every commit to ensure consistency of the source tree.

        @@ -33,12 +32,13 @@

        Build

        Running the Build

        - The build can be started by executing the following command with - ./org.jacoco.build/ as the working directory: + The build can be started by executing the + Maven Wrapper using following + command with ./org.jacoco.build/ as the working directory:

        -  mvn clean verify
        +  ../mvnw clean verify
         

        @@ -48,7 +48,7 @@

        Running the Build

        -  ./jacoco/target/jacoco-x.y.z.qualifier.zip
        +  ../jacoco/target/jacoco-x.y.z.qualifier.zip
         
        @@ -59,7 +59,7 @@

        Running Quick Build without Tests

        -  mvn clean verify -DskipTests
        +  ../mvnw clean verify -DskipTests
         
        @@ -305,7 +305,7 @@

        Compilation and testing with different JDKs

        -  mvn clean verify -Djdk.version=10 -Dbytecode.version=9
        +  ../mvnw clean verify -Djdk.version=10 -Dbytecode.version=9
         

        @@ -313,7 +313,7 @@

        Compilation and testing with different JDKs

        -  mvn clean verify -Decj
        +  ../mvnw clean verify -Decj
         

        @@ -321,27 +321,27 @@

        Compilation and testing with different JDKs

          -
        • mvn clean verify -Djdk.version=5 -Dbytecode.version=5
        • -
        • mvn clean verify -Djdk.version=6 -Dbytecode.version=6
        • -
        • mvn clean verify -Djdk.version=7 -Dbytecode.version=7
        • -
        • mvn clean verify -Djdk.version=8 -Dbytecode.version=8
        • -
        • mvn clean verify -Djdk.version=9 -Dbytecode.version=9
        • -
        • mvn clean verify -Djdk.version=10 -Dbytecode.version=10
        • -
        • mvn clean verify -Djdk.version=11 -Dbytecode.version=11
        • -
        • mvn clean verify -Djdk.version=11 -Dbytecode.version=11 -Decj
        • -
        • mvn clean verify -Djdk.version=12 -Dbytecode.version=12
        • -
        • mvn clean verify -Djdk.version=13 -Dbytecode.version=13
        • -
        • mvn clean verify -Djdk.version=14 -Dbytecode.version=14
        • -
        • mvn clean verify -Djdk.version=15 -Dbytecode.version=15
        • -
        • mvn clean verify -Djdk.version=16 -Dbytecode.version=16
        • -
        • mvn clean verify -Djdk.version=17 -Dbytecode.version=17
        • -
        • mvn clean verify -Djdk.version=17 -Dbytecode.version=17 -Decj
        • -
        • mvn clean verify -Djdk.version=18 -Dbytecode.version=18
        • -
        • mvn clean verify -Djdk.version=19 -Dbytecode.version=19
        • -
        • mvn clean verify -Djdk.version=20 -Dbytecode.version=20
        • -
        • mvn clean verify -Djdk.version=21 -Dbytecode.version=21
        • -
        • mvn clean verify -Djdk.version=21 -Dbytecode.version=21 -Decj
        • -
        • mvn clean verify -Djdk.version=22 -Dbytecode.version=22
        • +
        • ../mvnw clean verify -Djdk.version=5 -Dbytecode.version=5
        • +
        • ../mvnw clean verify -Djdk.version=6 -Dbytecode.version=6
        • +
        • ../mvnw clean verify -Djdk.version=7 -Dbytecode.version=7
        • +
        • ../mvnw clean verify -Djdk.version=8 -Dbytecode.version=8
        • +
        • ../mvnw clean verify -Djdk.version=9 -Dbytecode.version=9
        • +
        • ../mvnw clean verify -Djdk.version=10 -Dbytecode.version=10
        • +
        • ../mvnw clean verify -Djdk.version=11 -Dbytecode.version=11
        • +
        • ../mvnw clean verify -Djdk.version=11 -Dbytecode.version=11 -Decj
        • +
        • ../mvnw clean verify -Djdk.version=12 -Dbytecode.version=12
        • +
        • ../mvnw clean verify -Djdk.version=13 -Dbytecode.version=13
        • +
        • ../mvnw clean verify -Djdk.version=14 -Dbytecode.version=14
        • +
        • ../mvnw clean verify -Djdk.version=15 -Dbytecode.version=15
        • +
        • ../mvnw clean verify -Djdk.version=16 -Dbytecode.version=16
        • +
        • ../mvnw clean verify -Djdk.version=17 -Dbytecode.version=17
        • +
        • ../mvnw clean verify -Djdk.version=17 -Dbytecode.version=17 -Decj
        • +
        • ../mvnw clean verify -Djdk.version=18 -Dbytecode.version=18
        • +
        • ../mvnw clean verify -Djdk.version=19 -Dbytecode.version=19
        • +
        • ../mvnw clean verify -Djdk.version=20 -Dbytecode.version=20
        • +
        • ../mvnw clean verify -Djdk.version=21 -Dbytecode.version=21
        • +
        • ../mvnw clean verify -Djdk.version=21 -Dbytecode.version=21 -Decj
        • +
        • ../mvnw clean verify -Djdk.version=22 -Dbytecode.version=22
        diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index faf85507f1..564a417cfd 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -57,8 +57,10 @@

        Fixed bugs

        Non-functional Changes

          -
        • JaCoCo build now requires at least Maven 3.6.3 - (GitHub #1681).
        • +
        • JaCoCo build now uses Maven Wrapper and requires at least Maven 3.9.9 + (GitHub #1708, + #1707, + #1681).

        Release 0.8.12 (2024/03/31)

        diff --git a/org.jacoco.doc/docroot/doc/environment.html b/org.jacoco.doc/docroot/doc/environment.html index 1d827fe4f6..140a5e9f01 100644 --- a/org.jacoco.doc/docroot/doc/environment.html +++ b/org.jacoco.doc/docroot/doc/environment.html @@ -76,7 +76,7 @@

        Build

        The JaCoCo build is based on Maven - and requires at least Maven 3.6.3 and JDK 17. + and requires at least Maven 3.9.9 and JDK 17. See the build description for details.

        From 27427bd091e14fca210bed9953711103f5ce7cad Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:32:35 +0200 Subject: [PATCH 055/163] Enable checksum verification of Maven distribution (#1709) --- .mvn/wrapper/maven-wrapper.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index d58dfb70ba..fe9deed0b0 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -17,3 +17,4 @@ wrapperVersion=3.3.2 distributionType=only-script distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip +distributionSha256Sum=4ec3f26fb1a692473aea0235c300bd20f0f9fe741947c82c1234cefd76ac3a3c From 2b375134c541731816dea07e12ce7e720661d5b5 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:34:09 +0200 Subject: [PATCH 056/163] Add configuration for Dependabot to simplify updates of Maven plugins (#1701) --- .github/dependabot.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0cdb098373..f49500be46 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,7 +8,26 @@ updates: - "dependencies" - "component: build" - package-ecosystem: "maven" - directory: "/" + directory: "/org.jacoco.build" + schedule: + interval: "weekly" + labels: + - "dependencies" + - "component: build" + allow: + - dependency-name: "org.apache.maven.plugins:*" + - dependency-name: "org.codehaus.mojo:*" + - dependency-name: "com.diffplug.spotless:*" + - dependency-name: "org.sonarsource.scanner.maven:*" + ignore: + # It is known that upgrade from current version requires additional changes: + - dependency-name: "org.apache.maven.plugins:maven-plugin-plugin" + - dependency-name: "org.apache.maven.plugins:maven-invoker-plugin" + # Requires tests to be executed with Java 6: + - dependency-name: "org.apache.maven.plugins:maven-surefire-plugin" + versions: ">=2.20.0" + - package-ecosystem: "maven" + directory: "/org.jacoco.core" schedule: interval: "daily" labels: From 2f996967195423ac77390c6d43253bfc0bcdd40e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 20:30:54 +0200 Subject: [PATCH 057/163] Upgrade exec-maven-plugin to 3.4.1 (#1711) Bumps [org.codehaus.mojo:exec-maven-plugin](https://github.com/mojohaus/exec-maven-plugin) from 3.1.0 to 3.4.1. - [Release notes](https://github.com/mojohaus/exec-maven-plugin/releases) - [Commits](https://github.com/mojohaus/exec-maven-plugin/compare/exec-maven-plugin-3.1.0...3.4.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:exec-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 6a24dc0a69..50ba48cfc6 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -433,7 +433,7 @@ org.codehaus.mojo exec-maven-plugin - 3.1.0 + 3.4.1 From c185535411eda2e5974fe493a25d3998e6f1d35a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:27:50 +0000 Subject: [PATCH 058/163] Upgrade maven-toolchains-plugin to 3.2.0 (#1712) Bumps [org.apache.maven.plugins:maven-toolchains-plugin](https://github.com/apache/maven-toolchains-plugin) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/apache/maven-toolchains-plugin/releases) - [Commits](https://github.com/apache/maven-toolchains-plugin/compare/maven-toolchains-plugin-3.1.0...maven-toolchains-plugin-3.2.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-toolchains-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 50ba48cfc6..8bb3b1c24e 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -407,7 +407,7 @@ org.apache.maven.plugins maven-toolchains-plugin - 3.1.0 + 3.2.0 From a6521f1850fc494d93b630424a575610ab397493 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 20:34:00 +0000 Subject: [PATCH 059/163] Upgrade maven-clean-plugin to 3.4.0 (#1713) Bumps [org.apache.maven.plugins:maven-clean-plugin](https://github.com/apache/maven-clean-plugin) from 3.2.0 to 3.4.0. - [Release notes](https://github.com/apache/maven-clean-plugin/releases) - [Commits](https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-3.2.0...maven-clean-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-clean-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 8bb3b1c24e..0274c17461 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -307,7 +307,7 @@ org.apache.maven.plugins maven-clean-plugin - 3.2.0 + 3.4.0 org.apache.maven.plugins From d28300a5bc2bfca432b24bb660a0ceb1e1aa45d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 21:03:21 +0000 Subject: [PATCH 060/163] Upgrade build-helper-maven-plugin to 3.6.0 (#1710) Bumps [org.codehaus.mojo:build-helper-maven-plugin](https://github.com/mojohaus/build-helper-maven-plugin) from 3.4.0 to 3.6.0. - [Release notes](https://github.com/mojohaus/build-helper-maven-plugin/releases) - [Commits](https://github.com/mojohaus/build-helper-maven-plugin/compare/3.4.0...3.6.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:build-helper-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 0274c17461..012ccd702d 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -418,7 +418,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.4.0 + 3.6.0 org.codehaus.mojo From ae002e534ed9ec0ab0de17091e4f77bbe66b7346 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 23:15:10 +0000 Subject: [PATCH 061/163] Upgrade buildnumber-maven-plugin to 3.2.1 (#1714) Bumps [org.codehaus.mojo:buildnumber-maven-plugin](https://github.com/mojohaus/buildnumber-maven-plugin) from 3.1.0 to 3.2.1. - [Release notes](https://github.com/mojohaus/buildnumber-maven-plugin/releases) - [Commits](https://github.com/mojohaus/buildnumber-maven-plugin/compare/3.1.0...3.2.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:buildnumber-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 012ccd702d..c8f8323be0 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -423,7 +423,7 @@ org.codehaus.mojo buildnumber-maven-plugin - 3.1.0 + 3.2.1 org.codehaus.mojo From 9f2b0dd79f5ce74f6a5c327413d68c759bc83065 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 11:40:14 +0200 Subject: [PATCH 062/163] Upgrade org.apache.maven.plugins:maven-dependency-plugin to 3.8.0 (#1718) Bumps [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) from 3.6.0 to 3.8.0. - [Release notes](https://github.com/apache/maven-dependency-plugin/releases) - [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.6.0...maven-dependency-plugin-3.8.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-dependency-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index c8f8323be0..00bf86dd69 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -317,7 +317,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.6.0 + 3.8.0 org.apache.maven.plugins From 2e63a8db9ce73661958a332b3f8055d3c2dfb28e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:04:42 +0200 Subject: [PATCH 063/163] Upgrade maven-assembly-plugin to 3.7.1 (#1715) Bumps [org.apache.maven.plugins:maven-assembly-plugin](https://github.com/apache/maven-assembly-plugin) from 3.6.0 to 3.7.1. - [Release notes](https://github.com/apache/maven-assembly-plugin/releases) - [Commits](https://github.com/apache/maven-assembly-plugin/compare/maven-assembly-plugin-3.6.0...maven-assembly-plugin-3.7.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-assembly-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 00bf86dd69..f2103a5da4 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -302,7 +302,7 @@ org.apache.maven.plugins maven-assembly-plugin - 3.6.0 + 3.7.1 org.apache.maven.plugins From c277cd1a43fea8df96972fa00116a3c2286e9ca8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:56:04 +0200 Subject: [PATCH 064/163] Upgrade maven-jar-plugin to 3.4.2 (#1716) Bumps [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.3.0 to 3.4.2. - [Release notes](https://github.com/apache/maven-jar-plugin/releases) - [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.3.0...maven-jar-plugin-3.4.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-jar-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index f2103a5da4..eb55ce5a35 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -347,7 +347,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.3.0 + 3.4.2 org.apache.maven.plugins From 013e4c6e15ab5976dab37d0a5a987a69cf07944e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:46:35 +0200 Subject: [PATCH 065/163] Upgrade maven-enforcer-plugin to 3.5.0 (#1720) Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.3.0 to 3.5.0. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.3.0...enforcer-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index eb55ce5a35..8c9f2a1c4d 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -327,7 +327,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.3.0 + 3.5.0 org.apache.maven.plugins From 9cbd49769a18e11038869db153b242aef62ba93a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 19:10:08 +0000 Subject: [PATCH 066/163] Upgrade maven-shade-plugin to 3.6.0 (#1721) Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/apache/maven-shade-plugin/releases) - [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.0...maven-shade-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-shade-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evgeny Mandrikov --- org.jacoco.build/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 8c9f2a1c4d..23ebef2988 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -386,7 +386,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.5.0 + 3.6.0 org.apache.maven.plugins @@ -840,7 +840,7 @@ + 22 16 @@ -533,7 +533,7 @@ - + 22 16 From 91585a0eb39675200b8954d4bc9b2d428937a440 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:49:38 +0000 Subject: [PATCH 080/163] Upgrade maven-gpg-plugin to 3.2.7 (#1732) Bumps [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.2.6 to 3.2.7. - [Release notes](https://github.com/apache/maven-gpg-plugin/releases) - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.2.6...maven-gpg-plugin-3.2.7) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-gpg-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 4510045fd8..a6dfe84cde 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -342,7 +342,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.6 + 3.2.7 org.apache.maven.plugins From 66a46287d9c1cb10ae6fec3f9499554642d6a40c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 23:40:17 +0200 Subject: [PATCH 081/163] Upgrade ASM to 9.7.1 (#1739) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evgeny Mandrikov --- org.jacoco.build/licenses/{asm-9.7.html => asm-9.7.1.html} | 0 org.jacoco.build/pom.xml | 2 +- org.jacoco.doc/docroot/doc/changes.html | 2 ++ 3 files changed, 3 insertions(+), 1 deletion(-) rename org.jacoco.build/licenses/{asm-9.7.html => asm-9.7.1.html} (100%) diff --git a/org.jacoco.build/licenses/asm-9.7.html b/org.jacoco.build/licenses/asm-9.7.1.html similarity index 100% rename from org.jacoco.build/licenses/asm-9.7.html rename to org.jacoco.build/licenses/asm-9.7.1.html diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index a6dfe84cde..a870bd4b54 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -139,7 +139,7 @@ ${jvm.args} - 9.7 + 9.7.1 1.9.16 2.0.28 4.13.2 diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 564a417cfd..6b2e5f4297 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -61,6 +61,8 @@

        Non-functional Changes

        (GitHub #1708, #1707, #1681).
      • +
      • JaCoCo now depends on ASM 9.7.1 + (GitHub #1739).

      Release 0.8.12 (2024/03/31)

      From cb4b2138b49545814706c2cf5ec328940cf9b4d3 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:38:11 +0200 Subject: [PATCH 082/163] Happy birthday Java 23! (#1757) --- org.jacoco.doc/docroot/doc/build.html | 11 +++++++++++ org.jacoco.doc/docroot/doc/changes.html | 2 ++ org.jacoco.doc/docroot/doc/environment.html | 2 +- org.jacoco.doc/docroot/doc/faq.html | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/org.jacoco.doc/docroot/doc/build.html b/org.jacoco.doc/docroot/doc/build.html index f524bdbce4..3a304433a8 100644 --- a/org.jacoco.doc/docroot/doc/build.html +++ b/org.jacoco.doc/docroot/doc/build.html @@ -99,6 +99,7 @@

      Compilation and testing with different JDKs

      JDK 20 JDK 21 JDK 22 + JDK 23 @@ -122,6 +123,7 @@

      Compilation and testing with different JDKs

      21 21 + 21 org.jacoco.core.test.validation.java16 @@ -143,6 +145,7 @@

      Compilation and testing with different JDKs

      16 16 16 + 16 org.jacoco.core.test.validation.java14 @@ -164,6 +167,7 @@

      Compilation and testing with different JDKs

      14 14 14 + 14 org.jacoco.core.test.validation.java8 @@ -185,6 +189,7 @@

      Compilation and testing with different JDKs

      8 8 8 + 8 org.jacoco.core.test.validation.java7 @@ -206,6 +211,7 @@

      Compilation and testing with different JDKs

      8 8 8 + 8 org.jacoco.core.test.validation.groovy @@ -227,6 +233,7 @@

      Compilation and testing with different JDKs

      8 8 8 + 8 org.jacoco.core.test.validation.kotlin @@ -248,6 +255,7 @@

      Compilation and testing with different JDKs

      8 8 8 + 8 org.jacoco.core.test.validation.scala @@ -269,6 +277,7 @@

      Compilation and testing with different JDKs

      8 8 8 + 8 all other modules @@ -290,6 +299,7 @@

      Compilation and testing with different JDKs

      8 8 8 + 8 @@ -342,6 +352,7 @@

      Compilation and testing with different JDKs

    • ../mvnw clean verify -Djdk.version=21 -Dbytecode.version=21
    • ../mvnw clean verify -Djdk.version=21 -Dbytecode.version=21 -Decj
    • ../mvnw clean verify -Djdk.version=22 -Dbytecode.version=22
    • +
    • ../mvnw clean verify -Djdk.version=23 -Dbytecode.version=23
    diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 6b2e5f4297..144fe37ec9 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -22,6 +22,8 @@

    Snapshot Build @qualified.bundle.version@ (@build.date@)

    New Features

      +
    • JaCoCo now officially supports Java 23 + (GitHub #1757).
    • Calculation of line coverage for Kotlin inline functions (GitHub #1670).
    • Calculation of line coverage for Kotlin inline functions diff --git a/org.jacoco.doc/docroot/doc/environment.html b/org.jacoco.doc/docroot/doc/environment.html index 140a5e9f01..0bbb5c6d69 100644 --- a/org.jacoco.doc/docroot/doc/environment.html +++ b/org.jacoco.doc/docroot/doc/environment.html @@ -69,7 +69,7 @@

      JRE/JDK

      The minimum supported JRE version for JaCoCo is Java 5. To guarantee compatibility JaCoCo release builds should always be executed using JDK 5. In addition we run builds with 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 - 18, 19, 20, 21 and 22 JDKs. + 18, 19, 20, 21, 22 and 23 JDKs.

      Build

      diff --git a/org.jacoco.doc/docroot/doc/faq.html b/org.jacoco.doc/docroot/doc/faq.html index 54ba89885e..8dabc61b4b 100644 --- a/org.jacoco.doc/docroot/doc/faq.html +++ b/org.jacoco.doc/docroot/doc/faq.html @@ -45,7 +45,7 @@

      Does JaCoCo have a plug-in for [Eclipse|Netbeans|Whatever...]?

      What Java versions are supported by JaCoCo?

      - JaCoCo supports Java class files from version 1.0 to 22. However the minimum + JaCoCo supports Java class files from version 1.0 to 23. However the minimum JRE version required by the JaCoCo runtime (e.g. the agent) and the JaCoCo tools is 1.5. Also note that class files under test from version 1.6 and above have to contain valid stackmap frames. From 04d689e07e5613917d64a914d0bdf12477336a19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 09:33:26 +0000 Subject: [PATCH 083/163] Upgrade maven-javadoc-plugin to 3.10.1 (#1738) Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.10.0 to 3.10.1. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.10.0...maven-javadoc-plugin-3.10.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index a870bd4b54..90ad9e6889 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -352,7 +352,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.10.0 + 3.10.1 true false From 3a544915a86c7cbaf0b296c95c24322310c5a75b Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:08:15 +0200 Subject: [PATCH 084/163] Upgrade maven-compiler-plugin to 3.12.1 (#1730) --- .github/dependabot.yml | 6 ++++++ org.jacoco.build/pom.xml | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f49500be46..d5d2b4272d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -23,6 +23,12 @@ updates: # It is known that upgrade from current version requires additional changes: - dependency-name: "org.apache.maven.plugins:maven-plugin-plugin" - dependency-name: "org.apache.maven.plugins:maven-invoker-plugin" + # Because of + # https://github.com/apache/maven-compiler-plugin/blob/maven-compiler-plugin-3.13.0/pom.xml#L71 + # https://github.com/codehaus-plexus/plexus-compiler/blob/plexus-compiler-2.15.0/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java#L149-L163 + # requires javac version to be at least 6: + - dependency-name: "org.apache.maven.plugins:maven-compiler-plugin" + versions: ">=3.13.0" # Requires tests to be executed with Java 6: - dependency-name: "org.apache.maven.plugins:maven-surefire-plugin" versions: ">=2.20.0" diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 90ad9e6889..e41f899683 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -312,7 +312,8 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + + 3.12.1 org.apache.maven.plugins From eef103a35387855e5a4157e0aceab1d4428b5dd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:34:05 +0200 Subject: [PATCH 085/163] Upgrade exec-maven-plugin to 3.5.0 (#1760) Bumps [org.codehaus.mojo:exec-maven-plugin](https://github.com/mojohaus/exec-maven-plugin) from 3.4.1 to 3.5.0. - [Release notes](https://github.com/mojohaus/exec-maven-plugin/releases) - [Commits](https://github.com/mojohaus/exec-maven-plugin/compare/3.4.1...3.5.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:exec-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index e41f899683..f167167e3b 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -434,7 +434,7 @@ org.codehaus.mojo exec-maven-plugin - 3.4.1 + 3.5.0 From 1a6ad9dcd6fbeedfc7cb098f23b15e227ed1b275 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 23:03:43 +0100 Subject: [PATCH 086/163] Bump actions/checkout from 4.2.1 to 4.2.2 (#1761) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.1 to 4.2.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871...11bd71901bbe5b1630ceea73d27597364c9af683) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eac5fb5c5a..4de0942972 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: name: JDK ${{ matrix.jdk }}${{ matrix.ecj && ' with ECJ' || ''}} runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 with: distribution: 'zulu' @@ -58,7 +58,7 @@ jobs: Windows: runs-on: windows-2022 steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 with: distribution: 'zulu' From d5908a249db6aa76b14f9661bc7f40e41ec7bc0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 22:33:26 +0000 Subject: [PATCH 087/163] Bump actions/setup-java from 4.4.0 to 4.5.0 (#1763) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4.4.0 to 4.5.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/b36c23c0d998641eff861008f374ee103c25ac73...8df1039502a15bceb9433410b1a100fbe190c53b) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4de0942972..089b7f2f39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 + - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: distribution: 'zulu' java-version: | @@ -59,7 +59,7 @@ jobs: runs-on: windows-2022 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 + - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: distribution: 'zulu' java-version: | From bb9fdd670f2b5cf511520721461488cf1ecfc117 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 09:49:41 +0000 Subject: [PATCH 088/163] Upgrade maven-dependency-plugin to 3.8.1 (#1762) Bump org.apache.maven.plugins:maven-dependency-plugin Bumps [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) from 3.8.0 to 3.8.1. - [Release notes](https://github.com/apache/maven-dependency-plugin/releases) - [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.8.0...maven-dependency-plugin-3.8.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-dependency-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index f167167e3b..f074d89ad4 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -318,7 +318,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.8.0 + 3.8.1 org.apache.maven.plugins From 00312094ecf4ea543eeaf3beb7dcfdb932898405 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:03:49 +0100 Subject: [PATCH 089/163] Add configuration files for Java code formatting in IntelliJ IDEA (#1704) * `.idea/externalDependencies.xml` to require installation of EclipseCodeFormatter plugin into IntelliJ IDEA * `.idea/eclipseCodeFormatter.xml` configures plugin to use the same settings as for Eclipse IDE and spotelss-maven-plugin * `.idea/codeStyles/codeStyleConfig.xml` and `.idea/codeStyles/Project.xml` prevent use of wildcard imports --- .idea/codeStyles/Project.xml | 8 ++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 +++++ .idea/eclipseCodeFormatter.xml | 12 ++++++++++++ .idea/externalDependencies.xml | 6 ++++++ 4 files changed, 31 insertions(+) create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/eclipseCodeFormatter.xml create mode 100644 .idea/externalDependencies.xml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000000..a74a84d3a0 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000000..79ee123c2b --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/eclipseCodeFormatter.xml b/.idea/eclipseCodeFormatter.xml new file mode 100644 index 0000000000..992c75f5c6 --- /dev/null +++ b/.idea/eclipseCodeFormatter.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/externalDependencies.xml b/.idea/externalDependencies.xml new file mode 100644 index 0000000000..0502dcf71c --- /dev/null +++ b/.idea/externalDependencies.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 11567593d0d1d5a9a5cc674baf4cf0e82c74966c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:12:38 +0000 Subject: [PATCH 090/163] Upgrade maven-javadoc-plugin to 3.11.1 (#1767) Bump org.apache.maven.plugins:maven-javadoc-plugin in /org.jacoco.build Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.10.1 to 3.11.1. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.10.1...maven-javadoc-plugin-3.11.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index f074d89ad4..f5f451e58d 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -353,7 +353,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.10.1 + 3.11.1 true false From 7e3207484e2df256838186be8c7ed5c72e8f93ac Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 13 Nov 2024 07:59:28 +0100 Subject: [PATCH 091/163] Fix typo (#1775) --- .../src/org/jacoco/core/internal/analysis/LineImplTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/LineImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/LineImplTest.java index 1bba4f1109..fc35bd6293 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/LineImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/LineImplTest.java @@ -20,7 +20,7 @@ import org.junit.Test; /** - * Unit tests for {@link LineImplTest}. + * Unit tests for {@link LineImpl}. */ public class LineImplTest { From a69d52865f34cd5cb1b7a673c1b57282dea74dec Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:48:00 +0100 Subject: [PATCH 092/163] Fix warning "'reportOutputDirectory' is unknown for plugin 'maven-javadoc-plugin:3.11.1:jar (attach-javadocs)'" (#1776) `reportOutputDirectory` parameter was removed in maven-javadoc-plugin version 3.10.0 by https://github.com/apache/maven-javadoc-plugin/commit/9638a6a76c6db53c3bf8ffbd5cec7318b0e25303 (https://issues.apache.org/jira/browse/MJAVADOC-785). This was overlooked in commit 435579f27cb8259ba14c1a868245a843e053211f. `outputDirectory` parameter can be used to restore prior behavior, but this customization seems unnecessary. --- org.jacoco.doc/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/org.jacoco.doc/pom.xml b/org.jacoco.doc/pom.xml index 6176308713..afd5f62766 100644 --- a/org.jacoco.doc/pom.xml +++ b/org.jacoco.doc/pom.xml @@ -198,7 +198,6 @@ jar - ${project.build.directory}/apidocs true *.internal.*,*.internal,org.jacoco.ant,org.jacoco.maven,org.jacoco.examples From 3c44d5fd8d74f768301d9957237cf8db2052794b Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 15 Nov 2024 22:52:12 +0100 Subject: [PATCH 093/163] KotlinWhenFilter should handle nullable enums (#1774) --- .../targets/KotlinWhenExpressionTarget.kt | 33 +++ .../analysis/filter/KotlinWhenFilterTest.java | 198 ++++++++++++++++++ .../analysis/filter/KotlinWhenFilter.java | 45 +++- org.jacoco.doc/docroot/doc/changes.html | 4 + 4 files changed, 276 insertions(+), 4 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt index ccf98244bb..6f5b004b5c 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt @@ -50,6 +50,27 @@ object KotlinWhenExpressionTarget { else -> throw NoWhenBranchMatchedException() // assertEmpty() } // assertFullyCovered() + private fun whenByNullableEnumWithNullCaseAndWithoutElse(e: Enum?): String = + when (e) { // assertFullyCovered(0, 3) + Enum.A -> "a" // assertFullyCovered() + Enum.B -> "b" // assertFullyCovered() + null -> "null" // assertFullyCovered() + } // assertFullyCovered() + + private fun whenByNullableEnumWithoutNullCaseAndWithElse(e: Enum?): String = + when (e) { // assertFullyCovered(0, 3) + Enum.A -> "a" // assertFullyCovered() + Enum.B -> "b" // assertFullyCovered() + else -> "else" // assertFullyCovered() + } // assertFullyCovered() + + private fun whenByNullableEnumWithNullAndElseCases(e: Enum?): String = + when (e) { // assertFullyCovered(0, 3) + Enum.A -> "a" // assertFullyCovered() + null -> "null" // assertFullyCovered() + else -> "else" // assertFullyCovered() + } // assertFullyCovered() + private fun whenString(p: String): Int = when (p) { // assertFullyCovered(0, 7) "a" -> 1 // assertFullyCovered() "b" -> 2 // assertFullyCovered() @@ -88,6 +109,18 @@ object KotlinWhenExpressionTarget { whenEnumRedundantElse(Enum.A) whenEnumRedundantElse(Enum.B) + whenByNullableEnumWithNullCaseAndWithoutElse(Enum.A) + whenByNullableEnumWithNullCaseAndWithoutElse(Enum.B) + whenByNullableEnumWithNullCaseAndWithoutElse(null) + + whenByNullableEnumWithoutNullCaseAndWithElse(Enum.A) + whenByNullableEnumWithoutNullCaseAndWithElse(Enum.B) + whenByNullableEnumWithoutNullCaseAndWithElse(null) + + whenByNullableEnumWithNullAndElseCases(Enum.A) + whenByNullableEnumWithNullAndElseCases(Enum.B) + whenByNullableEnumWithNullAndElseCases(null) + whenString("") whenString("a") whenString("b") diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilterTest.java index bc366aac5a..77dcd4b583 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilterTest.java @@ -121,4 +121,202 @@ public void should_filter_implicit_default() { assertReplacedBranches(switchNode, newTargets); } + /** + *

      +	 * enum class E { A, B }
      +	 * fun example(e: E?) = when (e) {
      +	 *     E.A -> "a"
      +	 *     E.B -> "b"
      +	 *     null -> "null"
      +	 * }
      +	 * 
      + */ + @Test + public void should_filter_when_by_nullable_enum_with_null_case_and_without_else() { + final Range range1 = new Range(); + final Range range2 = new Range(); + final HashSet newTargets = new HashSet(); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "example", "(LE;)Ljava/lang/String;", null, null); + final Label l1 = new Label(); + final Label l2 = new Label(); + final Label caseNull = new Label(); + final Label caseElse = new Label(); + final Label caseA = new Label(); + final Label caseB = new Label(); + final Label after = new Label(); + + m.visitVarInsn(Opcodes.ALOAD, 1); + m.visitInsn(Opcodes.DUP); + range1.fromInclusive = m.instructions.getLast(); + m.visitJumpInsn(Opcodes.IFNONNULL, l1); + m.visitInsn(Opcodes.POP); + m.visitInsn(Opcodes.ICONST_M1); + m.visitJumpInsn(Opcodes.GOTO, l2); + m.visitLabel(l1); + m.visitFieldInsn(Opcodes.GETSTATIC, "ExampleKt$WhenMappings", + "$EnumSwitchMapping$0", "[I"); + m.visitInsn(Opcodes.SWAP); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "ExampleKt$Enum", "ordinal", + "()I", false); + m.visitInsn(Opcodes.IALOAD); + m.visitLabel(l2); + range1.toInclusive = m.instructions.getLast(); + m.visitTableSwitchInsn(-1, 2, caseElse, caseNull, caseElse, caseA, + caseB); + final AbstractInsnNode switchNode = m.instructions.getLast(); + + m.visitLabel(caseA); + m.visitLdcInsn("a"); + newTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, after); + + m.visitLabel(caseB); + m.visitLdcInsn("b"); + newTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, after); + + m.visitLabel(caseNull); + m.visitLdcInsn("null"); + newTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, after); + + m.visitLabel(caseElse); + range2.fromInclusive = m.instructions.getLast(); + m.visitTypeInsn(Opcodes.NEW, "kotlin/NoWhenBranchMatchedException"); + m.visitInsn(Opcodes.DUP); + m.visitMethodInsn(Opcodes.INVOKESPECIAL, + "kotlin/NoWhenBranchMatchedException", "", "()V", false); + m.visitInsn(Opcodes.ATHROW); + range2.toInclusive = m.instructions.getLast(); + + m.visitLabel(after); + m.visitInsn(Opcodes.ARETURN); + + filter.filter(m, context, output); + + assertIgnored(range1, range2); + assertReplacedBranches(switchNode, newTargets); + } + + /** + *
      +	 * enum class E { A, B }
      +	 * fun example(e: E?) = when (e) {
      +	 *     E.A -> "a"
      +	 *     E.B -> "b"
      +	 *     else -> "else"
      +	 * }
      +	 * 
      + */ + @Test + public void should_filter_when_by_nullable_enum_without_null_case_and_with_else() { + final Range range1 = new Range(); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "example", "(LE;)Ljava/lang/String;", null, null); + final Label l1 = new Label(); + final Label l2 = new Label(); + final Label caseElse = new Label(); + final Label caseA = new Label(); + final Label caseB = new Label(); + final Label after = new Label(); + + m.visitVarInsn(Opcodes.ALOAD, 1); + m.visitInsn(Opcodes.DUP); + range1.fromInclusive = m.instructions.getLast(); + m.visitJumpInsn(Opcodes.IFNONNULL, l1); + m.visitInsn(Opcodes.POP); + m.visitInsn(Opcodes.ICONST_M1); + m.visitJumpInsn(Opcodes.GOTO, l2); + m.visitLabel(l1); + m.visitFieldInsn(Opcodes.GETSTATIC, "ExampleKt$WhenMappings", + "$EnumSwitchMapping$0", "[I"); + m.visitInsn(Opcodes.SWAP); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "ExampleKt$Enum", "ordinal", + "()I", false); + m.visitInsn(Opcodes.IALOAD); + m.visitLabel(l2); + range1.toInclusive = m.instructions.getLast(); + m.visitTableSwitchInsn(1, 2, caseElse, caseA, caseB); + + m.visitLabel(caseA); + m.visitLdcInsn("a"); + m.visitJumpInsn(Opcodes.GOTO, after); + + m.visitLabel(caseB); + m.visitLdcInsn("b"); + m.visitJumpInsn(Opcodes.GOTO, after); + + m.visitLabel(caseElse); + m.visitLdcInsn("else"); + + m.visitLabel(after); + m.visitInsn(Opcodes.ARETURN); + + filter.filter(m, context, output); + + assertIgnored(range1); + assertNoReplacedBranches(); + } + + /** + *
      +	 * enum class E { A, B }
      +	 * fun example(e: E?) = when (e) {
      +	 *     E.A -> "a"
      +	 *     null -> "null"
      +	 *     else -> "else"
      +	 * }
      +	 * 
      + */ + @Test + public void should_filter_when_by_nullable_enum_with_null_and_else_cases() { + final Range range1 = new Range(); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "example", "(LE;)Ljava/lang/String;", null, null); + final Label l1 = new Label(); + final Label l2 = new Label(); + final Label caseNull = new Label(); + final Label caseElse = new Label(); + final Label caseA = new Label(); + final Label after = new Label(); + + m.visitVarInsn(Opcodes.ALOAD, 1); + m.visitInsn(Opcodes.DUP); + range1.fromInclusive = m.instructions.getLast(); + m.visitJumpInsn(Opcodes.IFNONNULL, l1); + m.visitInsn(Opcodes.POP); + m.visitInsn(Opcodes.ICONST_M1); + m.visitJumpInsn(Opcodes.GOTO, l2); + m.visitLabel(l1); + m.visitFieldInsn(Opcodes.GETSTATIC, "ExampleKt$WhenMappings", + "$EnumSwitchMapping$0", "[I"); + m.visitInsn(Opcodes.SWAP); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "ExampleKt$Enum", "ordinal", + "()I", false); + m.visitInsn(Opcodes.IALOAD); + m.visitLabel(l2); + range1.toInclusive = m.instructions.getLast(); + m.visitTableSwitchInsn(-1, 1, caseElse, caseNull, caseA); + + m.visitLabel(caseA); + m.visitLdcInsn("a"); + m.visitJumpInsn(Opcodes.GOTO, after); + + m.visitLabel(caseNull); + m.visitLdcInsn("null"); + m.visitJumpInsn(Opcodes.GOTO, after); + + m.visitLabel(caseElse); + m.visitLdcInsn("else"); + + m.visitLabel(after); + m.visitInsn(Opcodes.ARETURN); + + filter.filter(m, context, output); + + assertIgnored(range1); + assertNoReplacedBranches(); + } + } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java index 354161918e..202ed3bea6 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java @@ -18,6 +18,7 @@ import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.FieldInsnNode; import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.LabelNode; import org.objectweb.asm.tree.LookupSwitchInsnNode; @@ -26,9 +27,8 @@ /** * Filters bytecode that Kotlin compiler generates for when - * expressions which list all cases of enum or - * sealed class, i.e. which don't require explicit - * else. + * expressions and statements with subject of type enum class or + * sealed class. */ public final class KotlinWhenFilter implements IFilter { @@ -39,6 +39,7 @@ public void filter(final MethodNode methodNode, final Matcher matcher = new Matcher(); for (final AbstractInsnNode i : methodNode.instructions) { matcher.match(i, output); + matcher.matchNullableEnum(i, output); } } @@ -69,6 +70,39 @@ void match(final AbstractInsnNode start, final IFilterOutput output) { } } } + + void matchNullableEnum(final AbstractInsnNode start, + final IFilterOutput output) { + if (start.getOpcode() != Opcodes.DUP) { + return; + } + cursor = start; + // https://github.com/JetBrains/kotlin/blob/v2.0.0/compiler/backend/src/org/jetbrains/kotlin/codegen/when/EnumSwitchCodegen.java#L46 + nextIs(Opcodes.IFNONNULL); + final JumpInsnNode jump1 = (JumpInsnNode) cursor; + nextIs(Opcodes.POP); + nextIs(Opcodes.ICONST_M1); + nextIs(Opcodes.GOTO); + final JumpInsnNode jump2 = (JumpInsnNode) cursor; + nextIs(Opcodes.GETSTATIC); + final FieldInsnNode fieldInsnNode = (FieldInsnNode) cursor; + // https://github.com/JetBrains/kotlin/blob/v2.0.0/compiler/backend/src/org/jetbrains/kotlin/codegen/when/WhenByEnumsMapping.java#L27-L28 + if (fieldInsnNode == null + || !fieldInsnNode.owner.endsWith("$WhenMappings") + || !fieldInsnNode.name.startsWith("$EnumSwitchMapping$")) { + return; + } + nextIs(Opcodes.SWAP); + nextIs(Opcodes.INVOKEVIRTUAL); // ordinal()I + nextIs(Opcodes.IALOAD); + nextIsSwitch(); + if (cursor != null + && skipNonOpcodes(jump1.label) == skipNonOpcodes( + jump2.getNext()) + && skipNonOpcodes(jump2.label) == cursor) { + output.ignore(start, cursor.getPrevious()); + } + } } private static LabelNode getDefaultLabel(final AbstractInsnNode i) { @@ -90,9 +124,12 @@ private static void ignoreDefaultBranch(final AbstractInsnNode switchNode, } else { labels = ((TableSwitchInsnNode) switchNode).labels; } + final LabelNode defaultLabel = getDefaultLabel(switchNode); final Set newTargets = new HashSet(); for (final LabelNode label : labels) { - newTargets.add(AbstractMatcher.skipNonOpcodes(label)); + if (label != defaultLabel) { + newTargets.add(AbstractMatcher.skipNonOpcodes(label)); + } } output.replaceBranches(switchNode, newTargets); } diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 144fe37ec9..2a5caaa836 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -43,6 +43,10 @@

      New Features

    • Part of bytecode generated by the Kotlin compiler for suspending lambdas without suspension points is filtered out during generation of report (GitHub #1283).
    • +
    • Part of bytecode generated by the Kotlin compiler for when + expressions and statements with nullable enum subject is filtered out during + generation of report + (GitHub #1774).
    • Method getEntries generated by the Kotlin compiler for enum classes is filtered out during generation of report (GitHub #1625).
    • From c533dedc7cc6d1408836059c01459a8487db6485 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sat, 16 Nov 2024 07:40:53 +0100 Subject: [PATCH 094/163] Fix typo (#1777) --- .../src/org/jacoco/core/internal/flow/LabelInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java index 48e813bd79..e3217d3e6d 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java @@ -119,7 +119,7 @@ public static void setMethodInvocationLine(final Label label) { } /** - * Checks whether the a given label has been marked as a line with method + * Checks whether the given label has been marked as a line with method * invocations. * * @param label From 9368edebe136dba2477ad05a05873c08842f3b6b Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:31:24 +0100 Subject: [PATCH 095/163] Split KotlinWhenExpressionTarget (#1778) --- ...ssionTest.java => KotlinWhenEnumTest.java} | 10 +-- .../kotlin/KotlinWhenSealedTest.java | 27 ++++++++ .../kotlin/KotlinWhenStringTest.java | 27 ++++++++ ...ssionTarget.kt => KotlinWhenEnumTarget.kt} | 66 +------------------ .../kotlin/targets/KotlinWhenSealedTarget.kt | 46 +++++++++++++ .../kotlin/targets/KotlinWhenStringTarget.kt | 62 +++++++++++++++++ 6 files changed, 169 insertions(+), 69 deletions(-) rename org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/{KotlinWhenExpressionTest.java => KotlinWhenEnumTest.java} (77%) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenSealedTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenStringTest.java rename org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/{KotlinWhenExpressionTarget.kt => KotlinWhenEnumTarget.kt} (54%) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenSealedTarget.kt create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenStringTarget.kt diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenExpressionTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenEnumTest.java similarity index 77% rename from org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenExpressionTest.java rename to org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenEnumTest.java index 5bfe46d5d5..4aae895a46 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenExpressionTest.java +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenEnumTest.java @@ -13,15 +13,15 @@ package org.jacoco.core.test.validation.kotlin; import org.jacoco.core.test.validation.ValidationTestBase; -import org.jacoco.core.test.validation.kotlin.targets.KotlinWhenExpressionTarget; +import org.jacoco.core.test.validation.kotlin.targets.KotlinWhenEnumTarget; /** - * Test of when expressions. + * Test of code coverage in {@link KotlinWhenEnumTarget}. */ -public class KotlinWhenExpressionTest extends ValidationTestBase { +public class KotlinWhenEnumTest extends ValidationTestBase { - public KotlinWhenExpressionTest() { - super(KotlinWhenExpressionTarget.class); + public KotlinWhenEnumTest() { + super(KotlinWhenEnumTarget.class); } } diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenSealedTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenSealedTest.java new file mode 100644 index 0000000000..25424b0dd6 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenSealedTest.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.KotlinWhenSealedTarget; + +/** + * Test of code coverage in {@link KotlinWhenSealedTarget}. + */ +public class KotlinWhenSealedTest extends ValidationTestBase { + + public KotlinWhenSealedTest() { + super(KotlinWhenSealedTarget.class); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenStringTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenStringTest.java new file mode 100644 index 0000000000..404931faba --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinWhenStringTest.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.KotlinWhenStringTarget; + +/** + * Test of code coverage in {@link KotlinWhenStringTarget}. + */ +public class KotlinWhenStringTest extends ValidationTestBase { + + public KotlinWhenStringTest() { + super(KotlinWhenStringTarget.class); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenEnumTarget.kt similarity index 54% rename from org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt rename to org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenEnumTarget.kt index 6f5b004b5c..5983d5b3ce 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenExpressionTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenEnumTarget.kt @@ -13,26 +13,9 @@ package org.jacoco.core.test.validation.kotlin.targets /** - * This test target is `when` expression. + * Test target with `when` expressions with subject of type `enum class`. */ -object KotlinWhenExpressionTarget { - - private sealed class Sealed { - object Sealed1 : Sealed() - object Sealed2 : Sealed() - } - - private fun whenSealed(p: Sealed): Int = when (p) { // assertFullyCovered() - is Sealed.Sealed1 -> 1 // assertFullyCovered(0, 2) - is Sealed.Sealed2 -> 2 // assertFullyCovered() - } // assertFullyCovered() - - @Suppress("REDUNDANT_ELSE_IN_WHEN") - private fun whenSealedRedundantElse(p: Sealed): Int = when (p) { // assertFullyCovered() - is Sealed.Sealed1 -> 1 // assertFullyCovered(0, 2) - is Sealed.Sealed2 -> 2 // assertFullyCovered(0, 0) - else -> throw NoWhenBranchMatchedException() // assertEmpty() - } // assertFullyCovered() +object KotlinWhenEnumTarget { private enum class Enum { A, B @@ -71,38 +54,8 @@ object KotlinWhenExpressionTarget { else -> "else" // assertFullyCovered() } // assertFullyCovered() - private fun whenString(p: String): Int = when (p) { // assertFullyCovered(0, 7) - "a" -> 1 // assertFullyCovered() - "b" -> 2 // assertFullyCovered() - "c" -> 3 // assertFullyCovered() - "\u0000a" -> 4 // assertFullyCovered() - "\u0000b" -> 5 // assertFullyCovered() - "\u0000c" -> 6 // assertFullyCovered() - else -> 7 // assertFullyCovered() - } // assertFullyCovered() - - /** - * Unlike [whenString] - * in this example first case is the only case with biggest hashCode value. - * FIXME https://github.com/jacoco/jacoco/issues/1295 - */ - private fun whenStringBiggestHashCodeFirst(p: String): Int = when (p) { // assertPartlyCovered(3, 11) - "c" -> 1 // assertFullyCovered() - "b" -> 2 // assertFullyCovered() - "\u0000b" -> 3 // assertFullyCovered() - "a" -> 4 // assertFullyCovered() - "\u0000a" -> 5 // assertFullyCovered() - else -> 6 // assertFullyCovered() - } // assertFullyCovered() - @JvmStatic fun main(args: Array) { - whenSealed(Sealed.Sealed1) - whenSealed(Sealed.Sealed2) - - whenSealedRedundantElse(Sealed.Sealed1) - whenSealedRedundantElse(Sealed.Sealed2) - whenEnum(Enum.A) whenEnum(Enum.B) @@ -120,21 +73,6 @@ object KotlinWhenExpressionTarget { whenByNullableEnumWithNullAndElseCases(Enum.A) whenByNullableEnumWithNullAndElseCases(Enum.B) whenByNullableEnumWithNullAndElseCases(null) - - whenString("") - whenString("a") - whenString("b") - whenString("c") - whenString("\u0000a") - whenString("\u0000b") - whenString("\u0000c") - - whenStringBiggestHashCodeFirst("") - whenStringBiggestHashCodeFirst("a") - whenStringBiggestHashCodeFirst("b") - whenStringBiggestHashCodeFirst("c") - whenStringBiggestHashCodeFirst("\u0000a") - whenStringBiggestHashCodeFirst("\u0000b") } } diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenSealedTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenSealedTarget.kt new file mode 100644 index 0000000000..12ec77ab52 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenSealedTarget.kt @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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 + +/** + * Test target with `when` expressions with subject of type `enum class`. + */ +object KotlinWhenSealedTarget { + + private sealed class Sealed { + object Sealed1 : Sealed() + object Sealed2 : Sealed() + } + + private fun whenSealed(p: Sealed): Int = when (p) { // assertFullyCovered() + is Sealed.Sealed1 -> 1 // assertFullyCovered(0, 2) + is Sealed.Sealed2 -> 2 // assertFullyCovered() + } // assertFullyCovered() + + @Suppress("REDUNDANT_ELSE_IN_WHEN") + private fun whenSealedRedundantElse(p: Sealed): Int = when (p) { // assertFullyCovered() + is Sealed.Sealed1 -> 1 // assertFullyCovered(0, 2) + is Sealed.Sealed2 -> 2 // assertFullyCovered(0, 0) + else -> throw NoWhenBranchMatchedException() // assertEmpty() + } // assertFullyCovered() + + @JvmStatic + fun main(args: Array) { + whenSealed(Sealed.Sealed1) + whenSealed(Sealed.Sealed2) + + whenSealedRedundantElse(Sealed.Sealed1) + whenSealedRedundantElse(Sealed.Sealed2) + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenStringTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenStringTarget.kt new file mode 100644 index 0000000000..234c141221 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenStringTarget.kt @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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 + +/** + * Test target with `when` expressions with subject of type `String`. + */ +object KotlinWhenStringTarget { + + private fun whenString(p: String): Int = when (p) { // assertFullyCovered(0, 7) + "a" -> 1 // assertFullyCovered() + "b" -> 2 // assertFullyCovered() + "c" -> 3 // assertFullyCovered() + "\u0000a" -> 4 // assertFullyCovered() + "\u0000b" -> 5 // assertFullyCovered() + "\u0000c" -> 6 // assertFullyCovered() + else -> 7 // assertFullyCovered() + } // assertFullyCovered() + + /** + * Unlike [whenString] + * in this example first case is the only case with biggest hashCode value. + * FIXME https://github.com/jacoco/jacoco/issues/1295 + */ + private fun whenStringBiggestHashCodeFirst(p: String): Int = when (p) { // assertPartlyCovered(3, 11) + "c" -> 1 // assertFullyCovered() + "b" -> 2 // assertFullyCovered() + "\u0000b" -> 3 // assertFullyCovered() + "a" -> 4 // assertFullyCovered() + "\u0000a" -> 5 // assertFullyCovered() + else -> 6 // assertFullyCovered() + } // assertFullyCovered() + + @JvmStatic + fun main(args: Array) { + whenString("") + whenString("a") + whenString("b") + whenString("c") + whenString("\u0000a") + whenString("\u0000b") + whenString("\u0000c") + + whenStringBiggestHashCodeFirst("") + whenStringBiggestHashCodeFirst("a") + whenStringBiggestHashCodeFirst("b") + whenStringBiggestHashCodeFirst("c") + whenStringBiggestHashCodeFirst("\u0000a") + whenStringBiggestHashCodeFirst("\u0000b") + } + +} From f34c838f1c31531b60d905607f35d531ddaacae1 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:00:28 +0100 Subject: [PATCH 096/163] Validation tests should create ASMified and TEXTified bytecode representations (#1770) --- .../test/validation/ValidationTestBase.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java index 50ccd23e15..e3417a3d7a 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java @@ -17,6 +17,7 @@ import java.io.File; import java.io.IOException; +import java.io.PrintWriter; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -43,6 +44,10 @@ import org.junit.Before; import org.junit.Test; import org.junit.runners.model.MultipleFailureException; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.util.ASMifier; +import org.objectweb.asm.util.Textifier; +import org.objectweb.asm.util.TraceClassVisitor; /** * Base class for validation tests. It executes the given class under code @@ -107,6 +112,23 @@ private void analyze(final Analyzer analyzer, final ExecutionData data) final byte[] bytes = TargetLoader .getClassDataAsBytes(target.getClassLoader(), data.getName()); analyzer.analyzeClass(bytes, data.getName()); + saveBytecodeRepresentations(bytes, data.getName()); + } + + private void saveBytecodeRepresentations(final byte[] classBytes, + final String className) throws IOException { + final File outputDir = new File("target/asm/" + target.getSimpleName()); + outputDir.mkdirs(); + final String fileName = className.replace('/', '.'); + final PrintWriter textWriter = new PrintWriter( + new File(outputDir, fileName + ".txt")); + final PrintWriter asmWriter = new PrintWriter( + new File(outputDir, fileName + ".java")); + new ClassReader(classBytes).accept(new TraceClassVisitor( + new TraceClassVisitor(null, new Textifier(), textWriter), + new ASMifier(), asmWriter), 0); + textWriter.close(); + asmWriter.close(); } /** From 1e8b179cc08dc00f8507b67db6582861fe3068f5 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 20 Nov 2024 08:24:40 +0100 Subject: [PATCH 097/163] Fix typo: replace "a instrumented" by "an instrumented" (#1781) "an" should be used instead of "a" when the following word starts with a vowel sound. --- .../core/test/perf/ExecuteInstrumentedCodeScenario.java | 2 +- .../src/org/jacoco/core/instr/Instrumenter.java | 8 ++++---- .../org/jacoco/core/internal/instr/ClassInstrumenter.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/ExecuteInstrumentedCodeScenario.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/ExecuteInstrumentedCodeScenario.java index 0bd610fd98..54e455ab7d 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/ExecuteInstrumentedCodeScenario.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/ExecuteInstrumentedCodeScenario.java @@ -22,7 +22,7 @@ /** * This scenario runs a given scenario twice and reports the execution time: - * Once on its original version, once in a instrumented version. + * Once on its original version, once in an instrumented version. */ public class ExecuteInstrumentedCodeScenario extends TimedScenario { diff --git a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java index 7aaa4bb9d0..0b78892373 100644 --- a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java +++ b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java @@ -93,7 +93,7 @@ protected String getCommonSuperClass(final String type1, } /** - * Creates a instrumented version of the given class if possible. + * Creates an instrumented version of the given class if possible. * * @param buffer * definition of the class @@ -113,7 +113,7 @@ public byte[] instrument(final byte[] buffer, final String name) } /** - * Creates a instrumented version of the given class if possible. The + * Creates an instrumented version of the given class if possible. The * provided {@link InputStream} is not closed by this method. * * @param input @@ -137,7 +137,7 @@ public byte[] instrument(final InputStream input, final String name) } /** - * Creates a instrumented version of the given class file. The provided + * Creates an instrumented version of the given class file. The provided * {@link InputStream} and {@link OutputStream} instances are not closed by * this method. * @@ -166,7 +166,7 @@ private IOException instrumentError(final String name, } /** - * Creates a instrumented version of the given resource depending on its + * Creates an instrumented version of the given resource depending on its * type. Class files and the content of archive files are instrumented. All * other files are copied without modification. The provided * {@link InputStream} and {@link OutputStream} instances are not closed by diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java index ff76b441c6..52847b2370 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java @@ -28,7 +28,7 @@ public class ClassInstrumenter extends ClassProbesVisitor { private String className; /** - * Emits a instrumented version of this class to the given class visitor. + * Emits an instrumented version of this class to the given class visitor. * * @param probeArrayStrategy * this strategy will be used to access the probe array From 20f076cb921588b80e6bb0b397b9aaf4dde910b5 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 20 Nov 2024 20:49:24 +0100 Subject: [PATCH 098/163] Fix typo: replace "an child" by "a child" (#1782) "a" should be used instead of "an" when the following word doesn't start with a vowel sound. --- .../src/org/jacoco/report/internal/xml/XMLElement.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java index 7908970c90..950b377647 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java @@ -157,7 +157,7 @@ private void quote(final String text) throws IOException { } /** - * Adds an attribute to this element. May only be called before an child + * Adds an attribute to this element. May only be called before a child * element is added or this element has been closed. The attribute value * will be quoted. If the value is null the attribute will not * be added. @@ -188,7 +188,7 @@ public final void attr(final String name, final String value) } /** - * Adds an attribute to this element. May only be called before an child + * Adds an attribute to this element. May only be called before a child * element is added or this element has been closed. The attribute value is * the decimal representation of the given int value. * @@ -206,7 +206,7 @@ public final void attr(final String name, final int value) } /** - * Adds an attribute to this element. May only be called before an child + * Adds an attribute to this element. May only be called before a child * element is added or this element has been closed. The attribute value is * the decimal representation of the given long value. * From 764b1d1026c9dc58028cfbb03a90f6048135ffcf Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 21 Nov 2024 06:50:12 +0100 Subject: [PATCH 099/163] Fix typo (#1783) --- .../src/org/jacoco/report/internal/html/page/SessionsPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/SessionsPage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/SessionsPage.java index a51c3f7680..4ec8ad08d0 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/SessionsPage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/SessionsPage.java @@ -54,7 +54,7 @@ public class SessionsPage extends ReportPage { private final ElementIndex index; /** - * Creates a new page page to display session information. + * Creates a new page to display session information. * * @param sessionInfos * session info objects From ed3cb650e1dd477fcdf8a74e799b60825e5a98a3 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 21 Nov 2024 21:43:21 +0100 Subject: [PATCH 100/163] Build should not produce warning about generation of JUnit report (#1784) --- org.jacoco.doc/pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/org.jacoco.doc/pom.xml b/org.jacoco.doc/pom.xml index afd5f62766..cd4f5c1df1 100644 --- a/org.jacoco.doc/pom.xml +++ b/org.jacoco.doc/pom.xml @@ -157,7 +157,6 @@ - From e68ecf2385522009dc74dace96037f8d90be311e Mon Sep 17 00:00:00 2001 From: "Marc R. Hoffmann" Date: Thu, 21 Nov 2024 22:50:50 +0100 Subject: [PATCH 101/163] Do not test with SecurityManager when Java version 24 and above (#1780) Co-authored-by: Evgeny Mandrikov --- org.jacoco.ant.test/pom.xml | 4 ++ .../src/org/jacoco/ant/CoverageTaskTest.xml | 16 ------- .../src/org/jacoco/ant/InstrumentTaskTest.xml | 10 ++--- .../org/jacoco/ant/SecurityManagerTest.java | 41 ++++++++++++++++++ .../org/jacoco/ant/SecurityManagerTest.xml | 43 +++++++++++++++++++ .../src/org/jacoco/ant/empty.xml | 17 ++++++++ 6 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.java create mode 100644 org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml create mode 100644 org.jacoco.ant.test/src/org/jacoco/ant/empty.xml diff --git a/org.jacoco.ant.test/pom.xml b/org.jacoco.ant.test/pom.xml index 0decb5008b..8e33b6e2f2 100644 --- a/org.jacoco.ant.test/pom.xml +++ b/org.jacoco.ant.test/pom.xml @@ -33,6 +33,10 @@ ${project.groupId} org.jacoco.ant + + ${project.groupId} + org.jacoco.core.test + junit junit diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml index a4024d2ea7..3c7308632a 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml @@ -166,20 +166,4 @@ - - - - - - - - - - - - - - - - diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml index 8046900240..6fea583c16 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml @@ -63,7 +63,7 @@ - + @@ -84,7 +84,7 @@ - + @@ -95,7 +95,7 @@ - + destfile=test.exec @@ -112,7 +112,7 @@ - + @@ -129,7 +129,7 @@ - + diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.java b/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.java new file mode 100644 index 0000000000..ef9207cef7 --- /dev/null +++ b/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; + +import org.apache.ant.antunit.junit3.AntUnitSuite; +import org.apache.ant.antunit.junit4.AntUnitSuiteRunner; +import org.jacoco.core.test.validation.JavaVersion; +import org.junit.runner.RunWith; + +import junit.framework.TestSuite; + +@RunWith(AntUnitSuiteRunner.class) +public class SecurityManagerTest { + + public static TestSuite suite() { + if (JavaVersion.current().isBefore("24")) { + System.setProperty("org.jacoco.ant.securityManagerTest.classes.dir", + TestTarget.getClassPath()); + final File file = new File( + "src/org/jacoco/ant/SecurityManagerTest.xml"); + return new AntUnitSuite(file, SecurityManagerTest.class); + } + // Ability to enable Security Manager was removed in Java 24 + // https://openjdk.org/jeps/486 + final File file = new File("src/org/jacoco/ant/empty.xml"); + return new AntUnitSuite(file, SecurityManagerTest.class); + } + +} diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml new file mode 100644 index 0000000000..0ce62cffac --- /dev/null +++ b/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/empty.xml b/org.jacoco.ant.test/src/org/jacoco/ant/empty.xml new file mode 100644 index 0000000000..70a5a1dded --- /dev/null +++ b/org.jacoco.ant.test/src/org/jacoco/ant/empty.xml @@ -0,0 +1,17 @@ + + + + + + + From 92936c51fb3572f77a4eca9a2c1775afb7580dfa Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 22 Nov 2024 08:22:26 +0100 Subject: [PATCH 102/163] SecurityManagerTest should not depend on CoverageTaskTest (#1785) --- org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml index 0ce62cffac..beec33cd44 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/SecurityManagerTest.xml @@ -27,7 +27,7 @@ - + From a1571a8d82b0a99df2131dfdfd6749605fee93db Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 22 Nov 2024 09:07:07 +0100 Subject: [PATCH 103/163] Fix typo: replace "a instance" by "an instance" (#1786) "an" should be used instead of "a" when the following word starts with a vowel sound. --- .../src/org/jacoco/core/data/ExecutionDataStore.java | 2 +- .../core/internal/analysis/MethodCoverageCalculator.java | 6 +++--- .../src/org/jacoco/report/internal/xml/XMLElement.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java index 0b62309d4a..b6aad5268f 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java +++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java @@ -24,7 +24,7 @@ * {@link IExecutionDataVisitor} interface. If execution data is provided * multiple times for the same class the data is merged, i.e. a probe is marked * as executed if it is reported as executed at least once. This allows to merge - * coverage date from multiple runs. A instance of this class is not thread + * coverage date from multiple runs. An instance of this class is not thread * safe. */ public final class ExecutionDataStore implements IExecutionDataVisitor { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageCalculator.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageCalculator.java index 2c7dec6dac..1e0bbe4e5c 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageCalculator.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageCalculator.java @@ -25,9 +25,9 @@ import org.objectweb.asm.tree.AbstractInsnNode; /** - * Calculates the filtered coverage of a single method. A instance of this class - * can be first used as {@link IFilterOutput} before the coverage result is - * calculated. + * Calculates the filtered coverage of a single method. An instance of this + * class can be first used as {@link IFilterOutput} before the coverage result + * is calculated. */ class MethodCoverageCalculator implements IFilterOutput { diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java index 950b377647..4ecfdfcc05 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java @@ -246,7 +246,7 @@ public final void text(final String text) throws IOException { /** * Creates a new child element for this element. Might be overridden in - * subclasses to return a instance of the subclass. + * subclasses to return an instance of the subclass. * * @param name * name of the child element From 91bf76cbbbd42d733e6b8bef7a094a01ecaccd74 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 22 Nov 2024 20:50:48 +0100 Subject: [PATCH 104/163] Fix typo: replace "an listener" by "a listener" (#1789) "a" should be used instead of "an" when the following word doesn't start with a vowel sound. --- .../src/org/jacoco/core/data/ExecutionDataReader.java | 4 ++-- .../src/org/jacoco/core/runtime/RemoteControlReader.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataReader.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataReader.java index f30a3c4d74..0f7aaf79a3 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataReader.java +++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataReader.java @@ -46,7 +46,7 @@ public ExecutionDataReader(final InputStream input) { } /** - * Sets an listener for session information. + * Sets a listener for session information. * * @param visitor * visitor to retrieve session info events @@ -56,7 +56,7 @@ public void setSessionInfoVisitor(final ISessionInfoVisitor visitor) { } /** - * Sets an listener for execution data. + * Sets a listener for execution data. * * @param visitor * visitor to retrieve execution data events diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlReader.java b/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlReader.java index d5b9c81785..7f4ff118db 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlReader.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlReader.java @@ -50,7 +50,7 @@ protected boolean readBlock(final byte blockid) throws IOException { } /** - * Sets an listener for agent commands. + * Sets a listener for agent commands. * * @param visitor * visitor to retrieve agent commands From 1d9f0bb2ec7bcf7c68466e43d911ab7b58fe2817 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:19:58 +0100 Subject: [PATCH 105/163] Fix javadoc doclint warning "no @param for fragment" (#1788) This was overlooked in commit 831ecd609e17a3a5f8e114134fa0ce1d2071c6bd. --- .../src/org/jacoco/core/internal/analysis/SourceNodeImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java index bab8b9edfd..44149c62f1 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java @@ -42,6 +42,8 @@ public SourceNodeImpl(final ElementType elementType, final String name) { } /** + * @param fragment + * fragment to apply * @return true if fragment contains lines of this node */ public boolean applyFragment(final SourceNodeImpl fragment) { From 10705517b5d9a0bc8c8a9d3386c84adc0740112c Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 25 Nov 2024 00:07:45 +0100 Subject: [PATCH 106/163] Add validation test for Kotlin `when` statement with `sealed class` subject type (#1791) --- .../kotlin/targets/KotlinWhenSealedTarget.kt | 73 +++++++++++++++---- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenSealedTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenSealedTarget.kt index 12ec77ab52..0b3b3d87ec 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenSealedTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenSealedTarget.kt @@ -12,8 +12,10 @@ *******************************************************************************/ package org.jacoco.core.test.validation.kotlin.targets +import org.jacoco.core.test.validation.targets.Stubs.nop + /** - * Test target with `when` expressions with subject of type `enum class`. + * Test target with `when` expressions and statements with subject of type `sealed class`. */ object KotlinWhenSealedTarget { @@ -22,25 +24,70 @@ object KotlinWhenSealedTarget { object Sealed2 : Sealed() } - private fun whenSealed(p: Sealed): Int = when (p) { // assertFullyCovered() - is Sealed.Sealed1 -> 1 // assertFullyCovered(0, 2) - is Sealed.Sealed2 -> 2 // assertFullyCovered() - } // assertFullyCovered() + private fun expression(sealed: Sealed): String = + when (sealed) { // assertFullyCovered() + is Sealed.Sealed1 -> "case 1" // assertFullyCovered(0, 2) + is Sealed.Sealed2 -> "case 2" // assertFullyCovered() + } // assertFullyCovered() @Suppress("REDUNDANT_ELSE_IN_WHEN") - private fun whenSealedRedundantElse(p: Sealed): Int = when (p) { // assertFullyCovered() - is Sealed.Sealed1 -> 1 // assertFullyCovered(0, 2) - is Sealed.Sealed2 -> 2 // assertFullyCovered(0, 0) - else -> throw NoWhenBranchMatchedException() // assertEmpty() + private fun expressionWithRedundantElse(sealed: Sealed): String = + when (sealed) { // assertFullyCovered() + is Sealed.Sealed1 -> "case 1" // assertFullyCovered(0, 2) + is Sealed.Sealed2 -> "case 2" // assertFullyCovered(0, 0) + else -> throw NoWhenBranchMatchedException() // assertEmpty() + } // assertFullyCovered() + + /** + * Since Kotlin 1.7 `when` statement with subject of type `sealed class` + * must be exhaustive (error otherwise, warning in 1.6), however + * Kotlin compiler prior to version 2.0 was generating bytecode + * indistinguishable from [nonSealedWhen] and [nonSealedIf] + * that do not have coverage for the case of [NonSealed.NonSealed3]. + */ + private fun statement(sealed: Sealed) { // assertEmpty() + when (sealed) { // assertFullyCovered() + is Sealed.Sealed1 -> nop("case 1") // assertFullyCovered(0, 2) + is Sealed.Sealed2 -> nop("case 2") // assertFullyCovered() + } // assertEmpty() + } // assertFullyCovered() + + private abstract class NonSealed { + class NonSealed1 : NonSealed() + class NonSealed2 : NonSealed() + class NonSealed3 : NonSealed() + } + + private fun nonSealedWhen(nonSealed: NonSealed) { // assertEmpty() + when (nonSealed) { // assertFullyCovered() + is NonSealed.NonSealed1 -> nop("case 1") // assertFullyCovered(0, 2) + is NonSealed.NonSealed2 -> nop("case 2") // assertFullyCovered(1, 1) + /* missing is NonSealed.NonSealed3 */ + } // assertEmpty() + } // assertFullyCovered() + + private fun nonSealedIf(nonSealed: NonSealed) { // assertEmpty() + if (nonSealed is NonSealed.NonSealed1) nop("case 1") // assertFullyCovered(0, 2) + else if (nonSealed is NonSealed.NonSealed2) nop("case 2") // assertFullyCovered(1, 1) + /* missing is NonSealed.NonSealed3 */ } // assertFullyCovered() @JvmStatic fun main(args: Array) { - whenSealed(Sealed.Sealed1) - whenSealed(Sealed.Sealed2) + expression(Sealed.Sealed1) + expression(Sealed.Sealed2) + + expressionWithRedundantElse(Sealed.Sealed1) + expressionWithRedundantElse(Sealed.Sealed2) + + statement(Sealed.Sealed1) + statement(Sealed.Sealed2) + + nonSealedWhen(NonSealed.NonSealed1()) + nonSealedWhen(NonSealed.NonSealed2()) - whenSealedRedundantElse(Sealed.Sealed1) - whenSealedRedundantElse(Sealed.Sealed2) + nonSealedIf(NonSealed.NonSealed1()) + nonSealedIf(NonSealed.NonSealed2()) } } From 0ebc1d93eb58b451dae75c5825647fef270f70e5 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 25 Nov 2024 08:46:09 +0100 Subject: [PATCH 107/163] Fix typo: replace "a XML" by "an XML" (#1790) "an" should be used instead of "a" when the following word starts with a vowel sound. --- org.jacoco.doc/docroot/doc/ant.html | 2 +- .../src/org/jacoco/report/internal/xml/ReportElement.java | 2 +- .../src/org/jacoco/report/internal/xml/XMLElement.java | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/org.jacoco.doc/docroot/doc/ant.html b/org.jacoco.doc/docroot/doc/ant.html index f0ddfd58f5..1b1b37e39c 100644 --- a/org.jacoco.doc/docroot/doc/ant.html +++ b/org.jacoco.doc/docroot/doc/ant.html @@ -89,7 +89,7 @@

      Prerequisites

      - Declaring a XML namespace for JaCoCo tasks is optional but always recommended + Declaring an XML namespace for JaCoCo tasks is optional but always recommended if you mix tasks from different libraries. All subsequent examples use the jacoco prefix declared above. If you don't declare a separate namespace the jacoco prefix must be removed from the following diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/ReportElement.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/ReportElement.java index 3e35fc129b..18fbd735f8 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/xml/ReportElement.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/ReportElement.java @@ -32,7 +32,7 @@ public class ReportElement extends XMLElement { private static final String SYSTEM = "report.dtd"; /** - * Creates a report root element for a XML report. + * Creates a report root element for an XML report. * * @param name * value for the name attribute diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java index 4ecfdfcc05..3e527906fa 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java @@ -20,8 +20,8 @@ import java.io.Writer; /** - * Simple API to create well formed XML streams with minimal memory overhead. A - * {@link XMLElement} instance represents a single element in a XML document. + * Simple API to create well formed XML streams with minimal memory overhead. An + * {@link XMLElement} instance represents a single element in an XML document. * {@link XMLElement} can be used directly or might be subclassed for schema * specific convenience methods. */ @@ -60,7 +60,7 @@ private XMLElement(final Writer writer, final String name, } /** - * Creates a root element of a XML document. + * Creates a root element of an XML document. * * @param name * element name @@ -95,7 +95,7 @@ public XMLElement(final String name, final String pubId, } /** - * Creates a new child element within a XML document. May only be called + * Creates a new child element within an XML document. May only be called * before the parent element has been closed. * * @param name From e1340eb7a6d96a5f1fd0dc2337b35bbc94220589 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 25 Nov 2024 11:56:14 +0100 Subject: [PATCH 108/163] Add unit test for LocalProbeArrayStrategy (#1792) --- .../instr/LocalProbeArrayStrategyTest.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 org.jacoco.core.test/src/org/jacoco/core/internal/instr/LocalProbeArrayStrategyTest.java diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/LocalProbeArrayStrategyTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/LocalProbeArrayStrategyTest.java new file mode 100644 index 0000000000..7a4ce363b8 --- /dev/null +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/LocalProbeArrayStrategyTest.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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.instr; + +import static org.junit.Assert.assertEquals; + +import org.jacoco.core.instr.MethodRecorder; +import org.jacoco.core.runtime.IExecutionDataAccessorGenerator; +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.ClassNode; + +/** + * Unit tests for {@link LocalProbeArrayStrategy}. + */ +public class LocalProbeArrayStrategyTest { + + private LocalProbeArrayStrategy strategy; + + @Before + public void setup() { + strategy = new LocalProbeArrayStrategy("ClassName", 1L, 2, + new IExecutionDataAccessorGenerator() { + public int generateDataAccessor(final long classid, + final String classname, final int probecount, + final MethodVisitor mv) { + assertEquals(1L, classid); + assertEquals(2, probecount); + assertEquals("ClassName", classname); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "Runtime", + "getProbes", "()[Z", false); + return 42; + } + }); + } + + @Test + public void should_store_instance() { + final MethodRecorder actualMethod = new MethodRecorder(); + final int maxStack = strategy.storeInstance(actualMethod.getVisitor(), + false, 13); + assertEquals(42, maxStack); + + final MethodRecorder expectedMethod = new MethodRecorder(); + final MethodVisitor expected = expectedMethod.getVisitor(); + expected.visitMethodInsn(Opcodes.INVOKESTATIC, "Runtime", "getProbes", + "()[Z", false); + expected.visitVarInsn(Opcodes.ASTORE, 13); + assertEquals(expectedMethod, actualMethod); + } + + @Test + public void should_not_add_members() { + final ClassNode c = new ClassNode(); + strategy.addMembers(c, 0); + + assertEquals(0, c.methods.size()); + assertEquals(0, c.fields.size()); + } + +} From 667655df85737199a0942943027c80e845a90aae Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 25 Nov 2024 12:26:41 +0100 Subject: [PATCH 109/163] Fix typo: replace "a HTML" by "an HTML" (#1793) "an" should be used instead of "a" when the following word starts with a vowel sound. --- .../src/org/jacoco/examples/ReportGenerator.java | 2 +- .../src/org/jacoco/report/internal/html/IHTMLReportContext.java | 2 +- .../src/org/jacoco/report/internal/html/index/ElementIndex.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.jacoco.examples/src/org/jacoco/examples/ReportGenerator.java b/org.jacoco.examples/src/org/jacoco/examples/ReportGenerator.java index 4aa3a0a86f..e63b5b051a 100644 --- a/org.jacoco.examples/src/org/jacoco/examples/ReportGenerator.java +++ b/org.jacoco.examples/src/org/jacoco/examples/ReportGenerator.java @@ -25,7 +25,7 @@ import org.jacoco.report.html.HTMLFormatter; /** - * This example creates a HTML report for eclipse like projects based on a + * This example creates an HTML report for eclipse like projects based on a * single execution data store called jacoco.exec. The report contains no * grouping information. * diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/IHTMLReportContext.java b/org.jacoco.report/src/org/jacoco/report/internal/html/IHTMLReportContext.java index 5ea660791f..8fbd97424b 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/IHTMLReportContext.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/IHTMLReportContext.java @@ -20,7 +20,7 @@ import org.jacoco.report.internal.html.table.Table; /** - * Context and configuration information during creation of a HTML report. + * Context and configuration information during creation of an HTML report. */ public interface IHTMLReportContext { diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/index/ElementIndex.java b/org.jacoco.report/src/org/jacoco/report/internal/html/index/ElementIndex.java index b72b8cd440..3721204dac 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/index/ElementIndex.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/index/ElementIndex.java @@ -29,7 +29,7 @@ public class ElementIndex implements IIndexUpdate { private final Map allClasses = new HashMap(); /** - * Creates a new empty index for a HTML report. + * Creates a new empty index for an HTML report. * * @param baseFolder * base folder where all links are calculated relative to From e4d600ab24ae2f3dea8231f15e13d71876e77bda Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:36:17 +0100 Subject: [PATCH 110/163] Fix typo: replace "a agent" by "an agent" (#1795) "an" should be used instead of "a" when the following word starts with a vowel sound. --- org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java | 2 +- org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java index 4d5d82179c..0568acb1b2 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java @@ -64,7 +64,7 @@ public void run() { } /** - * Returns a global instance which is already started. If a agent has not + * Returns a global instance which is already started. If an agent has not * been initialized before this method will fail. * * @return global instance diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java index d3b29d3c9d..e9e862db98 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java @@ -610,7 +610,7 @@ public String getQuotedVMArgument(final File agentJarFile) { /** * Generate required quotes JVM argument based on current configuration and - * prepends it to the given argument command line. If a agent with the same + * prepends it to the given argument command line. If an agent with the same * JAR file is already specified this parameter is removed from the existing * command line. * From 081d054a06e944625546d50a463fc72e1bba67d1 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 25 Nov 2024 21:13:45 +0100 Subject: [PATCH 111/163] Add unit test for ClassFieldProbeArrayStrategy (#1796) --- .../ClassFieldProbeArrayStrategyTest.java | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 org.jacoco.core.test/src/org/jacoco/core/internal/instr/ClassFieldProbeArrayStrategyTest.java diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ClassFieldProbeArrayStrategyTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ClassFieldProbeArrayStrategyTest.java new file mode 100644 index 0000000000..d96eccc05f --- /dev/null +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ClassFieldProbeArrayStrategyTest.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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.instr; + +import static org.junit.Assert.assertEquals; + +import org.jacoco.core.instr.MethodRecorder; +import org.jacoco.core.runtime.IExecutionDataAccessorGenerator; +import org.junit.Test; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodNode; + +/** + * Unit test for {@link ClassFieldProbeArrayStrategy}. + */ +public class ClassFieldProbeArrayStrategyTest { + + private ClassFieldProbeArrayStrategy create(final boolean withFrames) { + return new ClassFieldProbeArrayStrategy("ClassName", 1L, withFrames, + new IExecutionDataAccessorGenerator() { + public int generateDataAccessor(final long classid, + final String classname, final int probecount, + final MethodVisitor mv) { + assertEquals(1L, classid); + assertEquals("ClassName", classname); + assertEquals(2, probecount); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "Runtime", + "getProbes", "()[Z", false); + return 0; + } + }); + } + + @Test + public void should_add_field_and_init_method() { + for (final boolean withFrames : new boolean[] { true, false }) { + final ClassFieldProbeArrayStrategy strategy = create(withFrames); + + final ClassNode c = new ClassNode(); + strategy.addMembers(c, 2); + + assertEquals(1, c.fields.size()); + final FieldNode f = c.fields.get(0); + assertEquals( + Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PRIVATE + | Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT, + f.access); + assertEquals("$jacocoData", f.name); + assertEquals("[Z", f.desc); + + assertEquals(1, c.methods.size()); + final MethodNode m = c.methods.get(0); + assertEquals(Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PRIVATE + | Opcodes.ACC_STATIC, m.access); + assertEquals("$jacocoInit", m.name); + assertEquals("()[Z", m.desc); + final MethodRecorder expectedMethod = new MethodRecorder(); + final MethodVisitor expected = expectedMethod.getVisitor(); + expected.visitFieldInsn(Opcodes.GETSTATIC, "ClassName", + "$jacocoData", "[Z"); + expected.visitInsn(Opcodes.DUP); + final Label label = new Label(); + expected.visitJumpInsn(Opcodes.IFNONNULL, label); + expected.visitInsn(Opcodes.POP); + expected.visitMethodInsn(Opcodes.INVOKESTATIC, "Runtime", + "getProbes", "()[Z", false); + expected.visitInsn(Opcodes.DUP); + expected.visitFieldInsn(Opcodes.PUTSTATIC, "ClassName", + "$jacocoData", "[Z"); + if (withFrames) { + expected.visitFrame(Opcodes.F_FULL, 0, new Object[] {}, 1, + new Object[] { "[Z" }); + } + expected.visitLabel(label); + expected.visitInsn(Opcodes.ARETURN); + final MethodRecorder actualMethod = new MethodRecorder(); + m.instructions.accept(actualMethod.getVisitor()); + assertEquals(expectedMethod, actualMethod); + } + } + + @Test + public void should_store_instance() { + final ClassFieldProbeArrayStrategy strategy = create(true); + + final MethodRecorder actualMethod = new MethodRecorder(); + final int maxStack = strategy.storeInstance(actualMethod.getVisitor(), + false, 13); + assertEquals(1, maxStack); + + final MethodRecorder expectedMethod = new MethodRecorder(); + final MethodVisitor expected = expectedMethod.getVisitor(); + expected.visitMethodInsn(Opcodes.INVOKESTATIC, "ClassName", + "$jacocoInit", "()[Z", false); + expected.visitVarInsn(Opcodes.ASTORE, 13); + assertEquals(expectedMethod, actualMethod); + } + +} From b71736944cf29cfc0a51292a3f6885ea3a377cd4 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 25 Nov 2024 23:56:20 +0100 Subject: [PATCH 112/163] Fix javadoc doclint warnings "no comment" (#1798) --- .../src/org/jacoco/core/analysis/CounterComparator.java | 7 +++++++ .../src/org/jacoco/core/analysis/NodeComparator.java | 6 ++++++ .../core/data/IncompatibleExecDataVersionException.java | 3 +++ .../jacoco/core/internal/analysis/ClassCoverageImpl.java | 7 +++++++ .../internal/analysis/filter/KotlinGeneratedFilter.java | 9 +++++++++ .../jacoco/core/internal/analysis/filter/KotlinSMAP.java | 4 ++++ 6 files changed, 36 insertions(+) diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/CounterComparator.java b/org.jacoco.core/src/org/jacoco/core/analysis/CounterComparator.java index 2845a6a381..fcf143e739 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/CounterComparator.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/CounterComparator.java @@ -56,7 +56,14 @@ public class CounterComparator implements Comparator, Serializable { public static final CounterComparator MISSEDRATIO = new CounterComparator( CounterValue.MISSEDRATIO); + /** + * Counter value to sort on. + */ private final CounterValue value; + + /** + * Specifies whether values are sorted in reverse order or not. + */ private final boolean reverse; private CounterComparator(final CounterValue value) { diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/NodeComparator.java b/org.jacoco.core/src/org/jacoco/core/analysis/NodeComparator.java index e5ad65bf72..1bbbbff9ca 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/NodeComparator.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/NodeComparator.java @@ -31,8 +31,14 @@ public class NodeComparator implements Comparator, Serializable { private static final long serialVersionUID = 8550521643608826519L; + /** + * Comparator to compare {@link ICounter} objects. + */ private final Comparator counterComparator; + /** + * Counter entity to sort on. + */ private final CounterEntity entity; NodeComparator(final Comparator counterComparator, diff --git a/org.jacoco.core/src/org/jacoco/core/data/IncompatibleExecDataVersionException.java b/org.jacoco.core/src/org/jacoco/core/data/IncompatibleExecDataVersionException.java index 7cb998043b..32d93c4840 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/IncompatibleExecDataVersionException.java +++ b/org.jacoco.core/src/org/jacoco/core/data/IncompatibleExecDataVersionException.java @@ -21,6 +21,9 @@ public class IncompatibleExecDataVersionException extends IOException { private static final long serialVersionUID = 1L; + /** + * Actual version found in the execution data. + */ private final int actualVersion; /** diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java index f4dc7e8870..b315d25703 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java @@ -119,6 +119,13 @@ public Collection getFragments() { return fragments; } + /** + * Stores fragments that contain coverage information about other nodes + * collected during the creation of this node. + * + * @param fragments + * fragments to store + */ public void setFragments(final Collection fragments) { this.fragments = fragments; } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java index 2bc32b1a21..535bd6a082 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java @@ -24,6 +24,15 @@ public class KotlinGeneratedFilter implements IFilter { static final String KOTLIN_METADATA_DESC = "Lkotlin/Metadata;"; + /** + * Checks whether the class corresponding to the given context has + * kotlin/Metadata annotation. + * + * @param context + * context information + * @return true if the class corresponding to the given context + * has kotlin/Metadata annotation + */ public static boolean isKotlinClass(final IFilterContext context) { return context.getClassAnnotations().contains(KOTLIN_METADATA_DESC); } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java index aa7a8d7b12..a3de7d9a77 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSMAP.java @@ -26,6 +26,10 @@ */ public final class KotlinSMAP { + /** + * Parsed representation of a single LineSection from SourceDebugExtension + * attribute. + */ public static final class Mapping { private final String inputClassName; private final int inputStartLine; From 83dba7880aef2ebffcec91012a3544cab6877ad8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:38:01 +0000 Subject: [PATCH 113/163] Upgrade Kotlin to 2.1.0 (#1802) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evgeny Mandrikov --- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- org.jacoco.core.test.validation/pom.xml | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index 24e23fa3c9..3708dc868d 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -25,7 +25,7 @@ JaCoCo :: Test :: Core :: Validation Kotlin - 2.0.21 + 2.1.0 diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index b18a0e1690..2d6edc5f12 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -504,8 +504,7 @@ - - 22 + 23 16 @@ -533,8 +532,8 @@ - - 22 + + 23 16 From 46f0a6dfe349a3a220187735bcf0e3dd27018a28 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 28 Nov 2024 00:24:19 +0100 Subject: [PATCH 114/163] Upgrade maven-invoker-plugin to 3.8.1 (#1457) --- .github/dependabot.yml | 1 - jacoco-maven-plugin.test/pom.xml | 12 +++++++++--- org.jacoco.build/pom.xml | 2 +- org.jacoco.examples.test/pom.xml | 6 ++++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d5d2b4272d..0a6c79fce2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -22,7 +22,6 @@ updates: ignore: # It is known that upgrade from current version requires additional changes: - dependency-name: "org.apache.maven.plugins:maven-plugin-plugin" - - dependency-name: "org.apache.maven.plugins:maven-invoker-plugin" # Because of # https://github.com/apache/maven-compiler-plugin/blob/maven-compiler-plugin-3.13.0/pom.xml#L71 # https://github.com/codehaus-plexus/plexus-compiler/blob/plexus-compiler-2.15.0/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java#L149-L163 diff --git a/jacoco-maven-plugin.test/pom.xml b/jacoco-maven-plugin.test/pom.xml index ffca23e99c..81e8e2468e 100644 --- a/jacoco-maven-plugin.test/pom.xml +++ b/jacoco-maven-plugin.test/pom.xml @@ -32,6 +32,15 @@ org.jacoco.maven.* + + + ${project.groupId} + jacoco-maven-plugin + ${project.version} + maven-plugin + + + @@ -52,9 +61,6 @@ install it/settings.xml - - org.jacoco:org.jacoco.agent:${project.version}:jar:runtime - ecj diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index 2d6edc5f12..10583e0524 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -554,6 +554,39 @@ + + java25-bytecode + + + bytecode.version + 25 + + + + + 23 + + 16 + + 25 + 25 + + + + ../org.jacoco.core.test.validation.java7 + ../org.jacoco.core.test.validation.java8 + ../org.jacoco.core.test.validation.java14 + ../org.jacoco.core.test.validation.java16 + ../org.jacoco.core.test.validation.java21 + + ../org.jacoco.core.test.validation.scala + + + diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java index b4ac0c865b..69d7af7763 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java @@ -132,13 +132,13 @@ private static byte[] createClass(final int version) { */ @Test public void analyzeClass_should_throw_exception_for_unsupported_class_file_version() { - final byte[] bytes = createClass(Opcodes.V23 + 2); + final byte[] bytes = createClass(Opcodes.V24 + 2); try { analyzer.analyzeClass(bytes, "UnsupportedVersion"); fail("exception expected"); } catch (IOException e) { assertExceptionMessage("UnsupportedVersion", e); - assertEquals("Unsupported class file major version 69", + assertEquals("Unsupported class file major version 70", e.getCause().getMessage()); } } @@ -218,14 +218,14 @@ public void testAnalyzeClass_BrokenStream() throws IOException { */ @Test public void analyzeAll_should_throw_exception_for_unsupported_class_file_version() { - final byte[] bytes = createClass(Opcodes.V23 + 2); + final byte[] bytes = createClass(Opcodes.V24 + 2); try { analyzer.analyzeAll(new ByteArrayInputStream(bytes), "UnsupportedVersion"); fail("exception expected"); } catch (IOException e) { assertExceptionMessage("UnsupportedVersion", e); - assertEquals("Unsupported class file major version 69", + assertEquals("Unsupported class file major version 70", e.getCause().getMessage()); } } diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java index e3b31b2d9d..2d8172a779 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java @@ -31,6 +31,9 @@ import static org.objectweb.asm.Opcodes.V14; import static org.objectweb.asm.Opcodes.V15; import static org.objectweb.asm.Opcodes.V16; +import static org.objectweb.asm.Opcodes.V17; +import static org.objectweb.asm.Opcodes.V18; +import static org.objectweb.asm.Opcodes.V19; import static org.objectweb.asm.Opcodes.V1_1; import static org.objectweb.asm.Opcodes.V1_2; import static org.objectweb.asm.Opcodes.V1_3; @@ -39,6 +42,11 @@ import static org.objectweb.asm.Opcodes.V1_6; import static org.objectweb.asm.Opcodes.V1_7; import static org.objectweb.asm.Opcodes.V1_8; +import static org.objectweb.asm.Opcodes.V20; +import static org.objectweb.asm.Opcodes.V21; +import static org.objectweb.asm.Opcodes.V22; +import static org.objectweb.asm.Opcodes.V23; +import static org.objectweb.asm.Opcodes.V24; import static org.objectweb.asm.Opcodes.V9; import java.io.IOException; @@ -139,6 +147,51 @@ public void test_16() throws IOException { testVersion(V16, true); } + @Test + public void test_17() throws IOException { + testVersion(V17, true); + } + + @Test + public void test_18() throws IOException { + testVersion(V18, true); + } + + @Test + public void test_19() throws IOException { + testVersion(V19, true); + } + + @Test + public void test_20() throws IOException { + testVersion(V20, true); + } + + @Test + public void test_21() throws IOException { + testVersion(V21, true); + } + + @Test + public void test_22() throws IOException { + testVersion(V22, true); + } + + @Test + public void test_23() throws IOException { + testVersion(V23, true); + } + + @Test + public void test_24() throws IOException { + testVersion(V24, true); + } + + @Test + public void test_25() throws IOException { + testVersion(V24 + 1, true); + } + private void testVersion(int version, boolean frames) throws IOException { final byte[] original = createClass(version, frames); diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java index 04a0ba972f..2c9d596e70 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java @@ -123,13 +123,13 @@ private static byte[] createClass(final int version) { */ @Test public void instrument_should_throw_exception_for_unsupported_class_file_version() { - final byte[] bytes = createClass(Opcodes.V23 + 2); + final byte[] bytes = createClass(Opcodes.V24 + 2); try { instrumenter.instrument(bytes, "UnsupportedVersion"); fail("exception expected"); } catch (final IOException e) { assertExceptionMessage("UnsupportedVersion", e); - assertEquals("Unsupported class file major version 69", + assertEquals("Unsupported class file major version 70", e.getCause().getMessage()); } } @@ -221,14 +221,14 @@ public void testSerialization() throws Exception { */ @Test public void instrumentAll_should_throw_exception_for_unsupported_class_file_version() { - final byte[] bytes = createClass(Opcodes.V23 + 2); + final byte[] bytes = createClass(Opcodes.V24 + 2); try { instrumenter.instrumentAll(new ByteArrayInputStream(bytes), new ByteArrayOutputStream(), "UnsupportedVersion"); fail("exception expected"); } catch (final IOException e) { assertExceptionMessage("UnsupportedVersion", e); - assertEquals("Unsupported class file major version 69", + assertEquals("Unsupported class file major version 70", e.getCause().getMessage()); } } diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java index 1ee2e7d74a..fa96a54caf 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java @@ -43,8 +43,8 @@ public void setup() { } @Test - public void classReaderFor_should_read_java_24_class() { - final byte[] bytes = createJava24Class(); + public void classReaderFor_should_read_java_25_class() { + final byte[] bytes = createJava25Class(); final ClassReader classReader = InstrSupport.classReaderFor(bytes); @@ -53,16 +53,16 @@ public void classReaderFor_should_read_java_24_class() { public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { - assertEquals(Opcodes.V23 + 1, version); + assertEquals(Opcodes.V24 + 1, version); } }, 0); - assertArrayEquals(createJava24Class(), bytes); + assertArrayEquals(createJava25Class(), bytes); } - private static byte[] createJava24Class() { + private static byte[] createJava25Class() { final ClassWriter cw = new ClassWriter(0); - cw.visit(Opcodes.V23 + 1, 0, "Foo", null, "java/lang/Object", null); + cw.visit(Opcodes.V24 + 1, 0, "Foo", null, "java/lang/Object", null); cw.visitEnd(); return cw.toByteArray(); } @@ -135,7 +135,8 @@ public void needFrames_should_return_true_for_versions_greater_than_or_equal_to_ assertTrue(InstrSupport.needsFrames(Opcodes.V21)); assertTrue(InstrSupport.needsFrames(Opcodes.V22)); assertTrue(InstrSupport.needsFrames(Opcodes.V23)); - assertTrue(InstrSupport.needsFrames(Opcodes.V23 + 1)); + assertTrue(InstrSupport.needsFrames(Opcodes.V24)); + assertTrue(InstrSupport.needsFrames(Opcodes.V24 + 1)); assertTrue(InstrSupport.needsFrames(0x0100)); } diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java index e3417a3d7a..bd54e2d680 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java @@ -32,6 +32,7 @@ import org.jacoco.core.data.ExecutionDataStore; import org.jacoco.core.data.SessionInfo; import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.core.internal.instr.InstrSupport; import org.jacoco.core.test.InstrumentingLoader; import org.jacoco.core.test.TargetLoader; import org.jacoco.core.test.validation.Source.Line; @@ -44,7 +45,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runners.model.MultipleFailureException; -import org.objectweb.asm.ClassReader; import org.objectweb.asm.util.ASMifier; import org.objectweb.asm.util.Textifier; import org.objectweb.asm.util.TraceClassVisitor; @@ -124,9 +124,10 @@ private void saveBytecodeRepresentations(final byte[] classBytes, new File(outputDir, fileName + ".txt")); final PrintWriter asmWriter = new PrintWriter( new File(outputDir, fileName + ".java")); - new ClassReader(classBytes).accept(new TraceClassVisitor( - new TraceClassVisitor(null, new Textifier(), textWriter), - new ASMifier(), asmWriter), 0); + InstrSupport.classReaderFor(classBytes) + .accept(new TraceClassVisitor(new TraceClassVisitor(null, + new Textifier(), textWriter), new ASMifier(), + asmWriter), 0); textWriter.close(); asmWriter.close(); } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java index c52810e663..dc4df54e01 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java @@ -273,9 +273,9 @@ public static void push(final MethodVisitor mv, final int value) { */ public static ClassReader classReaderFor(final byte[] b) { final int originalVersion = getMajorVersion(b); - if (originalVersion == Opcodes.V23 + 1) { + if (originalVersion == Opcodes.V24 + 1) { // temporarily downgrade version to bypass check in ASM - setMajorVersion(Opcodes.V23, b); + setMajorVersion(Opcodes.V24, b); } final ClassReader classReader = new ClassReader(b); setMajorVersion(originalVersion, b); diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 2a5caaa836..c4ce95b553 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -34,6 +34,8 @@

      New Features

      (GitHub #1700).
    • Experimental support for Java 24 class files (GitHub #1631).
    • +
    • Experimental support for Java 25 class files + (GitHub #1807).
    • Part of bytecode generated by the Kotlin Compose compiler plugin is filtered out during generation of report (GitHub #1616).
    • diff --git a/org.jacoco.doc/docroot/doc/faq.html b/org.jacoco.doc/docroot/doc/faq.html index 8dabc61b4b..27c5cae347 100644 --- a/org.jacoco.doc/docroot/doc/faq.html +++ b/org.jacoco.doc/docroot/doc/faq.html @@ -45,10 +45,11 @@

      Does JaCoCo have a plug-in for [Eclipse|Netbeans|Whatever...]?

      What Java versions are supported by JaCoCo?

      - JaCoCo supports Java class files from version 1.0 to 23. However the minimum - JRE version required by the JaCoCo runtime (e.g. the agent) and the JaCoCo - tools is 1.5. Also note that class files under test from version 1.6 and above - have to contain valid stackmap frames. + JaCoCo officially supports Java class files from version 1.0 to 23. Also + experimental support for class files of versions 24 and 25 is provided. + However the minimum JRE version required by the JaCoCo runtime + (e.g. the agent) and the JaCoCo tools is 1.5. Also note that class files under + test from version 1.6 and above have to contain valid stackmap frames.

      Why do I get the error "Can't add different class with same name"?

      From 5a6a5c4719aa009c1f2117f4ccc04d19d6d812fc Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:19:20 +0100 Subject: [PATCH 120/163] IFilter implementations should be package-private and final (#1806) --- .../core/internal/analysis/ClassAnalyzer.java | 4 +--- .../filter/AnnotationGeneratedFilter.java | 2 +- .../filter/EnumEmptyConstructorFilter.java | 2 +- .../internal/analysis/filter/EnumFilter.java | 2 +- .../core/internal/analysis/filter/Filters.java | 14 ++++++++++++++ .../internal/analysis/filter/FinallyFilter.java | 2 +- .../analysis/filter/KotlinComposeFilter.java | 2 +- .../analysis/filter/KotlinCoroutineFilter.java | 4 ++-- .../filter/KotlinDefaultArgumentsFilter.java | 4 ++-- .../filter/KotlinDefaultMethodsFilter.java | 2 +- .../analysis/filter/KotlinEnumFilter.java | 2 +- .../analysis/filter/KotlinGeneratedFilter.java | 17 ++--------------- .../filter/KotlinInlineClassFilter.java | 2 +- .../analysis/filter/KotlinInlineFilter.java | 4 ++-- .../analysis/filter/KotlinLateinitFilter.java | 2 +- .../filter/KotlinNotNullOperatorFilter.java | 2 +- .../filter/KotlinUnsafeCastOperatorFilter.java | 4 ++-- .../analysis/filter/KotlinWhenFilter.java | 2 +- .../analysis/filter/KotlinWhenStringFilter.java | 2 +- .../PrivateEmptyNoArgConstructorFilter.java | 2 +- .../internal/analysis/filter/RecordsFilter.java | 2 +- .../analysis/filter/StringSwitchFilter.java | 2 +- .../filter/StringSwitchJavacFilter.java | 2 +- .../analysis/filter/SynchronizedFilter.java | 2 +- .../analysis/filter/SyntheticFilter.java | 4 ++-- .../filter/TryWithResourcesEcjFilter.java | 2 +- .../filter/TryWithResourcesJavac11Filter.java | 2 +- .../filter/TryWithResourcesJavacFilter.java | 2 +- 28 files changed, 47 insertions(+), 48 deletions(-) diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java index d2268c5507..fa49d5385a 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java @@ -21,7 +21,6 @@ import org.jacoco.core.internal.analysis.filter.Filters; import org.jacoco.core.internal.analysis.filter.IFilter; import org.jacoco.core.internal.analysis.filter.IFilterContext; -import org.jacoco.core.internal.analysis.filter.KotlinGeneratedFilter; import org.jacoco.core.internal.analysis.filter.KotlinSMAP; import org.jacoco.core.internal.flow.ClassProbesVisitor; import org.jacoco.core.internal.flow.MethodProbesVisitor; @@ -144,8 +143,7 @@ private void addMethodCoverage(final String name, final String desc, private void calculateFragments( final Map instructions) { - if (sourceDebugExtension == null - || !KotlinGeneratedFilter.isKotlinClass(this)) { + if (sourceDebugExtension == null || !Filters.isKotlinClass(this)) { return; } if (smap == null) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java index cd7818d85c..9e80e75b98 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java @@ -23,7 +23,7 @@ * {@link java.lang.annotation.RetentionPolicy#CLASS invisible} annotation whose * simple name contains Generated. */ -public final class AnnotationGeneratedFilter implements IFilter { +final class AnnotationGeneratedFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java index bfc2d80988..e63e17c263 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java @@ -29,7 +29,7 @@ * constructors} - empty constructor in enums without additional parameters * should be filtered out even if it is not implicit. */ -public final class EnumEmptyConstructorFilter implements IFilter { +final class EnumEmptyConstructorFilter implements IFilter { private static final String CONSTRUCTOR_NAME = ""; private static final String CONSTRUCTOR_DESC = "(Ljava/lang/String;I)V"; diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java index 22bc1f0100..7ea7b99fcd 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java @@ -18,7 +18,7 @@ * Filters methods values and valueOf that compiler * creates for enums. */ -public final class EnumFilter implements IFilter { +final class EnumFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { 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 de1a1f3612..11b748caf5 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 @@ -65,4 +65,18 @@ public void filter(final MethodNode methodNode, } } + /** + * Checks whether the class corresponding to the given context has + * kotlin/Metadata annotation. + * + * @param context + * context information + * @return true if the class corresponding to the given context + * has kotlin/Metadata annotation + */ + public static boolean isKotlinClass(final IFilterContext context) { + return context.getClassAnnotations() + .contains(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + } + } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java index a421fc24b0..bc06d1d600 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java @@ -66,7 +66,7 @@ * at once, because execution can branch from one region to another (like it is * in given example due to "if" statement). */ -public final class FinallyFilter implements IFilter { +final class FinallyFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java index 48a1fbd565..62a53d9235 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java @@ -26,7 +26,7 @@ final class KotlinComposeFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!KotlinGeneratedFilter.isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } if (!isComposable(methodNode)) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java index 64a2016175..c83c28b8cc 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java @@ -26,12 +26,12 @@ /** * Filters branches that Kotlin compiler generates for coroutines. */ -public final class KotlinCoroutineFilter implements IFilter { +final class KotlinCoroutineFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!KotlinGeneratedFilter.isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } 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 978dd29750..61643f138d 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 @@ -50,7 +50,7 @@ * * This filter marks IFEQ instructions as ignored. */ -public final class KotlinDefaultArgumentsFilter implements IFilter { +final class KotlinDefaultArgumentsFilter implements IFilter { private static boolean isDefaultArgumentsMethod( final MethodNode methodNode) { @@ -76,7 +76,7 @@ public void filter(final MethodNode methodNode, if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) { return; } - if (!KotlinGeneratedFilter.isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java index 4ae6b1e93e..d79952216b 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java @@ -24,7 +24,7 @@ final class KotlinDefaultMethodsFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!KotlinGeneratedFilter.isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } new Matcher().match(methodNode, output); diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilter.java index 5d9891d3f9..43737cd6f0 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilter.java @@ -25,7 +25,7 @@ public void filter(final MethodNode methodNode, if (!"java/lang/Enum".equals(context.getSuperClassName())) { return; } - if (!KotlinGeneratedFilter.isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } if (!"getEntries".equals(methodNode.name)) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java index 535bd6a082..7e7b67e0b6 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java @@ -20,23 +20,10 @@ * identified by the @kotlin.Metadata annotations. In such classes * generated methods do not have line numbers. */ -public class KotlinGeneratedFilter implements IFilter { +final class KotlinGeneratedFilter implements IFilter { static final String KOTLIN_METADATA_DESC = "Lkotlin/Metadata;"; - /** - * Checks whether the class corresponding to the given context has - * kotlin/Metadata annotation. - * - * @param context - * context information - * @return true if the class corresponding to the given context - * has kotlin/Metadata annotation - */ - public static boolean isKotlinClass(final IFilterContext context) { - return context.getClassAnnotations().contains(KOTLIN_METADATA_DESC); - } - public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { @@ -46,7 +33,7 @@ public void filter(final MethodNode methodNode, return; } - if (!isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } 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 index 0279e04786..41ad6d4e19 100644 --- 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 @@ -73,7 +73,7 @@ final class KotlinInlineClassFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!KotlinGeneratedFilter.isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } if (!context.getClassAnnotations().contains("Lkotlin/jvm/JvmInline;")) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java index 55c2d77fbf..1a3bbe9e7c 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java @@ -19,7 +19,7 @@ /** * Filters out instructions that were inlined by Kotlin compiler. */ -public final class KotlinInlineFilter implements IFilter { +final class KotlinInlineFilter implements IFilter { private int firstGeneratedLineNumber = -1; @@ -29,7 +29,7 @@ public void filter(final MethodNode methodNode, return; } - if (!KotlinGeneratedFilter.isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java index 0dd736c57e..a098f48d17 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java @@ -22,7 +22,7 @@ * Filters branch in bytecode that Kotlin compiler generates for reading from * lateinit properties. */ -public class KotlinLateinitFilter implements IFilter { +final class KotlinLateinitFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { 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 index e6a2964284..d8d377224a 100644 --- 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 @@ -20,7 +20,7 @@ * Filters branch in bytecode that Kotlin compiler generates for not-null * assertion operator. */ -public final class KotlinNotNullOperatorFilter implements IFilter { +final class KotlinNotNullOperatorFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java index fd03de534e..559bda4b21 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java @@ -22,11 +22,11 @@ * Filters branch in bytecode that Kotlin compiler generates for "unsafe" cast * operator. */ -public final class KotlinUnsafeCastOperatorFilter implements IFilter { +final class KotlinUnsafeCastOperatorFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!KotlinGeneratedFilter.isKotlinClass(context)) { + if (!Filters.isKotlinClass(context)) { return; } final Matcher matcher = new Matcher(); diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java index 202ed3bea6..dcd5e810f4 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java @@ -30,7 +30,7 @@ * expressions and statements with subject of type enum class or * sealed class. */ -public final class KotlinWhenFilter implements IFilter { +final class KotlinWhenFilter implements IFilter { private static final String EXCEPTION = "kotlin/NoWhenBranchMatchedException"; diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java index 5f34035dab..9946178dcd 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java @@ -28,7 +28,7 @@ * Filters bytecode that Kotlin compiler generates for when * expressions with a String. */ -public final class KotlinWhenStringFilter implements IFilter { +final class KotlinWhenStringFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java index c2a4e64322..084814bf53 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java @@ -18,7 +18,7 @@ /** * Filters private empty constructors that do not have arguments. */ -public final class PrivateEmptyNoArgConstructorFilter implements IFilter { +final class PrivateEmptyNoArgConstructorFilter implements IFilter { private static final String CONSTRUCTOR_NAME = ""; private static final String CONSTRUCTOR_DESC = "()V"; diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/RecordsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/RecordsFilter.java index f7ab5c7f5d..8bedef2d09 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/RecordsFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/RecordsFilter.java @@ -22,7 +22,7 @@ * Filters methods toString, hashCode and * equals that compiler generates for records. */ -public final class RecordsFilter implements IFilter { +final class RecordsFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java index 16861854bb..10cf5917e2 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java @@ -29,7 +29,7 @@ * with a String and by Kotlin compiler 1.5 and above for a * when expression with a String. */ -public final class StringSwitchFilter implements IFilter { +final class StringSwitchFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java index cf48d00603..2dab00fad9 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java @@ -23,7 +23,7 @@ /** * Filters code that is generated by javac for a switch statement with a String. */ -public final class StringSwitchJavacFilter implements IFilter { +final class StringSwitchJavacFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java index 0e212a4890..35d7cff883 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java @@ -20,7 +20,7 @@ /** * Filters code that is generated for synchronized statement. */ -public final class SynchronizedFilter implements IFilter { +final class SynchronizedFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { 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 55e35a621c..f260d01cf2 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 @@ -18,7 +18,7 @@ /** * Filters synthetic methods unless they represent bodies of lambda expressions. */ -public final class SyntheticFilter implements IFilter { +final class SyntheticFilter implements IFilter { private static boolean isScalaClass(final IFilterContext context) { return context.getClassAttributes().contains("ScalaSig") @@ -41,7 +41,7 @@ public void filter(final MethodNode methodNode, } } - if (KotlinGeneratedFilter.isKotlinClass(context)) { + if (Filters.isKotlinClass(context)) { if (!methodNode.name.startsWith("access$")) { return; } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java index ec560a457d..c59398c4be 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java @@ -26,7 +26,7 @@ /** * Filters code that ECJ generates for try-with-resources statement. */ -public final class TryWithResourcesEcjFilter implements IFilter { +final class TryWithResourcesEcjFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java index ddd24c2a3b..e381c85041 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java @@ -22,7 +22,7 @@ * Filters code which is generated for try-with-resources statement by javac * starting from version 11. */ -public final class TryWithResourcesJavac11Filter implements IFilter { +final class TryWithResourcesJavac11Filter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java index e56a556980..261f4b0c3b 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java @@ -22,7 +22,7 @@ * Filters code which is generated for try-with-resources statement by javac * versions from 7 to 10. */ -public final class TryWithResourcesJavacFilter implements IFilter { +final class TryWithResourcesJavacFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { From fac812ea0c5de6cc5721ce6f22f27d69525efcde Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:49:08 +0100 Subject: [PATCH 121/163] Add validation test for `synchronized` block in Kotlin (#1703) --- .../kotlin/KotlinSynchronizedTest.java | 27 +++++++++ .../targets/KotlinSynchronizedTarget.kt | 57 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSynchronizedTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSynchronizedTarget.kt diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSynchronizedTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSynchronizedTest.java new file mode 100644 index 0000000000..9bb2904b68 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSynchronizedTest.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.KotlinSynchronizedTarget; + +/** + * Test of code coverage in {@link KotlinSynchronizedTarget} + */ +public class KotlinSynchronizedTest extends ValidationTestBase { + + public KotlinSynchronizedTest() { + super(KotlinSynchronizedTarget.class); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSynchronizedTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSynchronizedTarget.kt new file mode 100644 index 0000000000..7c52b03fd1 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSynchronizedTarget.kt @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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.* + +/** + * Test target with [synchronized] block. + */ +object KotlinSynchronizedTarget { + + private val lock = Any(); + + private fun normal() { + synchronized(lock) { // assertFullyCovered() + nop() // assertFullyCovered() + } // assertFullyCovered() + } + + private fun explicitException() { + synchronized(lock) { // assertFullyCovered() + throw StubException() // assertFullyCovered() + } // assertEmpty() + } + + private fun implicitException() { + synchronized(lock) { // assertPartlyCovered() + ex() // assertNotCovered() + } // assertNotCovered() + } + + @JvmStatic + fun main(args: Array) { + normal() + + try { + explicitException() + } catch (_: StubException) { + } + + try { + implicitException() + } catch (_: StubException) { + } + } + +} From e8f0907904649b98fb901b3834f9025813223570 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:11:43 +0100 Subject: [PATCH 122/163] Add validation test for exception based control flow in Kotlin (#1671) --- .../kotlin/KotlinExceptionsTest.java | 27 ++++ .../kotlin/targets/KotlinExceptionsTarget.kt | 133 ++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinExceptionsTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinExceptionsTarget.kt diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinExceptionsTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinExceptionsTest.java new file mode 100644 index 0000000000..98cc5211c8 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinExceptionsTest.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.KotlinExceptionsTarget; + +/** + * Test of code coverage in {@link KotlinExceptionsTarget}. + */ +public class KotlinExceptionsTest extends ValidationTestBase { + + public KotlinExceptionsTest() { + super(KotlinExceptionsTarget.class); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinExceptionsTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinExceptionsTarget.kt new file mode 100644 index 0000000000..2b2438c884 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinExceptionsTarget.kt @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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.* + +/** + * Test target with exception based control flow examples. + */ +object KotlinExceptionsTarget { + + private fun implicitArrayIndexOutOfBoundsException(a: Array) { + nop() // assertNotCovered() + a[0] // assertNotCovered() + nop() // assertNotCovered() + } + + private fun implicitException() { + nop() // assertFullyCovered() + ex() // assertNotCovered() + nop() // assertNotCovered() + } + + private fun explicitException() { + nop() // assertFullyCovered() + throw StubException() // assertFullyCovered() + } + + private fun noExceptionTryCatch() { + nop() // assertFullyCovered() + try { // assertFullyCovered() + nop() // assertFullyCovered() + } catch (e: StubException) { // assertNotCovered() + nop() // assertNotCovered() + } // assertEmpty() + } + + private fun implicitExceptionTryCatch() { + nop() // assertFullyCovered() + try { // assertFullyCovered() + nop() // assertFullyCovered() + ex() // assertNotCovered() + nop() // assertNotCovered() + } catch (e: StubException) { // assertFullyCovered() + nop() // assertFullyCovered() + } // assertEmpty() + } + + private fun explicitExceptionTryCatch() { + nop() // assertFullyCovered() + try { // assertFullyCovered() + nop() // assertFullyCovered() + throw StubException() // assertFullyCovered() + } catch (e: StubException) { // assertFullyCovered() + nop() // assertFullyCovered() + } // assertEmpty() + } + + private fun noExceptionFinally() { + nop() // assertFullyCovered() + try { // assertFullyCovered() + nop() // assertFullyCovered() + } finally { // assertEmpty() + nop() // assertFullyCovered() + } // assertEmpty() + } + + private fun implicitExceptionFinally() { + nop() // assertFullyCovered() + try { // assertFullyCovered() + nop() // assertFullyCovered() + ex() // assertNotCovered() + nop() // assertNotCovered() + } finally { // assertEmpty() + nop() // assertFullyCovered() + } // assertEmpty() + } + + private fun explicitExceptionFinally() { + nop() // assertFullyCovered() + try { // assertFullyCovered() + nop() // assertFullyCovered() + throw StubException() // assertFullyCovered() + } finally { // assertEmpty() + nop() // assertFullyCovered() + } + } + + @JvmStatic + fun main(args: Array) { + try { + implicitArrayIndexOutOfBoundsException(arrayOf()) + } catch (_: ArrayIndexOutOfBoundsException) { + } + try { + implicitException() + } catch (_: StubException) { + } + try { + explicitException() + } catch (_: StubException) { + } + noExceptionTryCatch() + try { + implicitExceptionTryCatch() + } catch (_: StubException) { + } + try { + explicitExceptionTryCatch() + } catch (_: StubException) { + } + noExceptionFinally() + try { + implicitExceptionFinally() + } catch (_: StubException) { + } + try { + explicitExceptionFinally() + } catch (_: StubException) { + } + } + +} From e6f29c902242c24c20f7740e27006a83330b8e88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:13:49 +0100 Subject: [PATCH 123/163] Upgrade maven-javadoc-plugin to 3.11.2 (#1808) Bump org.apache.maven.plugins:maven-javadoc-plugin in /org.jacoco.build Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.1 to 3.11.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.1...maven-javadoc-plugin-3.11.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index ba52aa121a..e3fbc9a7f7 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -353,7 +353,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.11.1 + 3.11.2 true false From aa0ebe8eb44d6ffe010afe134b6f0deb34491e81 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:09:16 +0100 Subject: [PATCH 124/163] Add validation test for chain of elvis operators in Kotlin (#1812) --- .../kotlin/KotlinElvisOperatorTest.java | 2 +- .../targets/KotlinElvisOperatorTarget.kt | 49 +++++++++++++++++-- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinElvisOperatorTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinElvisOperatorTest.java index b732d4453e..72c18440a9 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinElvisOperatorTest.java +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinElvisOperatorTest.java @@ -16,7 +16,7 @@ import org.jacoco.core.test.validation.kotlin.targets.KotlinElvisOperatorTarget; /** - * Test of elvis operator. + * Test of code coverage in {@link KotlinElvisOperatorTarget}. */ public class KotlinElvisOperatorTest extends ValidationTestBase { diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinElvisOperatorTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinElvisOperatorTarget.kt index 0310b6d072..c5d6b73315 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinElvisOperatorTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinElvisOperatorTarget.kt @@ -13,18 +13,57 @@ package org.jacoco.core.test.validation.kotlin.targets /** - * Test target for elvis operator. + * Test target for [elvis operator (`?:`)](https://kotlinlang.org/docs/null-safety.html#elvis-operator). */ object KotlinElvisOperatorTarget { - private fun example(x: String?): String { - return x ?: "" // assertFullyCovered(0, 2) + private fun elvis() { + fun nullOnly(a: String?): String = + a ?: "" // assertFullyCovered(1, 1) + + fun nonNullOnly(a: String?): String = + a ?: "" // assertPartlyCovered(1, 1) + + fun fullCoverage(a: String?): String = + a ?: "" // assertFullyCovered(0, 2) + + nullOnly(null) + nonNullOnly("") + fullCoverage(null) + fullCoverage("") + } + + private fun elvisChain() { + fun bothNull(a: String?, b: String?): String = + a ?: b ?: "" // assertFullyCovered(2, 2) + + fun secondNonNull(a: String?, b: String?): String = + a ?: b ?: "" // assertPartlyCovered(2, 2) + + fun firstNonNull(a: String?, b: String?): String = + a ?: b ?: "" // assertPartlyCovered(3, 1) + + fun firstOrSecondNonNull(a: String?, b: String?): String = + a ?: b ?: "" // assertPartlyCovered(1, 3) + + fun fullCoverage(a: String?, b: String?): String = + a ?: b ?: "" // assertFullyCovered(0, 4) + + bothNull(null, null) + secondNonNull(null, "") + firstNonNull("", null) + firstNonNull("", "") + firstOrSecondNonNull("", null) + firstOrSecondNonNull(null, "") + fullCoverage(null, null) + fullCoverage("", null) + fullCoverage(null, "") } @JvmStatic fun main(args: Array) { - example("") - example(null) + elvis() + elvisChain() } } From 5d8e0855e3ce82cabf0042c668df41a1bce50095 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:01:01 +0100 Subject: [PATCH 125/163] Upgrade sonar-maven-plugin to 5.0.0.4389 (#1771) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evgeny Mandrikov --- .azure-pipelines/azure-pipelines.yml | 2 +- org.jacoco.build/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 155504492b..7ed12a5f88 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -93,7 +93,7 @@ jobs: elif [[ "$BUILD_SOURCEBRANCH" == "refs/heads/master" && "$JDK_VERSION" == "11" ]]; then ./mvnw -V -B -e --no-transfer-progress -f org.jacoco.build \ verify -Djdk.version=$JDK_VERSION -Dbytecode.version=$JDK_VERSION \ - sonar:sonar \ + sonar:sonar -Dsonar.scanner.skipJreProvisioning \ --toolchains=toolchains.xml --settings=.azure-pipelines/maven-settings.xml else ./mvnw -V -B -e --no-transfer-progress \ diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index e3fbc9a7f7..4fa5493de5 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -455,7 +455,7 @@ org.sonarsource.scanner.maven sonar-maven-plugin - 4.0.0.4121 + 5.0.0.4389 From 6a1a43010d24eb79617b35795fd474d39a4f45a6 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sun, 15 Dec 2024 23:43:45 +0100 Subject: [PATCH 126/163] Add filter for Kotlin safe call operators chains (#1810) --- .../kotlin/KotlinSafeCallOperatorTest.java | 2 +- .../targets/KotlinSafeCallOperatorTarget.kt | 41 +++++++-- .../analysis/filter/FilterTestBase.java | 8 +- .../KotlinSafeCallOperatorFilterTest.java | 83 +++++++++++++++++ .../internal/analysis/filter/Filters.java | 1 + .../filter/KotlinSafeCallOperatorFilter.java | 90 +++++++++++++++++++ org.jacoco.doc/docroot/doc/changes.html | 3 + 7 files changed, 220 insertions(+), 8 deletions(-) create mode 100644 org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilterTest.java create mode 100644 org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilter.java diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSafeCallOperatorTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSafeCallOperatorTest.java index 203f62f3c9..ad5a25b31e 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSafeCallOperatorTest.java +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinSafeCallOperatorTest.java @@ -16,7 +16,7 @@ import org.jacoco.core.test.validation.kotlin.targets.KotlinSafeCallOperatorTarget; /** - * Test of safe call operator. + * Test of code coverage in {@link KotlinSafeCallOperatorTarget}. */ public class KotlinSafeCallOperatorTest extends ValidationTestBase { diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSafeCallOperatorTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSafeCallOperatorTarget.kt index ec8dd708c9..96c94559fc 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSafeCallOperatorTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinSafeCallOperatorTarget.kt @@ -13,18 +13,49 @@ package org.jacoco.core.test.validation.kotlin.targets /** - * Test target for safe call operator. + * Test target for [safe call operator (`?.`)](https://kotlinlang.org/docs/null-safety.html#safe-call-operator). */ object KotlinSafeCallOperatorTarget { - private fun example(x: String?): Int? { - return x?.length // assertFullyCovered(0, 2) + data class A(val b: B) + data class B(val c: String) + + private fun safeCall() { + fun nullOnly(b: B?): String? = + b?.c // assertPartlyCovered(1, 1) + + fun nonNullOnly(b: B?): String? = + b?.c // assertPartlyCovered(1, 1) + + fun fullCoverage(b: B?): String? = + b?.c // assertFullyCovered(0, 2) + + nullOnly(null) + nonNullOnly(B("")) + fullCoverage(null) + fullCoverage(B("")) + } + + private fun safeCallChain() { + fun nullOnly(a: A?): String? = + a?.b?.c // assertPartlyCovered(2, 2) + + fun nonNullOnly(a: A?): String? = + a?.b?.c // assertPartlyCovered(2, 2) + + fun fullCoverage(a: A?): String? = + a?.b?.c // assertFullyCovered(0, 4) + + nullOnly(null) + nonNullOnly(A(B(""))) + fullCoverage(null) + fullCoverage(A(B(""))) } @JvmStatic fun main(args: Array) { - example("") - example(null) + safeCall() + safeCallChain() } } diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/FilterTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/FilterTestBase.java index 66162e5ad0..0e24547a11 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/FilterTestBase.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/FilterTestBase.java @@ -73,8 +73,12 @@ final void assertNoReplacedBranches() { final void assertReplacedBranches(final AbstractInsnNode source, final Set newTargets) { - assertEquals(Collections.singletonMap(source, newTargets), - replacedBranches); + assertReplacedBranches(Collections.singletonMap(source, newTargets)); + } + + final void assertReplacedBranches( + final Map> expected) { + assertEquals(expected, replacedBranches); } static class Range { diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilterTest.java new file mode 100644 index 0000000000..9e0dc31290 --- /dev/null +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilterTest.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * 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 java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +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.AbstractInsnNode; +import org.objectweb.asm.tree.MethodNode; + +/** + * Unit tests for {@link KotlinSafeCallOperatorFilter}. + */ +public class KotlinSafeCallOperatorFilterTest extends FilterTestBase { + + private final IFilter filter = new KotlinSafeCallOperatorFilter(); + + /** + *
      +	 * data class A(val b: B)
      +	 * data class B(val c: String)
      +	 * fun example(a: A?): String? =
      +	 *     a?.b?.c
      +	 * 
      + * + * https://github.com/JetBrains/kotlin/commit/0a67ab54fec635f82e0507cbdd4299ae0dbe71b0 + */ + @Test + public void should_filter_safe_call_chain() { + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "example", "(LA;)Ljava/lang/String;", null, null); + m.visitVarInsn(Opcodes.ALOAD, 1); + final Label label1 = new Label(); + final Label label2 = new Label(); + + m.visitInsn(Opcodes.DUP); + m.visitJumpInsn(Opcodes.IFNULL, label1); + final AbstractInsnNode i1 = m.instructions.getLast(); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "A", "getB", "()LB;", false); + + m.visitInsn(Opcodes.DUP); + m.visitJumpInsn(Opcodes.IFNULL, label1); + final AbstractInsnNode i2 = m.instructions.getLast(); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "B", "getC", + "()Ljava/lang/String;", false); + final HashSet r = new HashSet(); + r.add(m.instructions.getLast()); + + m.visitJumpInsn(Opcodes.GOTO, label2); + + m.visitLabel(label1); + m.visitInsn(Opcodes.POP); + r.add(m.instructions.getLast()); + m.visitInsn(Opcodes.ACONST_NULL); + m.visitLabel(label2); + + filter.filter(m, context, output); + + assertIgnored(); + final HashMap> expected = new HashMap>(); + expected.put(i1, r); + expected.put(i2, r); + assertReplacedBranches(expected); + } + +} 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 11b748caf5..1f7e600edd 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 @@ -44,6 +44,7 @@ public static IFilter all() { new RecordPatternFilter(), // new AnnotationGeneratedFilter(), new KotlinGeneratedFilter(), new KotlinEnumFilter(), // + new KotlinSafeCallOperatorFilter(), // new KotlinLateinitFilter(), new KotlinWhenFilter(), new KotlinWhenStringFilter(), new KotlinUnsafeCastOperatorFilter(), diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilter.java new file mode 100644 index 0000000000..887ff7ad87 --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilter.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * 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 java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.JumpInsnNode; +import org.objectweb.asm.tree.LabelNode; +import org.objectweb.asm.tree.MethodNode; + +/** + * Filters bytecode that Kotlin compiler generates for chains of safe call + * operators ({@code ?.}). + */ +final class KotlinSafeCallOperatorFilter implements IFilter { + + public void filter(final MethodNode methodNode, + final IFilterContext context, final IFilterOutput output) { + if (!Filters.isKotlinClass(context)) { + return; + } + for (final ArrayList chain : findChains(methodNode)) { + if (chain.size() == 1) { + continue; + } + JumpInsnNode lastJump = chain.get(chain.size() - 1); + final HashSet newTargets = new HashSet(); + newTargets.add(AbstractMatcher.skipNonOpcodes(lastJump.getNext())); + newTargets.add(AbstractMatcher.skipNonOpcodes(lastJump.label)); + for (final AbstractInsnNode i : chain) { + output.replaceBranches(i, newTargets); + } + } + } + + /** + *
      +	 * DUP
      +	 * IFNULL label
      +	 * ... // call 0
      +	 *
      +	 * ...
      +	 *
      +	 * DUP
      +	 * IFNULL label
      +	 * ... // call N
      +	 *
      +	 * label:
      +	 * POP
      +	 * 
      + */ + private static Collection> findChains( + final MethodNode methodNode) { + final HashMap> chains = new HashMap>(); + for (final AbstractInsnNode i : methodNode.instructions) { + if (i.getOpcode() == Opcodes.IFNULL + && i.getPrevious().getOpcode() == Opcodes.DUP) { + final JumpInsnNode jump = (JumpInsnNode) i; + final LabelNode label = jump.label; + if (AbstractMatcher.skipNonOpcodes(label.getNext()) + .getOpcode() != Opcodes.POP) { + continue; + } + ArrayList chain = chains.get(label); + if (chain == null) { + chain = new ArrayList(); + chains.put(label, chain); + } + chain.add(jump); + } + } + return chains.values(); + } + +} diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index c4ce95b553..e098ee6d0d 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -49,6 +49,9 @@

      New Features

      expressions and statements with nullable enum subject is filtered out during generation of report (GitHub #1774). +
    • Part of bytecode generated by the Kotlin compiler for chains of safe call + operators is filtered out during generation of report + (GitHub #1810).
    • Method getEntries generated by the Kotlin compiler for enum classes is filtered out during generation of report (GitHub #1625).
    • From 1b2ebc3cd415c272b92c60d708b6d3b459a52d8b Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:52:45 +0100 Subject: [PATCH 127/163] Extract `KotlinSyntheticAccessorsFilter` from `SyntheticFilter` (#1811) --- .../filter/KotlinSyntheticFilterTest.java | 167 ++++++++++++++++++ .../analysis/filter/SyntheticFilterTest.java | 140 --------------- .../internal/analysis/filter/Filters.java | 1 + .../KotlinSyntheticAccessorsFilter.java | 38 ++++ .../analysis/filter/SyntheticFilter.java | 12 +- 5 files changed, 211 insertions(+), 147 deletions(-) create mode 100644 org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticFilterTest.java create mode 100644 org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticAccessorsFilter.java diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticFilterTest.java new file mode 100644 index 0000000000..b1cdd75351 --- /dev/null +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticFilterTest.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * 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.jacoco.core.internal.instr.InstrSupport; +import org.junit.Test; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.MethodNode; + +/** + * Unit tests for {@link KotlinSyntheticAccessorsFilter}. + */ +public class KotlinSyntheticFilterTest extends FilterTestBase { + + private final IFilter filter = new KotlinSyntheticAccessorsFilter(); + + /** + *
      +	 * @JvmSynthetic
      +	 * fun example() {
      +	 * }
      +	 * 
      + * + * @see #should_filter_synthetic_accessor_methods_in_Kotlin_classes() + */ + @Test + public void should_not_filter_synthetic_non_accessor_methods_in_Kotlin_classes() { + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_SYNTHETIC, "example", "()V", null, null); + m.visitInsn(Opcodes.RETURN); + + filter.filter(m, context, output); + + assertIgnored(); + } + + /** + *
      +	 * class Outer {
      +	 *   private var x = 42
      +	 *
      +	 *   inner class Inner {
      +	 *     fun example() {
      +	 *       x += 1
      +	 *     }
      +	 *   }
      +	 * }
      +	 * 
      + * + * @see #should_not_filter_synthetic_non_accessor_methods_in_Kotlin_classes() + */ + @Test + public void should_filter_synthetic_accessor_methods_in_Kotlin_classes() { + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_SYNTHETIC, "access$getX$p", "(Outer;)I", null, + null); + m.visitVarInsn(Opcodes.ALOAD, 0); + m.visitFieldInsn(Opcodes.GETFIELD, "Outer", "x", "I"); + m.visitInsn(Opcodes.IRETURN); + + filter.filter(m, context, output); + + assertMethodIgnored(m); + } + + @Test + public void should_not_filter_method_with_suffix_default_in_kotlin_classes() { + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE, "example$default", + "(LTarget;Ljava/lang/String;Ijava/lang/Object;)V", null, null); + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + m.visitInsn(Opcodes.NOP); + + filter.filter(m, context, output); + + assertIgnored(); + } + + @Test + public void should_not_filter_synthetic_constructor_containing_default_arguments_in_kotlin_classes() { + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_SYNTHETIC, "", + "(IILkotlin/jvm/internal/DefaultConstructorMarker;)V", null, + null); + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + m.visitInsn(Opcodes.NOP); + + filter.filter(m, context, output); + + assertIgnored(); + } + + /** + * For private suspending function Kotlin compiler versions prior to 1.5 + * produce package-local synthetic method that should not be filtered + * + *
      +	 * private suspend fun example() {
      +	 * }
      +	 * 
      + * + * @see #should_filter_synthetic_methods_whose_name_starts_with_access_dollar_even_if_last_argument_is_kotlin_coroutine_continuation() + */ + @Test + public void should_not_filter_synthetic_methods_whose_last_argument_is_kotlin_coroutine_continuation() { + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC, "example", + "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", null, + null); + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + m.visitInsn(Opcodes.NOP); + + filter.filter(m, context, output); + + assertIgnored(); + } + + /** + * For private suspending function Kotlin compiler versions starting from + * 1.5 produce additional public synthetic method with name starting with + * "access$" that should be filtered + * + *
      +	 * private suspend fun example() {
      +	 * }
      +	 * 
      + * + * @see #should_not_filter_synthetic_methods_whose_last_argument_is_kotlin_coroutine_continuation() + */ + @Test + public void should_filter_synthetic_methods_whose_name_starts_with_access_dollar_even_if_last_argument_is_kotlin_coroutine_continuation() { + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, + Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL + | Opcodes.ACC_SYNTHETIC, + "access$example", + "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", null, + null); + context.classAnnotations + .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); + m.visitVarInsn(Opcodes.ALOAD, 0); + m.visitMethodInsn(Opcodes.INVOKESTATIC, "ExampleKt", "example", + "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", false); + m.visitInsn(Opcodes.RETURN); + + filter.filter(m, context, output); + + assertMethodIgnored(m); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java index d0cd63f417..bdc502b35b 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java @@ -57,59 +57,6 @@ public void testLambda() { assertIgnored(); } - /** - *
      -	 * @JvmSynthetic
      -	 * fun example() {
      -	 * }
      -	 * 
      - * - * @see #should_filter_synthetic_accessor_methods_in_Kotlin_classes() - */ - @Test - public void should_not_filter_synthetic_non_accessor_methods_in_Kotlin_classes() { - context.classAnnotations - .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); - final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, - Opcodes.ACC_SYNTHETIC, "example", "()V", null, null); - m.visitInsn(Opcodes.RETURN); - - filter.filter(m, context, output); - - assertIgnored(); - } - - /** - *
      -	 * class Outer {
      -	 *   private var x = 42
      -	 *
      -	 *   inner class Inner {
      -	 *     fun example() {
      -	 *       x += 1
      -	 *     }
      -	 *   }
      -	 * }
      -	 * 
      - * - * @see #should_not_filter_synthetic_non_accessor_methods_in_Kotlin_classes() - */ - @Test - public void should_filter_synthetic_accessor_methods_in_Kotlin_classes() { - context.classAnnotations - .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); - final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, - Opcodes.ACC_SYNTHETIC, "access$getX$p", "(Outer;)I", null, - null); - m.visitVarInsn(Opcodes.ALOAD, 0); - m.visitFieldInsn(Opcodes.GETFIELD, "Outer", "x", "I"); - m.visitInsn(Opcodes.IRETURN); - - filter.filter(m, context, output); - - assertMethodIgnored(m); - } - @Test public void should_filter_synthetic_method_with_prefix_anonfun_in_non_Scala_classes() { final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, @@ -142,20 +89,6 @@ public void should_not_filter_synthetic_method_with_prefix_anonfun_in_Scala_inne assertIgnored(); } - @Test - public void should_not_filter_method_with_suffix_default_in_kotlin_classes() { - final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, - Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE, "example$default", - "(LTarget;Ljava/lang/String;Ijava/lang/Object;)V", null, null); - context.classAnnotations - .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); - m.visitInsn(Opcodes.NOP); - - filter.filter(m, context, output); - - assertIgnored(); - } - @Test public void should_filter_synthetic_method_with_suffix_default_in_non_kotlin_classes() { final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, @@ -168,77 +101,4 @@ public void should_filter_synthetic_method_with_suffix_default_in_non_kotlin_cla assertMethodIgnored(m); } - @Test - public void should_not_filter_synthetic_constructor_containing_default_arguments_in_kotlin_classes() { - final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, - Opcodes.ACC_SYNTHETIC, "", - "(IILkotlin/jvm/internal/DefaultConstructorMarker;)V", null, - null); - context.classAnnotations - .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); - m.visitInsn(Opcodes.NOP); - - filter.filter(m, context, output); - - assertIgnored(); - } - - /** - * For private suspending function Kotlin compiler versions prior to 1.5 - * produce package-local synthetic method that should not be filtered - * - *
      -	 * private suspend fun example() {
      -	 * }
      -	 * 
      - * - * @see #should_filter_synthetic_methods_whose_name_starts_with_access_dollar_even_if_last_argument_is_kotlin_coroutine_continuation() - */ - @Test - public void should_not_filter_synthetic_methods_whose_last_argument_is_kotlin_coroutine_continuation() { - final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, - Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC, "example", - "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", null, - null); - context.classAnnotations - .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); - m.visitInsn(Opcodes.NOP); - - filter.filter(m, context, output); - - assertIgnored(); - } - - /** - * For private suspending function Kotlin compiler versions starting from - * 1.5 produce additional public synthetic method with name starting with - * "access$" that should be filtered - * - *
      -	 * private suspend fun example() {
      -	 * }
      -	 * 
      - * - * @see #should_not_filter_synthetic_methods_whose_last_argument_is_kotlin_coroutine_continuation() - */ - @Test - public void should_filter_synthetic_methods_whose_name_starts_with_access_dollar_even_if_last_argument_is_kotlin_coroutine_continuation() { - final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, - Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL - | Opcodes.ACC_SYNTHETIC, - "access$example", - "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", null, - null); - context.classAnnotations - .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC); - m.visitVarInsn(Opcodes.ALOAD, 0); - m.visitMethodInsn(Opcodes.INVOKESTATIC, "ExampleKt", "example", - "(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;", false); - m.visitInsn(Opcodes.RETURN); - - filter.filter(m, context, output); - - assertMethodIgnored(m); - } - } 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 1f7e600edd..34754d3cb5 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 @@ -43,6 +43,7 @@ public static IFilter all() { new ExhaustiveSwitchFilter(), // new RecordPatternFilter(), // new AnnotationGeneratedFilter(), new KotlinGeneratedFilter(), + new KotlinSyntheticAccessorsFilter(), // new KotlinEnumFilter(), // new KotlinSafeCallOperatorFilter(), // new KotlinLateinitFilter(), new KotlinWhenFilter(), diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticAccessorsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticAccessorsFilter.java new file mode 100644 index 0000000000..c580f83d5c --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticAccessorsFilter.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * 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 synthetic accessors generated by the Kotlin compiler. + */ +final class KotlinSyntheticAccessorsFilter implements IFilter { + + public void filter(MethodNode methodNode, IFilterContext context, + IFilterOutput output) { + if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) { + return; + } + if (!Filters.isKotlinClass(context)) { + return; + } + if (!methodNode.name.startsWith("access$")) { + return; + } + output.ignore(methodNode.instructions.getFirst(), + methodNode.instructions.getLast()); + } + +} 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 f260d01cf2..fde5d3a744 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 @@ -16,7 +16,8 @@ import org.objectweb.asm.tree.MethodNode; /** - * Filters synthetic methods unless they represent bodies of lambda expressions. + * Filters synthetic methods in non-Kotlin classes unless they represent bodies + * of lambda expressions. */ final class SyntheticFilter implements IFilter { @@ -30,6 +31,9 @@ public void filter(final MethodNode methodNode, if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) { return; } + if (Filters.isKotlinClass(context)) { + return; + } if (methodNode.name.startsWith("lambda$")) { return; @@ -41,12 +45,6 @@ public void filter(final MethodNode methodNode, } } - if (Filters.isKotlinClass(context)) { - if (!methodNode.name.startsWith("access$")) { - return; - } - } - output.ignore(methodNode.instructions.getFirst(), methodNode.instructions.getLast()); } From 451e6b6b64161c1e18730160c6248ca8aa176874 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:49:08 +0100 Subject: [PATCH 128/163] Upgrade maven-invoker-plugin to 3.9.0 (#1817) Bump org.apache.maven.plugins:maven-invoker-plugin in /org.jacoco.build Bumps [org.apache.maven.plugins:maven-invoker-plugin](https://github.com/apache/maven-invoker-plugin) from 3.8.1 to 3.9.0. - [Release notes](https://github.com/apache/maven-invoker-plugin/releases) - [Commits](https://github.com/apache/maven-invoker-plugin/compare/maven-invoker-plugin-3.8.1...maven-invoker-plugin-3.9.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-invoker-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 4fa5493de5..2de8f12a45 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -338,7 +338,7 @@ org.apache.maven.plugins maven-invoker-plugin - 3.8.1 + 3.9.0 org.apache.maven.plugins From b1ad67d3009c29a6725a2548721041140a577a54 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 17 Dec 2024 22:54:00 +0100 Subject: [PATCH 129/163] IntelliJ IDEA should not suggest import of `jdk.internal.*` classes (#1820) Without this change IntelliJ shows me first `jdk.internal.org.objectweb.asm.Opcodes` in the list of suggestions and only then `org.objectweb.asm.Opcodes`. --- .idea/codeInsightSettings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .idea/codeInsightSettings.xml diff --git a/.idea/codeInsightSettings.xml b/.idea/codeInsightSettings.xml new file mode 100644 index 0000000000..62ce4d17bd --- /dev/null +++ b/.idea/codeInsightSettings.xml @@ -0,0 +1,8 @@ + + + + + jdk.internal.* + + + \ No newline at end of file From 1e37ea8645e4702bcc6a817adf08864a987fd19b Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 17 Dec 2024 23:43:31 +0100 Subject: [PATCH 130/163] Add validation test for `Serializable` lambda in Java (#1698) --- .../java8/LambdaSerializableTest.java | 51 +++++++++++++++++++ .../targets/LambdaSerializableTarget.java | 33 ++++++++++++ .../core/test/validation/targets/Stubs.java | 14 +++++ 3 files changed, 98 insertions(+) create mode 100644 org.jacoco.core.test.validation.java8/src/org/jacoco/core/test/validation/java8/LambdaSerializableTest.java create mode 100644 org.jacoco.core.test.validation.java8/src/org/jacoco/core/test/validation/java8/targets/LambdaSerializableTarget.java diff --git a/org.jacoco.core.test.validation.java8/src/org/jacoco/core/test/validation/java8/LambdaSerializableTest.java b/org.jacoco.core.test.validation.java8/src/org/jacoco/core/test/validation/java8/LambdaSerializableTest.java new file mode 100644 index 0000000000..399383e39b --- /dev/null +++ b/org.jacoco.core.test.validation.java8/src/org/jacoco/core/test/validation/java8/LambdaSerializableTest.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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.java8; + +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Method; +import java.util.HashSet; + +import org.jacoco.core.test.validation.ValidationTestBase; +import org.jacoco.core.test.validation.java8.targets.LambdaSerializableTarget; +import org.junit.Test; + +/** + * Test of code coverage in {@link LambdaSerializableTarget}. + */ +public class LambdaSerializableTest extends ValidationTestBase { + + public LambdaSerializableTest() { + super(LambdaSerializableTarget.class); + } + + @Test + public void compiler_should_generate_synthetic_deserializeLambda() { + final HashSet names = new HashSet<>(); + for (final Method method : LambdaSerializableTarget.class + .getDeclaredMethods()) { + if (method.isSynthetic()) { + names.add(method.getName()); + } + } + + assertTrue(names.contains("$deserializeLambda$")); + } + + @Test + public void test_method_count() { + assertMethodCount(/* constructor + main + lambda */ 3); + } + +} diff --git a/org.jacoco.core.test.validation.java8/src/org/jacoco/core/test/validation/java8/targets/LambdaSerializableTarget.java b/org.jacoco.core.test.validation.java8/src/org/jacoco/core/test/validation/java8/targets/LambdaSerializableTarget.java new file mode 100644 index 0000000000..78b7216d0d --- /dev/null +++ b/org.jacoco.core.test.validation.java8/src/org/jacoco/core/test/validation/java8/targets/LambdaSerializableTarget.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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.java8.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.execSerializable; +import static org.jacoco.core.test.validation.targets.Stubs.nop; + +import java.io.Serializable; + +/** + * Test target with {@link Serializable} lambda. + */ +public class LambdaSerializableTarget { + + public static void main(String[] args) { + + execSerializable(() -> { + nop(); // assertFullyCovered() + }); + + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java index 9e0a723b66..8c5b2d8dad 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java @@ -12,6 +12,7 @@ *******************************************************************************/ package org.jacoco.core.test.validation.targets; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -39,6 +40,12 @@ public SuperClass(boolean arg) { } + /** + * Serializable functional interface stub. + */ + public interface SerializableRunnable extends Serializable, Runnable { + } + /** * Enum stub. */ @@ -144,6 +151,13 @@ public static void exec(Runnable task) { public static void noexec(Runnable task) { } + /** + * Directly executes the given {@link SerializableRunnable}. + */ + public static void execSerializable(SerializableRunnable task) { + task.run(); + } + /** * List of logged events. Using a static member here works as this class is * loaded in a new class loader for every test case. From 22ead5e845a3db08b0f3051eb9f2fe8e6edcf827 Mon Sep 17 00:00:00 2001 From: "Marc R. Hoffmann" Date: Wed, 18 Dec 2024 00:50:16 +0100 Subject: [PATCH 131/163] Get rid of repetitive execution of `isKotlinClass` in Kotlin filters (#1809) Co-authored-by: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> --- .../KotlinDefaultArgumentsFilterTest.java | 11 --- .../KotlinDefaultMethodsFilterTest.java | 14 --- .../analysis/filter/KotlinEnumFilterTest.java | 15 ---- .../filter/KotlinGeneratedFilterTest.java | 12 --- .../filter/KotlinInlineClassFilterTest.java | 12 --- .../filter/KotlinInlineFilterTest.java | 12 --- .../KotlinUnsafeCastOperatorFilterTest.java | 19 ---- .../internal/analysis/filter/FilterSet.java | 35 ++++++++ .../internal/analysis/filter/Filters.java | 90 +++++++++++-------- .../analysis/filter/KotlinComposeFilter.java | 3 - .../filter/KotlinCoroutineFilter.java | 5 -- .../filter/KotlinDefaultArgumentsFilter.java | 6 +- .../filter/KotlinDefaultMethodsFilter.java | 3 - .../analysis/filter/KotlinEnumFilter.java | 3 - .../filter/KotlinGeneratedFilter.java | 5 -- .../filter/KotlinInlineClassFilter.java | 3 - .../analysis/filter/KotlinInlineFilter.java | 8 +- .../filter/KotlinSafeCallOperatorFilter.java | 5 +- .../KotlinUnsafeCastOperatorFilter.java | 3 - 19 files changed, 94 insertions(+), 170 deletions(-) create mode 100644 org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FilterSet.java diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java index 6b66fabc18..bb4f3d2a35 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilterTest.java @@ -63,17 +63,6 @@ public void should_filter() { assertIgnored(new Range(m.instructions.get(3), m.instructions.get(3))); } - @Test - public void should_not_filter_when_not_kotlin() { - final MethodNode m = createMethod(Opcodes.ACC_SYNTHETIC, - "not_kotlin_synthetic$default", - "(LTarget;IILjava/lang/Object;)V"); - - filter.filter(m, context, output); - - assertIgnored(); - } - @Test public void should_not_filter_when_suffix_absent() { final MethodNode m = createMethod(Opcodes.ACC_SYNTHETIC, diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilterTest.java index efa37ff891..58d6330379 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilterTest.java @@ -69,18 +69,4 @@ public void should_not_filter_when_instructions_do_not_match() { assertIgnored(); } - @Test - public void should_not_filter_when_not_kotlin() { - final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, - "m", "()V", null, null); - m.visitVarInsn(Opcodes.ALOAD, 0); - m.visitMethodInsn(Opcodes.INVOKESTATIC, "Target$DefaultImpls", "m", - "(LTarget;)V", false); - m.visitInsn(Opcodes.RETURN); - - filter.filter(m, context, output); - - assertIgnored(); - } - } diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilterTest.java index 2c3a885132..1fcfeae54e 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilterTest.java @@ -61,21 +61,6 @@ public void should_not_filter_when_not_Enum() { assertIgnored(); } - @Test - public void should_not_filter_when_not_Kotlin() { - context.superClassName = "java/lang/Enum"; - final MethodNode m = new MethodNode( - Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "getEntries", - "()Lkotlin/enums/EnumEntries;", null, null); - m.visitFieldInsn(Opcodes.GETSTATIC, "Example", "$ENTRIES", - "Lkotlin/enums/EnumEntries;"); - m.visitInsn(Opcodes.ARETURN); - - filter.filter(m, context, output); - - assertIgnored(); - } - @Test public void should_not_filter_when_not_getEntries_name() { context.superClassName = "java/lang/Enum"; diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilterTest.java index f0b01765de..a00c609cde 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilterTest.java @@ -55,18 +55,6 @@ public void testWithLinesForKotlinWithDebug() { assertIgnored(); } - @Test - public void testNoLinesNonKotlinWithDebug() { - final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, - "hashCode", "()I", null, null); - m.visitInsn(Opcodes.ICONST_0); - m.visitInsn(Opcodes.IRETURN); - - filter.filter(m, context, output); - - assertIgnored(); - } - @Test public void testNoLinesForKotlinNoDebug() { final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, 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 index 8fd77a0a4e..99a4a86902 100644 --- 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 @@ -83,16 +83,4 @@ public void should_not_filter_when_no_JvmInline_annotation() { 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.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java index 161faea31f..f54bd641e3 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilterTest.java @@ -284,18 +284,6 @@ public void should_filter_all_lines() { assertIgnored(expectedRanges.toArray(new Range[0])); } - @Test - public void should_not_parse_SourceDebugExtension_attribute_when_no_kotlin_metadata_annotation() { - context.sourceDebugExtension = "SMAP"; - - m.visitLineNumber(1, new Label()); - m.visitInsn(Opcodes.RETURN); - - filter.filter(m, context, output); - - assertIgnored(); - } - @Test public void should_not_filter_when_no_SourceDebugExtension_attribute() { context.classAnnotations diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilterTest.java index 2abd150952..5d4584424c 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilterTest.java @@ -146,23 +146,4 @@ public void should_filter_Kotlin_1_6() { assertIgnored(new Range(expectedFrom, expectedTo)); } - @Test - public void should_not_filter_when_not_kotlin() { - m.visitInsn(Opcodes.DUP); - final Label label = new Label(); - m.visitJumpInsn(Opcodes.IFNONNULL, label); - m.visitTypeInsn(Opcodes.NEW, "java/lang/NullPointerException"); - m.visitInsn(Opcodes.DUP); - m.visitLdcInsn("null cannot be cast to non-null type kotlin.String"); - m.visitMethodInsn(Opcodes.INVOKESPECIAL, - "java/lang/NullPointerException", "", - "(Ljava/lang/String;)V", false); - m.visitInsn(Opcodes.ATHROW); - m.visitLabel(label); - - filter.filter(m, context, output); - - assertIgnored(); - } - } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FilterSet.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FilterSet.java new file mode 100644 index 0000000000..f998ede6f2 --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FilterSet.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * 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.tree.MethodNode; + +/** + * Filter that combines other filters. + */ +class FilterSet implements IFilter { + + private final IFilter[] filters; + + FilterSet(final IFilter... filters) { + this.filters = filters; + } + + public void filter(final MethodNode methodNode, + final IFilterContext context, final IFilterOutput output) { + for (final IFilter filter : filters) { + filter.filter(methodNode, context, output); + } + } + +} 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 34754d3cb5..79ab5b1bc8 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 @@ -15,56 +15,76 @@ import org.objectweb.asm.tree.MethodNode; /** - * Filter that combines other filters. + * Factory for all JaCoCo filters. */ -public final class Filters implements IFilter { +public final class Filters { + + private Filters() { + // no instances + } /** * Filter that does nothing. */ - public static final IFilter NONE = new Filters(); - - private final IFilter[] filters; + public static final IFilter NONE = new FilterSet(); /** - * Creates filter that combines all other filters. + * Creates a filter that combines all filters. * - * @return filter that combines all other filters + * @return filter that combines all filters */ public static IFilter all() { - return new Filters(new EnumFilter(), new SyntheticFilter(), - new BridgeFilter(), new SynchronizedFilter(), - new TryWithResourcesJavac11Filter(), - new TryWithResourcesJavacFilter(), - new TryWithResourcesEcjFilter(), new FinallyFilter(), - new PrivateEmptyNoArgConstructorFilter(), new AssertFilter(), - new StringSwitchJavacFilter(), new StringSwitchFilter(), - new EnumEmptyConstructorFilter(), new RecordsFilter(), + return new FilterSet( // + allCommonFilters(), // + allKotlinFilters()); + } + + private static IFilter allCommonFilters() { + return new FilterSet( // + new EnumFilter(), // + new SyntheticFilter(), // + new BridgeFilter(), // + new SynchronizedFilter(), // + new TryWithResourcesJavac11Filter(), // + new TryWithResourcesJavacFilter(), // + new TryWithResourcesEcjFilter(), // + new FinallyFilter(), // + new PrivateEmptyNoArgConstructorFilter(), // + new AssertFilter(), // + new StringSwitchJavacFilter(), // + new StringSwitchFilter(), // + new EnumEmptyConstructorFilter(), // + new RecordsFilter(), // new ExhaustiveSwitchFilter(), // new RecordPatternFilter(), // - new AnnotationGeneratedFilter(), new KotlinGeneratedFilter(), + new AnnotationGeneratedFilter()); + } + + private static IFilter allKotlinFilters() { + return new FilterSet( // + new KotlinGeneratedFilter(), // new KotlinSyntheticAccessorsFilter(), // new KotlinEnumFilter(), // new KotlinSafeCallOperatorFilter(), // - new KotlinLateinitFilter(), new KotlinWhenFilter(), - new KotlinWhenStringFilter(), - new KotlinUnsafeCastOperatorFilter(), - new KotlinNotNullOperatorFilter(), - new KotlinInlineClassFilter(), - new KotlinDefaultArgumentsFilter(), new KotlinInlineFilter(), - new KotlinCoroutineFilter(), new KotlinDefaultMethodsFilter(), - new KotlinComposeFilter()); - } - - private Filters(final IFilter... filters) { - this.filters = filters; - } - - public void filter(final MethodNode methodNode, - final IFilterContext context, final IFilterOutput output) { - for (final IFilter filter : filters) { - filter.filter(methodNode, context, output); - } + new KotlinLateinitFilter(), // + new KotlinWhenFilter(), // + new KotlinWhenStringFilter(), // + new KotlinUnsafeCastOperatorFilter(), // + new KotlinNotNullOperatorFilter(), // + new KotlinInlineClassFilter(), // + new KotlinDefaultArgumentsFilter(), // + new KotlinInlineFilter(), // + new KotlinCoroutineFilter(), // + new KotlinDefaultMethodsFilter(), // + new KotlinComposeFilter()) { + @Override + public void filter(final MethodNode methodNode, + final IFilterContext context, final IFilterOutput output) { + if (isKotlinClass(context)) { + super.filter(methodNode, context, output); + } + } + }; } /** diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java index 62a53d9235..6c57d4e626 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinComposeFilter.java @@ -26,9 +26,6 @@ final class KotlinComposeFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!Filters.isKotlinClass(context)) { - return; - } if (!isComposable(methodNode)) { return; } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java index c83c28b8cc..8107845038 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java @@ -30,11 +30,6 @@ final class KotlinCoroutineFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - - if (!Filters.isKotlinClass(context)) { - return; - } - new Matcher().match(methodNode, output); new Matcher().matchOptimizedTailCall(methodNode, output); } 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 61643f138d..f5d5de2824 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 @@ -76,10 +76,6 @@ public void filter(final MethodNode methodNode, if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) { return; } - if (!Filters.isKotlinClass(context)) { - return; - } - if (isDefaultArgumentsMethod(methodNode)) { new Matcher().match(methodNode, output, false); } else if (isDefaultArgumentsConstructor(methodNode)) { @@ -133,7 +129,7 @@ public void match(final MethodNode methodNode, skipNonOpcodes(); } - for (AbstractInsnNode i : ignore) { + for (final AbstractInsnNode i : ignore) { output.ignore(i, i); } } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java index d79952216b..3ee8d06dfd 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java @@ -24,9 +24,6 @@ final class KotlinDefaultMethodsFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!Filters.isKotlinClass(context)) { - return; - } new Matcher().match(methodNode, output); } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilter.java index 43737cd6f0..ea91cdd61e 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinEnumFilter.java @@ -25,9 +25,6 @@ public void filter(final MethodNode methodNode, if (!"java/lang/Enum".equals(context.getSuperClassName())) { return; } - if (!Filters.isKotlinClass(context)) { - return; - } if (!"getEntries".equals(methodNode.name)) { return; } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java index 7e7b67e0b6..7d4a2cef2a 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java @@ -32,11 +32,6 @@ public void filter(final MethodNode methodNode, // disabled filtering as all methods might be erroneously skipped return; } - - if (!Filters.isKotlinClass(context)) { - return; - } - if (hasLineNumber(methodNode)) { for (final AbstractInsnNode i : methodNode.instructions) { if (AbstractInsnNode.LINE == i.getType()) { 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 index 41ad6d4e19..bf46771cf5 100644 --- 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 @@ -73,9 +73,6 @@ final class KotlinInlineClassFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!Filters.isKotlinClass(context)) { - return; - } if (!context.getClassAnnotations().contains("Lkotlin/jvm/JvmInline;")) { return; } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java index 1a3bbe9e7c..f323de3212 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java @@ -29,10 +29,6 @@ public void filter(final MethodNode methodNode, return; } - if (!Filters.isKotlinClass(context)) { - return; - } - if (firstGeneratedLineNumber == -1) { firstGeneratedLineNumber = getFirstGeneratedLineNumber( context.getClassName(), context.getSourceFileName(), @@ -53,8 +49,8 @@ public void filter(final MethodNode methodNode, private static int getFirstGeneratedLineNumber(final String className, final String sourceFileName, final String smap) { int min = Integer.MAX_VALUE; - for (KotlinSMAP.Mapping mapping : new KotlinSMAP(sourceFileName, smap) - .mappings()) { + for (final KotlinSMAP.Mapping mapping : new KotlinSMAP(sourceFileName, + smap).mappings()) { if (className.equals(mapping.inputClassName()) && mapping.inputStartLine() == mapping.outputStartLine()) { continue; diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilter.java index 887ff7ad87..c3fdec96eb 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSafeCallOperatorFilter.java @@ -31,14 +31,11 @@ final class KotlinSafeCallOperatorFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!Filters.isKotlinClass(context)) { - return; - } for (final ArrayList chain : findChains(methodNode)) { if (chain.size() == 1) { continue; } - JumpInsnNode lastJump = chain.get(chain.size() - 1); + final JumpInsnNode lastJump = chain.get(chain.size() - 1); final HashSet newTargets = new HashSet(); newTargets.add(AbstractMatcher.skipNonOpcodes(lastJump.getNext())); newTargets.add(AbstractMatcher.skipNonOpcodes(lastJump.label)); diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java index 559bda4b21..35af5efdb7 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java @@ -26,9 +26,6 @@ final class KotlinUnsafeCastOperatorFilter implements IFilter { public void filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output) { - if (!Filters.isKotlinClass(context)) { - return; - } final Matcher matcher = new Matcher(); for (final AbstractInsnNode i : methodNode.instructions) { matcher.match("kotlin/TypeCastException", i, output); From 70a82d91eac20b0b9286ac728ca63a27157fbc3a Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Thu, 19 Dec 2024 09:48:35 +0100 Subject: [PATCH 132/163] Add validation test for `Serializable` lambda in Kotlin (#1699) --- .../kotlin/KotlinLambdaSerializableTest.java | 52 +++++++++++++++++++ .../targets/KotlinLambdaSerializableTarget.kt | 32 ++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinLambdaSerializableTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinLambdaSerializableTarget.kt diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinLambdaSerializableTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinLambdaSerializableTest.java new file mode 100644 index 0000000000..bd6a7ef0ca --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinLambdaSerializableTest.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 static org.junit.Assert.assertEquals; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashSet; + +import org.jacoco.core.test.validation.ValidationTestBase; +import org.jacoco.core.test.validation.kotlin.targets.KotlinLambdaSerializableTarget; +import org.junit.Test; + +/** + * Test of code coverage in {@link KotlinLambdaSerializableTarget}. + */ +public class KotlinLambdaSerializableTest extends ValidationTestBase { + + public KotlinLambdaSerializableTest() { + super(KotlinLambdaSerializableTarget.class); + } + + @Test + public void compiler_should_generate_synthetic_deserializeLambda() { + final HashSet names = new HashSet(); + for (final Method method : KotlinLambdaSerializableTarget.class + .getDeclaredMethods()) { + if (method.isSynthetic()) { + names.add(method.getName()); + } + } + + assertEquals(Collections.singleton("$deserializeLambda$"), names); + } + + @Test + public void test_method_count() { + assertMethodCount(/* main + lambda */ 2); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinLambdaSerializableTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinLambdaSerializableTarget.kt new file mode 100644 index 0000000000..8d35464b81 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinLambdaSerializableTarget.kt @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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.execSerializable +import org.jacoco.core.test.validation.targets.Stubs.nop + +/** + * Test target with [java.io.Serializable] lambda. + */ +object KotlinLambdaSerializableTarget { + + @JvmStatic + fun main(args: Array) { + + execSerializable { + nop() // assertFullyCovered() + } + + } + +} From f59a132c87ca4bd7e975a6790191c3b7984a5276 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:28:26 +0100 Subject: [PATCH 133/163] =?UTF-8?q?Get=20rid=20of=20cycle=20Filters.allKot?= =?UTF-8?q?linFilters=20=E2=86=92=20SyntheticFilter=20=E2=86=92=20Filters.?= =?UTF-8?q?isKotlinClass=20(#1822)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/analysis/filter/FilterSet.java | 2 +- .../internal/analysis/filter/Filters.java | 33 +++++++++++-------- .../KotlinSyntheticAccessorsFilter.java | 3 -- .../analysis/filter/SyntheticFilter.java | 3 -- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FilterSet.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FilterSet.java index f998ede6f2..33cc26f9b6 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FilterSet.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FilterSet.java @@ -17,7 +17,7 @@ /** * Filter that combines other filters. */ -class FilterSet implements IFilter { +final class FilterSet implements IFilter { private final IFilter[] filters; 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 79ab5b1bc8..172c96bbfb 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,15 +34,25 @@ private Filters() { * @return filter that combines all filters */ public static IFilter all() { - return new FilterSet( // - allCommonFilters(), // - allKotlinFilters()); + final IFilter allCommonFilters = allCommonFilters(); + final IFilter allKotlinFilters = allKotlinFilters(); + final IFilter allNonKotlinFilters = allNonKotlinFilters(); + return new IFilter() { + public void filter(final MethodNode methodNode, + final IFilterContext context, final IFilterOutput output) { + allCommonFilters.filter(methodNode, context, output); + if (isKotlinClass(context)) { + allKotlinFilters.filter(methodNode, context, output); + } else { + allNonKotlinFilters.filter(methodNode, context, output); + } + } + }; } private static IFilter allCommonFilters() { return new FilterSet( // new EnumFilter(), // - new SyntheticFilter(), // new BridgeFilter(), // new SynchronizedFilter(), // new TryWithResourcesJavac11Filter(), // @@ -60,6 +70,11 @@ private static IFilter allCommonFilters() { new AnnotationGeneratedFilter()); } + private static IFilter allNonKotlinFilters() { + return new FilterSet( // + new SyntheticFilter()); + } + private static IFilter allKotlinFilters() { return new FilterSet( // new KotlinGeneratedFilter(), // @@ -76,15 +91,7 @@ private static IFilter allKotlinFilters() { new KotlinInlineFilter(), // new KotlinCoroutineFilter(), // new KotlinDefaultMethodsFilter(), // - new KotlinComposeFilter()) { - @Override - public void filter(final MethodNode methodNode, - final IFilterContext context, final IFilterOutput output) { - if (isKotlinClass(context)) { - super.filter(methodNode, context, output); - } - } - }; + new KotlinComposeFilter()); } /** diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticAccessorsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticAccessorsFilter.java index c580f83d5c..e92f0756e5 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticAccessorsFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinSyntheticAccessorsFilter.java @@ -25,9 +25,6 @@ public void filter(MethodNode methodNode, IFilterContext context, if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) { return; } - if (!Filters.isKotlinClass(context)) { - return; - } if (!methodNode.name.startsWith("access$")) { return; } 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 fde5d3a744..dea5ed0261 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,9 +31,6 @@ public void filter(final MethodNode methodNode, if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) { return; } - if (Filters.isKotlinClass(context)) { - return; - } if (methodNode.name.startsWith("lambda$")) { return; From e21a0b13a9da4aecb4b3c60faeacf45a5b11b9db Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sat, 21 Dec 2024 02:32:43 +0100 Subject: [PATCH 134/163] StringSwitchFilter should handle Kotlin nullable String (#1769) --- .../kotlin/targets/KotlinWhenStringTarget.kt | 28 +++ .../filter/StringSwitchFilterTest.java | 224 ++++++++++++++++-- .../analysis/filter/StringSwitchFilter.java | 32 ++- org.jacoco.doc/docroot/doc/changes.html | 4 + 4 files changed, 268 insertions(+), 20 deletions(-) diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenStringTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenStringTarget.kt index 234c141221..57415b6b64 100644 --- a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenStringTarget.kt +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinWhenStringTarget.kt @@ -27,6 +27,23 @@ object KotlinWhenStringTarget { else -> 7 // assertFullyCovered() } // assertFullyCovered() + private fun whenStringNullableDefault(p: String?): String = + when (p) { // assertFullyCovered(0, 4) + "a" -> "case a" // assertFullyCovered() + "b" -> "case b" // assertFullyCovered() + "c" -> "case c" // assertFullyCovered() + else -> "else" // assertFullyCovered() + } // assertFullyCovered() + + private fun whenStringNullableCase(p: String?): String = + when (p) { // assertFullyCovered(0, 5) + "a" -> "case a" // assertFullyCovered() + "b" -> "case b" // assertFullyCovered() + "c" -> "case c" // assertFullyCovered() + null -> "null" // assertFullyCovered() + else -> "else" // assertFullyCovered() + } // assertFullyCovered() + /** * Unlike [whenString] * in this example first case is the only case with biggest hashCode value. @@ -51,6 +68,17 @@ object KotlinWhenStringTarget { whenString("\u0000b") whenString("\u0000c") + whenStringNullableDefault("a") + whenStringNullableDefault("b") + whenStringNullableDefault("c") + whenStringNullableDefault("") + + whenStringNullableCase("a") + whenStringNullableCase("b") + whenStringNullableCase("c") + whenStringNullableCase(null) + whenStringNullableCase("") + whenStringBiggestHashCodeFirst("") whenStringBiggestHashCodeFirst("a") whenStringBiggestHashCodeFirst("b") diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilterTest.java index 8a8be810e0..68d6b4d3fd 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilterTest.java @@ -31,6 +31,7 @@ public class StringSwitchFilterTest extends FilterTestBase { @Test public void should_filter() { + final Range range = new Range(); final Set expectedNewTargets = new HashSet(); final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, @@ -53,8 +54,8 @@ public void should_filter() { m.visitVarInsn(Opcodes.ASTORE, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "hashCode", "()I", false); + range.fromInclusive = m.instructions.getLast(); m.visitTableSwitchInsn(97, 98, caseDefault, h1, h2); - final AbstractInsnNode switchNode = m.instructions.getLast(); m.visitLabel(h1); @@ -86,7 +87,7 @@ public void should_filter() { // goto default case m.visitJumpInsn(Opcodes.GOTO, caseDefault); - final AbstractInsnNode expectedToInclusive = m.instructions.getLast(); + range.toInclusive = m.instructions.getLast(); m.visitLabel(case1); m.visitInsn(Opcodes.RETURN); @@ -103,12 +104,14 @@ public void should_filter() { filter.filter(m, context, output); - assertReplacedBranches(switchNode, expectedNewTargets); - assertIgnored(new Range(switchNode.getNext(), expectedToInclusive)); + assertIgnored(range); + assertReplacedBranches(range.fromInclusive.getPrevious(), + expectedNewTargets); } @Test public void should_filter_when_default_is_first() { + final Range range = new Range(); final Set expectedNewTargets = new HashSet(); final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, @@ -128,20 +131,18 @@ public void should_filter_when_default_is_first() { m.visitVarInsn(Opcodes.ASTORE, 2); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "hashCode", "()I", false); + range.fromInclusive = m.instructions.getLast(); m.visitLookupSwitchInsn(caseDefault, new int[] { 97 }, new Label[] { h1 }); - final AbstractInsnNode switchNode = m.instructions.getLast(); m.visitLabel(h1); - m.visitVarInsn(Opcodes.ALOAD, 2); m.visitLdcInsn("a"); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); // if equal "a", then goto its case m.visitJumpInsn(Opcodes.IFNE, case1); - - final AbstractInsnNode expectedToInclusive = m.instructions.getLast(); + range.toInclusive = m.instructions.getLast(); m.visitLabel(caseDefault); m.visitInsn(Opcodes.RETURN); @@ -152,8 +153,9 @@ public void should_filter_when_default_is_first() { filter.filter(m, context, output); - assertReplacedBranches(switchNode, expectedNewTargets); - assertIgnored(new Range(switchNode.getNext(), expectedToInclusive)); + assertIgnored(range); + assertReplacedBranches(range.fromInclusive.getPrevious(), + expectedNewTargets); } /** @@ -172,6 +174,7 @@ public void should_filter_when_default_is_first() { */ @Test public void should_filter_Kotlin_1_5() { + final Range range = new Range(); final Set expectedNewTargets = new HashSet(); final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, @@ -188,13 +191,14 @@ public void should_filter_Kotlin_1_5() { final Label case5 = new Label(); final Label case6 = new Label(); + m.visitVarInsn(Opcodes.ASTORE, 1); m.visitVarInsn(Opcodes.ALOAD, 1); + range.fromInclusive = m.instructions.getLast(); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "hashCode", "()I", false); m.visitTableSwitchInsn(97, 99, defaultCase, h1, h2, h3); m.visitLabel(h1); - final AbstractInsnNode expectedFromInclusive = m.instructions.getLast(); m.visitVarInsn(Opcodes.ALOAD, 1); m.visitLdcInsn("a"); m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", @@ -238,7 +242,7 @@ public void should_filter_Kotlin_1_5() { m.visitJumpInsn(Opcodes.IFNE, case6); m.visitJumpInsn(Opcodes.GOTO, defaultCase); - final AbstractInsnNode expectedToInclusive = m.instructions.getLast(); + range.toInclusive = m.instructions.getLast(); m.visitLabel(case1); m.visitInsn(Opcodes.RETURN); @@ -264,8 +268,200 @@ public void should_filter_Kotlin_1_5() { filter.filter(m, context, output); - assertIgnored(new Range(expectedFromInclusive, expectedToInclusive)); - assertReplacedBranches(expectedFromInclusive.getPrevious(), + assertIgnored(range); + assertReplacedBranches(range.fromInclusive.getPrevious(), + expectedNewTargets); + } + + /** + *
      +	 * fun example(s: String?) = when (s) {
      +	 *     "a" -> "case a"
      +	 *     "b" -> "case b"
      +	 *     "c" -> "case c"
      +	 *     else -> "else"
      +	 * }
      +	 * 
      + */ + @Test + public void should_filter_Kotlin_nullable_else() { + final Range range = new Range(); + final Set expectedNewTargets = new HashSet(); + + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "example", "(Ljava/lang/String;)Ljava/lang/String;", null, + null); + final Label hashA = new Label(); + final Label hashB = new Label(); + final Label hashC = new Label(); + final Label caseA = new Label(); + final Label caseB = new Label(); + final Label caseC = new Label(); + final Label caseElse = new Label(); + final Label end = new Label(); + + m.visitVarInsn(Opcodes.ALOAD, 1); + m.visitVarInsn(Opcodes.ASTORE, 2); + m.visitVarInsn(Opcodes.ALOAD, 2); + range.fromInclusive = m.instructions.getLast(); + m.visitJumpInsn(Opcodes.IFNULL, caseElse); + m.visitVarInsn(Opcodes.ALOAD, 2); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "hashCode", + "()I", false); + m.visitTableSwitchInsn(97, 99, caseElse, + new Label[] { hashA, hashB, hashC }); + + m.visitLabel(hashA); + m.visitVarInsn(Opcodes.ALOAD, 2); + m.visitLdcInsn("a"); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", + "(Ljava/lang/Object;)Z", false); + m.visitJumpInsn(Opcodes.IFNE, caseA); + m.visitJumpInsn(Opcodes.GOTO, caseElse); + + m.visitLabel(hashB); + m.visitVarInsn(Opcodes.ALOAD, 2); + m.visitLdcInsn("b"); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", + "(Ljava/lang/Object;)Z", false); + m.visitJumpInsn(Opcodes.IFNE, caseB); + m.visitJumpInsn(Opcodes.GOTO, caseElse); + + m.visitLabel(hashC); + m.visitVarInsn(Opcodes.ALOAD, 2); + m.visitLdcInsn("c"); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", + "(Ljava/lang/Object;)Z", false); + m.visitJumpInsn(Opcodes.IFNE, caseC); + m.visitJumpInsn(Opcodes.GOTO, caseElse); + range.toInclusive = m.instructions.getLast(); + + m.visitLabel(caseA); + m.visitLdcInsn("case a"); + expectedNewTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, end); + + m.visitLabel(caseB); + m.visitLdcInsn("case b"); + expectedNewTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, end); + + m.visitLabel(caseC); + m.visitLdcInsn("case c"); + expectedNewTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, end); + + m.visitLabel(caseElse); + m.visitLdcInsn("else"); + expectedNewTargets.add(m.instructions.getLast()); + + m.visitLabel(end); + m.visitInsn(Opcodes.ARETURN); + + filter.filter(m, context, output); + + assertIgnored(range); + assertReplacedBranches(range.fromInclusive.getPrevious(), + expectedNewTargets); + } + + /** + *
      +	 * fun example(s: String?) = when (s) {
      +	 *     "a" -> "case a"
      +	 *     "b" -> "case b"
      +	 *     "c" -> "case c"
      +	 *     null -> "null"
      +	 *     else -> "else"
      +	 * }
      +	 * 
      + */ + @Test + public void should_filter_Kotlin_nullable_case() { + final Range range = new Range(); + final Set expectedNewTargets = new HashSet(); + + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "example", "(Ljava/lang/String;)Ljava/lang/String;", null, + null); + final Label hashA = new Label(); + final Label hashB = new Label(); + final Label hashC = new Label(); + final Label caseA = new Label(); + final Label caseB = new Label(); + final Label caseC = new Label(); + final Label caseNull = new Label(); + final Label caseElse = new Label(); + final Label end = new Label(); + + m.visitVarInsn(Opcodes.ALOAD, 1); + m.visitVarInsn(Opcodes.ASTORE, 2); + m.visitVarInsn(Opcodes.ALOAD, 2); + range.fromInclusive = m.instructions.getLast(); + m.visitInsn(Opcodes.DUP); + m.visitJumpInsn(Opcodes.IFNULL, caseNull); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "hashCode", + "()I", false); + m.visitTableSwitchInsn(97, 99, caseElse, + new Label[] { hashA, hashB, hashC }); + + m.visitLabel(hashA); + m.visitVarInsn(Opcodes.ALOAD, 2); + m.visitLdcInsn("a"); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", + "(Ljava/lang/Object;)Z", false); + m.visitJumpInsn(Opcodes.IFNE, caseA); + m.visitJumpInsn(Opcodes.GOTO, caseElse); + + m.visitLabel(hashB); + m.visitVarInsn(Opcodes.ALOAD, 2); + m.visitLdcInsn("b"); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", + "(Ljava/lang/Object;)Z", false); + m.visitJumpInsn(Opcodes.IFNE, caseB); + m.visitJumpInsn(Opcodes.GOTO, caseElse); + + m.visitLabel(hashC); + m.visitVarInsn(Opcodes.ALOAD, 2); + m.visitLdcInsn("c"); + m.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", + "(Ljava/lang/Object;)Z", false); + m.visitJumpInsn(Opcodes.IFNE, caseC); + m.visitJumpInsn(Opcodes.GOTO, caseElse); + range.toInclusive = m.instructions.getLast(); + + m.visitLabel(caseA); + m.visitLdcInsn("case a"); + expectedNewTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, end); + + m.visitLabel(caseB); + m.visitLdcInsn("case b"); + expectedNewTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, end); + + m.visitLabel(caseC); + m.visitLdcInsn("case c"); + expectedNewTargets.add(m.instructions.getLast()); + m.visitJumpInsn(Opcodes.GOTO, end); + + m.visitLabel(caseNull); + m.visitInsn(Opcodes.POP); + expectedNewTargets.add(m.instructions.getLast()); + m.visitLdcInsn("null"); + m.visitJumpInsn(Opcodes.GOTO, end); + + m.visitLabel(caseElse); + m.visitLdcInsn("else"); + expectedNewTargets.add(m.instructions.getLast()); + + m.visitLabel(end); + m.visitInsn(Opcodes.ARETURN); + + filter.filter(m, context, output); + + assertIgnored(range); + assertReplacedBranches(range.fromInclusive.getPrevious(), expectedNewTargets); } diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java index 10cf5917e2..21ab863e92 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java @@ -42,19 +42,35 @@ public void filter(final MethodNode methodNode, private static class Matcher extends AbstractMatcher { public void match(final AbstractInsnNode start, final IFilterOutput output) { - - if (start.getOpcode() != /* ECJ */ Opcodes.ASTORE - && start.getOpcode() != /* Kotlin */ Opcodes.ALOAD) { + if (start.getOpcode() != Opcodes.ASTORE) { return; } + vars.put("s", (VarInsnNode) start); cursor = start; + JumpInsnNode ifNullInstruction = null; + if (start.getNext().getOpcode() == Opcodes.ALOAD) { + // Kotlin + nextIsVar(Opcodes.ALOAD, "s"); + if (cursor == null) { + return; + } else if (cursor.getNext().getOpcode() == Opcodes.DUP) { + // nullable case + nextIs(Opcodes.DUP); + nextIs(Opcodes.IFNULL); + ifNullInstruction = (JumpInsnNode) cursor; + } else if (cursor.getNext().getOpcode() == Opcodes.IFNULL) { + // nullable else + nextIs(Opcodes.IFNULL); + ifNullInstruction = (JumpInsnNode) cursor; + nextIsVar(Opcodes.ALOAD, "s"); + } + } nextIsInvoke(Opcodes.INVOKEVIRTUAL, "java/lang/String", "hashCode", "()I"); nextIsSwitch(); if (cursor == null) { return; } - vars.put("s", (VarInsnNode) start); final AbstractInsnNode s = cursor; final int hashCodes; @@ -102,8 +118,12 @@ public void match(final AbstractInsnNode start, } } - output.ignore(s.getNext(), cursor); - output.replaceBranches(s, replacements); + if (ifNullInstruction != null) { + replacements.add(skipNonOpcodes(ifNullInstruction.label)); + } + + output.ignore(start.getNext(), cursor); + output.replaceBranches(start, replacements); } } diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index e098ee6d0d..f3b316c087 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -49,6 +49,10 @@

      New Features

      expressions and statements with nullable enum subject is filtered out during generation of report (GitHub #1774). +
    • Part of bytecode generated by the Kotlin compiler for when + expressions and statements with nullable String subject is filtered out during + generation of report + (GitHub #1769).
    • Part of bytecode generated by the Kotlin compiler for chains of safe call operators is filtered out during generation of report (GitHub #1810).
    • From a685e56a199689d9bdfe9ffc85fc06fac551b32a Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Sun, 22 Dec 2024 09:35:29 +0100 Subject: [PATCH 135/163] Use `Integer.valueOf` instead of deprecated constructor (#1826) --- .../src/org/jacoco/core/internal/analysis/CounterImplTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/CounterImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/CounterImplTest.java index 6534afbb5a..752abb44e0 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/CounterImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/CounterImplTest.java @@ -180,7 +180,7 @@ public void testEquals3() { @Test public void testEquals4() { ICounter c = CounterImpl.getInstance(300, 123); - assertFalse(c.equals(new Integer(123))); + assertFalse(c.equals(Integer.valueOf(123))); } @Test From f368aee3f4ee8abbd01a21b09eb7c7fc43298a32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 23:22:25 +0100 Subject: [PATCH 136/163] Bump actions/upload-artifact from 4.4.3 to 4.5.0 (#1830) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.4.3 to 4.5.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882...6f51ac03b9356f520e9adb1b1b7802705f340c2b) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 089b7f2f39..a01734b624 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: ./mvnw -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 id: artifact-upload-step with: name: jacoco From f39a12843f75d42ad9334bcb77bc9c1c4e9de586 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 22:52:37 +0000 Subject: [PATCH 137/163] Bump actions/setup-java from 4.5.0 to 4.6.0 (#1829) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/8df1039502a15bceb9433410b1a100fbe190c53b...7a6d8a8234af8eb26422e24e3006232cccaa061b) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a01734b624..70b04e8987 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 + - uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0 with: distribution: 'zulu' java-version: | @@ -59,7 +59,7 @@ jobs: runs-on: windows-2022 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 + - uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0 with: distribution: 'zulu' java-version: | From 4e159f7b351f8038bd72a0813445a427d62586b3 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Wed, 1 Jan 2025 21:57:35 +0100 Subject: [PATCH 138/163] Happy New Year 2025! --- LICENSE.md | 2 +- jacoco-maven-plugin.test/it/it-check-fails-halt/pom.xml | 2 +- .../it/it-check-fails-halt/src/main/java/Example.java | 2 +- .../it/it-check-fails-halt/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-check-fails-halt/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-check-fails-no-halt/pom.xml | 2 +- .../it/it-check-fails-no-halt/src/main/java/Example.java | 2 +- .../it/it-check-fails-no-halt/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-check-fails-no-halt/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-check-passes/pom.xml | 2 +- .../it/it-check-passes/src/main/java/Example.java | 2 +- .../it/it-check-passes/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-check-passes/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-customize-agent/pom.xml | 2 +- .../it/it-customize-agent/src/main/java/Example.java | 2 +- .../it/it-customize-agent/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-customize-agent/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-dump/pom.xml | 2 +- jacoco-maven-plugin.test/it/it-dump/src/main/java/Server.java | 2 +- jacoco-maven-plugin.test/it/it-dump/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-includes-excludes/pom.xml | 2 +- .../src/main/java/org/project/DatabaseUtil.java | 2 +- .../src/main/java/org/project/FileUtil.java | 2 +- .../src/main/java/org/project/TestUtil.java | 2 +- .../src/test/java/org/project/TestDatabaseUtil.java | 2 +- jacoco-maven-plugin.test/it/it-includes-excludes/verify.bsh | 2 +- .../it/it-java9-offline-instrumentation/pom.xml | 2 +- .../src/main/java/module-info.java | 2 +- .../src/main/java/org/example/Example.java | 2 +- .../src/test/java/org/example/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-java9/pom.xml | 2 +- .../it/it-java9/src/main/java/Example.java | 2 +- .../it/it-java9/src/test/java/ExampleTest.java | 2 +- .../it/it-merge-passes/it-merge-passes-merge/pom.xml | 2 +- .../it/it-merge-passes/it-merge-passes-project1/pom.xml | 2 +- .../it-merge-passes-project1/src/main/java/Example.java | 2 +- .../it-merge-passes-project1/src/test/java/ExampleTest.java | 2 +- .../it/it-merge-passes/it-merge-passes-project2/pom.xml | 2 +- .../it-merge-passes-project2/src/main/java/Example.java | 2 +- .../it-merge-passes-project2/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-merge-passes/pom.xml | 2 +- jacoco-maven-plugin.test/it/it-merge-passes/verify.bsh | 2 +- .../it/it-multi-module/child-jar-without-sources/pom.xml | 2 +- jacoco-maven-plugin.test/it/it-multi-module/child/pom.xml | 2 +- .../it/it-multi-module/child/src/main/java/Example.java | 2 +- .../child/src/main/java/somepackage/Example.java | 2 +- .../it/it-multi-module/child/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-multi-module/pom.xml | 2 +- .../it/it-multi-module/skip-child/pom.xml | 2 +- .../it/it-multi-module/skip-child/src/test/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-multi-module/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-multiple-executions/pom.xml | 2 +- .../it/it-multiple-executions/src/main/java/Example.java | 2 +- .../it/it-multiple-executions/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-multiple-executions/verify.bsh | 2 +- .../child-without-main-classes/pom.xml | 2 +- .../child-without-main-classes/src/test/java/ExampleTest.java | 2 +- .../it/it-offline-instrumentation/child/pom.xml | 2 +- .../child/src/main/java/DoNotInstrument.java | 2 +- .../child/src/main/java/Example.java | 2 +- .../child/src/test/java/ExampleTest.java | 2 +- .../it/it-offline-instrumentation/pom.xml | 2 +- .../it/it-offline-instrumentation/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-prepend-property-skip/pom.xml | 2 +- .../it-prepend-property-skip/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-prepend-property/pom.xml | 2 +- jacoco-maven-plugin.test/it/it-prepend-property/verify.bsh | 2 +- .../it/it-report-aggregate-customization/child1/pom.xml | 2 +- .../child1/src/main/java/package1/Example1.java | 2 +- .../child1/src/test/java/package1/Example1Test.java | 2 +- .../it/it-report-aggregate-customization/child2/pom.xml | 2 +- .../child2/src/main/java/package2/Example2.java | 2 +- .../child2/src/test/java/package2/Example2Test.java | 2 +- .../it/it-report-aggregate-customization/pom.xml | 2 +- .../it/it-report-aggregate-customization/report/pom.xml | 2 +- .../it/it-report-aggregate-customization/verify.bsh | 2 +- .../it/it-report-aggregate/child1-test/pom.xml | 2 +- .../child1-test/src/test/java/package1/Example1bTest.java | 2 +- .../it/it-report-aggregate/child1/pom.xml | 2 +- .../child1/src/main/java/package1/Example1a.java | 2 +- .../child1/src/main/java/package1/Example1b.java | 2 +- .../child1/src/test/java/package1/Example1aTest.java | 2 +- .../it/it-report-aggregate/child2/pom.xml | 2 +- .../child2/src/main/java/package2/Example2.java | 2 +- .../child2/src/test/java/package2/Example2Test.java | 2 +- .../it/it-report-aggregate/child2v2/pom.xml | 2 +- .../child2v2/src/main/java/package2/Example2.java | 2 +- .../child2v2/src/test/java/package2/Example2Test.java | 2 +- jacoco-maven-plugin.test/it/it-report-aggregate/pom.xml | 2 +- .../it/it-report-aggregate/report/pom.xml | 2 +- .../report/src/test/java/packagereport/ReportTest.java | 2 +- jacoco-maven-plugin.test/it/it-report-aggregate/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-report-nomatch/pom.xml | 2 +- .../it/it-report-nomatch/src/main/java/Example.java | 2 +- jacoco-maven-plugin.test/it/it-report-nomatch/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-report-select-formats/pom.xml | 2 +- .../it/it-report-select-formats/src/main/java/Example.java | 2 +- .../it-report-select-formats/src/test/java/ExampleTest.java | 2 +- .../it/it-report-select-formats/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-report-unreadable-dump/pom.xml | 2 +- .../it/it-report-unreadable-dump/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-report-without-debug/pom.xml | 2 +- .../it/it-report-without-debug/src/main/java/Example.java | 2 +- .../it/it-report-without-debug/src/test/java/ExampleTest.java | 2 +- .../it/it-report-without-debug/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-report-without-dump/pom.xml | 2 +- jacoco-maven-plugin.test/it/it-report-without-dump/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-site-failsafe/pom.xml | 2 +- .../it/it-site-failsafe/src/main/java/Example.java | 2 +- .../it/it-site-failsafe/src/test/java/ExampleIT.java | 2 +- .../it/it-site-failsafe/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-site-failsafe/verify.bsh | 2 +- jacoco-maven-plugin.test/it/it-site/pom.xml | 2 +- .../it/it-site/src/main/java/Example.java | 2 +- .../it/it-site/src/test/java/ExampleTest.java | 2 +- jacoco-maven-plugin.test/it/it-site/verify.bsh | 2 +- jacoco-maven-plugin.test/it/settings.xml | 2 +- jacoco-maven-plugin.test/it/setup-parent/pom.xml | 2 +- jacoco-maven-plugin.test/pom.xml | 2 +- .../META-INF/m2e/lifecycle-mapping-metadata.xml | 2 +- jacoco-maven-plugin/pom.xml | 2 +- .../src/org/jacoco/maven/AbstractAgentMojo.java | 2 +- .../src/org/jacoco/maven/AbstractJacocoMojo.java | 2 +- .../src/org/jacoco/maven/AbstractReportMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/AgentITMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/AgentMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/CheckMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/DumpMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/FileFilter.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/InstrumentMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/MergeMojo.java | 2 +- .../src/org/jacoco/maven/ReportAggregateMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/ReportFormat.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/ReportITMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/ReportMojo.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/ReportSupport.java | 2 +- jacoco-maven-plugin/src/org/jacoco/maven/RestoreMojo.java | 2 +- .../src/org/jacoco/maven/RuleConfiguration.java | 2 +- jacoco/assembly.xml | 2 +- jacoco/pom.xml | 2 +- org.jacoco.agent.rt.test/pom.xml | 2 +- .../src/org/jacoco/agent/rt/internal/AgentModuleTest.java | 2 +- .../src/org/jacoco/agent/rt/internal/AgentTest.java | 2 +- .../src/org/jacoco/agent/rt/internal/ClassFileDumperTest.java | 2 +- .../src/org/jacoco/agent/rt/internal/ConfigLoaderTest.java | 2 +- .../org/jacoco/agent/rt/internal/CoverageTransformerTest.java | 2 +- .../src/org/jacoco/agent/rt/internal/ExceptionRecorder.java | 2 +- .../org/jacoco/agent/rt/internal/output/ExecutorTestBase.java | 2 +- .../org/jacoco/agent/rt/internal/output/FileOutputTest.java | 2 +- .../org/jacoco/agent/rt/internal/output/MockServerSocket.java | 2 +- .../jacoco/agent/rt/internal/output/MockServerSocketTest.java | 2 +- .../jacoco/agent/rt/internal/output/MockSocketConnection.java | 2 +- .../agent/rt/internal/output/MockSocketConnectionTest.java | 2 +- .../jacoco/agent/rt/internal/output/TcpClientOutputTest.java | 2 +- .../jacoco/agent/rt/internal/output/TcpConnectionTest.java | 2 +- .../jacoco/agent/rt/internal/output/TcpServerOutputTest.java | 2 +- org.jacoco.agent.rt/pom.xml | 2 +- org.jacoco.agent.rt/src/com/vladium/emma/rt/RT.java | 2 +- org.jacoco.agent.rt/src/com/vladium/emma/rt/package-info.java | 2 +- org.jacoco.agent.rt/src/org/jacoco/agent/rt/IAgent.java | 2 +- org.jacoco.agent.rt/src/org/jacoco/agent/rt/RT.java | 2 +- .../src/org/jacoco/agent/rt/internal/Agent.java | 2 +- .../src/org/jacoco/agent/rt/internal/AgentModule.java | 2 +- .../src/org/jacoco/agent/rt/internal/ClassFileDumper.java | 2 +- .../src/org/jacoco/agent/rt/internal/ConfigLoader.java | 2 +- .../src/org/jacoco/agent/rt/internal/CoverageTransformer.java | 2 +- .../src/org/jacoco/agent/rt/internal/IExceptionLogger.java | 2 +- .../src/org/jacoco/agent/rt/internal/JmxRegistration.java | 2 +- .../src/org/jacoco/agent/rt/internal/Offline.java | 2 +- .../src/org/jacoco/agent/rt/internal/PreMain.java | 2 +- .../src/org/jacoco/agent/rt/internal/output/FileOutput.java | 2 +- .../src/org/jacoco/agent/rt/internal/output/IAgentOutput.java | 2 +- .../src/org/jacoco/agent/rt/internal/output/NoneOutput.java | 2 +- .../org/jacoco/agent/rt/internal/output/TcpClientOutput.java | 2 +- .../org/jacoco/agent/rt/internal/output/TcpConnection.java | 2 +- .../org/jacoco/agent/rt/internal/output/TcpServerOutput.java | 2 +- org.jacoco.agent.rt/src/org/jacoco/agent/rt/package-info.java | 2 +- org.jacoco.agent.test/pom.xml | 2 +- org.jacoco.agent.test/src/org/jacoco/agent/AgentJarTest.java | 2 +- org.jacoco.agent/pom.xml | 2 +- org.jacoco.agent/src/org/jacoco/agent/AgentJar.java | 2 +- org.jacoco.agent/src/org/jacoco/agent/package-info.java | 2 +- org.jacoco.ant.test/pom.xml | 2 +- org.jacoco.ant.test/src/TestTargetInDefault.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml | 2 +- .../src/org/jacoco/ant/AntFilesLocatorTest.java | 2 +- .../src/org/jacoco/ant/AntResourcesLocatorTest.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/CreateExecFiles.java | 2 +- .../src/org/jacoco/ant/DumpExecClassNames.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.xml | 2 +- .../src/org/jacoco/ant/DumpTaskWithServerTest.java | 2 +- .../src/org/jacoco/ant/DumpTaskWithServerTest.xml | 2 +- .../src/org/jacoco/ant/IllegalReflectiveAccessTarget.java | 2 +- .../src/org/jacoco/ant/InstrumentTaskTest.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/InstrumentTaskTest.xml | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.xml | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/RemoveDebugInfos.java | 2 +- .../src/org/jacoco/ant/ReportTaskLocaleTest.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.xml | 2 +- .../src/org/jacoco/ant/SecurityManagerTest.java | 2 +- .../src/org/jacoco/ant/SecurityManagerTest.xml | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/TestTarget.java | 2 +- org.jacoco.ant.test/src/org/jacoco/ant/empty.xml | 2 +- org.jacoco.ant/pom.xml | 2 +- org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/AgentTask.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/AntFilesLocator.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/AntResourcesLocator.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/CoverageTask.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/DumpTask.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/InstrumentTask.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/MergeTask.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/ReportTask.java | 2 +- org.jacoco.ant/src/org/jacoco/ant/antlib.xml | 2 +- org.jacoco.build/pom.xml | 4 ++-- org.jacoco.cli.test/pom.xml | 2 +- .../src/org/jacoco/cli/internal/CommandTestBase.java | 2 +- org.jacoco.cli.test/src/org/jacoco/cli/internal/MainTest.java | 2 +- .../src/org/jacoco/cli/internal/XmlDocumentationTest.java | 2 +- .../src/org/jacoco/cli/internal/commands/ClassInfoTest.java | 2 +- .../src/org/jacoco/cli/internal/commands/DumpTest.java | 2 +- .../src/org/jacoco/cli/internal/commands/ExecInfoTest.java | 2 +- .../src/org/jacoco/cli/internal/commands/InstrumentTest.java | 2 +- .../src/org/jacoco/cli/internal/commands/MergeTest.java | 2 +- .../src/org/jacoco/cli/internal/commands/ReportTest.java | 2 +- .../src/org/jacoco/cli/internal/commands/VersionTest.java | 2 +- org.jacoco.cli/pom.xml | 2 +- org.jacoco.cli/src/org/jacoco/cli/internal/Command.java | 2 +- .../src/org/jacoco/cli/internal/CommandHandler.java | 2 +- org.jacoco.cli/src/org/jacoco/cli/internal/CommandParser.java | 2 +- org.jacoco.cli/src/org/jacoco/cli/internal/Main.java | 2 +- .../src/org/jacoco/cli/internal/XmlDocumentation.java | 2 +- .../src/org/jacoco/cli/internal/commands/AllCommands.java | 2 +- .../src/org/jacoco/cli/internal/commands/ClassInfo.java | 2 +- org.jacoco.cli/src/org/jacoco/cli/internal/commands/Dump.java | 2 +- .../src/org/jacoco/cli/internal/commands/ExecInfo.java | 2 +- .../src/org/jacoco/cli/internal/commands/Instrument.java | 2 +- .../src/org/jacoco/cli/internal/commands/Merge.java | 2 +- .../src/org/jacoco/cli/internal/commands/Report.java | 2 +- .../src/org/jacoco/cli/internal/commands/Version.java | 2 +- org.jacoco.core.test.validation.groovy/pom.xml | 2 +- .../core/test/validation/groovy/GroovyAutoCloneClassTest.java | 2 +- .../validation/groovy/GroovyAutoExternalizeClassTest.java | 2 +- .../core/test/validation/groovy/GroovyBindableClassTest.java | 2 +- .../core/test/validation/groovy/GroovyBuilderClassTest.java | 2 +- .../core/test/validation/groovy/GroovyCanonicalClassTest.java | 2 +- .../core/test/validation/groovy/GroovyDelegateClassTest.java | 2 +- .../core/test/validation/groovy/GroovyImmutableClassTest.java | 2 +- .../test/validation/groovy/GroovyIndexPropertyClassTest.java | 2 +- .../core/test/validation/groovy/GroovySortableClassTest.java | 2 +- .../core/test/validation/groovy/GroovyVetoableClassTest.java | 2 +- .../groovy/targets/GroovyAutoCloneClassTarget.groovy | 2 +- .../groovy/targets/GroovyAutoExternalizeClassTarget.groovy | 2 +- .../groovy/targets/GroovyBindableClassTarget.groovy | 2 +- .../validation/groovy/targets/GroovyBuilderClassTarget.groovy | 2 +- .../groovy/targets/GroovyCanonicalClassTarget.groovy | 2 +- .../groovy/targets/GroovyDelegateClassTarget.groovy | 2 +- .../groovy/targets/GroovyImmutableClassTarget.groovy | 2 +- .../groovy/targets/GroovyIndexPropertyClassTarget.groovy | 2 +- .../groovy/targets/GroovySortableClassTarget.groovy | 2 +- .../groovy/targets/GroovyVetoableClassTarget.groovy | 2 +- org.jacoco.core.test.validation.java14/pom.xml | 2 +- .../core/test/validation/java14/SwitchExpressionsTest.java | 2 +- .../validation/java14/targets/SwitchExpressionsTarget.java | 2 +- org.jacoco.core.test.validation.java16/pom.xml | 2 +- .../jacoco/core/test/validation/java16/InstanceofTest.java | 2 +- .../org/jacoco/core/test/validation/java16/RecordsTest.java | 2 +- .../core/test/validation/java16/targets/InstanceofTarget.java | 2 +- .../core/test/validation/java16/targets/RecordsTarget.java | 2 +- org.jacoco.core.test.validation.java21/pom.xml | 2 +- .../core/test/validation/java21/RecordPatternsTest.java | 2 +- .../test/validation/java21/SwitchPatternMatchingTest.java | 2 +- .../test/validation/java21/targets/RecordPatternsTarget.java | 2 +- .../java21/targets/SwitchPatternMatchingTarget.java | 2 +- org.jacoco.core.test.validation.java5/pom.xml | 2 +- .../core/test/validation/java5/AnnotationGeneratedTest.java | 2 +- .../core/test/validation/java5/AnnotationInitializerTest.java | 2 +- .../src/org/jacoco/core/test/validation/java5/AssertTest.java | 2 +- .../jacoco/core/test/validation/java5/BadCycleClassTest.java | 2 +- .../core/test/validation/java5/BooleanExpressionsTest.java | 2 +- .../core/test/validation/java5/ClassInitializerTest.java | 2 +- .../jacoco/core/test/validation/java5/ConstructorsTest.java | 2 +- .../java5/ControlStructureBeforeSuperConstructorTest.java | 2 +- .../core/test/validation/java5/ControlStructuresTest.java | 2 +- .../core/test/validation/java5/CyclomaticComplexityTest.java | 2 +- .../core/test/validation/java5/EnumConstructorTest.java | 2 +- .../core/test/validation/java5/EnumImplicitMethodsTest.java | 2 +- .../org/jacoco/core/test/validation/java5/EnumSwitchTest.java | 2 +- .../org/jacoco/core/test/validation/java5/ExceptionsTest.java | 2 +- .../core/test/validation/java5/ExplicitInitialFrameTest.java | 2 +- .../java5/FieldInitializationInTwoConstructorsTest.java | 2 +- .../org/jacoco/core/test/validation/java5/FinallyTest.java | 2 +- .../src/org/jacoco/core/test/validation/java5/FramesTest.java | 2 +- .../validation/java5/ImplicitFieldInitializationTest.java | 2 +- .../test/validation/java5/InterfaceClassInitializerTest.java | 2 +- .../core/test/validation/java5/StructuredLockingTest.java | 2 +- .../jacoco/core/test/validation/java5/SynchronizedTest.java | 2 +- .../org/jacoco/core/test/validation/java5/SyntheticTest.java | 2 +- .../validation/java5/targets/AnnotationGeneratedTarget.java | 2 +- .../validation/java5/targets/AnnotationInitializerTarget.java | 2 +- .../core/test/validation/java5/targets/AssertTarget.java | 2 +- .../test/validation/java5/targets/BadCycleClassTarget.java | 2 +- .../validation/java5/targets/BooleanExpressionsTarget.java | 2 +- .../test/validation/java5/targets/ClassInitializerTarget.java | 2 +- .../test/validation/java5/targets/ConstructorsTarget.java | 2 +- .../targets/ControlStructureBeforeSuperConstructorTarget.java | 2 +- .../validation/java5/targets/ControlStructuresTarget.java | 2 +- .../test/validation/java5/targets/EnumConstructorTarget.java | 2 +- .../validation/java5/targets/EnumImplicitMethodsTarget.java | 2 +- .../core/test/validation/java5/targets/EnumSwitchTarget.java | 2 +- .../core/test/validation/java5/targets/ExceptionsTarget.java | 2 +- .../validation/java5/targets/ExplicitInitialFrameTarget.java | 2 +- .../targets/FieldInitializationInTwoConstructorsTarget.java | 2 +- .../core/test/validation/java5/targets/FinallyTarget.java | 2 +- .../java5/targets/ImplicitFieldInitializationTarget.java | 2 +- .../java5/targets/InterfaceClassInitializerTarget.java | 2 +- .../validation/java5/targets/StructuredLockingTarget.java | 2 +- .../test/validation/java5/targets/SynchronizedTarget.java | 2 +- .../core/test/validation/java5/targets/SyntheticTarget.java | 2 +- org.jacoco.core.test.validation.java7/pom.xml | 2 +- .../jacoco/core/test/validation/java7/StringSwitchTest.java | 2 +- .../core/test/validation/java7/TryWithResourcesTest.java | 2 +- .../test/validation/java7/targets/StringSwitchTarget.java | 2 +- .../test/validation/java7/targets/TryWithResourcesTarget.java | 2 +- org.jacoco.core.test.validation.java8/pom.xml | 2 +- .../test/validation/java8/AnnotationOnLocalVariableTest.java | 2 +- .../core/test/validation/java8/BadCycleInterfaceTest.java | 2 +- .../test/validation/java8/BootstrapMethodReferenceTest.java | 2 +- .../test/validation/java8/InterfaceDefaultMethodsTest.java | 2 +- .../validation/java8/InterfaceOnlyDefaultMethodsTest.java | 2 +- .../core/test/validation/java8/LambdaExpressionsTest.java | 2 +- .../core/test/validation/java8/LambdaInInterfaceTest.java | 2 +- .../core/test/validation/java8/LambdaSerializableTest.java | 2 +- .../java8/targets/AnnotationOnLocalVariableTarget.java | 2 +- .../validation/java8/targets/BadCycleInterfaceTarget.java | 2 +- .../java8/targets/InterfaceDefaultMethodsTarget.java | 2 +- .../java8/targets/InterfaceOnlyDefaultMethodsTarget.java | 2 +- .../validation/java8/targets/LambdaExpressionsTarget.java | 2 +- .../validation/java8/targets/LambdaInInterfaceTarget.java | 2 +- .../validation/java8/targets/LambdaSerializableTarget.java | 2 +- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- .../test/validation/kotlin/KotlinCallableReferenceTest.java | 2 +- .../test/validation/kotlin/KotlinControlStructuresTest.java | 2 +- .../core/test/validation/kotlin/KotlinCoroutineTest.java | 2 +- .../core/test/validation/kotlin/KotlinCrossinlineTest.java | 2 +- .../core/test/validation/kotlin/KotlinDataClassTest.java | 2 +- .../test/validation/kotlin/KotlinDefaultArgumentsTest.java | 2 +- .../core/test/validation/kotlin/KotlinDefaultMethodsTest.java | 2 +- .../core/test/validation/kotlin/KotlinDelegatesTest.java | 2 +- .../core/test/validation/kotlin/KotlinElvisOperatorTest.java | 2 +- .../jacoco/core/test/validation/kotlin/KotlinEnumTest.java | 2 +- .../core/test/validation/kotlin/KotlinExceptionsTest.java | 2 +- .../core/test/validation/kotlin/KotlinInlineClassTest.java | 2 +- .../core/test/validation/kotlin/KotlinInlineReifiedTest.java | 2 +- .../jacoco/core/test/validation/kotlin/KotlinInlineTest.java | 2 +- .../core/test/validation/kotlin/KotlinJvmSyntheticTest.java | 2 +- .../test/validation/kotlin/KotlinLambdaExpressionsTest.java | 2 +- .../test/validation/kotlin/KotlinLambdaSerializableTest.java | 2 +- .../core/test/validation/kotlin/KotlinLateinitTest.java | 2 +- .../test/validation/kotlin/KotlinNotNullOperatorTest.java | 2 +- .../test/validation/kotlin/KotlinSafeCallOperatorTest.java | 2 +- .../core/test/validation/kotlin/KotlinSafeCastTest.java | 2 +- .../core/test/validation/kotlin/KotlinSynchronizedTest.java | 2 +- .../test/validation/kotlin/KotlinSyntheticAccessorsTest.java | 2 +- .../test/validation/kotlin/KotlinTopLevelFunctionTest.java | 2 +- .../test/validation/kotlin/KotlinUnsafeCastOperatorTest.java | 2 +- .../core/test/validation/kotlin/KotlinWhenEnumTest.java | 2 +- .../core/test/validation/kotlin/KotlinWhenSealedTest.java | 2 +- .../core/test/validation/kotlin/KotlinWhenStringTest.java | 2 +- .../kotlin/targets/KotlinCallableReferenceTarget.kt | 2 +- .../kotlin/targets/KotlinControlStructuresTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinCoroutineTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinCrossinlineTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinDataClassTarget.kt | 2 +- .../validation/kotlin/targets/KotlinDefaultArgumentsTarget.kt | 2 +- .../validation/kotlin/targets/KotlinDefaultMethodsTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinDelegatesTarget.kt | 2 +- .../validation/kotlin/targets/KotlinElvisOperatorTarget.kt | 2 +- .../core/test/validation/kotlin/targets/KotlinEnumTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinExceptionsTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinInlineClassTarget.kt | 2 +- .../validation/kotlin/targets/KotlinInlineReifiedTarget.kt | 2 +- .../core/test/validation/kotlin/targets/KotlinInlineTarget.kt | 2 +- .../validation/kotlin/targets/KotlinJvmSyntheticTarget.kt | 2 +- .../kotlin/targets/KotlinLambdaExpressionsTarget.kt | 2 +- .../kotlin/targets/KotlinLambdaSerializableTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinLateinitTarget.kt | 2 +- .../validation/kotlin/targets/KotlinNotNullOperatorTarget.kt | 2 +- .../validation/kotlin/targets/KotlinSafeCallOperatorTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinSafeCastTarget.kt | 2 +- .../validation/kotlin/targets/KotlinSynchronizedTarget.kt | 2 +- .../kotlin/targets/KotlinSyntheticAccessorsTarget.kt | 2 +- .../validation/kotlin/targets/KotlinTopLevelFunctionTarget.kt | 2 +- .../kotlin/targets/KotlinUnsafeCastOperatorTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinWhenEnumTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinWhenSealedTarget.kt | 2 +- .../test/validation/kotlin/targets/KotlinWhenStringTarget.kt | 2 +- org.jacoco.core.test.validation.scala/pom.xml | 2 +- .../test/validation/scala/ScalaAnonymousFunctionTest.java | 2 +- .../core/test/validation/scala/ScalaSingletonObjectTest.java | 2 +- .../core/test/validation/scala/ScalaSynchronizedTest.java | 2 +- .../scala/targets/ScalaAnonymousFunctionTarget.scala | 2 +- .../validation/scala/targets/ScalaSingletonObjectTarget.scala | 2 +- .../validation/scala/targets/ScalaSynchronizedTarget.scala | 2 +- org.jacoco.core.test.validation/pom.xml | 2 +- org.jacoco.core.test/pom.xml | 2 +- org.jacoco.core.test/src/org/jacoco/core/JaCoCoTest.java | 2 +- .../src/org/jacoco/core/analysis/AnalyzerTest.java | 2 +- .../src/org/jacoco/core/analysis/CounterComparatorTest.java | 2 +- .../src/org/jacoco/core/analysis/CoverageBuilderTest.java | 2 +- .../src/org/jacoco/core/analysis/CoverageNodeImplTest.java | 2 +- .../src/org/jacoco/core/analysis/NodeComparatorTest.java | 2 +- .../org/jacoco/core/data/ExecutionDataReaderWriterTest.java | 2 +- .../src/org/jacoco/core/data/ExecutionDataStoreTest.java | 2 +- .../src/org/jacoco/core/data/ExecutionDataTest.java | 2 +- .../core/data/IncompatibleExecDataVersionExceptionTest.java | 2 +- .../src/org/jacoco/core/data/SessionInfoStoreTest.java | 2 +- .../src/org/jacoco/core/data/SessionInfoTest.java | 2 +- .../src/org/jacoco/core/instr/ClassFileVersionsTest.java | 2 +- .../src/org/jacoco/core/instr/InstrumenterTest.java | 2 +- .../src/org/jacoco/core/instr/MethodRecorder.java | 2 +- .../src/org/jacoco/core/instr/ResizeInstructionsTest.java | 2 +- .../src/org/jacoco/core/internal/ContentTypeDetectorTest.java | 2 +- .../src/org/jacoco/core/internal/Pack200StreamsTest.java | 2 +- .../jacoco/core/internal/analysis/BundleCoverageImplTest.java | 2 +- .../org/jacoco/core/internal/analysis/ClassAnalyzerTest.java | 2 +- .../jacoco/core/internal/analysis/ClassCoverageImplTest.java | 2 +- .../org/jacoco/core/internal/analysis/CounterImplTest.java | 2 +- .../org/jacoco/core/internal/analysis/InstructionTest.java | 2 +- .../core/internal/analysis/InstructionsBuilderTest.java | 2 +- .../src/org/jacoco/core/internal/analysis/LineImplTest.java | 2 +- .../org/jacoco/core/internal/analysis/MethodAnalyzerTest.java | 2 +- .../core/internal/analysis/MethodCoverageCalculatorTest.java | 2 +- .../jacoco/core/internal/analysis/MethodCoverageImplTest.java | 2 +- .../jacoco/core/internal/analysis/PackageCoverageTest.java | 2 +- .../core/internal/analysis/SourceFileCoverageImplTest.java | 2 +- .../org/jacoco/core/internal/analysis/SourceNodeImplTest.java | 2 +- .../src/org/jacoco/core/internal/analysis/StringPoolTest.java | 2 +- .../core/internal/analysis/filter/AbstractMatcherTest.java | 2 +- .../analysis/filter/AnnotationGeneratedFilterTest.java | 2 +- .../core/internal/analysis/filter/AssertFilterTest.java | 2 +- .../core/internal/analysis/filter/BridgeFilterTest.java | 2 +- .../analysis/filter/EnumEmptyConstructorFilterTest.java | 2 +- .../jacoco/core/internal/analysis/filter/EnumFilterTest.java | 2 +- .../internal/analysis/filter/ExhaustiveSwitchFilterTest.java | 2 +- .../core/internal/analysis/filter/FilterContextMock.java | 2 +- .../jacoco/core/internal/analysis/filter/FilterTestBase.java | 2 +- .../core/internal/analysis/filter/FinallyFilterTest.java | 2 +- .../internal/analysis/filter/KotlinComposeFilterTest.java | 2 +- .../internal/analysis/filter/KotlinCoroutineFilterTest.java | 2 +- .../analysis/filter/KotlinDefaultArgumentsFilterTest.java | 2 +- .../analysis/filter/KotlinDefaultMethodsFilterTest.java | 2 +- .../core/internal/analysis/filter/KotlinEnumFilterTest.java | 2 +- .../internal/analysis/filter/KotlinGeneratedFilterTest.java | 2 +- .../internal/analysis/filter/KotlinInlineClassFilterTest.java | 2 +- .../core/internal/analysis/filter/KotlinInlineFilterTest.java | 2 +- .../internal/analysis/filter/KotlinLateinitFilterTest.java | 2 +- .../analysis/filter/KotlinNotNullOperatorFilterTest.java | 2 +- .../jacoco/core/internal/analysis/filter/KotlinSMAPTest.java | 2 +- .../analysis/filter/KotlinSafeCallOperatorFilterTest.java | 2 +- .../internal/analysis/filter/KotlinSyntheticFilterTest.java | 2 +- .../analysis/filter/KotlinUnsafeCastOperatorFilterTest.java | 2 +- .../core/internal/analysis/filter/KotlinWhenFilterTest.java | 2 +- .../internal/analysis/filter/KotlinWhenStringFilterTest.java | 2 +- .../filter/PrivateEmptyNoArgConstructorFilterTest.java | 2 +- .../internal/analysis/filter/RecordPatternFilterTest.java | 2 +- .../core/internal/analysis/filter/RecordsFilterTest.java | 2 +- .../core/internal/analysis/filter/StringSwitchFilterTest.java | 2 +- .../internal/analysis/filter/StringSwitchJavacFilterTest.java | 2 +- .../core/internal/analysis/filter/SynchronizedFilterTest.java | 2 +- .../core/internal/analysis/filter/SyntheticFilterTest.java | 2 +- .../analysis/filter/TryWithResourcesEcjFilterTest.java | 2 +- .../analysis/filter/TryWithResourcesJavac11FilterTest.java | 2 +- .../analysis/filter/TryWithResourcesJavacFilterTest.java | 2 +- .../src/org/jacoco/core/internal/data/CRC64Test.java | 2 +- .../jacoco/core/internal/data/CompactDataInputOutputTest.java | 2 +- .../org/jacoco/core/internal/flow/ClassProbesAdapterTest.java | 2 +- .../src/org/jacoco/core/internal/flow/FrameSnapshotTest.java | 2 +- .../org/jacoco/core/internal/flow/LabelFlowAnalyzerTest.java | 2 +- .../src/org/jacoco/core/internal/flow/LabelInfoTest.java | 2 +- .../jacoco/core/internal/flow/MethodProbesAdapterTest.java | 2 +- .../org/jacoco/core/internal/flow/MethodSanitizerTest.java | 2 +- .../core/internal/instr/ClassFieldProbeArrayStrategyTest.java | 2 +- .../org/jacoco/core/internal/instr/ClassInstrumenterTest.java | 2 +- .../core/internal/instr/CondyProbeArrayStrategyTest.java | 2 +- .../core/internal/instr/DuplicateFrameEliminatorTest.java | 2 +- .../src/org/jacoco/core/internal/instr/InstrSupportTest.java | 2 +- .../internal/instr/InterfaceFieldProbeArrayStrategyTest.java | 2 +- .../core/internal/instr/LocalProbeArrayStrategyTest.java | 2 +- .../jacoco/core/internal/instr/MethodInstrumenterTest.java | 2 +- .../core/internal/instr/NoneProbeArrayStrategyTest.java | 2 +- .../core/internal/instr/ProbeArrayStrategyFactoryTest.java | 2 +- .../src/org/jacoco/core/internal/instr/ProbeCounterTest.java | 2 +- .../src/org/jacoco/core/internal/instr/ProbeInserterTest.java | 2 +- .../src/org/jacoco/core/internal/instr/SafetySlotTest.java | 2 +- .../org/jacoco/core/internal/instr/SignatureRemoverTest.java | 2 +- .../org/jacoco/core/internal/instr/ZeroLineNumberTest.java | 2 +- .../src/org/jacoco/core/runtime/AgentOptionsTest.java | 2 +- .../src/org/jacoco/core/runtime/CommandLineSupportTest.java | 2 +- .../src/org/jacoco/core/runtime/InjectedClassRuntimeTest.java | 2 +- .../src/org/jacoco/core/runtime/LoggerRuntimeTest.java | 2 +- .../jacoco/core/runtime/ModifiedSystemClassRuntimeTest.java | 2 +- .../runtime/OfflineInstrumentationAccessGeneratorTest.java | 2 +- .../jacoco/core/runtime/RemoteControlReaderWriterTest.java | 2 +- .../src/org/jacoco/core/runtime/RuntimeDataTest.java | 2 +- .../src/org/jacoco/core/runtime/RuntimeTestBase.java | 2 +- .../org/jacoco/core/runtime/SystemPropertiesRuntimeTest.java | 2 +- .../src/org/jacoco/core/runtime/TestStorage.java | 2 +- .../src/org/jacoco/core/runtime/WildcardMatcherTest.java | 2 +- .../src/org/jacoco/core/test/InstrumentingLoader.java | 2 +- .../src/org/jacoco/core/test/InstrumentingLoaderTest.java | 2 +- .../src/org/jacoco/core/test/TargetLoader.java | 2 +- .../src/org/jacoco/core/test/perf/AnalysisTimeScenario.java | 2 +- .../core/test/perf/ExecuteInstrumentedCodeScenario.java | 2 +- .../src/org/jacoco/core/test/perf/IPerfOutput.java | 2 +- .../src/org/jacoco/core/test/perf/IPerfScenario.java | 2 +- .../jacoco/core/test/perf/InstrumentationSizeSzenario.java | 2 +- .../jacoco/core/test/perf/InstrumentationTimeScenario.java | 2 +- .../src/org/jacoco/core/test/perf/PerfOutputWriter.java | 2 +- .../src/org/jacoco/core/test/perf/PerformanceSuite.java | 2 +- .../src/org/jacoco/core/test/perf/TimedScenario.java | 2 +- .../src/org/jacoco/core/test/perf/targets/Target01.java | 2 +- .../src/org/jacoco/core/test/perf/targets/Target02.java | 2 +- .../src/org/jacoco/core/test/perf/targets/Target03.java | 2 +- .../src/org/jacoco/core/test/validation/Compiler.java | 2 +- .../src/org/jacoco/core/test/validation/JavaVersion.java | 2 +- .../src/org/jacoco/core/test/validation/JavaVersionTest.java | 2 +- .../src/org/jacoco/core/test/validation/Source.java | 2 +- .../src/org/jacoco/core/test/validation/SourceTest.java | 2 +- .../org/jacoco/core/test/validation/StatementExecutor.java | 2 +- .../jacoco/core/test/validation/StatementExecutorTest.java | 2 +- .../src/org/jacoco/core/test/validation/StatementParser.java | 2 +- .../org/jacoco/core/test/validation/StatementParserTest.java | 2 +- .../org/jacoco/core/test/validation/ValidationTestBase.java | 2 +- .../src/org/jacoco/core/test/validation/targets/Stubs.java | 2 +- .../src/org/jacoco/core/tools/ExecDumpClientTest.java | 2 +- .../src/org/jacoco/core/tools/ExecFileLoaderTest.java | 2 +- org.jacoco.core/pom.xml | 2 +- org.jacoco.core/src/org/jacoco/core/JaCoCo.java | 2 +- org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java | 2 +- .../src/org/jacoco/core/analysis/CounterComparator.java | 2 +- .../src/org/jacoco/core/analysis/CoverageBuilder.java | 2 +- .../src/org/jacoco/core/analysis/CoverageNodeImpl.java | 2 +- .../src/org/jacoco/core/analysis/IBundleCoverage.java | 2 +- .../src/org/jacoco/core/analysis/IClassCoverage.java | 2 +- org.jacoco.core/src/org/jacoco/core/analysis/ICounter.java | 2 +- .../src/org/jacoco/core/analysis/ICoverageNode.java | 2 +- .../src/org/jacoco/core/analysis/ICoverageVisitor.java | 2 +- org.jacoco.core/src/org/jacoco/core/analysis/ILine.java | 2 +- .../src/org/jacoco/core/analysis/IMethodCoverage.java | 2 +- .../src/org/jacoco/core/analysis/IPackageCoverage.java | 2 +- .../src/org/jacoco/core/analysis/ISourceFileCoverage.java | 2 +- org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java | 2 +- .../src/org/jacoco/core/analysis/NodeComparator.java | 2 +- .../src/org/jacoco/core/analysis/package-info.java | 2 +- org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java | 2 +- .../src/org/jacoco/core/data/ExecutionDataReader.java | 2 +- .../src/org/jacoco/core/data/ExecutionDataStore.java | 2 +- .../src/org/jacoco/core/data/ExecutionDataWriter.java | 2 +- .../src/org/jacoco/core/data/IExecutionDataVisitor.java | 2 +- .../src/org/jacoco/core/data/ISessionInfoVisitor.java | 2 +- .../core/data/IncompatibleExecDataVersionException.java | 2 +- org.jacoco.core/src/org/jacoco/core/data/SessionInfo.java | 2 +- .../src/org/jacoco/core/data/SessionInfoStore.java | 2 +- org.jacoco.core/src/org/jacoco/core/data/package-info.java | 2 +- org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java | 2 +- org.jacoco.core/src/org/jacoco/core/instr/package-info.java | 2 +- .../src/org/jacoco/core/internal/ContentTypeDetector.java | 2 +- .../src/org/jacoco/core/internal/InputStreams.java | 2 +- .../src/org/jacoco/core/internal/Pack200Streams.java | 2 +- .../org/jacoco/core/internal/analysis/BundleCoverageImpl.java | 2 +- .../src/org/jacoco/core/internal/analysis/ClassAnalyzer.java | 2 +- .../org/jacoco/core/internal/analysis/ClassCoverageImpl.java | 2 +- .../src/org/jacoco/core/internal/analysis/CounterImpl.java | 2 +- .../src/org/jacoco/core/internal/analysis/Instruction.java | 2 +- .../jacoco/core/internal/analysis/InstructionsBuilder.java | 2 +- .../src/org/jacoco/core/internal/analysis/LineImpl.java | 2 +- .../src/org/jacoco/core/internal/analysis/MethodAnalyzer.java | 2 +- .../core/internal/analysis/MethodCoverageCalculator.java | 2 +- .../org/jacoco/core/internal/analysis/MethodCoverageImpl.java | 2 +- .../jacoco/core/internal/analysis/PackageCoverageImpl.java | 2 +- .../jacoco/core/internal/analysis/SourceFileCoverageImpl.java | 2 +- .../src/org/jacoco/core/internal/analysis/SourceNodeImpl.java | 2 +- .../src/org/jacoco/core/internal/analysis/StringPool.java | 2 +- .../jacoco/core/internal/analysis/filter/AbstractMatcher.java | 2 +- .../internal/analysis/filter/AnnotationGeneratedFilter.java | 2 +- .../jacoco/core/internal/analysis/filter/AssertFilter.java | 2 +- .../jacoco/core/internal/analysis/filter/BridgeFilter.java | 2 +- .../internal/analysis/filter/EnumEmptyConstructorFilter.java | 2 +- .../org/jacoco/core/internal/analysis/filter/EnumFilter.java | 2 +- .../core/internal/analysis/filter/ExhaustiveSwitchFilter.java | 2 +- .../org/jacoco/core/internal/analysis/filter/FilterSet.java | 2 +- .../src/org/jacoco/core/internal/analysis/filter/Filters.java | 2 +- .../jacoco/core/internal/analysis/filter/FinallyFilter.java | 2 +- .../src/org/jacoco/core/internal/analysis/filter/IFilter.java | 2 +- .../jacoco/core/internal/analysis/filter/IFilterContext.java | 2 +- .../jacoco/core/internal/analysis/filter/IFilterOutput.java | 2 +- .../core/internal/analysis/filter/KotlinComposeFilter.java | 2 +- .../core/internal/analysis/filter/KotlinCoroutineFilter.java | 2 +- .../analysis/filter/KotlinDefaultArgumentsFilter.java | 2 +- .../internal/analysis/filter/KotlinDefaultMethodsFilter.java | 2 +- .../core/internal/analysis/filter/KotlinEnumFilter.java | 2 +- .../core/internal/analysis/filter/KotlinGeneratedFilter.java | 2 +- .../internal/analysis/filter/KotlinInlineClassFilter.java | 2 +- .../core/internal/analysis/filter/KotlinInlineFilter.java | 2 +- .../core/internal/analysis/filter/KotlinLateinitFilter.java | 2 +- .../internal/analysis/filter/KotlinNotNullOperatorFilter.java | 2 +- .../org/jacoco/core/internal/analysis/filter/KotlinSMAP.java | 2 +- .../analysis/filter/KotlinSafeCallOperatorFilter.java | 2 +- .../analysis/filter/KotlinSyntheticAccessorsFilter.java | 2 +- .../analysis/filter/KotlinUnsafeCastOperatorFilter.java | 2 +- .../core/internal/analysis/filter/KotlinWhenFilter.java | 2 +- .../core/internal/analysis/filter/KotlinWhenStringFilter.java | 2 +- .../analysis/filter/PrivateEmptyNoArgConstructorFilter.java | 2 +- .../core/internal/analysis/filter/RecordPatternFilter.java | 2 +- .../jacoco/core/internal/analysis/filter/RecordsFilter.java | 2 +- .../core/internal/analysis/filter/StringSwitchFilter.java | 2 +- .../internal/analysis/filter/StringSwitchJavacFilter.java | 2 +- .../core/internal/analysis/filter/SynchronizedFilter.java | 2 +- .../jacoco/core/internal/analysis/filter/SyntheticFilter.java | 2 +- .../internal/analysis/filter/TryWithResourcesEcjFilter.java | 2 +- .../analysis/filter/TryWithResourcesJavac11Filter.java | 2 +- .../internal/analysis/filter/TryWithResourcesJavacFilter.java | 2 +- org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java | 2 +- .../src/org/jacoco/core/internal/data/CompactDataInput.java | 2 +- .../src/org/jacoco/core/internal/data/CompactDataOutput.java | 2 +- .../src/org/jacoco/core/internal/flow/ClassProbesAdapter.java | 2 +- .../src/org/jacoco/core/internal/flow/ClassProbesVisitor.java | 2 +- .../src/org/jacoco/core/internal/flow/FrameSnapshot.java | 2 +- org.jacoco.core/src/org/jacoco/core/internal/flow/IFrame.java | 2 +- .../src/org/jacoco/core/internal/flow/IProbeIdGenerator.java | 2 +- .../src/org/jacoco/core/internal/flow/LabelFlowAnalyzer.java | 2 +- .../src/org/jacoco/core/internal/flow/LabelInfo.java | 2 +- .../org/jacoco/core/internal/flow/MethodProbesAdapter.java | 2 +- .../org/jacoco/core/internal/flow/MethodProbesVisitor.java | 2 +- .../src/org/jacoco/core/internal/flow/MethodSanitizer.java | 2 +- .../core/internal/instr/ClassFieldProbeArrayStrategy.java | 2 +- .../src/org/jacoco/core/internal/instr/ClassInstrumenter.java | 2 +- .../jacoco/core/internal/instr/CondyProbeArrayStrategy.java | 2 +- .../jacoco/core/internal/instr/DuplicateFrameEliminator.java | 2 +- .../org/jacoco/core/internal/instr/IProbeArrayStrategy.java | 2 +- .../src/org/jacoco/core/internal/instr/IProbeInserter.java | 2 +- .../src/org/jacoco/core/internal/instr/InstrSupport.java | 2 +- .../core/internal/instr/InterfaceFieldProbeArrayStrategy.java | 2 +- .../jacoco/core/internal/instr/LocalProbeArrayStrategy.java | 2 +- .../org/jacoco/core/internal/instr/MethodInstrumenter.java | 2 +- .../jacoco/core/internal/instr/NoneProbeArrayStrategy.java | 2 +- .../jacoco/core/internal/instr/ProbeArrayStrategyFactory.java | 2 +- .../src/org/jacoco/core/internal/instr/ProbeCounter.java | 2 +- .../src/org/jacoco/core/internal/instr/ProbeInserter.java | 2 +- .../src/org/jacoco/core/internal/instr/SignatureRemover.java | 2 +- org.jacoco.core/src/org/jacoco/core/package-info.java | 2 +- .../src/org/jacoco/core/runtime/AbstractRuntime.java | 2 +- org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java | 2 +- .../src/org/jacoco/core/runtime/CommandLineSupport.java | 2 +- .../jacoco/core/runtime/IExecutionDataAccessorGenerator.java | 2 +- .../src/org/jacoco/core/runtime/IRemoteCommandVisitor.java | 2 +- org.jacoco.core/src/org/jacoco/core/runtime/IRuntime.java | 2 +- .../src/org/jacoco/core/runtime/InjectedClassRuntime.java | 2 +- .../src/org/jacoco/core/runtime/LoggerRuntime.java | 2 +- .../org/jacoco/core/runtime/ModifiedSystemClassRuntime.java | 2 +- .../core/runtime/OfflineInstrumentationAccessGenerator.java | 2 +- .../src/org/jacoco/core/runtime/RemoteControlReader.java | 2 +- .../src/org/jacoco/core/runtime/RemoteControlWriter.java | 2 +- org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java | 2 +- .../src/org/jacoco/core/runtime/SystemPropertiesRuntime.java | 2 +- .../src/org/jacoco/core/runtime/WildcardMatcher.java | 2 +- org.jacoco.core/src/org/jacoco/core/runtime/package-info.java | 2 +- org.jacoco.core/src/org/jacoco/core/tools/ExecDumpClient.java | 2 +- org.jacoco.core/src/org/jacoco/core/tools/ExecFileLoader.java | 2 +- org.jacoco.core/src/org/jacoco/core/tools/package-info.java | 2 +- org.jacoco.doc/pom.xml | 2 +- org.jacoco.doc/xsl/cli.xsl | 2 +- org.jacoco.doc/xsl/maven-goal.xsl | 2 +- org.jacoco.examples.test/pom.xml | 2 +- .../src/org/jacoco/examples/ClassInfoTest.java | 2 +- .../src/org/jacoco/examples/ConsoleOutput.java | 2 +- .../src/org/jacoco/examples/CoreTutorialTest.java | 2 +- .../src/org/jacoco/examples/ExecDumpTest.java | 2 +- .../src/org/jacoco/examples/MBeanClientTest.java | 2 +- org.jacoco.examples.test/src/test/resources/verify-it.bsh | 2 +- .../src/test/resources/verify-offline.bsh | 2 +- org.jacoco.examples.test/src/test/resources/verify.bsh | 2 +- org.jacoco.examples/assembly.xml | 2 +- org.jacoco.examples/build/build-offline.xml | 2 +- org.jacoco.examples/build/build.xml | 2 +- org.jacoco.examples/build/pom-it.xml | 2 +- org.jacoco.examples/build/pom-offline.xml | 2 +- org.jacoco.examples/build/pom.xml | 2 +- .../src/main/java/org/jacoco/examples/expressions/Add.java | 2 +- .../src/main/java/org/jacoco/examples/expressions/Const.java | 2 +- .../src/main/java/org/jacoco/examples/expressions/Div.java | 2 +- .../java/org/jacoco/examples/expressions/IExpression.java | 2 +- .../src/main/java/org/jacoco/examples/expressions/Mul.java | 2 +- .../src/main/java/org/jacoco/examples/expressions/Sub.java | 2 +- .../java/org/jacoco/examples/parser/ExpressionParser.java | 2 +- .../build/src/main/java/org/jacoco/examples/parser/Main.java | 2 +- .../java/org/jacoco/examples/parser/ExpressionParserIT.java | 2 +- .../java/org/jacoco/examples/parser/ExpressionParserTest.java | 2 +- org.jacoco.examples/pom.xml | 2 +- org.jacoco.examples/src/org/jacoco/examples/ClassInfo.java | 2 +- org.jacoco.examples/src/org/jacoco/examples/CoreTutorial.java | 2 +- org.jacoco.examples/src/org/jacoco/examples/ExecDump.java | 2 +- .../src/org/jacoco/examples/ExecutionDataClient.java | 2 +- .../src/org/jacoco/examples/ExecutionDataServer.java | 2 +- org.jacoco.examples/src/org/jacoco/examples/MBeanClient.java | 2 +- .../src/org/jacoco/examples/ReportGenerator.java | 2 +- org.jacoco.report.test/pom.xml | 2 +- .../src/org/jacoco/report/DirectorySourceFileLocatorTest.java | 2 +- .../src/org/jacoco/report/FileMultiReportOutputTest.java | 2 +- .../org/jacoco/report/InputStreamSourceFileLocatorTest.java | 2 +- .../src/org/jacoco/report/JavaNamesTest.java | 2 +- .../src/org/jacoco/report/MemoryMultiReportOutput.java | 2 +- .../src/org/jacoco/report/MemoryOutput.java | 2 +- .../src/org/jacoco/report/MultiReportVisitorTest.java | 2 +- .../src/org/jacoco/report/MultiSourceFileLocatorTest.java | 2 +- .../src/org/jacoco/report/ReportStructureTestDriver.java | 2 +- .../src/org/jacoco/report/ZipMultiReportOutputTest.java | 2 +- .../src/org/jacoco/report/check/BundleCheckerTest.java | 2 +- .../src/org/jacoco/report/check/LimitTest.java | 2 +- .../src/org/jacoco/report/check/RuleTest.java | 2 +- .../src/org/jacoco/report/check/RulesCheckerTest.java | 2 +- .../src/org/jacoco/report/csv/CSVFormatterTest.java | 2 +- .../src/org/jacoco/report/csv/CSVGroupHandlerTest.java | 2 +- .../src/org/jacoco/report/csv/ClassRowWriterTest.java | 2 +- .../src/org/jacoco/report/csv/DelimitedWriterTest.java | 2 +- .../src/org/jacoco/report/html/HTMLFormatterTest.java | 2 +- .../org/jacoco/report/internal/NormalizedFileNamesTest.java | 2 +- .../org/jacoco/report/internal/ReportOutputFolderTest.java | 2 +- .../src/org/jacoco/report/internal/html/HTMLElementTest.java | 2 +- .../src/org/jacoco/report/internal/html/HTMLSupport.java | 2 +- .../src/org/jacoco/report/internal/html/LinkableStub.java | 2 +- .../org/jacoco/report/internal/html/page/BundlePageTest.java | 2 +- .../org/jacoco/report/internal/html/page/ClassPageTest.java | 2 +- .../org/jacoco/report/internal/html/page/MethodItemTest.java | 2 +- .../org/jacoco/report/internal/html/page/NodePageTest.java | 2 +- .../org/jacoco/report/internal/html/page/PackagePageTest.java | 2 +- .../report/internal/html/page/PackageSourcePageTest.java | 2 +- .../org/jacoco/report/internal/html/page/PageTestBase.java | 2 +- .../org/jacoco/report/internal/html/page/ReportPageTest.java | 2 +- .../jacoco/report/internal/html/page/SessionsPageTest.java | 2 +- .../jacoco/report/internal/html/page/SourceFilePageTest.java | 2 +- .../report/internal/html/page/SourceHighlighterTest.java | 2 +- .../jacoco/report/internal/html/resources/ResourcesTest.java | 2 +- .../org/jacoco/report/internal/html/resources/StylesTest.java | 2 +- .../org/jacoco/report/internal/html/table/BarColumnTest.java | 2 +- .../jacoco/report/internal/html/table/CounterColumnTest.java | 2 +- .../jacoco/report/internal/html/table/LabelColumnTest.java | 2 +- .../report/internal/html/table/PercentageColumnTest.java | 2 +- .../org/jacoco/report/internal/html/table/SortIndexTest.java | 2 +- .../src/org/jacoco/report/internal/html/table/TableTest.java | 2 +- .../org/jacoco/report/internal/xml/LocalEntityResolver.java | 2 +- .../src/org/jacoco/report/internal/xml/XMLElementTest.java | 2 +- .../org/jacoco/report/internal/xml/XMLGroupVisitorTest.java | 2 +- .../src/org/jacoco/report/internal/xml/XMLSupport.java | 2 +- .../src/org/jacoco/report/xml/XMLFormatterTest.java | 2 +- org.jacoco.report/pom.xml | 2 +- .../src/org/jacoco/report/DirectorySourceFileLocator.java | 2 +- .../src/org/jacoco/report/FileMultiReportOutput.java | 2 +- org.jacoco.report/src/org/jacoco/report/ILanguageNames.java | 2 +- .../src/org/jacoco/report/IMultiReportOutput.java | 2 +- .../src/org/jacoco/report/IReportGroupVisitor.java | 2 +- org.jacoco.report/src/org/jacoco/report/IReportVisitor.java | 2 +- .../src/org/jacoco/report/ISourceFileLocator.java | 2 +- .../src/org/jacoco/report/InputStreamSourceFileLocator.java | 2 +- org.jacoco.report/src/org/jacoco/report/JavaNames.java | 2 +- .../src/org/jacoco/report/MultiReportVisitor.java | 2 +- .../src/org/jacoco/report/MultiSourceFileLocator.java | 2 +- .../src/org/jacoco/report/ZipMultiReportOutput.java | 2 +- .../src/org/jacoco/report/check/BundleChecker.java | 2 +- .../src/org/jacoco/report/check/IViolationsOutput.java | 2 +- org.jacoco.report/src/org/jacoco/report/check/Limit.java | 2 +- org.jacoco.report/src/org/jacoco/report/check/Rule.java | 2 +- .../src/org/jacoco/report/check/RulesChecker.java | 2 +- .../src/org/jacoco/report/check/package-info.java | 2 +- org.jacoco.report/src/org/jacoco/report/csv/CSVFormatter.java | 2 +- .../src/org/jacoco/report/csv/CSVGroupHandler.java | 2 +- .../src/org/jacoco/report/csv/ClassRowWriter.java | 2 +- .../src/org/jacoco/report/csv/DelimitedWriter.java | 2 +- org.jacoco.report/src/org/jacoco/report/csv/package-info.java | 2 +- .../src/org/jacoco/report/html/HTMLFormatter.java | 2 +- .../src/org/jacoco/report/html/package-info.java | 2 +- .../src/org/jacoco/report/internal/AbstractGroupVisitor.java | 2 +- .../src/org/jacoco/report/internal/NormalizedFileNames.java | 2 +- .../src/org/jacoco/report/internal/ReportOutputFolder.java | 2 +- .../src/org/jacoco/report/internal/html/HTMLElement.java | 2 +- .../src/org/jacoco/report/internal/html/HTMLGroupVisitor.java | 2 +- .../org/jacoco/report/internal/html/IHTMLReportContext.java | 2 +- .../src/org/jacoco/report/internal/html/ILinkable.java | 2 +- .../org/jacoco/report/internal/html/index/ElementIndex.java | 2 +- .../org/jacoco/report/internal/html/index/IIndexUpdate.java | 2 +- .../org/jacoco/report/internal/html/index/package-info.java | 2 +- .../src/org/jacoco/report/internal/html/page/BundlePage.java | 2 +- .../src/org/jacoco/report/internal/html/page/ClassPage.java | 2 +- .../src/org/jacoco/report/internal/html/page/GroupPage.java | 2 +- .../src/org/jacoco/report/internal/html/page/MethodItem.java | 2 +- .../src/org/jacoco/report/internal/html/page/NodePage.java | 2 +- .../src/org/jacoco/report/internal/html/page/PackagePage.java | 2 +- .../jacoco/report/internal/html/page/PackageSourcePage.java | 2 +- .../src/org/jacoco/report/internal/html/page/ReportPage.java | 2 +- .../org/jacoco/report/internal/html/page/SessionsPage.java | 2 +- .../org/jacoco/report/internal/html/page/SourceFileItem.java | 2 +- .../org/jacoco/report/internal/html/page/SourceFilePage.java | 2 +- .../jacoco/report/internal/html/page/SourceHighlighter.java | 2 +- .../src/org/jacoco/report/internal/html/page/TablePage.java | 2 +- .../org/jacoco/report/internal/html/resources/Resources.java | 2 +- .../src/org/jacoco/report/internal/html/resources/Styles.java | 2 +- .../jacoco/report/internal/html/resources/package-info.java | 2 +- .../src/org/jacoco/report/internal/html/resources/sort.js | 2 +- .../src/org/jacoco/report/internal/html/table/BarColumn.java | 2 +- .../org/jacoco/report/internal/html/table/CounterColumn.java | 2 +- .../jacoco/report/internal/html/table/IColumnRenderer.java | 2 +- .../src/org/jacoco/report/internal/html/table/ITableItem.java | 2 +- .../org/jacoco/report/internal/html/table/LabelColumn.java | 2 +- .../jacoco/report/internal/html/table/PercentageColumn.java | 2 +- .../src/org/jacoco/report/internal/html/table/SortIndex.java | 2 +- .../src/org/jacoco/report/internal/html/table/Table.java | 2 +- .../report/internal/html/table/TableItemComparator.java | 2 +- .../org/jacoco/report/internal/html/table/package-info.java | 2 +- .../src/org/jacoco/report/internal/xml/ReportElement.java | 2 +- .../src/org/jacoco/report/internal/xml/XMLCoverageWriter.java | 2 +- .../src/org/jacoco/report/internal/xml/XMLElement.java | 2 +- .../src/org/jacoco/report/internal/xml/XMLGroupVisitor.java | 2 +- org.jacoco.report/src/org/jacoco/report/package-info.java | 2 +- org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java | 2 +- org.jacoco.report/src/org/jacoco/report/xml/package-info.java | 2 +- org.jacoco.report/src/org/jacoco/report/xml/report.dtd | 2 +- org.jacoco.tests/pom.xml | 2 +- 834 files changed, 835 insertions(+), 835 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 0c2e74523f..50688de56c 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ License ======= -Copyright (c) 2009, 2024 Mountainminds GmbH & Co. KG and Contributors +Copyright (c) 2009, 2025 Mountainminds GmbH & Co. KG and Contributors The JaCoCo Java Code Coverage Library and all included documentation is made available by Mountainminds GmbH & Co. KG, Munich. Except indicated below, the diff --git a/jacoco-maven-plugin.test/it/it-check-fails-halt/pom.xml b/jacoco-maven-plugin.test/it/it-check-fails-halt/pom.xml index 2b58a34d1d..81656f0df3 100644 --- a/jacoco-maven-plugin.test/it/it-check-fails-halt/pom.xml +++ b/jacoco-maven-plugin.test/it/it-check-fails-halt/pom.xml @@ -1,6 +1,6 @@ ../org.jacoco.core.test.validation.java7 ../org.jacoco.core.test.validation.java8 ../org.jacoco.core.test.validation.java14 From 5ee4222067c261a0de17888b1236f004ac2b21e1 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Wed, 5 Feb 2025 09:59:55 +0100 Subject: [PATCH 152/163] Add validation test for `@JvmName` in Kotlin (#1842) --- .../validation/kotlin/KotlinJvmNameTest.java | 27 +++++++++++++++++++ .../kotlin/targets/KotlinJvmNameTarget.kt | 21 +++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinJvmNameTest.java create mode 100644 org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinJvmNameTarget.kt diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinJvmNameTest.java b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinJvmNameTest.java new file mode 100644 index 0000000000..4117fab294 --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/KotlinJvmNameTest.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009, 2025 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.KotlinJvmNameTarget; + +/** + * Test of code coverage in {@link KotlinJvmNameTarget}. + */ +public class KotlinJvmNameTest extends ValidationTestBase { + + public KotlinJvmNameTest() { + super(KotlinJvmNameTarget.class); + } + +} diff --git a/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinJvmNameTarget.kt b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinJvmNameTarget.kt new file mode 100644 index 0000000000..b647a2a27e --- /dev/null +++ b/org.jacoco.core.test.validation.kotlin/src/org/jacoco/core/test/validation/kotlin/targets/KotlinJvmNameTarget.kt @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2009, 2025 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 + * + *******************************************************************************/ +@file:JvmName("KotlinJvmNameTarget") + +package org.jacoco.core.test.validation.kotlin.targets + +import org.jacoco.core.test.validation.targets.Stubs.nop + +fun main(args: Array) { + nop() // assertFullyCovered() +} From c2596680f89fa1c1b66095a3d9e73cfe748a4a4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 18:43:06 +0000 Subject: [PATCH 153/163] Bump actions/setup-java from 4.6.0 to 4.7.0 (#1847) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4.6.0 to 4.7.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/7a6d8a8234af8eb26422e24e3006232cccaa061b...3a4f6e1af504cf6a31855fa899c6aa5355ba6c12) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06688790e3..034c2ec01a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0 + - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: 'zulu' java-version: | @@ -59,7 +59,7 @@ jobs: runs-on: windows-2022 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0 + - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: distribution: 'zulu' java-version: | From 0bb8bd525f22c6d2427c3b5e23b0292ec64201b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 09:41:52 +0100 Subject: [PATCH 154/163] Bump actions/upload-artifact from 4.6.0 to 4.6.1 (#1852) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.0 to 4.6.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08...4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 034c2ec01a..3650c2907e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: ./mvnw -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 id: artifact-upload-step with: name: jacoco From 80ebc77eaee121bfef3f132fdc4c9baa66137f0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 14:28:40 +0100 Subject: [PATCH 155/163] Upgrade maven-clean-plugin to 3.4.1 (#1850) --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 4b3816d68b..66369992cd 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -307,7 +307,7 @@ org.apache.maven.plugins maven-clean-plugin - 3.4.0 + 3.4.1 org.apache.maven.plugins From c7da68b0f15e7cfc8482e7b524751401abd9b1e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 20:08:13 +0100 Subject: [PATCH 156/163] Upgrade maven-install-plugin to 3.1.4 (#1853) --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 66369992cd..545eb861ed 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -333,7 +333,7 @@ org.apache.maven.plugins maven-install-plugin - 3.1.3 + 3.1.4 org.apache.maven.plugins From 21f6a99d7bbd518b22838855c93af9ad72ff36fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:53:15 +0000 Subject: [PATCH 157/163] Upgrade maven-deploy-plugin to 3.1.4 (#1854) --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 545eb861ed..cf114eb0bb 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -323,7 +323,7 @@ org.apache.maven.plugins maven-deploy-plugin - 3.1.3 + 3.1.4 org.apache.maven.plugins From 99707c3b2d540285b4418a9d056bba5ee18453e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Mar 2025 22:43:06 +0100 Subject: [PATCH 158/163] Upgrade spotless-maven-plugin to 2.44.3 (#1851) --- org.jacoco.build/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index cf114eb0bb..537be728bd 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -450,7 +450,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.44.2 + 2.44.3 org.sonarsource.scanner.maven From f0dcc6b0b78b04dd94617707551f6c2d18426d09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 14:06:54 +0100 Subject: [PATCH 159/163] Bump actions/upload-artifact from 4.6.1 to 4.6.2 (#1861) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.1 to 4.6.2. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1...ea165f8d65b6e75b540449e92b4886f43607fa02) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3650c2907e..e3c8ef4c7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: ./mvnw -V -B -e --no-transfer-progress \ verify -Djdk.version=6 -Dbytecode.version=5 \ --toolchains=toolchains.xml - - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 id: artifact-upload-step with: name: jacoco From ee07ecb663f256930aa3b12771855ff555ec4e1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 00:14:40 +0100 Subject: [PATCH 160/163] Upgrade Kotlin to 2.1.20 (#1860) --- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index 7faa2f8f9d..1933228e2d 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -25,7 +25,7 @@ JaCoCo :: Test :: Core :: Validation Kotlin - 2.1.10 + 2.1.20 From 17d31aa1073b1a327f1d7b631ff480a60cd40df5 Mon Sep 17 00:00:00 2001 From: Ed Merks Date: Tue, 1 Apr 2025 00:35:56 +0200 Subject: [PATCH 161/163] Upgrade ASM to 9.8 (#1863) --- org.jacoco.build/licenses/{asm-9.7.1.html => asm-9.8.html} | 2 +- org.jacoco.build/pom.xml | 2 +- org.jacoco.doc/docroot/doc/changes.html | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename org.jacoco.build/licenses/{asm-9.7.1.html => asm-9.8.html} (96%) diff --git a/org.jacoco.build/licenses/asm-9.7.1.html b/org.jacoco.build/licenses/asm-9.8.html similarity index 96% rename from org.jacoco.build/licenses/asm-9.7.1.html rename to org.jacoco.build/licenses/asm-9.8.html index 5aeeb0b5be..f74f83dc13 100644 --- a/org.jacoco.build/licenses/asm-9.7.1.html +++ b/org.jacoco.build/licenses/asm-9.8.html @@ -1,7 +1,7 @@

      ASM

      - ASM 9.7 is subject to the terms and + ASM 9.8 is subject to the terms and conditions of the following license:

      diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index 537be728bd..c9d0738d86 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -139,7 +139,7 @@ ${jvm.args} - 9.7.1 + 9.8 1.9.16 2.0.28 4.13.2 diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 1a43306989..6c5c69cf72 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -80,8 +80,8 @@

      Non-functional Changes

      (GitHub #1708, #1707, #1681). -
    • JaCoCo now depends on ASM 9.7.1 - (GitHub #1739).
    • +
    • JaCoCo now depends on ASM 9.8 + (GitHub #1862).
    • More context information when IllegalArgumentException occurs during reading of zip file (GitHub #1833).
    • From e579092d415247939c7098bfbaa3cbbe4dc7fe0d Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov <138671+Godin@users.noreply.github.com> Date: Tue, 1 Apr 2025 23:18:58 +0200 Subject: [PATCH 162/163] Happy birthday Java 24! (#1867) --- org.jacoco.doc/docroot/doc/changes.html | 12 ++++++------ org.jacoco.doc/docroot/doc/environment.html | 2 +- org.jacoco.doc/docroot/doc/faq.html | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 6c5c69cf72..389c8a4290 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -22,8 +22,12 @@

      Snapshot Build @qualified.bundle.version@ (@build.date@)

      New Features

        -
      • JaCoCo now officially supports Java 23 - (GitHub #1757).
      • +
      • JaCoCo now officially supports Java 23 and Java 24 + (GitHub #1757, + #1631, + #1867).
      • +
      • Experimental support for Java 25 class files + (GitHub #1807).
      • Calculation of line coverage for Kotlin inline functions (GitHub #1670).
      • Calculation of line coverage for Kotlin inline functions @@ -32,10 +36,6 @@

        New Features

        #1700).
      • Calculation of coverage for Kotlin JvmSynthetic functions (GitHub #1700).
      • -
      • Experimental support for Java 24 class files - (GitHub #1631).
      • -
      • Experimental support for Java 25 class files - (GitHub #1807).
      • Part of bytecode generated by the Kotlin Compose compiler plugin is filtered out during generation of report (GitHub #1616).
      • diff --git a/org.jacoco.doc/docroot/doc/environment.html b/org.jacoco.doc/docroot/doc/environment.html index 0bbb5c6d69..f56639a9bc 100644 --- a/org.jacoco.doc/docroot/doc/environment.html +++ b/org.jacoco.doc/docroot/doc/environment.html @@ -69,7 +69,7 @@

        JRE/JDK

        The minimum supported JRE version for JaCoCo is Java 5. To guarantee compatibility JaCoCo release builds should always be executed using JDK 5. In addition we run builds with 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 - 18, 19, 20, 21, 22 and 23 JDKs. + 18, 19, 20, 21, 22, 23, 24 and 25 JDKs.

        Build

        diff --git a/org.jacoco.doc/docroot/doc/faq.html b/org.jacoco.doc/docroot/doc/faq.html index 27c5cae347..afa6d507c7 100644 --- a/org.jacoco.doc/docroot/doc/faq.html +++ b/org.jacoco.doc/docroot/doc/faq.html @@ -45,8 +45,8 @@

        Does JaCoCo have a plug-in for [Eclipse|Netbeans|Whatever...]?

        What Java versions are supported by JaCoCo?

        - JaCoCo officially supports Java class files from version 1.0 to 23. Also - experimental support for class files of versions 24 and 25 is provided. + JaCoCo officially supports Java class files from version 1.0 to 24. Also + experimental support for class files of version 25 is provided. However the minimum JRE version required by the JaCoCo runtime (e.g. the agent) and the JaCoCo tools is 1.5. Also note that class files under test from version 1.6 and above have to contain valid stackmap frames. From 78d5eff856bbe6129f05012e40c13d1840e20598 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Tue, 1 Apr 2025 23:12:04 +0200 Subject: [PATCH 163/163] Prepare release 0.8.13 --- jacoco-maven-plugin.test/pom.xml | 2 +- jacoco-maven-plugin/pom.xml | 2 +- jacoco/pom.xml | 2 +- org.jacoco.agent.rt.test/pom.xml | 2 +- org.jacoco.agent.rt/pom.xml | 2 +- org.jacoco.agent.test/pom.xml | 2 +- org.jacoco.agent/pom.xml | 2 +- org.jacoco.ant.test/pom.xml | 2 +- org.jacoco.ant/pom.xml | 2 +- org.jacoco.build/pom.xml | 2 +- org.jacoco.cli.test/pom.xml | 2 +- org.jacoco.cli/pom.xml | 2 +- org.jacoco.core.test.validation.groovy/pom.xml | 2 +- org.jacoco.core.test.validation.java14/pom.xml | 2 +- org.jacoco.core.test.validation.java16/pom.xml | 2 +- org.jacoco.core.test.validation.java21/pom.xml | 2 +- org.jacoco.core.test.validation.java5/pom.xml | 2 +- org.jacoco.core.test.validation.java7/pom.xml | 2 +- org.jacoco.core.test.validation.java8/pom.xml | 2 +- org.jacoco.core.test.validation.kotlin/pom.xml | 2 +- org.jacoco.core.test.validation.scala/pom.xml | 2 +- org.jacoco.core.test.validation/pom.xml | 2 +- org.jacoco.core.test/pom.xml | 2 +- org.jacoco.core/pom.xml | 2 +- org.jacoco.doc/docroot/doc/changes.html | 2 +- org.jacoco.doc/pom.xml | 2 +- org.jacoco.examples.test/pom.xml | 2 +- org.jacoco.examples/pom.xml | 2 +- org.jacoco.report.test/pom.xml | 2 +- org.jacoco.report/pom.xml | 2 +- org.jacoco.tests/pom.xml | 2 +- pom.xml | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/jacoco-maven-plugin.test/pom.xml b/jacoco-maven-plugin.test/pom.xml index 133b9d6fcd..0f8d9a06db 100644 --- a/jacoco-maven-plugin.test/pom.xml +++ b/jacoco-maven-plugin.test/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/jacoco-maven-plugin/pom.xml b/jacoco-maven-plugin/pom.xml index 31bea49086..fa660549d9 100644 --- a/jacoco-maven-plugin/pom.xml +++ b/jacoco-maven-plugin/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/jacoco/pom.xml b/jacoco/pom.xml index 3112beb77d..0f0da04b2d 100644 --- a/jacoco/pom.xml +++ b/jacoco/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.agent.rt.test/pom.xml b/org.jacoco.agent.rt.test/pom.xml index 109cdbb6d1..5cd18fa386 100644 --- a/org.jacoco.agent.rt.test/pom.xml +++ b/org.jacoco.agent.rt.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/org.jacoco.agent.rt/pom.xml b/org.jacoco.agent.rt/pom.xml index 13c874308c..8de9b8e89e 100644 --- a/org.jacoco.agent.rt/pom.xml +++ b/org.jacoco.agent.rt/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.agent.test/pom.xml b/org.jacoco.agent.test/pom.xml index 08bb758910..f7902c5284 100644 --- a/org.jacoco.agent.test/pom.xml +++ b/org.jacoco.agent.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/org.jacoco.agent/pom.xml b/org.jacoco.agent/pom.xml index 1a2bcada17..7d70fb756d 100644 --- a/org.jacoco.agent/pom.xml +++ b/org.jacoco.agent/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.ant.test/pom.xml b/org.jacoco.ant.test/pom.xml index 0b45e2b634..8e3dec25b1 100644 --- a/org.jacoco.ant.test/pom.xml +++ b/org.jacoco.ant.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/org.jacoco.ant/pom.xml b/org.jacoco.ant/pom.xml index f5546815a0..6c6250c85b 100644 --- a/org.jacoco.ant/pom.xml +++ b/org.jacoco.ant/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml index c9d0738d86..0413ac4f1e 100644 --- a/org.jacoco.build/pom.xml +++ b/org.jacoco.build/pom.xml @@ -15,7 +15,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 pom JaCoCo diff --git a/org.jacoco.cli.test/pom.xml b/org.jacoco.cli.test/pom.xml index c425cc361f..bdba3be214 100644 --- a/org.jacoco.cli.test/pom.xml +++ b/org.jacoco.cli.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/org.jacoco.cli/pom.xml b/org.jacoco.cli/pom.xml index 65745da5d8..6ecb2355ca 100644 --- a/org.jacoco.cli/pom.xml +++ b/org.jacoco.cli/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.core.test.validation.groovy/pom.xml b/org.jacoco.core.test.validation.groovy/pom.xml index d6af226997..e278afda7b 100644 --- a/org.jacoco.core.test.validation.groovy/pom.xml +++ b/org.jacoco.core.test.validation.groovy/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java14/pom.xml b/org.jacoco.core.test.validation.java14/pom.xml index 4794f349b7..ed0c115355 100644 --- a/org.jacoco.core.test.validation.java14/pom.xml +++ b/org.jacoco.core.test.validation.java14/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java16/pom.xml b/org.jacoco.core.test.validation.java16/pom.xml index 49bfc1304e..d0521ec58c 100644 --- a/org.jacoco.core.test.validation.java16/pom.xml +++ b/org.jacoco.core.test.validation.java16/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java21/pom.xml b/org.jacoco.core.test.validation.java21/pom.xml index 6c06a3b633..dd00a524c3 100644 --- a/org.jacoco.core.test.validation.java21/pom.xml +++ b/org.jacoco.core.test.validation.java21/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java5/pom.xml b/org.jacoco.core.test.validation.java5/pom.xml index a7c0e7bcca..a1897ec9e9 100644 --- a/org.jacoco.core.test.validation.java5/pom.xml +++ b/org.jacoco.core.test.validation.java5/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java7/pom.xml b/org.jacoco.core.test.validation.java7/pom.xml index 4cd65d6e54..764971363e 100644 --- a/org.jacoco.core.test.validation.java7/pom.xml +++ b/org.jacoco.core.test.validation.java7/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.java8/pom.xml b/org.jacoco.core.test.validation.java8/pom.xml index 5cbac0fd73..10f7f26a4c 100644 --- a/org.jacoco.core.test.validation.java8/pom.xml +++ b/org.jacoco.core.test.validation.java8/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.kotlin/pom.xml b/org.jacoco.core.test.validation.kotlin/pom.xml index 1933228e2d..0e8a13a063 100644 --- a/org.jacoco.core.test.validation.kotlin/pom.xml +++ b/org.jacoco.core.test.validation.kotlin/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation.scala/pom.xml b/org.jacoco.core.test.validation.scala/pom.xml index d8a56fd7d0..e58f89ec84 100644 --- a/org.jacoco.core.test.validation.scala/pom.xml +++ b/org.jacoco.core.test.validation.scala/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.core.test.validation - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.core.test.validation diff --git a/org.jacoco.core.test.validation/pom.xml b/org.jacoco.core.test.validation/pom.xml index aa88fb502d..4e4070ed6f 100644 --- a/org.jacoco.core.test.validation/pom.xml +++ b/org.jacoco.core.test.validation/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/org.jacoco.core.test/pom.xml b/org.jacoco.core.test/pom.xml index f9f40ed3a0..4de0f35d79 100644 --- a/org.jacoco.core.test/pom.xml +++ b/org.jacoco.core.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/org.jacoco.core/pom.xml b/org.jacoco.core/pom.xml index aa2bc5d814..ec9a7b856c 100644 --- a/org.jacoco.core/pom.xml +++ b/org.jacoco.core/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 389c8a4290..eb4369f07d 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -18,7 +18,7 @@

        Change History

        -

        Snapshot Build @qualified.bundle.version@ (@build.date@)

        +

        Release 0.8.13 (2025/04/02)

        New Features

          diff --git a/org.jacoco.doc/pom.xml b/org.jacoco.doc/pom.xml index 1c765c2019..8c8fcdf131 100644 --- a/org.jacoco.doc/pom.xml +++ b/org.jacoco.doc/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.examples.test/pom.xml b/org.jacoco.examples.test/pom.xml index 67ea67ece9..e7f863910e 100644 --- a/org.jacoco.examples.test/pom.xml +++ b/org.jacoco.examples.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/org.jacoco.examples/pom.xml b/org.jacoco.examples/pom.xml index 04e62ffcae..0941470de2 100644 --- a/org.jacoco.examples/pom.xml +++ b/org.jacoco.examples/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.report.test/pom.xml b/org.jacoco.report.test/pom.xml index e789d4f722..4c1b1a19ca 100644 --- a/org.jacoco.report.test/pom.xml +++ b/org.jacoco.report.test/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.tests - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.tests diff --git a/org.jacoco.report/pom.xml b/org.jacoco.report/pom.xml index 1f657ce4c2..e8dd3af499 100644 --- a/org.jacoco.report/pom.xml +++ b/org.jacoco.report/pom.xml @@ -16,7 +16,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/org.jacoco.tests/pom.xml b/org.jacoco.tests/pom.xml index aa0e666363..705e78007a 100644 --- a/org.jacoco.tests/pom.xml +++ b/org.jacoco.tests/pom.xml @@ -17,7 +17,7 @@ org.jacoco org.jacoco.build - 0.8.13-SNAPSHOT + 0.8.13 ../org.jacoco.build diff --git a/pom.xml b/pom.xml index dc71687067..eafafe5514 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.jacoco root - 0.8.13-SNAPSHOT + 0.8.13 pom