Simplify storage of JVM signatures in binary metadata

Store the whole method & field descriptor strings. Moving these strings to
separate annotation arguments later will allow to reuse them with the ones in
the constant pool, presumably allowing to save lots of space (up to 10%)
This commit is contained in:
Alexander Udalov
2015-09-19 03:16:02 +03:00
parent 68051fa3bb
commit 7d5bd3cf50
12 changed files with 347 additions and 2991 deletions
@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.load.java.lazy.types.RawTypeCapabilities;
import org.jetbrains.kotlin.load.kotlin.SignatureDeserializer;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.serialization.*;
import org.jetbrains.kotlin.serialization.deserialization.NameResolver;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
@@ -35,8 +33,6 @@ import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.Arrays;
import static org.jetbrains.kotlin.codegen.AsmUtil.shortNameByAsmType;
import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*;
@@ -107,7 +103,8 @@ public class JvmSerializerExtension extends SerializerExtension {
if (callable instanceof DeserializedSimpleFunctionDescriptor) {
DeserializedSimpleFunctionDescriptor deserialized = (DeserializedSimpleFunctionDescriptor) callable;
signature = signatureSerializer.copyMethodSignature(
deserialized.getProto().getExtension(JvmProtoBuf.methodSignature), deserialized.getNameResolver());
deserialized.getProto().getExtension(JvmProtoBuf.methodSignature), deserialized.getNameResolver()
);
}
else {
Method method = bindings.get(METHOD_FOR_FUNCTION, (FunctionDescriptor) callable);
@@ -126,23 +123,22 @@ public class JvmSerializerExtension extends SerializerExtension {
Method setterMethod = setter == null ? null : bindings.get(METHOD_FOR_FUNCTION, setter);
Pair<Type, String> field = bindings.get(FIELD_FOR_PROPERTY, property);
Type fieldType;
String fieldName;
String fieldDesc;
boolean isStaticInOuter;
Method syntheticMethod;
if (field != null) {
fieldType = field.first;
fieldName = field.second;
fieldDesc = field.first.getDescriptor();
isStaticInOuter = bindings.get(STATIC_FIELD_IN_OUTER_CLASS, property);
syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, property);
}
else {
fieldType = null;
fieldName = null;
fieldDesc = null;
isStaticInOuter = false;
syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, property);
}
Method syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, property);
JvmProtoBuf.JvmPropertySignature signature;
if (callable instanceof DeserializedPropertyDescriptor) {
DeserializedPropertyDescriptor deserializedCallable = (DeserializedPropertyDescriptor) callable;
@@ -152,8 +148,12 @@ public class JvmSerializerExtension extends SerializerExtension {
);
}
else {
signature = signatureSerializer
.propertySignature(fieldType, fieldName, isStaticInOuter, syntheticMethod, getterMethod, setterMethod);
signature = signatureSerializer.propertySignature(
fieldName, fieldDesc, isStaticInOuter,
syntheticMethod != null ? signatureSerializer.methodSignature(syntheticMethod) : null,
getterMethod != null ? signatureSerializer.methodSignature(getterMethod) : null,
setterMethod != null ? signatureSerializer.methodSignature(setterMethod) : null
);
}
proto.setExtension(JvmProtoBuf.propertySignature, signature);
}
@@ -172,23 +172,18 @@ public class JvmSerializerExtension extends SerializerExtension {
@NotNull JvmProtoBuf.JvmMethodSignature signature,
@NotNull NameResolver nameResolver
) {
String method = new SignatureDeserializer(nameResolver).methodSignatureString(signature);
return methodSignature(getAsmMethod(method));
return methodSignature(new Method(
nameResolver.getString(signature.getName()),
nameResolver.getString(signature.getDesc())
));
}
@NotNull
public JvmProtoBuf.JvmMethodSignature methodSignature(@NotNull Method method) {
JvmProtoBuf.JvmMethodSignature.Builder signature = JvmProtoBuf.JvmMethodSignature.newBuilder();
signature.setName(stringTable.getStringIndex(method.getName()));
signature.setReturnType(type(method.getReturnType()));
for (Type type : method.getArgumentTypes()) {
signature.addParameterType(type(type));
}
return signature.build();
return JvmProtoBuf.JvmMethodSignature.newBuilder()
.setName(stringTable.getStringIndex(method.getName()))
.setDesc(stringTable.getStringIndex(method.getDescriptor()))
.build();
}
@NotNull
@@ -196,103 +191,68 @@ public class JvmSerializerExtension extends SerializerExtension {
@NotNull JvmProtoBuf.JvmPropertySignature signature,
@NotNull NameResolver nameResolver
) {
Type fieldType;
String fieldName;
String fieldDesc;
boolean isStaticInOuter;
SignatureDeserializer signatureDeserializer = new SignatureDeserializer(nameResolver);
if (signature.hasField()) {
JvmProtoBuf.JvmFieldSignature field = signature.getField();
fieldType = Type.getType(signatureDeserializer.typeDescriptor(field.getType()));
fieldName = nameResolver.getName(field.getName()).asString();
fieldName = nameResolver.getString(field.getName());
fieldDesc = nameResolver.getString(field.getDesc());
isStaticInOuter = field.getIsStaticInOuter();
}
else {
fieldType = null;
fieldName = null;
fieldDesc = null;
isStaticInOuter = false;
}
Method syntheticMethod = signature.hasSyntheticMethod()
? getAsmMethod(signatureDeserializer.methodSignatureString(signature.getSyntheticMethod()))
: null;
Method getter = signature.hasGetter() ? getAsmMethod(signatureDeserializer.methodSignatureString(signature.getGetter())) : null;
Method setter = signature.hasSetter() ? getAsmMethod(signatureDeserializer.methodSignatureString(signature.getSetter())) : null;
return propertySignature(fieldType, fieldName, isStaticInOuter, syntheticMethod, getter, setter);
return propertySignature(
fieldName, fieldDesc, isStaticInOuter,
signature.hasSyntheticMethod() ? copyMethodSignature(signature.getSyntheticMethod(), nameResolver) : null,
signature.hasGetter() ? copyMethodSignature(signature.getGetter(), nameResolver) : null,
signature.hasSetter() ? copyMethodSignature(signature.getSetter(), nameResolver) : null
);
}
@NotNull
public JvmProtoBuf.JvmPropertySignature propertySignature(
@Nullable Type fieldType,
@Nullable String fieldName,
@Nullable String fieldDesc,
boolean isStaticInOuter,
@Nullable Method syntheticMethod,
@Nullable Method getter,
@Nullable Method setter
@Nullable JvmProtoBuf.JvmMethodSignature syntheticMethod,
@Nullable JvmProtoBuf.JvmMethodSignature getter,
@Nullable JvmProtoBuf.JvmMethodSignature setter
) {
JvmProtoBuf.JvmPropertySignature.Builder signature = JvmProtoBuf.JvmPropertySignature.newBuilder();
if (fieldType != null) {
assert fieldName != null : "Field name shouldn't be null when there's a field type: " + fieldType;
signature.setField(fieldSignature(fieldType, fieldName, isStaticInOuter));
if (fieldDesc != null) {
assert fieldName != null : "Field name shouldn't be null when there's a field type: " + fieldDesc;
signature.setField(fieldSignature(fieldName, fieldDesc, isStaticInOuter));
}
if (syntheticMethod != null) {
signature.setSyntheticMethod(methodSignature(syntheticMethod));
signature.setSyntheticMethod(syntheticMethod);
}
if (getter != null) {
signature.setGetter(methodSignature(getter));
signature.setGetter(getter);
}
if (setter != null) {
signature.setSetter(methodSignature(setter));
signature.setSetter(setter);
}
return signature.build();
}
@NotNull
public JvmProtoBuf.JvmFieldSignature fieldSignature(@NotNull Type type, @NotNull String name, boolean isStaticInOuter) {
JvmProtoBuf.JvmFieldSignature.Builder signature = JvmProtoBuf.JvmFieldSignature.newBuilder();
signature.setName(stringTable.getStringIndex(name));
signature.setType(type(type));
public JvmProtoBuf.JvmFieldSignature fieldSignature(@NotNull String name, @NotNull String desc, boolean isStaticInOuter) {
JvmProtoBuf.JvmFieldSignature.Builder builder = JvmProtoBuf.JvmFieldSignature.newBuilder()
.setName(stringTable.getStringIndex(name))
.setDesc(stringTable.getStringIndex(desc));
if (isStaticInOuter) {
signature.setIsStaticInOuter(true);
builder.setIsStaticInOuter(true);
}
return signature.build();
}
@NotNull
public JvmProtoBuf.JvmType type(@NotNull Type givenType) {
JvmProtoBuf.JvmType.Builder builder = JvmProtoBuf.JvmType.newBuilder();
Type type = givenType;
if (type.getSort() == Type.ARRAY) {
builder.setArrayDimension(type.getDimensions());
type = type.getElementType();
}
if (type.getSort() == Type.OBJECT) {
FqName fqName = internalNameToFqName(type.getInternalName());
builder.setClassFqName(stringTable.getFqNameIndex(fqName));
}
else {
builder.setPrimitiveType(JvmProtoBuf.JvmType.PrimitiveType.valueOf(type.getSort()));
}
return builder.build();
}
@NotNull
private FqName internalNameToFqName(@NotNull String internalName) {
return FqName.fromSegments(Arrays.asList(internalName.split("/")));
}
}
@NotNull
private static Method getAsmMethod(@NotNull String nameAndDesc) {
int indexOf = nameAndDesc.indexOf('(');
return new Method(nameAndDesc.substring(0, indexOf), nameAndDesc.substring(indexOf));
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.name.FqName;
import java.io.OutputStream;
@@ -27,7 +26,5 @@ public interface StringTable {
int getFqNameIndex(@NotNull ClassDescriptor descriptor);
int getFqNameIndex(@NotNull FqName fqName);
void serializeTo(@NotNull OutputStream output);
}
@@ -91,7 +91,7 @@ public class StringTableImpl implements StringTable {
shortName = descriptor.getName().asString();
FqName packageFqName = ((PackageFragmentDescriptor) containingDeclaration).getFqName();
if (!packageFqName.isRoot()) {
builder.setParentQualifiedName(getFqNameIndex(packageFqName));
builder.setParentQualifiedName(getPackageFqNameIndex(packageFqName));
}
}
else if (containingDeclaration instanceof ClassDescriptor) {
@@ -109,8 +109,7 @@ public class StringTableImpl implements StringTable {
return qualifiedNames.intern(new FqNameProto(builder));
}
@Override
public int getFqNameIndex(@NotNull FqName fqName) {
private int getPackageFqNameIndex(@NotNull FqName fqName) {
int result = -1;
for (Name segment : fqName.pathSegments()) {
QualifiedName.Builder builder = QualifiedName.newBuilder();
File diff suppressed because it is too large Load Diff
@@ -22,39 +22,18 @@ import "core/deserialization/src/descriptors.proto";
option java_outer_classname = "JvmProtoBuf";
option optimize_for = LITE_RUNTIME;
message JvmType {
// Either a primitive type, or a class FQ name should be present
enum PrimitiveType {
// These values correspond to ASM Type sorts
VOID = 0;
BOOLEAN = 1;
CHAR = 2;
BYTE = 3;
SHORT = 4;
INT = 5;
FLOAT = 6;
LONG = 7;
DOUBLE = 8;
}
optional PrimitiveType primitive_type = 1;
// id in QualifiedNameTable of a name in the following format: 'package.Outer$Nested'
optional int32 class_fq_name = 2 [(fq_name_id_in_table) = true];
optional int32 array_dimension = 3 [default = 0];
}
message JvmMethodSignature {
required int32 name = 1 [(string_id_in_table) = true];
required JvmType return_type = 2;
repeated JvmType parameter_type = 3;
// JVM descriptor of the method, e.g. '(Ljava/util/List;)[Ljava/lang/Object;'
required int32 desc = 2 [(string_id_in_table) = true];
}
message JvmFieldSignature {
required int32 name = 1 [(string_id_in_table) = true];
required JvmType type = 2;
// JVM descriptor of the field type, e.g. 'Ljava/lang/String;'
required int32 desc = 2 [(string_id_in_table) = true];
// True iff this field is a backing field for a companion object and is really present as a static
// field in the outer class, not as an instance field here
@@ -62,11 +41,9 @@ message JvmFieldSignature {
}
message JvmPropertySignature {
// A property itself is identified either by the field, or by the synthetic method.
// If the property is annotated, then either field or synthetic_method should be present
optional JvmFieldSignature field = 1;
// Annotations on properties without backing fields are written on a synthetic method with this signature
// Annotations on properties are written on a synthetic method with this signature
optional JvmMethodSignature synthetic_method = 2;
optional JvmMethodSignature getter = 3;
@@ -243,11 +243,11 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
kotlinClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? {
return AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name.asString() + desc))
return AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name.asString(), desc))
}
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? {
val signature = MemberSignature.fromFieldNameAndDesc(name, desc)
val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), desc)
if (initializer != null) {
val constant = loadConstant(desc, initializer)
@@ -299,17 +299,16 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
): MemberSignature? {
if (!proto.hasExtension(propertySignature)) return null
val propertySignature = proto.getExtension(propertySignature)
val deserializer = SignatureDeserializer(nameResolver)
val signature = proto.getExtension(propertySignature)
if (field && propertySignature.hasField()) {
val field = propertySignature.field
val type = deserializer.typeDescriptor(field.type)
val name = nameResolver.getName(field.name)
return MemberSignature.fromFieldNameAndDesc(name, type)
if (field && signature.hasField()) {
return MemberSignature.fromFieldNameAndDesc(
nameResolver.getString(signature.field.name),
nameResolver.getString(signature.field.desc)
)
}
else if (synthetic && propertySignature.hasSyntheticMethod()) {
return deserializer.methodSignature(propertySignature.syntheticMethod)
else if (synthetic && signature.hasSyntheticMethod()) {
return MemberSignature.fromMethod(nameResolver, signature.syntheticMethod)
}
return null
@@ -320,17 +319,15 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
nameResolver: NameResolver,
kind: AnnotatedCallableKind
): MemberSignature? {
val deserializer = SignatureDeserializer(nameResolver)
when (kind) {
AnnotatedCallableKind.FUNCTION -> if (proto.hasExtension(methodSignature)) {
return deserializer.methodSignature(proto.getExtension(methodSignature))
return MemberSignature.fromMethod(nameResolver, proto.getExtension(methodSignature))
}
AnnotatedCallableKind.PROPERTY_GETTER -> if (proto.hasExtension(propertySignature)) {
return deserializer.methodSignature(proto.getExtension(propertySignature).getGetter())
return MemberSignature.fromMethod(nameResolver, proto.getExtension(propertySignature).getter)
}
AnnotatedCallableKind.PROPERTY_SETTER -> if (proto.hasExtension(propertySignature)) {
return deserializer.methodSignature(proto.getExtension(propertySignature).getSetter())
return MemberSignature.fromMethod(nameResolver, proto.getExtension(propertySignature).setter)
}
AnnotatedCallableKind.PROPERTY -> return getPropertySignature(proto, nameResolver, true, true)
}
@@ -341,4 +338,4 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
public val memberAnnotations: Map<MemberSignature, List<A>>,
public val propertyConstants: Map<MemberSignature, C>
)
}
}
@@ -16,20 +16,26 @@
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
// The purpose of this class is to hold a unique signature of either a method or a field, so that annotations on a member can be put
// into a map indexed by these signatures
data class MemberSignature private constructor(private val signature: String) {
companion object {
@JvmStatic
public fun fromMethodNameAndDesc(nameAndDesc: String): MemberSignature {
return MemberSignature(nameAndDesc)
public fun fromMethod(nameResolver: NameResolver, signature: JvmProtoBuf.JvmMethodSignature): MemberSignature {
return fromMethodNameAndDesc(nameResolver.getString(signature.name), nameResolver.getString(signature.desc))
}
@JvmStatic
public fun fromFieldNameAndDesc(name: Name, desc: String): MemberSignature {
return MemberSignature(name.asString() + "#" + desc)
public fun fromMethodNameAndDesc(name: String, desc: String): MemberSignature {
return MemberSignature(name + desc)
}
@JvmStatic
public fun fromFieldNameAndDesc(name: String, desc: String): MemberSignature {
return MemberSignature(name + "#" + desc)
}
@JvmStatic
@@ -1,82 +0,0 @@
/*
* 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.load.kotlin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
import org.jetbrains.kotlin.serialization.deserialization.NameResolver;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
public class SignatureDeserializer {
// These types are ordered according to their sorts, this is significant for deserialization
private static final char[] PRIMITIVE_TYPES = new char[] {'V', 'Z', 'C', 'B', 'S', 'I', 'F', 'J', 'D'};
private final NameResolver nameResolver;
public SignatureDeserializer(@NotNull NameResolver nameResolver) {
this.nameResolver = nameResolver;
}
@NotNull
public String methodSignatureString(@NotNull JvmProtoBuf.JvmMethodSignature signature) {
Name name = nameResolver.getName(signature.getName());
StringBuilder sb = new StringBuilder();
sb.append('(');
for (int i = 0, length = signature.getParameterTypeCount(); i < length; i++) {
typeDescriptor(signature.getParameterType(i), sb);
}
sb.append(')');
typeDescriptor(signature.getReturnType(), sb);
return name.asString() + sb.toString();
}
@NotNull
public MemberSignature methodSignature(@NotNull JvmProtoBuf.JvmMethodSignature signature) {
return MemberSignature.fromMethodNameAndDesc(methodSignatureString(signature));
}
@NotNull
public String typeDescriptor(@NotNull JvmProtoBuf.JvmType type) {
return typeDescriptor(type, new StringBuilder()).toString();
}
@NotNull
private StringBuilder typeDescriptor(@NotNull JvmProtoBuf.JvmType type, @NotNull StringBuilder sb) {
for (int i = 0; i < type.getArrayDimension(); i++) {
sb.append('[');
}
if (type.hasPrimitiveType()) {
sb.append(PRIMITIVE_TYPES[type.getPrimitiveType().ordinal()]);
}
else {
sb.append("L");
sb.append(fqNameToInternalName(nameResolver.getFqName(type.getClassFqName())));
sb.append(";");
}
return sb;
}
@NotNull
private static String fqNameToInternalName(@NotNull FqName fqName) {
return fqName.asString().replace('.', '/');
}
}
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.JvmType.PrimitiveType.*
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Method
@@ -229,9 +228,44 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
private fun loadParameterTypes(nameResolver: NameResolver, signature: JvmProtoBuf.JvmMethodSignature): List<Class<*>> {
val classLoader = jClass.safeClassLoader
return signature.parameterTypeList.map { jvmType ->
loadJvmType(jvmType, nameResolver, classLoader)
val result = arrayListOf<Class<*>>()
val desc = nameResolver.getString(signature.desc)
var i = 1
while (desc[i] != ')') {
var arrayDimension = 0
while (desc[i] == '[') {
arrayDimension++
i++
}
var type = when (desc[i++]) {
'L' -> {
val semicolon = desc.indexOf(';', i)
val internalName = desc.substring(i, semicolon)
i = semicolon + 1
classLoader.loadClass(internalName.replace('/', '.'))
}
'V' -> Void.TYPE
'Z' -> java.lang.Boolean.TYPE
'C' -> java.lang.Character.TYPE
'B' -> java.lang.Byte.TYPE
'S' -> java.lang.Short.TYPE
'I' -> java.lang.Integer.TYPE
'F' -> java.lang.Float.TYPE
'J' -> java.lang.Long.TYPE
'D' -> java.lang.Double.TYPE
else -> throw KotlinReflectionInternalError("Unknown type prefix in the method signature: $desc")
}
repeat(arrayDimension) {
type = type.createArrayType()
}
result.add(type)
}
return result
}
// TODO: check resulting field's type
@@ -268,42 +302,7 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
return jClass.safeClassLoader.loadClass(classId.asSingleFqName().asString())
}
private fun loadJvmType(
type: JvmProtoBuf.JvmType,
nameResolver: NameResolver,
classLoader: ClassLoader,
arrayDimension: Int = type.getArrayDimension()
): Class<*> {
if (arrayDimension > 0) {
return loadJvmType(type, nameResolver, classLoader, arrayDimension - 1).createArrayType()
}
if (type.hasPrimitiveType()) {
return PRIMITIVE_TYPES[type.getPrimitiveType()]
?: throw KotlinReflectionInternalError("Unknown primitive type: ${type.getPrimitiveType()}")
}
if (type.hasClassFqName()) {
val fqName = nameResolver.getFqName(type.getClassFqName())
return classLoader.loadClass(fqName.asString())
}
throw KotlinReflectionInternalError("Inconsistent metadata for JVM type")
}
companion object {
private val PRIMITIVE_TYPES = mapOf(
VOID to Void.TYPE,
BOOLEAN to java.lang.Boolean.TYPE,
CHAR to java.lang.Character.TYPE,
BYTE to java.lang.Byte.TYPE,
SHORT to java.lang.Short.TYPE,
INT to java.lang.Integer.TYPE,
FLOAT to java.lang.Float.TYPE,
LONG to java.lang.Long.TYPE,
DOUBLE to java.lang.Double.TYPE
)
private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker")
}
}
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.reflect.*
import org.jetbrains.kotlin.load.kotlin.SignatureDeserializer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -52,7 +51,7 @@ internal sealed class JvmFunctionSignature {
val nameResolver: NameResolver
) : JvmFunctionSignature() {
override fun asString(): String =
SignatureDeserializer(nameResolver).methodSignatureString(signature)
nameResolver.getString(signature.name) + nameResolver.getString(signature.desc)
}
class JavaMethod(val method: Method) : JvmFunctionSignature() {
@@ -96,12 +95,12 @@ internal sealed class JvmPropertySignature {
init {
if (signature.hasGetter()) {
string = SignatureDeserializer(nameResolver).methodSignatureString(signature.getter)
string = nameResolver.getString(signature.getter.name) + nameResolver.getString(signature.getter.desc)
}
else {
string = JvmAbi.getterName(nameResolver.getString(signature.field.name)) +
"()" +
SignatureDeserializer(nameResolver).typeDescriptor(signature.field.type)
nameResolver.getString(signature.field.desc)
}
}
@@ -174,15 +173,15 @@ internal object RuntimeTypeMapper {
when (function.name.asString()) {
"equals" -> if (parameters.size() == 1 && KotlinBuiltIns.isNullableAny(parameters.single().type)) {
return JvmFunctionSignature.BuiltInFunction.Predefined("equals(Ljava/lang/Object;)Z",
javaClass<Any>().getDeclaredMethod("equals", javaClass<Any>()))
Any::class.java.getDeclaredMethod("equals", Any::class.java))
}
"hashCode" -> if (parameters.isEmpty()) {
return JvmFunctionSignature.BuiltInFunction.Predefined("hashCode()I",
javaClass<Any>().getDeclaredMethod("hashCode"))
Any::class.java.getDeclaredMethod("hashCode"))
}
"toString" -> if (parameters.isEmpty()) {
return JvmFunctionSignature.BuiltInFunction.Predefined("toString()Ljava/lang/String;",
javaClass<Any>().getDeclaredMethod("toString"))
Any::class.java.getDeclaredMethod("toString"))
}
// TODO: generalize and support other functions from built-ins
}
@@ -299,9 +299,7 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
open fun checkEquals(old: JvmProtoBuf.JvmMethodSignature, new: JvmProtoBuf.JvmMethodSignature): Boolean {
if (!checkStringEquals(old.name, new.name)) return false
if (!checkEquals(old.returnType, new.returnType)) return false
if (!checkEqualsJvmMethodSignatureParameterType(old, new)) return false
if (!checkStringEquals(old.desc, new.desc)) return false
return true
}
@@ -352,29 +350,10 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
return true
}
open fun checkEquals(old: JvmProtoBuf.JvmType, new: JvmProtoBuf.JvmType): Boolean {
if (old.hasPrimitiveType() != new.hasPrimitiveType()) return false
if (old.hasPrimitiveType()) {
if (old.primitiveType != new.primitiveType) return false
}
if (old.hasClassFqName() != new.hasClassFqName()) return false
if (old.hasClassFqName()) {
if (!checkClassIdEquals(old.classFqName, new.classFqName)) return false
}
if (old.hasArrayDimension() != new.hasArrayDimension()) return false
if (old.hasArrayDimension()) {
if (old.arrayDimension != new.arrayDimension) return false
}
return true
}
open fun checkEquals(old: JvmProtoBuf.JvmFieldSignature, new: JvmProtoBuf.JvmFieldSignature): Boolean {
if (!checkStringEquals(old.name, new.name)) return false
if (!checkEquals(old.type, new.type)) return false
if (!checkStringEquals(old.desc, new.desc)) return false
if (old.hasIsStaticInOuter() != new.hasIsStaticInOuter()) return false
if (old.hasIsStaticInOuter()) {
@@ -550,16 +529,6 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
return true
}
open fun checkEqualsJvmMethodSignatureParameterType(old: JvmProtoBuf.JvmMethodSignature, new: JvmProtoBuf.JvmMethodSignature): Boolean {
if (old.parameterTypeCount != new.parameterTypeCount) return false
for(i in 0..old.parameterTypeCount - 1) {
if (!checkEquals(old.getParameterType(i), new.getParameterType(i))) return false
}
return true
}
open fun checkEqualsAnnotationArgumentValueArrayElement(old: ProtoBuf.Annotation.Argument.Value, new: ProtoBuf.Annotation.Argument.Value): Boolean {
if (old.arrayElementCount != new.arrayElementCount) return false
@@ -814,11 +783,7 @@ public fun JvmProtoBuf.JvmMethodSignature.hashCode(stringIndexes: (Int) -> Int,
hashCode = 31 * hashCode + stringIndexes(name)
hashCode = 31 * hashCode + returnType.hashCode(stringIndexes, fqNameIndexes)
for(i in 0..parameterTypeCount - 1) {
hashCode = 31 * hashCode + getParameterType(i).hashCode(stringIndexes, fqNameIndexes)
}
hashCode = 31 * hashCode + stringIndexes(desc)
return hashCode
}
@@ -869,30 +834,12 @@ public fun ProtoBuf.Annotation.Argument.hashCode(stringIndexes: (Int) -> Int, fq
return hashCode
}
public fun JvmProtoBuf.JvmType.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1
if (hasPrimitiveType()) {
hashCode = 31 * hashCode + primitiveType.hashCode()
}
if (hasClassFqName()) {
hashCode = 31 * hashCode + fqNameIndexes(classFqName)
}
if (hasArrayDimension()) {
hashCode = 31 * hashCode + arrayDimension
}
return hashCode
}
public fun JvmProtoBuf.JvmFieldSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1
hashCode = 31 * hashCode + stringIndexes(name)
hashCode = 31 * hashCode + type.hashCode(stringIndexes, fqNameIndexes)
hashCode = 31 * hashCode + stringIndexes(desc)
if (hasIsStaticInOuter()) {
hashCode = 31 * hashCode + isStaticInOuter.hashCode()