diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 4dd9a03a06c..ffeb94c43ba 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -152,6 +152,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl { if (kind == JvmMethodParameterKind.VALUE) { ValueParameterDescriptor parameter = iterator.next(); + v.getMemberMap().recordIndexForValueParameter(parameter, i); AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameter); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JavaSerializerExtension.java b/compiler/backend/src/org/jetbrains/jet/codegen/JavaSerializerExtension.java index 754c7e44681..77cac7989f5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JavaSerializerExtension.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JavaSerializerExtension.java @@ -48,6 +48,18 @@ public class JavaSerializerExtension extends SerializerExtension { saveImplClassName(callable, proto, nameTable); } + @Override + public void serializeValueParameter( + @NotNull ValueParameterDescriptor descriptor, + @NotNull ProtoBuf.Callable.ValueParameter.Builder proto, + @NotNull NameTable nameTable + ) { + Integer index = memberMap.getIndexForValueParameter(descriptor); + if (index != null) { + proto.setExtension(JavaProtoBuf.index, index); + } + } + private void saveSignature( @NotNull CallableMemberDescriptor callable, @NotNull ProtoBuf.Callable.Builder proto, diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberMap.java index 6914750cb2a..32e0edc3332 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberMap.java @@ -24,6 +24,7 @@ import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import java.util.*; @@ -33,6 +34,7 @@ public final class MemberMap { private final Map syntheticMethodForProperty = new HashMap(); private final Map implClassNameForCallable = new HashMap(); private final Set staticFieldInOuterClass = new HashSet(); + private final Map indexForValueParameter = new HashMap(); @NotNull public static MemberMap union(@NotNull Collection maps) { @@ -57,6 +59,10 @@ public final class MemberMap { for (PropertyDescriptor property : map.staticFieldInOuterClass) { result.recordStaticFieldInOuterClass(property); } + + for (Map.Entry entry : map.indexForValueParameter.entrySet()) { + result.recordIndexForValueParameter(entry.getKey(), entry.getValue()); + } } return result; @@ -87,6 +93,11 @@ public final class MemberMap { assert added : "Duplicate static field in outer class: " + property; } + public void recordIndexForValueParameter(@NotNull ValueParameterDescriptor descriptor, int index) { + Integer old = indexForValueParameter.put(descriptor, index); + assert old == null || old == index : "Duplicate index for value parameter: " + descriptor; + } + @Nullable public Method getMethodOfDescriptor(@NotNull FunctionDescriptor descriptor) { return methodForFunction.get(descriptor); @@ -111,11 +122,17 @@ public final class MemberMap { return staticFieldInOuterClass.contains(property); } + @Nullable + public Integer getIndexForValueParameter(@NotNull ValueParameterDescriptor descriptor) { + return indexForValueParameter.get(descriptor); + } + @Override public String toString() { return "Functions: " + methodForFunction.size() + ", fields: " + fieldForProperty.size() + ", synthetic methods: " + syntheticMethodForProperty.size() + - ", impl class names: " + implClassNameForCallable.size(); + ", impl class names: " + implClassNameForCallable.size() + + ", value parameters: " + indexForValueParameter.size(); } } diff --git a/compiler/frontend/serialization/src/descriptors.proto b/compiler/frontend/serialization/src/descriptors.proto index f93fe74ebf7..60f5f829864 100644 --- a/compiler/frontend/serialization/src/descriptors.proto +++ b/compiler/frontend/serialization/src/descriptors.proto @@ -189,6 +189,7 @@ message Callable { required Type type = 3; optional Type vararg_element_type = 4; + extensions 100 to 199; } repeated ValueParameter value_parameter = 7; diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorSerializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorSerializer.java index b996b220e4c..a88c73e6cec 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorSerializer.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorSerializer.java @@ -272,7 +272,8 @@ public class DescriptorSerializer { return ProtoBuf.Callable.CallableKind.FUN; } - private ProtoBuf.Callable.ValueParameter.Builder valueParameter(ValueParameterDescriptor descriptor) { + @NotNull + private ProtoBuf.Callable.ValueParameter.Builder valueParameter(@NotNull ValueParameterDescriptor descriptor) { ProtoBuf.Callable.ValueParameter.Builder builder = ProtoBuf.Callable.ValueParameter.newBuilder(); builder.setFlags(Flags.getValueParameterFlags(hasAnnotations(descriptor), descriptor.declaresDefaultValue())); @@ -286,6 +287,8 @@ public class DescriptorSerializer { builder.setVarargElementType(type(varargElementType)); } + extension.serializeValueParameter(descriptor, builder, nameTable); + return builder; } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ProtoBuf.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ProtoBuf.java index 734df5095cb..13b697c6890 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ProtoBuf.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ProtoBuf.java @@ -7515,8 +7515,9 @@ public final class ProtoBuf { // @@protoc_insertion_point(enum_scope:org.jetbrains.jet.descriptors.serialization.Callable.CallableKind) } - public interface ValueParameterOrBuilder - extends com.google.protobuf.MessageLiteOrBuilder { + public interface ValueParameterOrBuilder extends + com.google.protobuf.GeneratedMessageLite. + ExtendableMessageOrBuilder { // optional int32 flags = 1; /** @@ -7574,10 +7575,10 @@ public final class ProtoBuf { * Protobuf type {@code org.jetbrains.jet.descriptors.serialization.Callable.ValueParameter} */ public static final class ValueParameter extends - com.google.protobuf.GeneratedMessageLite - implements ValueParameterOrBuilder { + com.google.protobuf.GeneratedMessageLite.ExtendableMessage< + ValueParameter> implements ValueParameterOrBuilder { // Use ValueParameter.newBuilder() to construct. - private ValueParameter(com.google.protobuf.GeneratedMessageLite.Builder builder) { + private ValueParameter(com.google.protobuf.GeneratedMessageLite.ExtendableBuilder builder) { super(builder); } @@ -7781,6 +7782,10 @@ public final class ProtoBuf { return false; } } + if (!extensionsAreInitialized()) { + memoizedIsInitialized = 0; + return false; + } memoizedIsInitialized = 1; return true; } @@ -7788,6 +7793,9 @@ public final class ProtoBuf { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); + com.google.protobuf.GeneratedMessageLite + .ExtendableMessage.ExtensionWriter extensionWriter = + newExtensionWriter(); if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeInt32(1, flags_); } @@ -7800,6 +7808,7 @@ public final class ProtoBuf { if (((bitField0_ & 0x00000008) == 0x00000008)) { output.writeMessage(4, varargElementType_); } + extensionWriter.writeUntil(200, output); } private int memoizedSerializedSize = -1; @@ -7824,6 +7833,7 @@ public final class ProtoBuf { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, varargElementType_); } + size += extensionsSerializedSize(); memoizedSerializedSize = size; return size; } @@ -7899,9 +7909,8 @@ public final class ProtoBuf { * Protobuf type {@code org.jetbrains.jet.descriptors.serialization.Callable.ValueParameter} */ public static final class Builder extends - com.google.protobuf.GeneratedMessageLite.Builder< - org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.ValueParameter, Builder> - implements org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.ValueParameterOrBuilder { + com.google.protobuf.GeneratedMessageLite.ExtendableBuilder< + org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.ValueParameter, Builder> implements org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.ValueParameterOrBuilder { // Construct using org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.ValueParameter.newBuilder() private Builder() { maybeForceBuilderInitialization(); @@ -7980,6 +7989,7 @@ public final class ProtoBuf { if (other.hasVarargElementType()) { mergeVarargElementType(other.getVarargElementType()); } + this.mergeExtensionFields(other); return this; } @@ -8002,6 +8012,10 @@ public final class ProtoBuf { return false; } } + if (!extensionsAreInitialized()) { + + return false; + } return true; } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/SerializerExtension.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/SerializerExtension.java index 53215e36252..bff8ffeae04 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/SerializerExtension.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/SerializerExtension.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.descriptors.serialization; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; public abstract class SerializerExtension { public static final SerializerExtension DEFAULT = new SerializerExtension() {}; @@ -33,4 +34,11 @@ public abstract class SerializerExtension { @NotNull NameTable nameTable ) { } + + public void serializeValueParameter( + @NotNull ValueParameterDescriptor descriptor, + @NotNull ProtoBuf.Callable.ValueParameter.Builder proto, + @NotNull NameTable nameTable + ) { + } } diff --git a/core/serialization.java/src/java_descriptors.proto b/core/serialization.java/src/java_descriptors.proto index 1988f103cdb..548e99d7e41 100644 --- a/core/serialization.java/src/java_descriptors.proto +++ b/core/serialization.java/src/java_descriptors.proto @@ -81,3 +81,8 @@ extend Callable { // 2) annotations on properties in traits are written to TImpl classes optional int32 impl_class_name = 102; } + +extend Callable.ValueParameter { + // Index of the corresponding parameter of this method in JVM (counting receiver parameters, enum constructor synthetic parameters, etc.) + optional int32 index = 100; +} diff --git a/core/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBuf.java b/core/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBuf.java index 245b9b7b9eb..b9d7782c35d 100644 --- a/core/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBuf.java +++ b/core/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBuf.java @@ -10,6 +10,7 @@ public final class JavaProtoBuf { registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.methodSignature); registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.propertySignature); registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.implClassName); + registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.index); } public interface JavaTypeOrBuilder extends com.google.protobuf.MessageLiteOrBuilder { @@ -2840,6 +2841,21 @@ public final class JavaProtoBuf { null, 102, com.google.protobuf.WireFormat.FieldType.INT32); + public static final int INDEX_FIELD_NUMBER = 100; + /** + * extend .org.jetbrains.jet.descriptors.serialization.Callable.ValueParameter { ... } + */ + public static final + com.google.protobuf.GeneratedMessageLite.GeneratedExtension< + org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.ValueParameter, + java.lang.Integer> index = com.google.protobuf.GeneratedMessageLite + .newSingularGeneratedExtension( + org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.ValueParameter.getDefaultInstance(), + 0, + null, + null, + 100, + com.google.protobuf.WireFormat.FieldType.INT32); static { }