From a680067ac3e6c57e30de91dd879262b443a3ebba Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 7 May 2019 18:49:42 +0200 Subject: [PATCH] Use new kotlinx-metadata API in binary-compatibility-validator --- .../kotlinMetadataVisibilities.kt | 181 +++++------------- 1 file changed, 43 insertions(+), 138 deletions(-) diff --git a/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/kotlinMetadataVisibilities.kt b/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/kotlinMetadataVisibilities.kt index 50e9b9d8a42..c45b16b3654 100644 --- a/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/kotlinMetadataVisibilities.kt +++ b/libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools/kotlinMetadataVisibilities.kt @@ -5,7 +5,10 @@ package org.jetbrains.kotlin.tools -import kotlinx.metadata.* +import kotlinx.metadata.Flag +import kotlinx.metadata.Flags +import kotlinx.metadata.KmDeclarationContainer +import kotlinx.metadata.flagsOf import kotlinx.metadata.jvm.* import org.objectweb.asm.tree.ClassNode @@ -34,149 +37,51 @@ fun KotlinClassMetadata?.isFileOrMultipartFacade() = fun KotlinClassMetadata?.isSyntheticClass() = this is KotlinClassMetadata.SyntheticClass - -private val VISIBILITY_FLAGS_MAP = mapOf( - Flag.IS_INTERNAL to "internal", - Flag.IS_PRIVATE to "private", - Flag.IS_PRIVATE_TO_THIS to "private", - Flag.IS_PROTECTED to "protected", - Flag.IS_PUBLIC to "public", - Flag.IS_LOCAL to "local" -) - -private fun Flags.toVisibility() = VISIBILITY_FLAGS_MAP.entries.firstOrNull { (modifier) -> modifier(this) }?.value - -private fun visitFunction(flags: Flags, name: String, addMember: (MemberVisibility) -> Unit) = - object : KmFunctionVisitor() { - var desc: JvmMemberSignature? = null - - override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor? { - if (type != JvmFunctionExtensionVisitor.TYPE) return null - return object : JvmFunctionExtensionVisitor() { - override fun visit(signature: JvmMethodSignature?) { - desc = signature - } - } - } - - override fun visitEnd() { - desc?.let { jvmDesc -> - addMember(MemberVisibility(jvmDesc, flags)) - } - } - } - -private fun visitConstructor(flags: Flags, addMember: (MemberVisibility) -> Unit) = - object : KmConstructorVisitor() { - var desc: JvmMemberSignature? = null - - override fun visitExtensions(type: KmExtensionType): KmConstructorExtensionVisitor? { - if (type != JvmConstructorExtensionVisitor.TYPE) return null - return object : JvmConstructorExtensionVisitor() { - override fun visit(signature: JvmMethodSignature?) { - desc = signature - } - } - } - - override fun visitEnd() { - desc?.let { signature -> - addMember(MemberVisibility(signature, flags)) - } - } - } - -private fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags, addMember: (MemberVisibility) -> Unit) = - object : KmPropertyVisitor() { - var fieldDesc: JvmMemberSignature? = null - var getterDesc: JvmMemberSignature? = null - var setterDesc: JvmMemberSignature? = null - - override fun visitExtensions(type: KmExtensionType): KmPropertyExtensionVisitor? { - if (type != JvmPropertyExtensionVisitor.TYPE) return null - return object : JvmPropertyExtensionVisitor() { - override fun visit( - jvmFlags: Flags, - fieldSignature: JvmFieldSignature?, - getterSignature: JvmMethodSignature?, - setterSignature: JvmMethodSignature? - ) { - fieldDesc = fieldSignature - getterDesc = getterSignature - setterDesc = setterSignature - } - } - } - - override fun visitEnd() { - getterDesc?.let { addMember(MemberVisibility(it, getterFlags)) } - setterDesc?.let { addMember(MemberVisibility(it, setterFlags)) } - fieldDesc?.let { - val fieldVisibility = when { - Flag.Property.IS_LATEINIT(flags) -> setterFlags - getterDesc == null && setterDesc == null -> flags // JvmField or const case - else -> flagsOf(Flag.IS_PRIVATE) - } - addMember(MemberVisibility(it, fieldVisibility)) - } - } - } - -private fun visitPackage(addMember: (MemberVisibility) -> Unit) = - object : KmPackageVisitor() { - override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor? { - return visitFunction(flags, name, addMember) - } - - override fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags): KmPropertyVisitor? { - return visitProperty(flags, name, getterFlags, setterFlags, addMember) - } - - override fun visitTypeAlias(flags: Flags, name: String): KmTypeAliasVisitor? { - return super.visitTypeAlias(flags, name) - } - } - -private fun visitClass(flags: (Flags) -> Unit, addMember: (MemberVisibility) -> Unit) = - object : KmClassVisitor() { - override fun visit(flags: Flags, name: ClassName) { - flags(flags) - } - - override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor? { - return visitFunction(flags, name, addMember) - } - - override fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags): KmPropertyVisitor? { - return visitProperty(flags, name, getterFlags, setterFlags, addMember) - } - - override fun visitConstructor(flags: Flags): KmConstructorVisitor? { - return visitConstructor(flags, addMember) - } - - override fun visitTypeAlias(flags: Flags, name: String): KmTypeAliasVisitor? { - return super.visitTypeAlias(flags, name) - } - } - fun KotlinClassMetadata.toClassVisibility(classNode: ClassNode): ClassVisibility? { var flags: Flags? = null var _facadeClassName: String? = null val members = mutableListOf() - val addMember: (MemberVisibility) -> Unit = { members.add(it) } - when (this) { - is KotlinClassMetadata.Class -> - this.accept(visitClass({ flags = it }, addMember)) - is KotlinClassMetadata.FileFacade -> - this.accept(visitPackage(addMember)) - is KotlinClassMetadata.MultiFileClassPart -> { - _facadeClassName = this.facadeClassName - this.accept(visitPackage(addMember)) + fun addMember(signature: JvmMemberSignature?, flags: Flags) { + if (signature != null) { + members.add(MemberVisibility(signature, flags)) } - else -> {} } + + val container: KmDeclarationContainer? = when (this) { + is KotlinClassMetadata.Class -> + toKmClass().also { klass -> + flags = klass.flags + + for (constructor in klass.constructors) { + addMember(constructor.signature, constructor.flags) + } + } + is KotlinClassMetadata.FileFacade -> + toKmPackage() + is KotlinClassMetadata.MultiFileClassPart -> + toKmPackage().also { _facadeClassName = this.facadeClassName } + else -> null + } + + if (container != null) { + for (function in container.functions) { + addMember(function.signature, function.flags) + } + + for (property in container.properties) { + addMember(property.getterSignature, property.getterFlags) + addMember(property.setterSignature, property.setterFlags) + + val fieldVisibility = when { + Flag.Property.IS_LATEINIT(property.flags) -> property.setterFlags + property.getterSignature == null && property.setterSignature == null -> property.flags // JvmField or const case + else -> flagsOf(Flag.IS_PRIVATE) + } + addMember(property.fieldSignature, fieldVisibility) + } + } + return ClassVisibility(classNode.name, flags, members.associateBy { it.member }, _facadeClassName) } @@ -194,4 +99,4 @@ fun Sequence.readKotlinVisibilities(): Map = values.asSequence().filter { it.facadeClassName != null }.forEach { getValue(it.facadeClassName!!).partVisibilities.add(it) } - } \ No newline at end of file + }