Serialize FQ names of Kotlin classes

This helps to avoid a nasty hack with loading inner Kotlin classes in JDR,
which makes it a bit easier to 'lazify' JDR, since now the container of a
Kotlin class is no longer required to be resolved eagerly before resolution of
the class itself
This commit is contained in:
Alexander Udalov
2013-09-23 18:49:05 +04:00
parent a16db2c773
commit a97bb80216
219 changed files with 208 additions and 230 deletions
@@ -108,7 +108,7 @@ message Class {
optional int32 flags = 1 [default = 0 /*internal final class, no annotations*/];
optional string extra_visibility = 2; // for things like java-specific visibilities
required int32 name = 4;
required int32 fq_name = 3;
repeated TypeParameter type_parameter = 5;
repeated Type supertype = 6;
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNullable;
import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager;
@@ -47,16 +46,9 @@ public abstract class AbstractDescriptorFinder implements DescriptorFinder {
return null;
}
ProtoBuf.Class classProto = classData.getClassProto();
DeclarationDescriptor owner =
classId.isTopLevelClass() ? findPackage(classId.getPackageFqName()) : findClass(classId.getOuterClassId());
assert owner != null : "No owner found for " + classId;
AbstractDescriptorFinder _this = AbstractDescriptorFinder.this;
ClassDescriptor classDescriptor = new DeserializedClassDescriptor(
classId, storageManager, owner, classData.getNameResolver(),
_this.annotationDeserializer, _this, classProto, null);
ClassDescriptor classDescriptor =
new DeserializedClassDescriptor(storageManager, _this.annotationDeserializer, _this, classData);
classDescriptorCreated(classDescriptor);
return classDescriptor;
}
@@ -84,7 +84,7 @@ public class DescriptorSerializer {
// TODO extra visibility
builder.setName(nameTable.getSimpleNameIndex(classDescriptor.getName()));
builder.setFqName(getClassId(classDescriptor));
DescriptorSerializer local = createChildSerializer();
@@ -4344,15 +4344,15 @@ public final class ProtoBuf {
com.google.protobuf.ByteString
getExtraVisibilityBytes();
// required int32 name = 4;
// required int32 fq_name = 3;
/**
* <code>required int32 name = 4;</code>
* <code>required int32 fq_name = 3;</code>
*/
boolean hasName();
boolean hasFqName();
/**
* <code>required int32 name = 4;</code>
* <code>required int32 fq_name = 3;</code>
*/
int getName();
int getFqName();
// repeated .org.jetbrains.jet.descriptors.serialization.TypeParameter type_parameter = 5;
/**
@@ -4537,9 +4537,9 @@ public final class ProtoBuf {
extraVisibility_ = input.readBytes();
break;
}
case 32: {
case 24: {
bitField0_ |= 0x00000004;
name_ = input.readInt32();
fqName_ = input.readInt32();
break;
}
case 42: {
@@ -4890,20 +4890,20 @@ public final class ProtoBuf {
}
}
// required int32 name = 4;
public static final int NAME_FIELD_NUMBER = 4;
private int name_;
// required int32 fq_name = 3;
public static final int FQ_NAME_FIELD_NUMBER = 3;
private int fqName_;
/**
* <code>required int32 name = 4;</code>
* <code>required int32 fq_name = 3;</code>
*/
public boolean hasName() {
public boolean hasFqName() {
return ((bitField0_ & 0x00000004) == 0x00000004);
}
/**
* <code>required int32 name = 4;</code>
* <code>required int32 fq_name = 3;</code>
*/
public int getName() {
return name_;
public int getFqName() {
return fqName_;
}
// repeated .org.jetbrains.jet.descriptors.serialization.TypeParameter type_parameter = 5;
@@ -5141,7 +5141,7 @@ public final class ProtoBuf {
private void initFields() {
flags_ = 0;
extraVisibility_ = "";
name_ = 0;
fqName_ = 0;
typeParameter_ = java.util.Collections.emptyList();
supertype_ = java.util.Collections.emptyList();
nestedClassName_ = java.util.Collections.emptyList();
@@ -5156,7 +5156,7 @@ public final class ProtoBuf {
byte isInitialized = memoizedIsInitialized;
if (isInitialized != -1) return isInitialized == 1;
if (!hasName()) {
if (!hasFqName()) {
memoizedIsInitialized = 0;
return false;
}
@@ -5198,7 +5198,7 @@ public final class ProtoBuf {
output.writeBytes(2, getExtraVisibilityBytes());
}
if (((bitField0_ & 0x00000004) == 0x00000004)) {
output.writeInt32(4, name_);
output.writeInt32(3, fqName_);
}
for (int i = 0; i < typeParameter_.size(); i++) {
output.writeMessage(5, typeParameter_.get(i));
@@ -5242,7 +5242,7 @@ public final class ProtoBuf {
}
if (((bitField0_ & 0x00000004) == 0x00000004)) {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(4, name_);
.computeInt32Size(3, fqName_);
}
for (int i = 0; i < typeParameter_.size(); i++) {
size += com.google.protobuf.CodedOutputStream
@@ -5386,7 +5386,7 @@ public final class ProtoBuf {
bitField0_ = (bitField0_ & ~0x00000001);
extraVisibility_ = "";
bitField0_ = (bitField0_ & ~0x00000002);
name_ = 0;
fqName_ = 0;
bitField0_ = (bitField0_ & ~0x00000004);
typeParameter_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000008);
@@ -5438,7 +5438,7 @@ public final class ProtoBuf {
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
to_bitField0_ |= 0x00000004;
}
result.name_ = name_;
result.fqName_ = fqName_;
if (((bitField0_ & 0x00000008) == 0x00000008)) {
typeParameter_ = java.util.Collections.unmodifiableList(typeParameter_);
bitField0_ = (bitField0_ & ~0x00000008);
@@ -5491,8 +5491,8 @@ public final class ProtoBuf {
extraVisibility_ = other.extraVisibility_;
}
if (other.hasName()) {
setName(other.getName());
if (other.hasFqName()) {
setFqName(other.getFqName());
}
if (!other.typeParameter_.isEmpty()) {
if (typeParameter_.isEmpty()) {
@@ -5564,7 +5564,7 @@ public final class ProtoBuf {
}
public final boolean isInitialized() {
if (!hasName()) {
if (!hasFqName()) {
return false;
}
@@ -5781,35 +5781,35 @@ public final class ProtoBuf {
return this;
}
// required int32 name = 4;
private int name_ ;
// required int32 fq_name = 3;
private int fqName_ ;
/**
* <code>required int32 name = 4;</code>
* <code>required int32 fq_name = 3;</code>
*/
public boolean hasName() {
public boolean hasFqName() {
return ((bitField0_ & 0x00000004) == 0x00000004);
}
/**
* <code>required int32 name = 4;</code>
* <code>required int32 fq_name = 3;</code>
*/
public int getName() {
return name_;
public int getFqName() {
return fqName_;
}
/**
* <code>required int32 name = 4;</code>
* <code>required int32 fq_name = 3;</code>
*/
public Builder setName(int value) {
public Builder setFqName(int value) {
bitField0_ |= 0x00000004;
name_ = value;
fqName_ = value;
return this;
}
/**
* <code>required int32 name = 4;</code>
* <code>required int32 fq_name = 3;</code>
*/
public Builder clearName() {
public Builder clearFqName() {
bitField0_ = (bitField0_ & ~0x00000004);
name_ = 0;
fqName_ = 0;
return this;
}
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -45,7 +46,7 @@ import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeP
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName;
public class DeserializedClassDescriptor extends ClassDescriptorBase implements ClassDescriptor {
public class DeserializedClassDescriptor extends AbstractClassDescriptor implements ClassDescriptor {
private final ClassId classId;
private final ProtoBuf.Class classProto;
@@ -64,6 +65,7 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements
private final NestedClassDescriptors nestedClasses;
private final NestedClassDescriptors nestedObjects;
private final NotNullLazyValue<DeclarationDescriptor> containingDeclaration;
private final DeserializedClassTypeConstructor typeConstructor;
private final Modality modality;
private final Visibility visibility;
@@ -73,29 +75,33 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements
private final DescriptorFinder descriptorFinder;
public DeserializedClassDescriptor(
@NotNull ClassId classId,
@NotNull StorageManager storageManager,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull NameResolver nameResolver,
@NotNull AnnotationDeserializer annotationResolver,
@NotNull final DescriptorFinder descriptorFinder,
@NotNull ProtoBuf.Class classProto,
@Nullable TypeDeserializer outerTypeDeserializer
@NotNull ClassData classData
) {
super(containingDeclaration, nameResolver.getName(classProto.getName()));
super(classData.getNameResolver().getClassId(classData.getClassProto().getFqName()).getRelativeClassName().shortName());
NameResolver nameResolver = classData.getNameResolver();
this.classProto = classData.getClassProto();
this.classId = classId;
this.classProto = classProto;
this.classId = nameResolver.getClassId(classProto.getFqName());
this.descriptorFinder = descriptorFinder;
TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, outerTypeDeserializer, nameResolver,
descriptorFinder, "Deserializer for class " + getName(), NONE);
TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, null, nameResolver,
descriptorFinder, "Deserializer for class " + name, NONE);
DescriptorDeserializer outerDeserializer = DescriptorDeserializer.create(storageManager, notNullTypeDeserializer,
this, nameResolver, annotationResolver);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(classProto.getTypeParameterCount());
this.deserializer = outerDeserializer.createChildDeserializer(this, classProto.getTypeParameterList(), typeParameters);
this.typeDeserializer = deserializer.getTypeDeserializer();
this.containingDeclaration = storageManager.createLazyValue(new Computable<DeclarationDescriptor>() {
@Override
public DeclarationDescriptor compute() {
return computeContainingDeclaration();
}
});
this.typeConstructor = new DeserializedClassTypeConstructor(typeParameters);
this.memberScope = new DeserializedClassMemberScope(storageManager, this);
this.innerClassesScope = new InnerClassesScopeWrapper(memberScope);
@@ -131,13 +137,13 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements
this.nestedClasses = new NestedClassDescriptors(storageManager, stringSet(classProto.getNestedClassNameList(), nameResolver)) {
@Override
protected ClassDescriptor resolveNestedClass(@NotNull Name name) {
return descriptorFinder.findClass(DeserializedClassDescriptor.this.classId.createNestedClassId(name));
return descriptorFinder.findClass(classId.createNestedClassId(name));
}
};
this.nestedObjects = new NestedClassDescriptors(storageManager, stringSet(classProto.getNestedObjectNameList(), nameResolver)) {
@Override
protected ClassDescriptor resolveNestedClass(@NotNull Name name) {
return descriptorFinder.findClass(DeserializedClassDescriptor.this.classId.createNestedClassId(name));
return descriptorFinder.findClass(classId.createNestedClassId(name));
}
};
}
@@ -151,6 +157,20 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements
return result;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return containingDeclaration.compute();
}
@NotNull
private DeclarationDescriptor computeContainingDeclaration() {
ClassOrNamespaceDescriptor result = classId.isTopLevelClass() ?
descriptorFinder.findPackage(classId.getPackageFqName()) :
descriptorFinder.findClass(classId.getOuterClassId());
return result != null ? result : ErrorUtils.getErrorModule();
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {