Getting rid of mutable state in TypeDeserializer

This commit is contained in:
Andrey Breslav
2013-06-19 15:20:13 +04:00
committed by Alexander Udalov
parent e960247936
commit 867adcc167
4 changed files with 94 additions and 41 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
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.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.Modality;
@@ -33,6 +34,7 @@ import org.jetbrains.jet.lang.types.Variance;
import java.util.*;
import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.*;
import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE;
public class DescriptorDeserializer {
@@ -43,8 +45,9 @@ public class DescriptorDeserializer {
@NotNull ClassResolver classResolver,
@NotNull AnnotationDeserializer annotationDeserializer
) {
return new DescriptorDeserializer(new TypeDeserializer(null, nameResolver, classResolver, "Deserializer for " + containingDeclaration),
containingDeclaration, nameResolver, annotationDeserializer);
return new DescriptorDeserializer(
new TypeDeserializer(null, nameResolver, classResolver, "Deserializer for " + containingDeclaration, NONE),
containingDeclaration, nameResolver, annotationDeserializer);
}
@NotNull
@@ -76,15 +79,42 @@ public class DescriptorDeserializer {
this.annotationDeserializer = annotationDeserializer;
}
@NotNull
public TypeDeserializer getTypeDeserializer() {
return typeDeserializer;
}
@NotNull
public NameResolver getNameResolver() {
return nameResolver;
}
@NotNull
private DescriptorDeserializer createChildDeserializer(@NotNull DeclarationDescriptor descriptor) {
return create(new TypeDeserializer(typeDeserializer, "Child deserializer for " + descriptor),
descriptor, nameResolver, annotationDeserializer);
public DescriptorDeserializer createChildDeserializer(
@NotNull DeclarationDescriptor descriptor,
@NotNull final List<TypeParameter> typeParameterProtos,
@NotNull final List<TypeParameterDescriptor> typeParameters
) {
TypeDeserializer childTypeDeserializer = new TypeDeserializer(
typeDeserializer, "Child deserializer for " + descriptor,
new TypeDeserializer.TypeParameterResolver() {
@NotNull
@Override
public List<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer) {
List<DeserializedTypeParameterDescriptor> descriptors = typeParameters(typeParameterProtos, typeDeserializer);
typeParameters.addAll(descriptors);
return descriptors;
}
});
return create(childTypeDeserializer, descriptor, nameResolver, annotationDeserializer);
}
@NotNull
public ClassDescriptor loadClass(@NotNull ProtoBuf.Class proto, @NotNull NestedClassResolver nestedClassResolver) {
return new DeserializedClassDescriptor(
containingDeclaration, getNameResolver(), annotationDeserializer,
typeDeserializer.getClassResolver(), nestedClassResolver, proto, typeDeserializer
);
}
@NotNull
@@ -114,8 +144,8 @@ public class DescriptorDeserializer {
nameResolver.getName(proto.getName()),
memberKind(Flags.MEMBER_KIND.get(flags))
);
DescriptorDeserializer local = createChildDeserializer(property);
List<TypeParameterDescriptor> typeParameters = local.typeParameters(proto.getTypeParametersList());
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParametersCount());
DescriptorDeserializer local = createChildDeserializer(property, proto.getTypeParametersList(), typeParameters);
property.setType(
local.typeDeserializer.type(proto.getReturnType()),
typeParameters,
@@ -172,8 +202,8 @@ public class DescriptorDeserializer {
nameResolver.getName(proto.getName()),
memberKind(Flags.MEMBER_KIND.get(flags))
);
DescriptorDeserializer local = createChildDeserializer(function);
List<TypeParameterDescriptor> typeParameters = local.typeParameters(proto.getTypeParametersList());
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParametersCount());
DescriptorDeserializer local = createChildDeserializer(function, proto.getTypeParametersList(), typeParameters);
function.initialize(
local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null),
getExpectedThisObject(),
@@ -202,7 +232,8 @@ public class DescriptorDeserializer {
getAnnotations(proto),
// TODO: primary
true);
DescriptorDeserializer local = createChildDeserializer(descriptor);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParametersCount());
DescriptorDeserializer local = createChildDeserializer(descriptor, Collections.<TypeParameter>emptyList(), typeParameters);
descriptor.initialize(
classDescriptor.getTypeConstructor().getParameters(),
local.valueParameters(proto.getValueParametersList()),
@@ -290,33 +321,28 @@ public class DescriptorDeserializer {
}
@NotNull
public List<TypeParameterDescriptor> typeParameters(@NotNull List<TypeParameter> protos) {
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>(protos.size());
public List<DeserializedTypeParameterDescriptor> typeParameters(
@NotNull List<TypeParameter> protos,
@NotNull TypeDeserializer typeDeserializer
) {
List<DeserializedTypeParameterDescriptor> result = new ArrayList<DeserializedTypeParameterDescriptor>(protos.size());
for (int i = 0; i < protos.size(); i++) {
TypeParameter proto = protos.get(i);
DeserializedTypeParameterDescriptor descriptor = typeParameter(proto, i);
DeserializedTypeParameterDescriptor descriptor = new DeserializedTypeParameterDescriptor(
storageManager,
typeDeserializer,
proto,
containingDeclaration,
nameResolver.getName(proto.getName()),
variance(proto.getVariance()),
proto.getReified(),
i
);
result.add(descriptor);
}
return result;
}
@NotNull
private DeserializedTypeParameterDescriptor typeParameter(TypeParameter proto, int index) {
int id = proto.getId();
DeserializedTypeParameterDescriptor descriptor = new DeserializedTypeParameterDescriptor(
storageManager,
typeDeserializer,
proto,
containingDeclaration,
nameResolver.getName(proto.getName()),
variance(proto.getVariance()),
proto.getReified(),
index
);
typeDeserializer.registerTypeParameter(id, descriptor);
return descriptor;
}
private static Variance variance(TypeParameter.Variance proto) {
switch (proto) {
case IN:
@@ -19,6 +19,7 @@ package org.jetbrains.jet.descriptors.serialization;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
@@ -34,6 +35,20 @@ import java.util.Collections;
import java.util.List;
public class TypeDeserializer {
public interface TypeParameterResolver {
TypeParameterResolver NONE = new TypeParameterResolver() {
@NotNull
@Override
public List<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer) {
return Collections.emptyList();
}
};
@NotNull
List<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer);
}
private final NameResolver nameResolver;
private final ClassResolver classResolver;
private final TypeDeserializer parent;
@@ -44,21 +59,27 @@ public class TypeDeserializer {
public TypeDeserializer(
@NotNull TypeDeserializer parent,
@NotNull String debugName
@NotNull String debugName,
@NotNull TypeParameterResolver typeParameterResolver
) {
this(parent, parent.nameResolver, parent.classResolver, debugName);
this(parent, parent.nameResolver, parent.classResolver, debugName, typeParameterResolver);
}
public TypeDeserializer(
@Nullable TypeDeserializer parent,
@NotNull NameResolver nameResolver,
@NotNull ClassResolver classResolver,
@NotNull String debugName
@NotNull String debugName,
@NotNull TypeParameterResolver typeParameterResolver
) {
this.parent = parent;
this.nameResolver = nameResolver;
this.classResolver = classResolver;
this.debugName = debugName + (parent == null ? "" : ". Child of " + parent.debugName);
for (DeserializedTypeParameterDescriptor typeParameterDescriptor : typeParameterResolver.getTypeParameters(this)) {
typeParameterDescriptors.put(typeParameterDescriptor.getProtoId(), typeParameterDescriptor);
}
}
@NotNull
@@ -66,10 +87,6 @@ public class TypeDeserializer {
return classResolver;
}
public void registerTypeParameter(int id, TypeParameterDescriptor typeParameter) {
typeParameterDescriptors.put(id, typeParameter);
}
@Nullable
public JetType typeOrNull(@Nullable ProtoBuf.Type proto) {
if (proto == null) {
@@ -79,7 +96,7 @@ public class TypeDeserializer {
}
@NotNull
public JetType type(@NotNull final ProtoBuf.Type proto) {
public JetType type(@NotNull ProtoBuf.Type proto) {
return new DeserializedType(proto);
}
@@ -36,6 +36,8 @@ import org.jetbrains.jet.lang.types.TypeConstructor;
import java.util.*;
import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE;
public class DeserializedClassDescriptor extends ClassDescriptorBase implements ClassDescriptor {
private final ProtoBuf.Class classProto;
@@ -76,11 +78,15 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements
this.classProto = classProto;
this.name = nameResolver.getName(classProto.getName());
this.typeDeserializer = new TypeDeserializer(outerTypeDeserializer, nameResolver, classResolver, "Deserializer for class " + name);
this.deserializer = DescriptorDeserializer.create(typeDeserializer, this, nameResolver, annotationResolver);
TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(outerTypeDeserializer, nameResolver, classResolver,
"Deserializer for class " + name, NONE);
DescriptorDeserializer outerDeserializer = DescriptorDeserializer.create(notNullTypeDeserializer, this, nameResolver, annotationResolver);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(classProto.getTypeParametersCount());
this.deserializer = outerDeserializer.createChildDeserializer(this, classProto.getTypeParametersList(), typeParameters);
this.typeDeserializer = deserializer.getTypeDeserializer();
this.containingDeclaration = containingDeclaration;
this.typeConstructor = new DeserializedClassTypeConstructor(deserializer.typeParameters(classProto.getTypeParametersList()));
this.typeConstructor = new DeserializedClassTypeConstructor(typeParameters);
this.memberScope = new DeserializedClassMemberScope(this);
this.innerClassesScope = new InnerClassesScopeWrapper(memberScope);
this.thisAsReceiverParameter = new LazyClassReceiverParameterDescriptor();
@@ -62,4 +62,8 @@ public class DeserializedTypeParameterDescriptor extends AbstractLazyTypeParamet
}
return result;
}
public int getProtoId() {
return proto.getId();
}
}