From 867adcc1674d7095d45080185ab2e90974d76804 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 19 Jun 2013 15:20:13 +0400 Subject: [PATCH] Getting rid of mutable state in TypeDeserializer --- .../serialization/DescriptorDeserializer.java | 86 ++++++++++++------- .../serialization/TypeDeserializer.java | 33 +++++-- .../DeserializedClassDescriptor.java | 12 ++- .../DeserializedTypeParameterDescriptor.java | 4 + 4 files changed, 94 insertions(+), 41 deletions(-) diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java index 8d894df73f4..69e5b483e2a 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java @@ -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 typeParameterProtos, + @NotNull final List typeParameters + ) { + TypeDeserializer childTypeDeserializer = new TypeDeserializer( + typeDeserializer, "Child deserializer for " + descriptor, + new TypeDeserializer.TypeParameterResolver() { + @NotNull + @Override + public List getTypeParameters(@NotNull TypeDeserializer typeDeserializer) { + List 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 typeParameters = local.typeParameters(proto.getTypeParametersList()); + List typeParameters = new ArrayList(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 typeParameters = local.typeParameters(proto.getTypeParametersList()); + List typeParameters = new ArrayList(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 typeParameters = new ArrayList(proto.getTypeParametersCount()); + DescriptorDeserializer local = createChildDeserializer(descriptor, Collections.emptyList(), typeParameters); descriptor.initialize( classDescriptor.getTypeConstructor().getParameters(), local.valueParameters(proto.getValueParametersList()), @@ -290,33 +321,28 @@ public class DescriptorDeserializer { } @NotNull - public List typeParameters(@NotNull List protos) { - List result = new ArrayList(protos.size()); + public List typeParameters( + @NotNull List protos, + @NotNull TypeDeserializer typeDeserializer + ) { + List result = new ArrayList(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: diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java index 966c969d21f..248ce840a0b 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java @@ -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 getTypeParameters(@NotNull TypeDeserializer typeDeserializer) { + return Collections.emptyList(); + } + }; + + @NotNull + List 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); } 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 903d4357575..da1f2757154 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 @@ -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 typeParameters = new ArrayList(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(); diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedTypeParameterDescriptor.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedTypeParameterDescriptor.java index 13606b0ed76..18e8eccb917 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedTypeParameterDescriptor.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedTypeParameterDescriptor.java @@ -62,4 +62,8 @@ public class DeserializedTypeParameterDescriptor extends AbstractLazyTypeParamet } return result; } + + public int getProtoId() { + return proto.getId(); + } }