[KPM] Exclude 'InternalKotlinGradlePluginApi' apis from binary validation

^KT-51262
This commit is contained in:
sebastian.sellmair
2022-02-13 10:22:43 +01:00
committed by Space
parent 113e363b22
commit 627cb0be3a
13 changed files with 62 additions and 155 deletions
@@ -15,6 +15,13 @@ dependencies {
testArtifacts project(':kotlin-stdlib-jdk8')
testArtifacts project(':kotlin-reflect')
testArtifacts project(':kotlin-gradle-plugin-idea')
testCompileOnly("org.ow2.asm:asm-tree:9.0") {
because(
"Necessary to compile copied 'filterOutAnnotated' implementation. " +
"Can be removed after https://github.com/Kotlin/binary-compatibility-validator/pull/75"
)
}
}
pill {
@@ -10,27 +10,6 @@ public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinF
public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentDependency : java/io/Serializable {
}
public final class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentImpl : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragment {
public fun <init> (Ljava/lang/String;Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings;
public final fun component3 ()Ljava/util/Collection;
public final fun component4 ()Ljava/util/Collection;
public final fun component5 ()Ljava/util/Collection;
public final fun component6 ()Ljava/util/Collection;
public final fun copy (Ljava/lang/String;Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentImpl;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentImpl;Ljava/lang/String;Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getDependencies ()Ljava/util/Collection;
public fun getDirectRefinesDependencies ()Ljava/util/Collection;
public fun getLanguageSettings ()Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings;
public fun getName ()Ljava/lang/String;
public fun getResourceDirectories ()Ljava/util/Collection;
public fun getSourceDirectories ()Ljava/util/Collection;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings : java/io/Serializable {
public abstract fun getApiVersion ()Ljava/lang/String;
public abstract fun getCompilerPluginArguments ()Ljava/util/Collection;
@@ -42,71 +21,16 @@ public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinL
public abstract fun isProgressiveMode ()Z
}
public final class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettingsImpl : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings {
public fun <init> (Ljava/lang/String;Ljava/lang/String;ZLjava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Z
public final fun component4 ()Ljava/util/Collection;
public final fun component5 ()Ljava/util/Collection;
public final fun component6 ()Ljava/util/Collection;
public final fun component7 ()Ljava/util/Collection;
public final fun component8 ()Ljava/util/Collection;
public final fun copy (Ljava/lang/String;Ljava/lang/String;ZLjava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettingsImpl;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettingsImpl;Ljava/lang/String;Ljava/lang/String;ZLjava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;Ljava/util/Collection;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettingsImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getApiVersion ()Ljava/lang/String;
public fun getCompilerPluginArguments ()Ljava/util/Collection;
public fun getCompilerPluginClasspath ()Ljava/util/Collection;
public fun getEnabledLanguageFeatures ()Ljava/util/Collection;
public fun getFreeCompilerArgs ()Ljava/util/Collection;
public fun getLanguageVersion ()Ljava/lang/String;
public fun getOptInAnnotationsInUse ()Ljava/util/Collection;
public fun hashCode ()I
public fun isProgressiveMode ()Z
public fun toString ()Ljava/lang/String;
}
public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLocalModuleIdentifier : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier {
public abstract fun getBuildId ()Ljava/lang/String;
public abstract fun getProjectId ()Ljava/lang/String;
}
public final class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLocalModuleIdentifierImpl : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLocalModuleIdentifier {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLocalModuleIdentifierImpl;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLocalModuleIdentifierImpl;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLocalModuleIdentifierImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getBuildId ()Ljava/lang/String;
public fun getModuleClassifier ()Ljava/lang/String;
public fun getProjectId ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinMavenModuleIdentifier : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier {
public abstract fun getGroup ()Ljava/lang/String;
public abstract fun getName ()Ljava/lang/String;
}
public final class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinMavenModuleIdentifierImpl : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinMavenModuleIdentifier {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinMavenModuleIdentifierImpl;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinMavenModuleIdentifierImpl;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinMavenModuleIdentifierImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getGroup ()Ljava/lang/String;
public fun getModuleClassifier ()Ljava/lang/String;
public fun getName ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModule : java/io/Serializable {
public abstract fun getFragments ()Ljava/util/Collection;
public abstract fun getModuleIdentifier ()Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier;
@@ -116,19 +40,6 @@ public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinM
public abstract fun getModuleClassifier ()Ljava/lang/String;
}
public final class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleImpl : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModule {
public fun <init> (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier;Ljava/util/Collection;)V
public final fun component1 ()Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier;
public final fun component2 ()Ljava/util/Collection;
public final fun copy (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier;Ljava/util/Collection;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleImpl;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleImpl;Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier;Ljava/util/Collection;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getFragments ()Ljava/util/Collection;
public fun getModuleIdentifier ()Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModel : java/io/Serializable {
public abstract fun getCoreLibrariesVersion ()Ljava/lang/String;
public abstract fun getExplicitApiModeCliOption ()Ljava/lang/String;
@@ -136,53 +47,14 @@ public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinP
public abstract fun getModules ()Ljava/util/List;
}
public final class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModelImpl : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModel {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/util/List;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/io/File;
public final fun component4 ()Ljava/util/List;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/util/List;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModelImpl;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModelImpl;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;Ljava/util/List;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModelImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getCoreLibrariesVersion ()Ljava/lang/String;
public fun getExplicitApiModeCliOption ()Ljava/lang/String;
public fun getKotlinNativeHome ()Ljava/io/File;
public fun getModules ()Ljava/util/List;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectory : java/io/Serializable {
public abstract fun getFile ()Ljava/io/File;
}
public final class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectoryImpl : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectory {
public fun <init> (Ljava/io/File;)V
public final fun component1 ()Ljava/io/File;
public final fun copy (Ljava/io/File;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectoryImpl;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectoryImpl;Ljava/io/File;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectoryImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getFile ()Ljava/io/File;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectory : java/io/Serializable {
public abstract fun getFile ()Ljava/io/File;
}
public final class org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectoryImpl : org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectory {
public fun <init> (Ljava/io/File;)V
public final fun component1 ()Ljava/io/File;
public final fun copy (Ljava/io/File;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectoryImpl;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectoryImpl;Ljava/io/File;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectoryImpl;
public fun equals (Ljava/lang/Object;)Z
public fun getFile ()Ljava/io/File;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface annotation class org/jetbrains/kotlin/gradle/kpm/idea/KotlinGradlePluginApi : java/lang/annotation/Annotation {
public abstract interface annotation class org/jetbrains/kotlin/gradle/kpm/idea/InternalKotlinGradlePluginApi : java/lang/annotation/Annotation {
}
@@ -34,14 +34,18 @@ class RuntimePublicAPITest {
}
@Test fun kotlinGradlePluginIdea() {
snapshotAPIAndCompare("../kotlin-gradle-plugin-idea/build/libs", "kotlin-gradle-plugin-idea(?!-[-a-z]+)")
snapshotAPIAndCompare(
"../kotlin-gradle-plugin-idea/build/libs", "kotlin-gradle-plugin-idea(?!-[-a-z]+)",
nonPublicAnnotations = listOf("org/jetbrains/kotlin/gradle/kpm/idea/InternalKotlinGradlePluginApi")
)
}
private fun snapshotAPIAndCompare(
basePath: String,
jarPattern: String,
publicPackages: List<String> = emptyList(),
nonPublicPackages: List<String> = emptyList()
nonPublicPackages: List<String> = emptyList(),
nonPublicAnnotations: List<String> = emptyList()
) {
val base = File(basePath).absoluteFile.normalize()
val jarFile = getJarPath(base, jarPattern, System.getProperty("kotlinVersion"))
@@ -50,7 +54,9 @@ class RuntimePublicAPITest {
val publicPackageFilter = { className: String -> publicPackagePrefixes.none { className.startsWith(it) } }
println("Reading binary API from $jarFile")
val api = JarFile(jarFile).loadApiFromJvmClasses(publicPackageFilter).filterOutNonPublic(nonPublicPackages)
val api = JarFile(jarFile).loadApiFromJvmClasses(publicPackageFilter)
.filterOutNonPublic(nonPublicPackages)
.filterOutAnnotated(nonPublicAnnotations.toSet())
val target = File("reference-public-api")
.resolve(testName.methodName.replaceCamelCaseWithDashedLowerCase() + ".txt")
@@ -72,3 +78,26 @@ class RuntimePublicAPITest {
}
/*
Copied from `binary-compatibility-validator
Can be removed after:
https://github.com/Kotlin/binary-compatibility-validator/pull/75
*/
private fun List<ClassBinarySignature>.filterOutAnnotated(targetAnnotations: Set<String>): List<ClassBinarySignature> {
if (targetAnnotations.isEmpty()) return this
return filter {
it.annotations.all { ann -> !targetAnnotations.any { ann.refersToName(it) } }
}.map {
ClassBinarySignature(
it.name,
it.superName,
it.outerName,
it.supertypes,
it.memberSignatures.filter { it.annotations.all { ann -> !targetAnnotations.any { ann.refersToName(it) } } },
it.access,
it.isEffectivelyPublic,
it.isNotUsedWhenEmpty,
it.annotations
)
}
}
@@ -6,19 +6,12 @@ as well as in the IDE import (GradleProject).
## Binary Compatibility:
Binary compatibility can be tested by
`./gradlew :tools:binary-compatibility-validator:clean :tools:binary-compatibility-validator:test`
Binary incompatible changes have to go through a proper deprecation cycle after releases
### Unstable APIs / KotlinGradlePluginApi
### Unstable APIs / InternalKotlinGradlePluginApi
Some APIs are marked with 'KotlinGradlePluginApi' which means, that those are not kept binary compatible and are considered 'unstable' from
the IDEA perspective. Typically constructors for models are marked like this
Non Stable by default:
- data class componentX methods
Kept Stable
- data class .copy methods
Some APIs are marked with 'InternalKotlinGradlePluginApi' which means, that those are not kept binary compatible and are considered 'unstable' from
the IDEA perspective.
@@ -16,7 +16,8 @@ interface IdeaKotlinFragment : Serializable {
val resourceDirectories: Collection<IdeaKotlinResourceDirectory>
}
data class IdeaKotlinFragmentImpl @KotlinGradlePluginApi constructor(
@InternalKotlinGradlePluginApi
data class IdeaKotlinFragmentImpl(
override val name: String,
override val languageSettings: IdeaKotlinLanguageSettings?,
override val dependencies: Collection<IdeaKotlinFragmentDependency>,
@@ -24,5 +25,3 @@ data class IdeaKotlinFragmentImpl @KotlinGradlePluginApi constructor(
override val sourceDirectories: Collection<IdeaKotlinSourceDirectory>,
override val resourceDirectories: Collection<IdeaKotlinResourceDirectory>
) : IdeaKotlinFragment
@@ -19,7 +19,8 @@ interface IdeaKotlinLanguageSettings : Serializable {
val freeCompilerArgs: Collection<String>
}
data class IdeaKotlinLanguageSettingsImpl @KotlinGradlePluginApi constructor(
@InternalKotlinGradlePluginApi
data class IdeaKotlinLanguageSettingsImpl(
override val languageVersion: String?,
override val apiVersion: String?,
override val isProgressiveMode: Boolean,
@@ -12,7 +12,8 @@ interface IdeaKotlinModule : Serializable {
val fragments: Collection<IdeaKotlinFragment>
}
data class IdeaKotlinModuleImpl @KotlinGradlePluginApi constructor(
@InternalKotlinGradlePluginApi
data class IdeaKotlinModuleImpl(
override val moduleIdentifier: IdeaKotlinModuleIdentifier,
override val fragments: Collection<IdeaKotlinFragment>
) : IdeaKotlinModule
@@ -21,13 +21,15 @@ interface IdeaKotlinMavenModuleIdentifier : IdeaKotlinModuleIdentifier {
val name: String
}
data class IdeaKotlinLocalModuleIdentifierImpl @KotlinGradlePluginApi constructor(
@InternalKotlinGradlePluginApi
data class IdeaKotlinLocalModuleIdentifierImpl(
override val moduleClassifier: String?,
override val buildId: String,
override val projectId: String
) : IdeaKotlinLocalModuleIdentifier
data class IdeaKotlinMavenModuleIdentifierImpl @KotlinGradlePluginApi constructor(
@InternalKotlinGradlePluginApi
data class IdeaKotlinMavenModuleIdentifierImpl(
override val moduleClassifier: String?,
override val group: String,
override val name: String
@@ -15,7 +15,8 @@ interface IdeaKotlinProjectModel : Serializable {
val modules: List<IdeaKotlinModule>
}
data class IdeaKotlinProjectModelImpl @KotlinGradlePluginApi constructor(
@InternalKotlinGradlePluginApi
data class IdeaKotlinProjectModelImpl(
override val coreLibrariesVersion: String,
override val explicitApiModeCliOption: String?,
override val kotlinNativeHome: File,
@@ -12,6 +12,7 @@ interface IdeaKotlinResourceDirectory : Serializable {
val file: File
}
data class IdeaKotlinResourceDirectoryImpl @KotlinGradlePluginApi constructor(
@InternalKotlinGradlePluginApi
data class IdeaKotlinResourceDirectoryImpl(
override val file: File
) : IdeaKotlinResourceDirectory
@@ -12,6 +12,7 @@ interface IdeaKotlinSourceDirectory : Serializable {
val file: File
}
data class IdeaKotlinSourceDirectoryImpl @KotlinGradlePluginApi constructor(
@InternalKotlinGradlePluginApi
data class IdeaKotlinSourceDirectoryImpl(
override val file: File,
) : IdeaKotlinSourceDirectory
@@ -9,4 +9,4 @@ package org.jetbrains.kotlin.gradle.kpm.idea
level = RequiresOptIn.Level.ERROR,
message = "This API can only be used by the Kotlin Gradle Plugin and is not kept stable for access inside the IDE process"
)
annotation class KotlinGradlePluginApi
annotation class InternalKotlinGradlePluginApi
@@ -30,7 +30,7 @@ kotlin.sourceSets.all {
languageSettings.optIn("kotlin.RequiresOptIn")
languageSettings.optIn("org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalVariantApi")
languageSettings.optIn("org.jetbrains.kotlin.gradle.plugin.mpp.external.AdvancedExternalVariantApi")
languageSettings.optIn("org.jetbrains.kotlin.gradle.kpm.idea.KotlinGradlePluginApi")
languageSettings.optIn("org.jetbrains.kotlin.gradle.kpm.idea.InternalKotlinGradlePluginApi")
}
dependencies {