Don't always write JVM method signatures to metadata

When the trivial type mapping (implemented in JvmProtoBufUtil) from
ProtoBuf.Type instances works fine, don't write the signature since it can be
loaded by exactly the same trivial type mapping
This commit is contained in:
Alexander Udalov
2015-10-07 15:36:03 +03:00
parent 168f1000e4
commit 864926ee2e
12 changed files with 259 additions and 241 deletions
@@ -62,10 +62,10 @@ message StringTableTypes {
}
message JvmMethodSignature {
required int32 name = 1 [(string_id_in_table) = true];
optional int32 name = 1 [(string_id_in_table) = true];
// JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
required int32 desc = 2 [(string_id_in_table) = true];
optional int32 desc = 2 [(string_id_in_table) = true];
}
message JvmFieldSignature {
@@ -24,7 +24,11 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.*
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.index
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.methodImplClassName
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.propertyImplClassName
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.propertySignature
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.JetType
import java.util.*
@@ -297,11 +301,11 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
private fun getCallableSignature(proto: MessageLite, nameResolver: NameResolver, kind: AnnotatedCallableKind): MemberSignature? {
return when {
proto is ProtoBuf.Constructor && proto.hasExtension(constructorSignature) -> {
MemberSignature.fromMethod(nameResolver, proto.getExtension(constructorSignature))
proto is ProtoBuf.Constructor -> {
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver) ?: return null)
}
proto is ProtoBuf.Function && proto.hasExtension(methodSignature) -> {
MemberSignature.fromMethod(nameResolver, proto.getExtension(methodSignature))
proto is ProtoBuf.Function -> {
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver) ?: return null)
}
proto is ProtoBuf.Property && proto.hasExtension(propertySignature) -> {
val signature = proto.getExtension(propertySignature)
@@ -33,6 +33,11 @@ data class MemberSignature private constructor(private val signature: String) {
return MemberSignature(name + desc)
}
@JvmStatic
public fun fromMethodNameAndDesc(namePlusDesc: String): MemberSignature {
return MemberSignature(namePlusDesc)
}
@JvmStatic
public fun fromFieldNameAndDesc(name: String, desc: String): MemberSignature {
return MemberSignature(name + "#" + desc)
@@ -1860,19 +1860,19 @@ public final class JvmProtoBuf {
public interface JvmMethodSignatureOrBuilder
extends com.google.protobuf.MessageLiteOrBuilder {
// required int32 name = 1;
// optional int32 name = 1;
/**
* <code>required int32 name = 1;</code>
* <code>optional int32 name = 1;</code>
*/
boolean hasName();
/**
* <code>required int32 name = 1;</code>
* <code>optional int32 name = 1;</code>
*/
int getName();
// required int32 desc = 2;
// optional int32 desc = 2;
/**
* <code>required int32 desc = 2;</code>
* <code>optional int32 desc = 2;</code>
*
* <pre>
* JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -1880,7 +1880,7 @@ public final class JvmProtoBuf {
*/
boolean hasDesc();
/**
* <code>required int32 desc = 2;</code>
* <code>optional int32 desc = 2;</code>
*
* <pre>
* JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -1968,27 +1968,27 @@ public final class JvmProtoBuf {
}
private int bitField0_;
// required int32 name = 1;
// optional int32 name = 1;
public static final int NAME_FIELD_NUMBER = 1;
private int name_;
/**
* <code>required int32 name = 1;</code>
* <code>optional int32 name = 1;</code>
*/
public boolean hasName() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>required int32 name = 1;</code>
* <code>optional int32 name = 1;</code>
*/
public int getName() {
return name_;
}
// required int32 desc = 2;
// optional int32 desc = 2;
public static final int DESC_FIELD_NUMBER = 2;
private int desc_;
/**
* <code>required int32 desc = 2;</code>
* <code>optional int32 desc = 2;</code>
*
* <pre>
* JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -1998,7 +1998,7 @@ public final class JvmProtoBuf {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>required int32 desc = 2;</code>
* <code>optional int32 desc = 2;</code>
*
* <pre>
* JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2017,14 +2017,6 @@ public final class JvmProtoBuf {
byte isInitialized = memoizedIsInitialized;
if (isInitialized != -1) return isInitialized == 1;
if (!hasName()) {
memoizedIsInitialized = 0;
return false;
}
if (!hasDesc()) {
memoizedIsInitialized = 0;
return false;
}
memoizedIsInitialized = 1;
return true;
}
@@ -2196,14 +2188,6 @@ public final class JvmProtoBuf {
}
public final boolean isInitialized() {
if (!hasName()) {
return false;
}
if (!hasDesc()) {
return false;
}
return true;
}
@@ -2226,22 +2210,22 @@ public final class JvmProtoBuf {
}
private int bitField0_;
// required int32 name = 1;
// optional int32 name = 1;
private int name_ ;
/**
* <code>required int32 name = 1;</code>
* <code>optional int32 name = 1;</code>
*/
public boolean hasName() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>required int32 name = 1;</code>
* <code>optional int32 name = 1;</code>
*/
public int getName() {
return name_;
}
/**
* <code>required int32 name = 1;</code>
* <code>optional int32 name = 1;</code>
*/
public Builder setName(int value) {
bitField0_ |= 0x00000001;
@@ -2250,7 +2234,7 @@ public final class JvmProtoBuf {
return this;
}
/**
* <code>required int32 name = 1;</code>
* <code>optional int32 name = 1;</code>
*/
public Builder clearName() {
bitField0_ = (bitField0_ & ~0x00000001);
@@ -2259,10 +2243,10 @@ public final class JvmProtoBuf {
return this;
}
// required int32 desc = 2;
// optional int32 desc = 2;
private int desc_ ;
/**
* <code>required int32 desc = 2;</code>
* <code>optional int32 desc = 2;</code>
*
* <pre>
* JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2272,7 +2256,7 @@ public final class JvmProtoBuf {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>required int32 desc = 2;</code>
* <code>optional int32 desc = 2;</code>
*
* <pre>
* JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2282,7 +2266,7 @@ public final class JvmProtoBuf {
return desc_;
}
/**
* <code>required int32 desc = 2;</code>
* <code>optional int32 desc = 2;</code>
*
* <pre>
* JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -2295,7 +2279,7 @@ public final class JvmProtoBuf {
return this;
}
/**
* <code>required int32 desc = 2;</code>
* <code>optional int32 desc = 2;</code>
*
* <pre>
* JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
@@ -3164,24 +3148,6 @@ public final class JvmProtoBuf {
return false;
}
}
if (hasSyntheticMethod()) {
if (!getSyntheticMethod().isInitialized()) {
memoizedIsInitialized = 0;
return false;
}
}
if (hasGetter()) {
if (!getGetter().isInitialized()) {
memoizedIsInitialized = 0;
return false;
}
}
if (hasSetter()) {
if (!getSetter().isInitialized()) {
memoizedIsInitialized = 0;
return false;
}
}
memoizedIsInitialized = 1;
return true;
}
@@ -3391,24 +3357,6 @@ public final class JvmProtoBuf {
return false;
}
}
if (hasSyntheticMethod()) {
if (!getSyntheticMethod().isInitialized()) {
return false;
}
}
if (hasGetter()) {
if (!getGetter().isInitialized()) {
return false;
}
}
if (hasSetter()) {
if (!getSetter().isInitialized()) {
return false;
}
}
return true;
}
@@ -17,10 +17,15 @@
package org.jetbrains.kotlin.serialization.jvm
import com.google.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
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.PackageData
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import java.io.ByteArrayInputStream
public object JvmProtoBufUtil {
@@ -53,4 +58,64 @@ public object JvmProtoBufUtil {
val packageProto = ProtoBuf.Package.parseFrom(input, EXTENSION_REGISTRY)
return PackageData(nameResolver, packageProto)
}
// returns JVM signature in the format: "equals(Ljava/lang/Object;)Z"
fun getJvmMethodSignature(proto: ProtoBuf.FunctionOrBuilder, nameResolver: NameResolver): String? {
val signature =
if (proto.hasExtension(JvmProtoBuf.methodSignature)) proto.getExtension(JvmProtoBuf.methodSignature) else null
val name = if (signature != null && signature.hasName()) signature.name else proto.name
val desc = if (signature != null && signature.hasDesc()) {
nameResolver.getString(signature.desc)
}
else {
val parameterTypes =
(if (proto.hasReceiverType()) listOf(proto.receiverType) else listOf()) + proto.valueParameterList.map { it.type }
val parametersDesc = parameterTypes.map { mapTypeDefault(it, nameResolver) ?: return null }
val returnTypeDesc = mapTypeDefault(proto.returnType, nameResolver) ?: return null
parametersDesc.joinToString(separator = "", prefix = "(", postfix = ")") + returnTypeDesc
}
return nameResolver.getString(name) + desc
}
fun getJvmConstructorSignature(proto: ProtoBuf.ConstructorOrBuilder, nameResolver: NameResolver): String? {
val signature =
if (proto.hasExtension(JvmProtoBuf.constructorSignature)) proto.getExtension(JvmProtoBuf.constructorSignature) else null
val desc = if (signature != null && signature.hasDesc()) {
nameResolver.getString(signature.desc)
}
else {
proto.valueParameterList.map {
mapTypeDefault(it.type, nameResolver) ?: return null
}.joinToString(separator = "", prefix = "(", postfix = ")V")
}
return "<init>" + desc
}
private fun mapTypeDefault(type: ProtoBuf.Type, nameResolver: NameResolver): String? {
return if (type.hasClassName()) mapClassIdDefault(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;"
}
}