diff --git a/compiler/frontend/serialization/src/descriptors.proto b/compiler/frontend/serialization/src/descriptors.proto index e502813ca16..575df4cfc6e 100644 --- a/compiler/frontend/serialization/src/descriptors.proto +++ b/compiler/frontend/serialization/src/descriptors.proto @@ -124,6 +124,8 @@ message Class { // todo: other constructors? repeated Callable member = 11; + + repeated int32 enum_entry = 12; } message Callable { 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 b973c1d2db1..507794e0e37 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 @@ -128,6 +128,16 @@ public class DescriptorSerializer { builder.setClassObjectPresent(true); } + if (classDescriptor.getKind() == ClassKind.ENUM_CLASS) { + ClassDescriptor classObject = classDescriptor.getClassObjectDescriptor(); + assert classObject != null : "Enum class object shouldn't be null: " + classDescriptor; + for (ClassDescriptor descriptor : classObject.getDefaultType().getMemberScope().getObjectDescriptors()) { + if (descriptor.getKind() == ClassKind.ENUM_ENTRY) { + builder.addEnumEntry(nameTable.getSimpleNameIndex(descriptor.getName())); + } + } + } + return builder; } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/NameResolver.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/NameResolver.java index c7f9c006dae..c27e1dbf855 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/NameResolver.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/NameResolver.java @@ -45,7 +45,7 @@ public class NameResolver { @NotNull public ClassId getClassId(int index) { QualifiedName fqNameProto = qualifiedNames.getQualifiedName(index); - assert fqNameProto.getKind() == ProtoBuf.QualifiedNameTable.QualifiedName.Kind.CLASS : "Not a class fqName: " + getClassId(index); + assert fqNameProto.getKind() == ProtoBuf.QualifiedNameTable.QualifiedName.Kind.CLASS : "Not a class fqName: " + fqNameProto.getKind(); StringBuilder relativeClassName = new StringBuilder(); QualifiedName packageFqNameProto = renderFqName(relativeClassName, fqNameProto, QualifiedName.Kind.CLASS); 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 47545c45f3a..5844e6c5b7e 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 @@ -3371,6 +3371,11 @@ public final class ProtoBuf { getMemberList(); org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable getMember(int index); int getMemberCount(); + + // repeated int32 enum_entry = 12; + java.util.List getEnumEntryList(); + int getEnumEntryCount(); + int getEnumEntry(int index); } public static final class Class extends com.google.protobuf.GeneratedMessageLite @@ -3610,6 +3615,20 @@ public final class ProtoBuf { return member_.get(index); } + // repeated int32 enum_entry = 12; + public static final int ENUM_ENTRY_FIELD_NUMBER = 12; + private java.util.List enumEntry_; + public java.util.List + getEnumEntryList() { + return enumEntry_; + } + public int getEnumEntryCount() { + return enumEntry_.size(); + } + public int getEnumEntry(int index) { + return enumEntry_.get(index); + } + private void initFields() { flags_ = 0; extraVisibility_ = ""; @@ -3621,6 +3640,7 @@ public final class ProtoBuf { classObjectPresent_ = false; primaryConstructor_ = org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.getDefaultInstance(); member_ = java.util.Collections.emptyList(); + enumEntry_ = java.util.Collections.emptyList();; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -3692,6 +3712,9 @@ public final class ProtoBuf { for (int i = 0; i < member_.size(); i++) { output.writeMessage(11, member_.get(i)); } + for (int i = 0; i < enumEntry_.size(); i++) { + output.writeInt32(12, enumEntry_.get(i)); + } } private int memoizedSerializedSize = -1; @@ -3750,6 +3773,15 @@ public final class ProtoBuf { size += com.google.protobuf.CodedOutputStream .computeMessageSize(11, member_.get(i)); } + { + int dataSize = 0; + for (int i = 0; i < enumEntry_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeInt32SizeNoTag(enumEntry_.get(i)); + } + size += dataSize; + size += 1 * getEnumEntryList().size(); + } memoizedSerializedSize = size; return size; } @@ -3872,6 +3904,8 @@ public final class ProtoBuf { bitField0_ = (bitField0_ & ~0x00000100); member_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000200); + enumEntry_ = java.util.Collections.emptyList();; + bitField0_ = (bitField0_ & ~0x00000400); return this; } @@ -3950,6 +3984,11 @@ public final class ProtoBuf { bitField0_ = (bitField0_ & ~0x00000200); } result.member_ = member_; + if (((bitField0_ & 0x00000400) == 0x00000400)) { + enumEntry_ = java.util.Collections.unmodifiableList(enumEntry_); + bitField0_ = (bitField0_ & ~0x00000400); + } + result.enumEntry_ = enumEntry_; result.bitField0_ = to_bitField0_; return result; } @@ -4020,6 +4059,16 @@ public final class ProtoBuf { member_.addAll(other.member_); } + } + if (!other.enumEntry_.isEmpty()) { + if (enumEntry_.isEmpty()) { + enumEntry_ = other.enumEntry_; + bitField0_ = (bitField0_ & ~0x00000400); + } else { + ensureEnumEntryIsMutable(); + enumEntry_.addAll(other.enumEntry_); + } + } return this; } @@ -4148,6 +4197,20 @@ public final class ProtoBuf { addMember(subBuilder.buildPartial()); break; } + case 96: { + ensureEnumEntryIsMutable(); + enumEntry_.add(input.readInt32()); + break; + } + case 98: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + while (input.getBytesUntilLimit() > 0) { + addEnumEntry(input.readInt32()); + } + input.popLimit(limit); + break; + } } } } @@ -4653,6 +4716,51 @@ public final class ProtoBuf { return this; } + // repeated int32 enum_entry = 12; + private java.util.List enumEntry_ = java.util.Collections.emptyList();; + private void ensureEnumEntryIsMutable() { + if (!((bitField0_ & 0x00000400) == 0x00000400)) { + enumEntry_ = new java.util.ArrayList(enumEntry_); + bitField0_ |= 0x00000400; + } + } + public java.util.List + getEnumEntryList() { + return java.util.Collections.unmodifiableList(enumEntry_); + } + public int getEnumEntryCount() { + return enumEntry_.size(); + } + public int getEnumEntry(int index) { + return enumEntry_.get(index); + } + public Builder setEnumEntry( + int index, int value) { + ensureEnumEntryIsMutable(); + enumEntry_.set(index, value); + + return this; + } + public Builder addEnumEntry(int value) { + ensureEnumEntryIsMutable(); + enumEntry_.add(value); + + return this; + } + public Builder addAllEnumEntry( + java.lang.Iterable values) { + ensureEnumEntryIsMutable(); + super.addAll(values, enumEntry_); + + return this; + } + public Builder clearEnumEntry() { + enumEntry_ = java.util.Collections.emptyList();; + bitField0_ = (bitField0_ & ~0x00000400); + + return this; + } + // @@protoc_insertion_point(builder_scope:org.jetbrains.jet.descriptors.serialization.Class) } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java index 94f8e56f131..9bd055c83e1 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java @@ -25,8 +25,9 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.AbstractReceiverParameterDescriptor; import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorBase; -import org.jetbrains.jet.lang.resolve.OverrideResolver; -import org.jetbrains.jet.lang.resolve.TraceUtil; +import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; +import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; +import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.lazy.storage.*; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper; @@ -39,6 +40,7 @@ import org.jetbrains.jet.lang.types.TypeConstructor; import java.util.*; import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName; public class DeserializedClassDescriptor extends ClassDescriptorBase implements ClassDescriptor { @@ -120,7 +122,7 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements this.classObjectDescriptor = storageManager.createNullableLazyValue(new Computable() { @Override public ClassDescriptor compute() { - return computeClassObjectDecriptor(); + return computeClassObjectDescriptor(); } }); this.nestedClasses = new NestedClassDescriptors(storageManager, stringSet(classProto.getNestedClassNameList(), nameResolver)) { @@ -250,11 +252,32 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements } @Nullable - private ClassDescriptor computeClassObjectDecriptor() { + private ClassDescriptor computeClassObjectDescriptor() { if (!classProto.getClassObjectPresent()) { return null; } + if (getKind() == ClassKind.ENUM_CLASS) { + MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor( + this, getUnsubstitutedInnerClassesScope() /* TODO ?! */, ClassKind.CLASS_OBJECT, false, getClassObjectName(getName())); + classObjectDescriptor.setModality(Modality.FINAL); + classObjectDescriptor.setVisibility(getVisibility()); + classObjectDescriptor.setTypeParameterDescriptors(Collections.emptyList()); + classObjectDescriptor.createTypeConstructor(); + + // TODO: do something if trace has errors? + BindingTrace trace = new BindingTraceContext(); + ConstructorDescriptorImpl primaryConstructorForObject = DescriptorResolver.createPrimaryConstructorForObject(classObjectDescriptor); + primaryConstructorForObject.setReturnType(classObjectDescriptor.getDefaultType()); + classObjectDescriptor.setPrimaryConstructor(primaryConstructorForObject, trace); + + classObjectDescriptor.getBuilder().addFunctionDescriptor( + DescriptorResolver.createEnumClassObjectValuesMethod(classObjectDescriptor, trace)); + classObjectDescriptor.getBuilder().addFunctionDescriptor( + DescriptorResolver.createEnumClassObjectValueOfMethod(classObjectDescriptor, trace)); + return classObjectDescriptor; + } + return nestedClassResolver.resolveClassObject(this); }