Extract ClassMapperLite, add enlightening comment

This commit is contained in:
Alexander Udalov
2015-10-21 14:53:07 +03:00
parent 0302b9504f
commit 1ce5f8458c
3 changed files with 55 additions and 29 deletions
@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.serialization.AnnotationSerializer;
import org.jetbrains.kotlin.serialization.ProtoBuf; import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.serialization.SerializerExtension; import org.jetbrains.kotlin.serialization.SerializerExtension;
import org.jetbrains.kotlin.serialization.StringTable; import org.jetbrains.kotlin.serialization.StringTable;
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf; import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.Method; import org.jetbrains.org.objectweb.asm.commons.Method;
@@ -217,7 +217,7 @@ public class JvmSerializerExtension extends SerializerExtension {
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
if (!(classifier instanceof ClassDescriptor)) return null; if (!(classifier instanceof ClassDescriptor)) return null;
ClassId classId = classId((ClassDescriptor) classifier); ClassId classId = classId((ClassDescriptor) classifier);
return classId == null ? null : JvmProtoBufUtil.mapClassIdDefault(classId); return classId == null ? null : ClassMapperLite.mapClass(classId);
} }
@Nullable @Nullable
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.serialization.jvm
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
// The purpose of this class is to map Kotlin classes to JVM bytecode desc strings, as JetTypeMapper does in the backend.
// It's used as an optimization during serialization/deserialization: if there's no JVM signature for a method/property/constructor,
// it means that the JVM signature should be trivially computable from the Kotlin signature with this class.
// It's not required to support everything in JetTypeMapper, but the more it does, the more we save on JVM signatures in proto metadata.
// Note that improving the behavior of this class may break binary compatibility of code compiled by Kotlin, because it may make
// the new compiler skip writing the signatures it now thinks are trivial, and the old compiler would recreate them incorrectly.
object ClassMapperLite {
@JvmStatic
fun mapClass(classId: ClassId): String {
val internalName = classId.asString().replace('.', '$')
val simpleName = internalName.removePrefix("kotlin/")
if (simpleName != internalName) {
for (jvmPrimitive in JvmPrimitiveType.values) {
val primitiveType = jvmPrimitive.primitiveType
if (simpleName == primitiveType.typeName.asString()) return jvmPrimitive.desc
if (simpleName == primitiveType.arrayTypeName.asString()) return "[" + jvmPrimitive.desc
}
if (simpleName == KotlinBuiltIns.FQ_NAMES.unit.shortName().asString()) return "V"
}
val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(classId.asSingleFqName().toUnsafe())
if (javaClassId != null) {
return "L" + javaClassId.asString().replace('.', '$') + ";"
}
return "L$internalName;"
}
}
@@ -17,11 +17,7 @@
package org.jetbrains.kotlin.serialization.jvm package org.jetbrains.kotlin.serialization.jvm
import com.google.protobuf.ExtensionRegistryLite import com.google.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.load.kotlin.JvmNameResolver import org.jetbrains.kotlin.load.kotlin.JvmNameResolver
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.serialization.ClassData import org.jetbrains.kotlin.serialization.ClassData
import org.jetbrains.kotlin.serialization.PackageData import org.jetbrains.kotlin.serialization.PackageData
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
@@ -122,28 +118,6 @@ public object JvmProtoBufUtil {
data class PropertySignature(val name: String, val desc: String) data class PropertySignature(val name: String, val desc: String)
private fun mapTypeDefault(type: ProtoBuf.Type, nameResolver: NameResolver): String? { private fun mapTypeDefault(type: ProtoBuf.Type, nameResolver: NameResolver): String? {
return if (type.hasClassName()) mapClassIdDefault(nameResolver.getClassId(type.className)) else null return if (type.hasClassName()) ClassMapperLite.mapClass(nameResolver.getClassId(type.className)) else null
}
@JvmStatic
fun mapClassIdDefault(classId: ClassId): String {
val internalName = classId.asString().replace('.', '$')
val simpleName = internalName.removePrefix("kotlin/")
if (simpleName != internalName) {
for (jvmPrimitive in JvmPrimitiveType.values()) {
val primitiveType = jvmPrimitive.primitiveType
if (simpleName == primitiveType.typeName.asString()) return jvmPrimitive.desc
if (simpleName == primitiveType.arrayTypeName.asString()) return "[" + jvmPrimitive.desc
}
if (simpleName == KotlinBuiltIns.FQ_NAMES.unit.shortName().asString()) return "V"
}
val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(classId.asSingleFqName().toUnsafe())
if (javaClassId != null) {
return "L" + javaClassId.asString().replace('.', '$') + ";"
}
return "L$internalName;"
} }
} }