Write lambdaClassOriginName for lambdas copied during inline

Similarly to anonymousObjectOriginName which is written for copied
anonymous objects

 #KT-21320
This commit is contained in:
Alexander Udalov
2018-02-02 19:27:31 +01:00
parent 6da3f37fc3
commit 12e31cedfd
8 changed files with 161 additions and 79 deletions
@@ -45,7 +45,10 @@ import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
@@ -878,7 +881,12 @@ public class AsmUtil {
public static void writeAnnotationData(
@NotNull AnnotationVisitor av, @NotNull MessageLite message, @NotNull JvmStringTable stringTable
) {
String[] data = BitEncoding.encodeBytes(DescriptorSerializer.serialize(message, stringTable));
writeAnnotationData(av, BitEncoding.encodeBytes(DescriptorSerializer.serialize(message, stringTable)), stringTable.getStrings());
}
public static void writeAnnotationData(
@NotNull AnnotationVisitor av, @NotNull String[] data, @NotNull List<String> strings
) {
AnnotationVisitor dataVisitor = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME);
for (String string : data) {
dataVisitor.visit(null, string);
@@ -886,7 +894,7 @@ public class AsmUtil {
dataVisitor.visitEnd();
AnnotationVisitor stringsVisitor = av.visitArray(JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME);
for (String string : stringTable.getStrings()) {
for (String string : strings) {
stringsVisitor.visit(null, string);
}
stringsVisitor.visitEnd();
@@ -172,7 +172,7 @@ class AnonymousObjectTransformer(
val header = metadataReader.createHeader()
if (header != null) {
transformMetadata(header, classBuilder)
writeTransformedMetadata(header, classBuilder)
}
writeOuterInfo(visitor)
@@ -182,26 +182,45 @@ class AnonymousObjectTransformer(
return transformationResult
}
private fun transformMetadata(header: KotlinClassHeader, classBuilder: ClassBuilder) {
val newProto: MessageLite
val newStringTable: JvmStringTable
if (header.kind == KotlinClassHeader.Kind.CLASS) {
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(header.data!!, header.strings!!)
newStringTable = JvmStringTable(state.typeMapper, nameResolver as JvmNameResolver)
newProto = classProto.toBuilder().apply {
setExtension(JvmProtoBuf.anonymousObjectOriginName, newStringTable.getStringIndex(oldObjectType.internalName))
}.build()
} else if (header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS) {
// TODO: transform metadata for synthetic classes
return
} else return
writeKotlinMetadata(classBuilder, state, header.kind, header.extraInt) { av ->
private fun writeTransformedMetadata(header: KotlinClassHeader, classBuilder: ClassBuilder) {
writeKotlinMetadata(classBuilder, state, header.kind, header.extraInt) action@ { av ->
val (newProto, newStringTable) = transformMetadata(header) ?: run {
val data = header.data
val strings = header.strings
if (data != null && strings != null) {
AsmUtil.writeAnnotationData(av, data, strings.asList())
}
return@action
}
AsmUtil.writeAnnotationData(av, newProto, newStringTable)
}
}
private fun transformMetadata(header: KotlinClassHeader): Pair<MessageLite, JvmStringTable>? {
val data = header.data ?: return null
val strings = header.strings ?: return null
when (header.kind) {
KotlinClassHeader.Kind.CLASS -> {
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(data, strings)
val newStringTable = JvmStringTable(state.typeMapper, nameResolver as JvmNameResolver)
val newProto = classProto.toBuilder().apply {
setExtension(JvmProtoBuf.anonymousObjectOriginName, newStringTable.getStringIndex(oldObjectType.internalName))
}.build()
return newProto to newStringTable
}
KotlinClassHeader.Kind.SYNTHETIC_CLASS -> {
val (nameResolver, functionProto) = JvmProtoBufUtil.readFunctionDataFrom(data, strings)
val newStringTable = JvmStringTable(state.typeMapper, nameResolver)
val newProto = functionProto.toBuilder().apply {
setExtension(JvmProtoBuf.lambdaClassOriginName, newStringTable.getStringIndex(oldObjectType.internalName))
}.build()
return newProto to newStringTable
}
else -> return null
}
}
private fun writeOuterInfo(visitor: ClassVisitor) {
val info = inliningContext.callSiteInfo
visitor.visitOuterClass(info.ownerClassName, info.functionName, info.functionDesc)