Change object deserialization strategy

Objects now have synthetic class objects in deserialization as well. "Class"
proto message now can have a synthetic class object proto within, if it's not
contained in any external class file, which is the case with objects. Drop
"class_object_present" field from binary format, since its value is equivalent
to the presence of "class_object" field
This commit is contained in:
Alexander Udalov
2013-10-29 22:11:07 +04:00
parent 26bd1ff189
commit c04f63e157
17 changed files with 709 additions and 165 deletions
@@ -210,14 +210,12 @@ public class NamespaceCodegen extends MemberCodegen {
* @param namespaceFiles all files should have same package name
* @return
*/
public static boolean shouldGenerateNSClass(Collection<JetFile> namespaceFiles) {
public static boolean shouldGenerateNSClass(@NotNull Collection<JetFile> namespaceFiles) {
checkAllFilesHaveSameNamespace(namespaceFiles);
for (JetFile file : namespaceFiles) {
for (JetDeclaration declaration : file.getDeclarations()) {
if (declaration instanceof JetProperty ||
declaration instanceof JetNamedFunction ||
declaration instanceof JetObjectDeclaration) {
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
return true;
}
}
Binary file not shown.
Binary file not shown.
@@ -110,6 +110,15 @@ message Class {
required int32 fq_name = 3;
message ClassObject {
// If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
// Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
optional Class data = 1;
}
// This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
optional ClassObject class_object = 4;
repeated TypeParameter type_parameter = 5;
repeated Type supertype = 6;
@@ -118,8 +127,6 @@ message Class {
repeated int32 nested_class_name = 7;
repeated int32 nested_object_name = 8;
optional bool class_object_present = 9 [default = false];
repeated Callable member = 11;
repeated int32 enum_entry = 12;
@@ -26,7 +26,6 @@ import org.jetbrains.jet.storage.MemoizedFunctionToNullable;
import org.jetbrains.jet.storage.StorageManager;
public abstract class AbstractDescriptorFinder implements DescriptorFinder {
private final MemoizedFunctionToNullable<ClassId, ClassDescriptor> findClass;
private final AnnotationDeserializer annotationDeserializer;
@@ -46,7 +45,8 @@ public abstract class AbstractDescriptorFinder implements DescriptorFinder {
AbstractDescriptorFinder _this = AbstractDescriptorFinder.this;
ClassDescriptor classDescriptor =
new DeserializedClassDescriptor(storageManager, _this.annotationDeserializer, _this, classData);
new DeserializedClassDescriptor(storageManager, _this.annotationDeserializer, _this, classData.getNameResolver(),
classData.getClassProto());
classDescriptorCreated(classDescriptor);
return classDescriptor;
}
@@ -29,17 +29,14 @@ import org.jetbrains.jet.renderer.DescriptorRenderer;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getEnumEntriesScope;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTopLevelOrInnerClass;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
public class DescriptorSerializer {
private static final DescriptorRenderer RENDERER = DescriptorRenderer.STARTS_FROM_NAME;
private static final Comparator<DeclarationDescriptor> DESCRIPTOR_COMPARATOR = new Comparator<DeclarationDescriptor>() {
@Override
public int compare(
DeclarationDescriptor o1, DeclarationDescriptor o2
) {
public int compare(@NotNull DeclarationDescriptor o1, @NotNull DeclarationDescriptor o2) {
int names = o1.getName().compareTo(o2.getName());
if (names != 0) return names;
@@ -134,9 +131,9 @@ public class DescriptorSerializer {
builder.addNestedObjectName(nameIndex);
}
if (classDescriptor.getClassObjectDescriptor() != null) {
// false is default
builder.setClassObjectPresent(true);
ClassDescriptor classObject = classDescriptor.getClassObjectDescriptor();
if (classObject != null) {
builder.setClassObject(classObjectProto(classObject));
}
if (classDescriptor.getKind() == ClassKind.ENUM_CLASS) {
@@ -150,6 +147,15 @@ public class DescriptorSerializer {
return builder;
}
@NotNull
private ProtoBuf.Class.ClassObject classObjectProto(@NotNull ClassDescriptor classObject) {
if (isObject(classObject.getContainingDeclaration())) {
return ProtoBuf.Class.ClassObject.newBuilder().setData(classProto(classObject)).build();
}
return ProtoBuf.Class.ClassObject.getDefaultInstance();
}
@NotNull
public ProtoBuf.Callable.Builder callableProto(@NotNull CallableMemberDescriptor descriptor) {
ProtoBuf.Callable.Builder builder = ProtoBuf.Callable.newBuilder();
@@ -48,6 +48,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
private final ClassId classId;
private final ProtoBuf.Class classProto;
private final StorageManager storageManager;
private final TypeDeserializer typeDeserializer;
private final DescriptorDeserializer deserializer;
private final DeserializedMemberScope memberScope;
@@ -74,14 +75,13 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
@NotNull StorageManager storageManager,
@NotNull AnnotationDeserializer annotationResolver,
@NotNull DescriptorFinder descriptorFinder,
@NotNull ClassData classData
@NotNull NameResolver nameResolver,
@NotNull ProtoBuf.Class classProto
) {
super(storageManager,
classData.getNameResolver().getClassId(classData.getClassProto().getFqName()).getRelativeClassName().shortName());
NameResolver nameResolver = classData.getNameResolver();
this.classProto = classData.getClassProto();
super(storageManager, nameResolver.getClassId(classProto.getFqName()).getRelativeClassName().shortName());
this.classProto = classProto;
this.classId = nameResolver.getClassId(classProto.getFqName());
this.storageManager = storageManager;
this.descriptorFinder = descriptorFinder;
TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, null, nameResolver,
@@ -238,7 +238,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
@Nullable
private ClassDescriptor computeClassObjectDescriptor() {
if (!classProto.getClassObjectPresent()) {
if (!classProto.hasClassObject()) {
return null;
}
@@ -252,6 +252,16 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
return classObject;
}
if (getKind() == ClassKind.OBJECT) {
ProtoBuf.Class.ClassObject classObjectProto = classProto.getClassObject();
if (!classObjectProto.hasData()) {
throw new IllegalStateException("Object should have a serialized class object: " + classId);
}
return new DeserializedClassDescriptor(storageManager, annotationDeserializer, descriptorFinder, deserializer.getNameResolver(),
classObjectProto.getData());
}
return descriptorFinder.findClass(classId.createNestedClassId(getClassObjectName(getName())));
}
@@ -55,11 +55,7 @@ public final class JavaPackageScope extends JavaBaseScope {
@Override
public ClassifierDescriptor getClassifier(@NotNull Name name) {
ClassDescriptor classDescriptor = memberResolver.resolveClass(packageFQN.child(name), IGNORE_KOTLIN_SOURCES);
if (classDescriptor == null || classDescriptor.getKind().isSingleton()) {
return null;
}
return classDescriptor;
return memberResolver.resolveClass(packageFQN.child(name), IGNORE_KOTLIN_SOURCES);
}
@Override
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.kotlin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassData;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.descriptors.serialization.DescriptorFinder;
import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil;
@@ -97,15 +98,22 @@ public final class DeserializedDescriptorResolver {
@Nullable
public ClassDescriptor resolveClass(@NotNull KotlinJvmBinaryClass kotlinClass) {
String[] data = readData(kotlinClass);
return data == null ? null : new DeserializedClassDescriptor(storageManager, annotationDeserializer, javaDescriptorFinder,
JavaProtoBufUtil.readClassDataFrom(data));
if (data != null) {
ClassData classData = JavaProtoBufUtil.readClassDataFrom(data);
return new DeserializedClassDescriptor(storageManager, annotationDeserializer, javaDescriptorFinder,
classData.getNameResolver(), classData.getClassProto());
}
return null;
}
@Nullable
public JetScope createKotlinPackageScope(@NotNull NamespaceDescriptor descriptor, @NotNull KotlinJvmBinaryClass kotlinClass) {
String[] data = readData(kotlinClass);
return data == null ? null : new DeserializedPackageMemberScope(storageManager, descriptor, annotationDeserializer,
javaDescriptorFinder, JavaProtoBufUtil.readPackageDataFrom(data));
if (data != null) {
return new DeserializedPackageMemberScope(storageManager, descriptor, annotationDeserializer, javaDescriptorFinder,
JavaProtoBufUtil.readPackageDataFrom(data));
}
return null;
}
@Nullable