Add anonymousObjectOriginName/lambdaClassOriginName to kotlinx-metadata

#KT-21320
 #KT-23198
This commit is contained in:
Alexander Udalov
2018-05-16 15:23:25 +02:00
parent b97379b39b
commit e1a4bd01f5
10 changed files with 117 additions and 3 deletions
@@ -5,6 +5,11 @@ inline fun a() {}
inline fun b() {} inline fun b() {}
inline fun c() {} inline fun c(crossinline f: () -> Unit) {
object { init { f() }}
{ f() }
}
inline fun d() {} inline fun d() {
c {}
}
@@ -2,5 +2,5 @@ package test
public inline fun a(): kotlin.Unit public inline fun a(): kotlin.Unit
public inline fun b(): kotlin.Unit public inline fun b(): kotlin.Unit
public inline fun c(): kotlin.Unit public inline fun c(/*0*/ crossinline f: () -> kotlin.Unit): kotlin.Unit
public inline fun d(): kotlin.Unit public inline fun d(): kotlin.Unit
@@ -19,9 +19,23 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.metadata.serialization.StringTable import org.jetbrains.kotlin.metadata.serialization.StringTable
internal class JvmMetadataExtensions : MetadataExtensions { internal class JvmMetadataExtensions : MetadataExtensions {
override fun readClassExtensions(v: KmClassVisitor, proto: ProtoBuf.Class, strings: NameResolver, types: TypeTable) {
val ext = v.visitExtensions(JvmClassExtensionVisitor.TYPE) as? JvmClassExtensionVisitor ?: return
val anonymousObjectOriginName = proto.getExtensionOrNull(JvmProtoBuf.anonymousObjectOriginName)
if (anonymousObjectOriginName != null) {
ext.visitAnonymousObjectOriginName(strings.getString(anonymousObjectOriginName))
}
}
override fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, strings: NameResolver, types: TypeTable) { override fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, strings: NameResolver, types: TypeTable) {
val ext = v.visitExtensions(JvmFunctionExtensionVisitor.TYPE) as? JvmFunctionExtensionVisitor ?: return val ext = v.visitExtensions(JvmFunctionExtensionVisitor.TYPE) as? JvmFunctionExtensionVisitor ?: return
ext.visit(JvmProtoBufUtil.getJvmMethodSignature(proto, strings, types)) ext.visit(JvmProtoBufUtil.getJvmMethodSignature(proto, strings, types))
val lambdaClassOriginName = proto.getExtensionOrNull(JvmProtoBuf.lambdaClassOriginName)
if (lambdaClassOriginName != null) {
ext.visitLambdaClassOriginName(strings.getString(lambdaClassOriginName))
}
} }
override fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, strings: NameResolver, types: TypeTable) { override fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, strings: NameResolver, types: TypeTable) {
@@ -68,6 +82,17 @@ internal class JvmMetadataExtensions : MetadataExtensions {
ext.visitEnd() ext.visitEnd()
} }
override fun writeClassExtensions(
type: KmExtensionType, proto: ProtoBuf.Class.Builder, strings: StringTable
): KmClassExtensionVisitor? {
if (type != JvmClassExtensionVisitor.TYPE) return null
return object : JvmClassExtensionVisitor() {
override fun visitAnonymousObjectOriginName(internalName: String) {
proto.setExtension(JvmProtoBuf.anonymousObjectOriginName, strings.getStringIndex(internalName))
}
}
}
override fun writeFunctionExtensions( override fun writeFunctionExtensions(
type: KmExtensionType, proto: ProtoBuf.Function.Builder, strings: StringTable type: KmExtensionType, proto: ProtoBuf.Function.Builder, strings: StringTable
): KmFunctionExtensionVisitor? { ): KmFunctionExtensionVisitor? {
@@ -78,6 +103,10 @@ internal class JvmMetadataExtensions : MetadataExtensions {
proto.setExtension(JvmProtoBuf.methodSignature, desc.toJvmMethodSignature(strings)) proto.setExtension(JvmProtoBuf.methodSignature, desc.toJvmMethodSignature(strings))
} }
} }
override fun visitLambdaClassOriginName(internalName: String) {
proto.setExtension(JvmProtoBuf.lambdaClassOriginName, strings.getStringIndex(internalName))
}
} }
} }
@@ -8,6 +8,31 @@ package kotlinx.metadata.jvm
import kotlinx.metadata.* import kotlinx.metadata.*
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
/**
* A visitor to visit JVM extensions for a function.
*/
open class JvmClassExtensionVisitor @JvmOverloads constructor(
private val delegate: JvmClassExtensionVisitor? = null
) : KmClassExtensionVisitor {
/**
* Visits the JVM internal name of the original class this anonymous object is copied from. This method is called for
* anonymous objects copied from bodies of inline functions to the use site by the Kotlin compiler.
*/
open fun visitAnonymousObjectOriginName(internalName: String) {
delegate?.visitAnonymousObjectOriginName(internalName)
}
companion object {
/**
* The type of this extension visitor.
*
* @see KmExtensionType
*/
@JvmField
val TYPE: KmExtensionType = KmExtensionType(JvmClassExtensionVisitor::class)
}
}
/** /**
* A visitor to visit JVM extensions for a function. * A visitor to visit JVM extensions for a function.
*/ */
@@ -24,6 +49,14 @@ open class JvmFunctionExtensionVisitor @JvmOverloads constructor(
delegate?.visit(desc) delegate?.visit(desc)
} }
/**
* Visits the JVM internal name of the original class the lambda class for this function is copied from.
* This information is present for lambdas copied from bodies of inline functions to the use site by the Kotlin compiler.
*/
open fun visitLambdaClassOriginName(internalName: String) {
delegate?.visitLambdaClassOriginName(internalName)
}
companion object { companion object {
/** /**
* The type of this extension visitor. * The type of this extension visitor.
@@ -35,6 +35,11 @@ data class KmExtensionType(val klass: KClass<out KmExtensionVisitor>)
*/ */
interface KmExtensionVisitor interface KmExtensionVisitor
/**
* A visitor to visit platform-specific extensions for a class.
*/
interface KmClassExtensionVisitor : KmExtensionVisitor
/** /**
* A visitor to visit platform-specific extensions for a function. * A visitor to visit platform-specific extensions for a function.
*/ */
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.metadata.serialization.StringTable
import java.util.* import java.util.*
interface MetadataExtensions { interface MetadataExtensions {
fun readClassExtensions(v: KmClassVisitor, proto: ProtoBuf.Class, strings: NameResolver, types: TypeTable)
fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, strings: NameResolver, types: TypeTable) fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, strings: NameResolver, types: TypeTable)
fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, strings: NameResolver, types: TypeTable) fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, strings: NameResolver, types: TypeTable)
@@ -23,6 +25,8 @@ interface MetadataExtensions {
fun readTypeExtensions(v: KmTypeVisitor, proto: ProtoBuf.Type, strings: NameResolver) fun readTypeExtensions(v: KmTypeVisitor, proto: ProtoBuf.Type, strings: NameResolver)
fun writeClassExtensions(type: KmExtensionType, proto: ProtoBuf.Class.Builder, strings: StringTable): KmClassExtensionVisitor?
fun writeFunctionExtensions(type: KmExtensionType, proto: ProtoBuf.Function.Builder, strings: StringTable): KmFunctionExtensionVisitor? fun writeFunctionExtensions(type: KmExtensionType, proto: ProtoBuf.Function.Builder, strings: StringTable): KmFunctionExtensionVisitor?
fun writePropertyExtensions(type: KmExtensionType, proto: ProtoBuf.Property.Builder, strings: StringTable): KmPropertyExtensionVisitor? fun writePropertyExtensions(type: KmExtensionType, proto: ProtoBuf.Property.Builder, strings: StringTable): KmPropertyExtensionVisitor?
@@ -81,6 +81,10 @@ fun ProtoBuf.Class.accept(v: KmClassVisitor, strings: NameResolver) {
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(it, c) } v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(it, c) }
} }
for (extension in c.extensions) {
extension.readClassExtensions(v, this, c.strings, c.types)
}
v.visitEnd() v.visitEnd()
} }
@@ -455,6 +455,11 @@ open class ClassWriter(stringTable: StringTable) : KmClassVisitor() {
override fun visitVersionRequirement(): KmVersionRequirementVisitor? = override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
writeVersionRequirement(c) { t.versionRequirement = it } writeVersionRequirement(c) { t.versionRequirement = it }
override fun visitExtensions(type: KmExtensionType): KmClassExtensionVisitor? =
c.applySingleExtension(type) {
writeClassExtensions(type, t, c.strings)
}
override fun visitEnd() { override fun visitEnd() {
c.versionRequirements.serialize()?.let { c.versionRequirements.serialize()?.let {
t.versionRequirementTable = it t.versionRequirementTable = it
@@ -131,6 +131,14 @@ abstract class KmClassVisitor @JvmOverloads constructor(delegate: KmClassVisitor
open fun visitVersionRequirement(): KmVersionRequirementVisitor? = open fun visitVersionRequirement(): KmVersionRequirementVisitor? =
delegate?.visitVersionRequirement() delegate?.visitVersionRequirement()
/**
* Visits the extensions of the given type on the class.
*
* @param type the type of extension visitor to be returned
*/
open fun visitExtensions(type: KmExtensionType): KmClassExtensionVisitor? =
delegate?.visitExtensions(type)
/** /**
* Visits the end of the class. * Visits the end of the class.
*/ */
@@ -20,6 +20,7 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
var returnType: String? = null var returnType: String? = null
var versionRequirement: String? = null var versionRequirement: String? = null
var jvmDesc: String? = null var jvmDesc: String? = null
var lambdaClassOriginName: String? = null
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? = override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
printType(flags) { receiverParameterType = it } printType(flags) { receiverParameterType = it }
@@ -44,11 +45,18 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
override fun visit(desc: String?) { override fun visit(desc: String?) {
jvmDesc = desc jvmDesc = desc
} }
override fun visitLambdaClassOriginName(internalName: String) {
lambdaClassOriginName = internalName
}
} }
} }
override fun visitEnd() { override fun visitEnd() {
sb.appendln() sb.appendln()
if (lambdaClassOriginName != null) {
sb.appendln(" // lambda class origin: $lambdaClassOriginName")
}
if (versionRequirement != null) { if (versionRequirement != null) {
sb.appendln(" // $versionRequirement") sb.appendln(" // $versionRequirement")
} }
@@ -520,6 +528,7 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
private val typeParams = mutableListOf<String>() private val typeParams = mutableListOf<String>()
private val supertypes = mutableListOf<String>() private val supertypes = mutableListOf<String>()
private var versionRequirement: String? = null private var versionRequirement: String? = null
private var anonymousObjectOriginName: String? = null
override fun visit(flags: Flags, name: ClassName) { override fun visit(flags: Flags, name: ClassName) {
this.flags = flags this.flags = flags
@@ -527,6 +536,9 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
} }
override fun visitEnd() { override fun visitEnd() {
if (anonymousObjectOriginName != null) {
result.appendln("// anonymous object origin: $anonymousObjectOriginName")
}
if (versionRequirement != null) { if (versionRequirement != null) {
result.appendln(" // $versionRequirement") result.appendln(" // $versionRequirement")
} }
@@ -585,6 +597,15 @@ class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), Ab
override fun visitVersionRequirement(): KmVersionRequirementVisitor? = override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
printVersionRequirement { versionRequirement = it } printVersionRequirement { versionRequirement = it }
override fun visitExtensions(type: KmExtensionType): KmClassExtensionVisitor? {
if (type != JvmClassExtensionVisitor.TYPE) return null
return object : JvmClassExtensionVisitor() {
override fun visitAnonymousObjectOriginName(internalName: String) {
anonymousObjectOriginName = internalName
}
}
}
override fun print(klass: KotlinClassMetadata.Class): String { override fun print(klass: KotlinClassMetadata.Class): String {
klass.accept(this) klass.accept(this)
return result.toString() return result.toString()