From 81b89a86f1c29fff1b41ff59c4a11fa56ad6ae48 Mon Sep 17 00:00:00 2001 From: Tony Robalik Date: Wed, 4 Dec 2024 13:40:13 -0800 Subject: [PATCH] fix: use stable kotlin-metadata 2.0.21. Can't use latest, because I'm still compiling against Kotlin 1.9. --- build.gradle.kts | 8 +- gradle/libs.versions.toml | 4 +- .../autonomousapps/internal/JarExploder.kt | 2 +- .../kotlin/com/autonomousapps/internal/asm.kt | 2 +- .../internal/kotlin/PublicApiDump.kt | 171 +++++++++--------- .../internal/kotlin/asmUtils.kt | 11 +- .../kotlin/kotlinMetadataVisibilities.kt | 4 +- .../internal/kotlin/kotlinVisibilities.kt | 4 +- .../autonomousapps/model/internal/KtFile.kt | 4 +- .../tasks/FindKotlinMagicTask.kt | 4 +- 10 files changed, 111 insertions(+), 103 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 52093cc30..7d2dcf5bc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -119,12 +119,8 @@ dependencies { implementation(libs.moshi.kotlin) implementation(libs.moshix.sealed.reflect) implementation(libs.okio) - - implementation(libs.kotlinx.metadata.jvm) { - because("For Kotlin ABI analysis") - // Depends on Kotlin 1.6, which I don't want. We also don't want to set a strict constraint, because - // I think that is exposed to consumers, and which would invariably break their projects. In the end, - // this is merely aesthetic. + implementation(libs.kotlin.metadata.jvm) { + // Depends on Kotlin 2.x, which I don't want. This is fragile, though. Will eventually have to update to Kotlin 2. isTransitive = false } implementation(libs.caffeine) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5870b1763..6d73ba14d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,9 @@ grammar = "0.3" guava = "33.3.1-jre" java = "11" junit = "5.10.2" +# TODO: sync these two: kotlin = "1.9.25" +kotlin-metadata = "2.0.21" # Cannot be called kotlin-editor as it causes `libs.versions.kotlin.get()` to fail kotlineditor-core = "0.10" @@ -56,7 +58,7 @@ kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version. kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } kotlin-stdlib-core = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" } -kotlinx-metadata-jvm = { module = "org.jetbrains.kotlinx:kotlinx-metadata-jvm", version.ref = "kotlinx-metadata" } +kotlin-metadata-jvm = { module = "org.jetbrains.kotlin:kotlin-metadata-jvm", version.ref = "kotlin-metadata" } moshi-core = { module = "com.squareup.moshi:moshi", version.ref = "moshi" } moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" } diff --git a/src/main/kotlin/com/autonomousapps/internal/JarExploder.kt b/src/main/kotlin/com/autonomousapps/internal/JarExploder.kt index 815943d9b..028b02111 100644 --- a/src/main/kotlin/com/autonomousapps/internal/JarExploder.kt +++ b/src/main/kotlin/com/autonomousapps/internal/JarExploder.kt @@ -9,8 +9,8 @@ import com.autonomousapps.model.internal.KtFile import com.autonomousapps.model.internal.PhysicalArtifact import com.autonomousapps.model.internal.PhysicalArtifact.Mode import com.autonomousapps.model.internal.intermediates.AndroidLinterDependency -import com.autonomousapps.model.internal.intermediates.producer.ExplodedJar import com.autonomousapps.model.internal.intermediates.ExplodingJar +import com.autonomousapps.model.internal.intermediates.producer.ExplodedJar import com.autonomousapps.services.InMemoryCache import com.autonomousapps.tasks.ExplodeJarTask import java.util.zip.ZipFile diff --git a/src/main/kotlin/com/autonomousapps/internal/asm.kt b/src/main/kotlin/com/autonomousapps/internal/asm.kt index 54445bb97..8c51e08c5 100644 --- a/src/main/kotlin/com/autonomousapps/internal/asm.kt +++ b/src/main/kotlin/com/autonomousapps/internal/asm.kt @@ -10,7 +10,7 @@ import com.autonomousapps.internal.utils.METHOD_DESCRIPTOR_REGEX import com.autonomousapps.internal.utils.efficient import com.autonomousapps.internal.utils.genericTypes import com.autonomousapps.model.internal.intermediates.consumer.MemberAccess -import kotlinx.metadata.jvm.Metadata +import kotlin.metadata.jvm.Metadata import org.gradle.api.logging.Logger import java.util.SortedSet import java.util.concurrent.atomic.AtomicReference diff --git a/src/main/kotlin/com/autonomousapps/internal/kotlin/PublicApiDump.kt b/src/main/kotlin/com/autonomousapps/internal/kotlin/PublicApiDump.kt index 150832d83..4178db5b3 100644 --- a/src/main/kotlin/com/autonomousapps/internal/kotlin/PublicApiDump.kt +++ b/src/main/kotlin/com/autonomousapps/internal/kotlin/PublicApiDump.kt @@ -15,12 +15,12 @@ import com.autonomousapps.internal.utils.annotationTypes import com.autonomousapps.internal.utils.appendReproducibleNewLine import com.autonomousapps.internal.utils.filterNotToSet import com.autonomousapps.internal.utils.genericTypes -import kotlinx.metadata.jvm.JvmFieldSignature -import kotlinx.metadata.jvm.JvmMethodSignature import java.io.File import java.io.InputStream import java.io.PrintStream import java.util.jar.JarFile +import kotlin.metadata.jvm.JvmFieldSignature +import kotlin.metadata.jvm.JvmMethodSignature fun main(args: Array) { val src = args[0] @@ -36,10 +36,16 @@ internal fun JarFile.classEntries() = Sequence { entries().iterator() }.filter { internal fun getBinaryAPI(jar: JarFile, visibilityFilter: (String) -> Boolean = { true }): List = getBinaryAPI(jar.classEntries().map { entry -> jar.getInputStream(entry) }, visibilityFilter) -internal fun getBinaryAPI(classes: Set, visibilityFilter: (String) -> Boolean = { true }): List = +internal fun getBinaryAPI( + classes: Set, + visibilityFilter: (String) -> Boolean = { true } +): List = getBinaryAPI(classes.asSequence().map { it.inputStream() }, visibilityFilter) -internal fun getBinaryAPI(classStreams: Sequence, visibilityFilter: (String) -> Boolean = { true }): List { +internal fun getBinaryAPI( + classStreams: Sequence, + visibilityFilter: (String) -> Boolean = { true } +): List { val classNodes = classStreams.map { it.use { stream -> val classNode = ClassNode() @@ -54,82 +60,82 @@ internal fun getBinaryAPI(classStreams: Sequence, visibilityFilter: val visibilityMapNew = classNodes.readKotlinVisibilities().filterKeys(visibilityFilter) return classNodes - .filter { it != moduleInfo } - .map { clazz -> - with(clazz) { - val metadata = kotlinMetadata - val mVisibility = visibilityMapNew[name] - val classAccess = AccessFlags(effectiveAccess and Opcodes.ACC_STATIC.inv()) - - val supertypes = listOf(superName) - "java/lang/Object" + interfaces.sorted() - - val memberSignatures = ( - fields.map { field -> - with(field) { - FieldBinarySignature( - jvmMember = JvmFieldSignature(name, desc), - genericTypes = signature?.genericTypes().orEmpty(), - annotations = visibleAnnotations.annotationTypes(), - invisibleAnnotations = invisibleAnnotations.annotationTypes(), - isPublishedApi = isPublishedApi(), - access = AccessFlags(access) - ) - } - } + methods.map { method -> - with(method) { - val parameterAnnotations = visibleParameterAnnotations.orEmpty() - .filterNotNull() - .flatMap { annos -> - annos - .filterNotNull() - .mapNotNull { it.desc } - } - - val typeAnnotations = visibleTypeAnnotations.orEmpty() + .filter { it != moduleInfo } + .map { clazz -> + with(clazz) { + val metadata = kotlinMetadata + val mVisibility = visibilityMapNew[name] + val classAccess = AccessFlags(effectiveAccess and Opcodes.ACC_STATIC.inv()) + + val supertypes = listOf(superName) - "java/lang/Object" + interfaces.sorted() + + val memberSignatures = ( + fields.map { field -> + with(field) { + FieldBinarySignature( + jvmMember = JvmFieldSignature(name, desc), + genericTypes = signature?.genericTypes().orEmpty(), + annotations = visibleAnnotations.annotationTypes(), + invisibleAnnotations = invisibleAnnotations.annotationTypes(), + isPublishedApi = isPublishedApi(), + access = AccessFlags(access) + ) + } + } + methods.map { method -> + with(method) { + val parameterAnnotations = visibleParameterAnnotations.orEmpty() + .filterNotNull() + .flatMap { annos -> + annos .filterNotNull() - .map { it.desc } - - MethodBinarySignature( - jvmMember = JvmMethodSignature(name, desc), - genericTypes = signature?.genericTypes().orEmpty(), - annotations = visibleAnnotations.annotationTypes(), - invisibleAnnotations = invisibleAnnotations.annotationTypes(), - parameterAnnotations = parameterAnnotations, - typeAnnotations = typeAnnotations, - isPublishedApi = isPublishedApi(), - access = AccessFlags(access), - // nb: MethodNode.exceptions is NOT expressed as a type descriptor, rather as a path. - // e.g., not `Lcom/example/Foo;`, but just `com/example/Foo` - exceptions = exceptions - ) + .mapNotNull { it.desc } } - } - ).filter { - it.isEffectivelyPublic(classAccess, exportedPackages?.contains(clazz.packageName())?:true, mVisibility) + + val typeAnnotations = visibleTypeAnnotations.orEmpty() + .filterNotNull() + .map { it.desc } + + MethodBinarySignature( + jvmMember = JvmMethodSignature(name, desc), + genericTypes = signature?.genericTypes().orEmpty(), + annotations = visibleAnnotations.annotationTypes(), + invisibleAnnotations = invisibleAnnotations.annotationTypes(), + parameterAnnotations = parameterAnnotations, + typeAnnotations = typeAnnotations, + isPublishedApi = isPublishedApi(), + access = AccessFlags(access), + // nb: MethodNode.exceptions is NOT expressed as a type descriptor, rather as a path. + // e.g., not `Lcom/example/Foo;`, but just `com/example/Foo` + exceptions = exceptions + ) } + } + ).filter { + it.isEffectivelyPublic(classAccess, exportedPackages?.contains(clazz.packageName()) ?: true, mVisibility) + } - val genericTypes = signature?.genericTypes().orEmpty() - // Strip out JDK classes - .filterNotToSet { it.startsWith("Ljava/lang") } - - ClassBinarySignature( - name = name, - superName = superName, - outerName = outerClassName, - supertypes = supertypes, - genericTypes = genericTypes, - memberSignatures = memberSignatures, - access = classAccess, - isEffectivelyPublic = isEffectivelyPublic(mVisibility), - isNotUsedWhenEmpty = metadata.isFileOrMultipartFacade() || isDefaultImpls(metadata), - annotations = visibleAnnotations.annotationTypes(), - invisibleAnnotations = invisibleAnnotations.annotationTypes(), - sourceFile = clazz.sourceFile - ) - } + val genericTypes = signature?.genericTypes().orEmpty() + // Strip out JDK classes + .filterNotToSet { it.startsWith("Ljava/lang") } + + ClassBinarySignature( + name = name, + superName = superName, + outerName = outerClassName, + supertypes = supertypes, + genericTypes = genericTypes, + memberSignatures = memberSignatures, + access = classAccess, + isEffectivelyPublic = isEffectivelyPublic(mVisibility), + isNotUsedWhenEmpty = metadata.isFileOrMultipartFacade() || isDefaultImpls(metadata), + annotations = visibleAnnotations.annotationTypes(), + invisibleAnnotations = invisibleAnnotations.annotationTypes(), + sourceFile = clazz.sourceFile + ) } - .asIterable() - .sortedBy { it.name } + } + .asIterable() + .sortedBy { it.name } } internal fun List.filterOutNonPublic( @@ -148,11 +154,11 @@ internal fun List.filterOutNonPublic( } fun ClassBinarySignature.isPublicAndAccessible(): Boolean = - isEffectivelyPublic && - (outerName == null || classByName[outerName]?.let { outerClass -> - !(this.access.isProtected && outerClass.access.isFinal) - && outerClass.isPublicAndAccessible() - } ?: true) + isEffectivelyPublic && + (outerName == null || classByName[outerName]?.let { outerClass -> + !(this.access.isProtected && outerClass.access.isFinal) + && outerClass.isPublicAndAccessible() + } ?: true) fun supertypes(superName: String) = generateSequence({ classByName[superName] }, { classByName[it.superName] }) @@ -165,7 +171,10 @@ internal fun List.filterOutNonPublic( val inheritedStaticSignatures = nonPublicSupertypes.flatMap { it.memberSignatures.filter { it.access.isStatic } } // not covered the case when there is public superclass after chain of private superclasses - return this.copy(memberSignatures = memberSignatures + inheritedStaticSignatures, supertypes = supertypes - superName) + return this.copy( + memberSignatures = memberSignatures + inheritedStaticSignatures, + supertypes = supertypes - superName + ) } return filter { diff --git a/src/main/kotlin/com/autonomousapps/internal/kotlin/asmUtils.kt b/src/main/kotlin/com/autonomousapps/internal/kotlin/asmUtils.kt index 7b5e3d5a5..bfaf60150 100644 --- a/src/main/kotlin/com/autonomousapps/internal/kotlin/asmUtils.kt +++ b/src/main/kotlin/com/autonomousapps/internal/kotlin/asmUtils.kt @@ -11,10 +11,10 @@ import com.autonomousapps.internal.ClassNames.canonicalize import com.autonomousapps.internal.asm.Opcodes import com.autonomousapps.internal.asm.tree.* import com.autonomousapps.internal.utils.appendReproducibleNewLine -import kotlinx.metadata.jvm.JvmFieldSignature -import kotlinx.metadata.jvm.JvmMemberSignature -import kotlinx.metadata.jvm.JvmMethodSignature -import kotlinx.metadata.jvm.KotlinClassMetadata +import kotlin.metadata.jvm.JvmFieldSignature +import kotlin.metadata.jvm.JvmMemberSignature +import kotlin.metadata.jvm.JvmMethodSignature +import kotlin.metadata.jvm.KotlinClassMetadata internal val ACCESS_NAMES = mapOf( Opcodes.ACC_PUBLIC to "public", @@ -113,7 +113,8 @@ internal data class MethodBinarySignature( "\$annotations" )) - private fun isDummyDefaultConstructor() = access.isSynthetic && name == "" && desc == "(Lkotlin/jvm/internal/DefaultConstructorMarker;)V" + private fun isDummyDefaultConstructor() = + access.isSynthetic && name == "" && desc == "(Lkotlin/jvm/internal/DefaultConstructorMarker;)V" /** * Calculates the signature of this method without default parameters diff --git a/src/main/kotlin/com/autonomousapps/internal/kotlin/kotlinMetadataVisibilities.kt b/src/main/kotlin/com/autonomousapps/internal/kotlin/kotlinMetadataVisibilities.kt index deb66d8f9..ba58596a0 100644 --- a/src/main/kotlin/com/autonomousapps/internal/kotlin/kotlinMetadataVisibilities.kt +++ b/src/main/kotlin/com/autonomousapps/internal/kotlin/kotlinMetadataVisibilities.kt @@ -8,8 +8,8 @@ package com.autonomousapps.internal.kotlin import com.autonomousapps.internal.asm.tree.ClassNode -import kotlinx.metadata.* -import kotlinx.metadata.jvm.* +import kotlin.metadata.* +import kotlin.metadata.jvm.* internal val ClassNode.kotlinMetadata: KotlinClassMetadata? get() { diff --git a/src/main/kotlin/com/autonomousapps/internal/kotlin/kotlinVisibilities.kt b/src/main/kotlin/com/autonomousapps/internal/kotlin/kotlinVisibilities.kt index d6de7fbac..57d594595 100644 --- a/src/main/kotlin/com/autonomousapps/internal/kotlin/kotlinVisibilities.kt +++ b/src/main/kotlin/com/autonomousapps/internal/kotlin/kotlinVisibilities.kt @@ -7,8 +7,8 @@ package com.autonomousapps.internal.kotlin -import kotlinx.metadata.Visibility -import kotlinx.metadata.jvm.JvmMemberSignature +import kotlin.metadata.Visibility +import kotlin.metadata.jvm.JvmMemberSignature internal class ClassVisibility( val name: String, diff --git a/src/main/kotlin/com/autonomousapps/model/internal/KtFile.kt b/src/main/kotlin/com/autonomousapps/model/internal/KtFile.kt index 900f17e72..6e0afe0dc 100644 --- a/src/main/kotlin/com/autonomousapps/model/internal/KtFile.kt +++ b/src/main/kotlin/com/autonomousapps/model/internal/KtFile.kt @@ -3,11 +3,11 @@ package com.autonomousapps.model.internal import com.squareup.moshi.JsonClass -import kotlinx.metadata.jvm.KotlinModuleMetadata -import kotlinx.metadata.jvm.UnstableMetadataApi import java.io.File import java.io.InputStream import java.util.zip.ZipFile +import kotlin.metadata.jvm.KotlinModuleMetadata +import kotlin.metadata.jvm.UnstableMetadataApi /** * A "KT File" is one that has top-level declarations, and so the class file is something like diff --git a/src/main/kotlin/com/autonomousapps/tasks/FindKotlinMagicTask.kt b/src/main/kotlin/com/autonomousapps/tasks/FindKotlinMagicTask.kt index b5dbd7cd3..4bc088ba8 100644 --- a/src/main/kotlin/com/autonomousapps/tasks/FindKotlinMagicTask.kt +++ b/src/main/kotlin/com/autonomousapps/tasks/FindKotlinMagicTask.kt @@ -15,8 +15,8 @@ import com.autonomousapps.model.internal.TypealiasCapability import com.autonomousapps.model.internal.intermediates.InlineMemberDependency import com.autonomousapps.model.internal.intermediates.TypealiasDependency import com.autonomousapps.services.InMemoryCache -import kotlinx.metadata.* -import kotlinx.metadata.jvm.KotlinClassMetadata +import kotlin.metadata.* +import kotlin.metadata.jvm.KotlinClassMetadata import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.RegularFileProperty