diff --git a/compiler/testData/codegen/box/jvmPackageName/metadataField.kt b/compiler/testData/codegen/box/jvmPackageName/metadataField.kt index c1641af6152..1bab482ee7c 100644 --- a/compiler/testData/codegen/box/jvmPackageName/metadataField.kt +++ b/compiler/testData/codegen/box/jvmPackageName/metadataField.kt @@ -12,10 +12,8 @@ fun f() {} // FILE: bar.kt -@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") - fun getPackageName(classFqName: String): String = - Class.forName(classFqName).getAnnotation(Metadata::class.java).pn + Class.forName(classFqName).getAnnotation(Metadata::class.java).packageName fun box(): String { val bar = getPackageName("BarKt") diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/explicitMetadata.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/explicitMetadata.kt index 8da9f48b2f2..f810078dfd2 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/explicitMetadata.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/explicitMetadata.kt @@ -1,9 +1,9 @@ @Metadata class A -@Metadata(xs = "_") +@Metadata(extraString = "_") annotation class B(val m: Metadata) -@Metadata(xi = 0) +@Metadata(extraInt = 0) @B(Metadata()) fun f() {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/explicitMetadata.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/explicitMetadata.txt index 140b65c65a0..92cf4d6037e 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/explicitMetadata.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/explicitMetadata.txt @@ -1,6 +1,6 @@ package -@kotlin.Metadata(xi = 0) @B(m = kotlin.Metadata) public fun f(): kotlin.Unit +@kotlin.Metadata(extraInt = 0) @B(m = kotlin.Metadata) public fun f(): kotlin.Unit @kotlin.Metadata public final class A { public constructor A() @@ -9,7 +9,7 @@ package public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -@kotlin.Metadata(xs = "_") public final annotation class B : kotlin.Annotation { +@kotlin.Metadata(extraString = "_") public final annotation class B : kotlin.Annotation { public constructor B(/*0*/ m: kotlin.Metadata) public final val m: kotlin.Metadata public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean diff --git a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmProtoBufUtil.kt b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmProtoBufUtil.kt index 6f0ba580817..df7bffff15a 100644 --- a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmProtoBufUtil.kt +++ b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmProtoBufUtil.kt @@ -50,7 +50,7 @@ object JvmProtoBufUtil { JvmNameResolver(JvmProtoBuf.StringTableTypes.parseDelimitedFrom(this, EXTENSION_REGISTRY), strings) /** - * Serializes [message] and [stringTable] into a string array which must be further written to [Metadata.d1] + * Serializes [message] and [stringTable] into a string array which must be further written to [Metadata.data1] */ @JvmStatic fun writeData(message: MessageLite, stringTable: JvmStringTable): Array = diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/reflectLambda.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/reflectLambda.kt index 06519167ed5..9020e2a9afe 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/reflectLambda.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/reflectLambda.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") - package kotlin.reflect.jvm import org.jetbrains.kotlin.load.java.JvmAnnotationNames @@ -35,10 +33,12 @@ import kotlin.reflect.jvm.internal.deserializeToDescriptor */ fun Function.reflect(): KFunction? { val annotation = javaClass.getAnnotation(Metadata::class.java) ?: return null - val data = annotation.d1.takeUnless(Array::isEmpty) ?: return null - val (nameResolver, proto) = JvmProtoBufUtil.readFunctionDataFrom(data, annotation.d2) - val metadataVersion = - JvmMetadataVersion(annotation.mv, (annotation.xi and JvmAnnotationNames.METADATA_STRICT_VERSION_SEMANTICS_FLAG) != 0) + val data = annotation.data1.takeUnless(Array::isEmpty) ?: return null + val (nameResolver, proto) = JvmProtoBufUtil.readFunctionDataFrom(data, annotation.data2) + val metadataVersion = JvmMetadataVersion( + annotation.metadataVersion, + (annotation.extraInt and JvmAnnotationNames.METADATA_STRICT_VERSION_SEMANTICS_FLAG) != 0 + ) val descriptor = deserializeToDescriptor( javaClass, proto, nameResolver, TypeTable(proto.typeTable), metadataVersion, MemberDeserializer::loadFunction diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/KotlinClassHeader.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/KotlinClassHeader.kt index acdb9fa8a39..d43ea3cc402 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/KotlinClassHeader.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/KotlinClassHeader.kt @@ -10,12 +10,7 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion /** * A mirror to the [Metadata] annotation on a JVM class file, containing the metadata of Kotlin declarations declared in the class file. - * Properties of this class correspond to the properties of [Metadata], but the names are not shortened because there's no restriction - * on the bytecode size here. - * - * Note that [Metadata] is not yet public (see https://youtrack.jetbrains.com/issue/KT-23602). In order to create an instance of - * [KotlinClassHeader] from the [Metadata] annotation instance obtained reflectively, one could use Java code to workaround - * the internal visibility error. + * Properties of this class correspond 1:1 to the properties of [Metadata]. * * @param kind see [kind] * @param metadataVersion see [metadataVersion] @@ -39,7 +34,7 @@ class KotlinClassHeader( /** * A kind of the metadata this header encodes. * - * @see Metadata.k + * @see Metadata.kind * @see CLASS_KIND * @see FILE_FACADE_KIND * @see SYNTHETIC_CLASS_KIND @@ -51,7 +46,7 @@ class KotlinClassHeader( /** * The version of the metadata provided in other properties of this header. * - * @see Metadata.mv + * @see Metadata.metadataVersion * @see COMPATIBLE_METADATA_VERSION */ val metadataVersion: IntArray = metadataVersion ?: intArrayOf() @@ -59,7 +54,7 @@ class KotlinClassHeader( /** * The version of the bytecode interface (naming conventions, signatures) of the corresponding class file. * - * @see Metadata.bv + * @see Metadata.bytecodeVersion * @see COMPATIBLE_BYTECODE_VERSION */ val bytecodeVersion: IntArray = bytecodeVersion ?: intArrayOf() @@ -67,35 +62,35 @@ class KotlinClassHeader( /** * The first array of strings used to encode the metadata. * - * @see Metadata.d1 + * @see Metadata.data1 */ val data1: Array = data1 ?: emptyArray() /** * The second array of strings used to encode the metadata. * - * @see Metadata.d2 + * @see Metadata.data2 */ val data2: Array = data2 ?: emptyArray() /** * An extra string field for the metadata. * - * @see Metadata.xs + * @see Metadata.extraString */ val extraString: String = extraString ?: "" /** * Fully qualified name of the Kotlin package of the corresponding class, in case [JvmPackageName] was used. * - * @see Metadata.pn + * @see Metadata.packageName */ val packageName: String = packageName ?: "" /** * An extra int field for the metadata. * - * @see Metadata.xi + * @see Metadata.extraInt */ val extraInt: Int = extraInt ?: 0 diff --git a/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt b/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt index d9c2868bfe5..c5364ebcdd6 100644 --- a/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt +++ b/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt @@ -15,10 +15,9 @@ import java.net.URLClassLoader import kotlin.reflect.full.primaryConstructor class MetadataSmokeTest { - @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") private fun Class<*>.readMetadata(): KotlinClassHeader { return getAnnotation(Metadata::class.java).run { - KotlinClassHeader(k, mv, bv, d1, d2, xs, pn, xi) + KotlinClassHeader(kind, metadataVersion, bytecodeVersion, data1, data2, extraString, packageName, extraInt) } } diff --git a/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt b/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt index 50562e184d8..a2052040132 100644 --- a/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt +++ b/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt @@ -7,7 +7,7 @@ package kotlin /** * This annotation is present on any class file produced by the Kotlin compiler and is read by the compiler and reflection. - * Parameters have very short names on purpose: these names appear in the generated class files, and we'd like to reduce their size. + * Parameters have very short JVM names on purpose: these names appear in all generated class files, and we'd like to reduce their size. */ @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.CLASS) @@ -24,35 +24,42 @@ public annotation class Metadata( * * The class file with a kind not listed here is treated as a non-Kotlin file. */ - val k: Int = 1, + @get:JvmName("k") + val kind: Int = 1, /** * The version of the metadata provided in the arguments of this annotation. */ - val mv: IntArray = [], + @get:JvmName("mv") + val metadataVersion: IntArray = [], /** * The version of the bytecode interface (naming conventions, signatures) of the class file annotated with this annotation. */ - val bv: IntArray = [], + @get:JvmName("bv") + val bytecodeVersion: IntArray = [], /** * Metadata in a custom format. The format may be different (or even absent) for different kinds. */ - val d1: Array = [], + @get:JvmName("d1") + val data1: Array = [], /** * An addition to [d1]: array of strings which occur in metadata, written in plain text so that strings already present * in the constant pool are reused. These strings may be then indexed in the metadata by an integer index in this array. */ - val d2: Array = [], + @get:JvmName("d2") + val data2: Array = [], /** * An extra string. For a multi-file part class, internal name of the facade class. */ - val xs: String = "", + @get:JvmName("xs") + val extraString: String = "", /** * Fully qualified name of the package this class is located in, from Kotlin's point of view, or empty string if this name * does not differ from the JVM's package FQ name. These names can be different in case the [JvmPackageName] annotation is used. * Note that this information is also stored in the corresponding module's `.kotlin_module` file. */ @SinceKotlin("1.2") - val pn: String = "", + @get:JvmName("pn") + val packageName: String = "", /** * An extra int. Bits of this number represent the following flags: * @@ -63,5 +70,6 @@ public annotation class Metadata( * the major.minor version of this metadata ([mv]). */ @SinceKotlin("1.1") - val xi: Int = 0 + @get:JvmName("xi") + val extraInt: Int = 0 ) diff --git a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/readKotlinClassHeader.kt b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/readKotlinClassHeader.kt index f5ec236115e..653c01dee4e 100644 --- a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/readKotlinClassHeader.kt +++ b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/readKotlinClassHeader.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.kotlinp import kotlinx.metadata.jvm.KotlinClassHeader -import org.objectweb.asm.AnnotationVisitor -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.Opcodes +import org.objectweb.asm.* import java.io.File import java.io.FileInputStream @@ -17,9 +14,10 @@ internal fun File.readKotlinClassHeader(): KotlinClassHeader? { var header: KotlinClassHeader? = null try { + val metadataDesc = Type.getDescriptor(Metadata::class.java) ClassReader(FileInputStream(this)).accept(object : ClassVisitor(Opcodes.ASM4) { override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? = - if (desc == "Lkotlin/Metadata;") readMetadataVisitor { header = it } + if (desc == metadataDesc) readMetadataVisitor { header = it } else null }, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES) } catch (e: Exception) { @@ -29,7 +27,6 @@ internal fun File.readKotlinClassHeader(): KotlinClassHeader? { return header } -@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") private fun readMetadataVisitor(output: (KotlinClassHeader) -> Unit): AnnotationVisitor = object : AnnotationVisitor(Opcodes.ASM4) { var kind: Int? = null @@ -43,19 +40,19 @@ private fun readMetadataVisitor(output: (KotlinClassHeader) -> Unit): Annotation override fun visit(name: String?, value: Any?) { when (name) { - Metadata::k.name -> kind = value as? Int - Metadata::mv.name -> metadataVersion = value as? IntArray - Metadata::bv.name -> bytecodeVersion = value as? IntArray - Metadata::xs.name -> extraString = value as? String - Metadata::xi.name -> extraInt = value as? Int - Metadata::pn.name -> packageName = value as? String + "k" -> kind = value as? Int + "mv" -> metadataVersion = value as? IntArray + "bv" -> bytecodeVersion = value as? IntArray + "xs" -> extraString = value as? String + "xi" -> extraInt = value as? Int + "pn" -> packageName = value as? String } } override fun visitArray(name: String?): AnnotationVisitor? = when (name) { - Metadata::d1.name -> stringArrayVisitor { data1 = it } - Metadata::d2.name -> stringArrayVisitor { data2 = it } + "d1" -> stringArrayVisitor { data1 = it } + "d2" -> stringArrayVisitor { data2 = it } else -> null }