Skip to content

Commit ad2d627

Browse files
fzhinkinshanshin
authored andcommitted
[ABI Validation] Support Java package-level annotations
* Support Java package-level annotations. Closes Kotlin/binary-compatibility-validator#156 Pull request Kotlin/binary-compatibility-validator#175
1 parent 049bbb0 commit ad2d627

24 files changed

+254
-4
lines changed

libraries/tools/abi-validation/api/binary-compatibility-validator.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public final class kotlinx/validation/api/ClassBinarySignature {
6767
public final class kotlinx/validation/api/KotlinSignaturesLoadingKt {
6868
public static final fun dump (Ljava/util/List;)Ljava/io/PrintStream;
6969
public static final fun dump (Ljava/util/List;Ljava/lang/Appendable;)Ljava/lang/Appendable;
70+
public static final fun extractAnnotatedPackages (Ljava/util/List;Ljava/util/Set;)Ljava/util/List;
7071
public static final fun filterOutAnnotated (Ljava/util/List;Ljava/util/Set;)Ljava/util/List;
7172
public static final fun filterOutNonPublic (Ljava/util/List;Ljava/util/Collection;Ljava/util/Collection;)Ljava/util/List;
7273
public static synthetic fun filterOutNonPublic$default (Ljava/util/List;Ljava/util/Collection;Ljava/util/Collection;ILjava/lang/Object;)Ljava/util/List;

libraries/tools/abi-validation/src/functionalTest/kotlin/kotlinx/validation/test/NonPublicMarkersTest.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
package kotlinx.validation.test
77

88
import kotlinx.validation.api.*
9+
import org.assertj.core.api.Assertions
910
import org.junit.*
11+
import kotlin.test.assertTrue
1012

1113
class NonPublicMarkersTest : BaseKotlinGradleTest() {
1214

@@ -35,4 +37,38 @@ class NonPublicMarkersTest : BaseKotlinGradleTest() {
3537
assertTaskSuccess(":apiCheck")
3638
}
3739
}
40+
41+
@Test
42+
fun testFiltrationByPackageLevelAnnotations() {
43+
val runner = test {
44+
buildGradleKts {
45+
resolve("/examples/gradle/base/withPlugin.gradle.kts")
46+
resolve("/examples/gradle/configuration/nonPublicMarkers/packages.gradle.kts")
47+
}
48+
java("annotated/PackageAnnotation.java") {
49+
resolve("/examples/classes/PackageAnnotation.java")
50+
}
51+
java("annotated/package-info.java") {
52+
resolve("/examples/classes/package-info.java")
53+
}
54+
kotlin("ClassFromAnnotatedPackage.kt") {
55+
resolve("/examples/classes/ClassFromAnnotatedPackage.kt")
56+
}
57+
kotlin("AnotherBuildConfig.kt") {
58+
resolve("/examples/classes/AnotherBuildConfig.kt")
59+
}
60+
runner {
61+
arguments.add(":apiDump")
62+
}
63+
}
64+
65+
runner.build().apply {
66+
assertTaskSuccess(":apiDump")
67+
68+
assertTrue(rootProjectApiDump.exists(), "api dump file should exist")
69+
70+
val expected = readFileList("/examples/classes/AnotherBuildConfig.dump")
71+
Assertions.assertThat(rootProjectApiDump.readText()).isEqualToIgnoringNewLines(expected)
72+
}
73+
}
3874
}

libraries/tools/abi-validation/src/functionalTest/kotlin/kotlinx/validation/test/PublicMarkersTest.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import kotlinx.validation.api.buildGradleKts
1010
import kotlinx.validation.api.kotlin
1111
import kotlinx.validation.api.resolve
1212
import kotlinx.validation.api.test
13+
import org.assertj.core.api.Assertions
1314
import org.junit.Test
15+
import kotlin.test.assertTrue
1416

1517
class PublicMarkersTest : BaseKotlinGradleTest() {
1618

@@ -43,4 +45,38 @@ class PublicMarkersTest : BaseKotlinGradleTest() {
4345
assertTaskSuccess(":apiCheck")
4446
}
4547
}
48+
49+
@Test
50+
fun testFiltrationByPackageLevelAnnotations() {
51+
val runner = test {
52+
buildGradleKts {
53+
resolve("/examples/gradle/base/withPlugin.gradle.kts")
54+
resolve("/examples/gradle/configuration/publicMarkers/packages.gradle.kts")
55+
}
56+
java("annotated/PackageAnnotation.java") {
57+
resolve("/examples/classes/PackageAnnotation.java")
58+
}
59+
java("annotated/package-info.java") {
60+
resolve("/examples/classes/package-info.java")
61+
}
62+
kotlin("ClassFromAnnotatedPackage.kt") {
63+
resolve("/examples/classes/ClassFromAnnotatedPackage.kt")
64+
}
65+
kotlin("AnotherBuildConfig.kt") {
66+
resolve("/examples/classes/AnotherBuildConfig.kt")
67+
}
68+
runner {
69+
arguments.add(":apiDump")
70+
}
71+
}
72+
73+
runner.build().apply {
74+
assertTaskSuccess(":apiDump")
75+
76+
assertTrue(rootProjectApiDump.exists(), "api dump file should exist")
77+
78+
val expected = readFileList("/examples/classes/AnnotatedPackage.dump")
79+
Assertions.assertThat(rootProjectApiDump.readText()).isEqualToIgnoringNewLines(expected)
80+
}
81+
}
4682
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public final class annotated/ClassFromAnnotatedPackage {
2+
public fun <init> ()V
3+
}
4+
5+
public abstract interface annotation class annotated/PackageAnnotation : java/lang/annotation/Annotation {
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright 2016-2024 JetBrains s.r.o.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package annotated
7+
8+
class ClassFromAnnotatedPackage {
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package annotated;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target(ElementType.PACKAGE)
10+
public @interface PackageAnnotation {
11+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@PackageAnnotation
2+
package annotated;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Copyright 2016-2024 JetBrains s.r.o.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
configure<kotlinx.validation.ApiValidationExtension> {
7+
nonPublicMarkers.add("annotated.PackageAnnotation")
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Copyright 2016-2024 JetBrains s.r.o.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
configure<kotlinx.validation.ApiValidationExtension> {
7+
publicMarkers.add("annotated.PackageAnnotation")
8+
}

libraries/tools/abi-validation/src/main/kotlin/KotlinApiBuildTask.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,13 @@ public open class KotlinApiBuildTask @Inject constructor(
9595
throw GradleException("KotlinApiBuildTask should have either inputClassesDirs, or inputJar property set")
9696
}
9797

98+
val publicPackagesNames = signatures.extractAnnotatedPackages(publicMarkers.map(::replaceDots).toSet())
99+
val ignoredPackagesNames = signatures.extractAnnotatedPackages(nonPublicMarkers.map(::replaceDots).toSet())
98100

99101
val filteredSignatures = signatures
100-
.retainExplicitlyIncludedIfDeclared(publicPackages, publicClasses, publicMarkers)
101-
.filterOutNonPublic(ignoredPackages, ignoredClasses)
102+
.retainExplicitlyIncludedIfDeclared(publicPackages + publicPackagesNames,
103+
publicClasses, publicMarkers)
104+
.filterOutNonPublic(ignoredPackages + ignoredPackagesNames, ignoredClasses)
102105
.filterOutAnnotated(nonPublicMarkers.map(::replaceDots).toSet())
103106

104107
outputApiDir.resolve("$projectName.api").bufferedWriter().use { writer ->

0 commit comments

Comments
 (0)