From eadf9a13b9f97aa11f9b36d42414c7c58bd2e795 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 19 Nov 2014 21:00:09 +0300 Subject: [PATCH] Untangle circular dependency of TypeDeserializer and context --- .../serialization/MemberDeserializer.java | 16 +++--- .../serialization/TypeDeserializer.java | 49 ++++++------------- .../serialization/context/context.kt | 31 ++++-------- .../DeserializedClassDescriptor.kt | 11 ++--- 4 files changed, 36 insertions(+), 71 deletions(-) diff --git a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/MemberDeserializer.java b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/MemberDeserializer.java index 667c7514abb..fcf2bd992c0 100644 --- a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/MemberDeserializer.java +++ b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/MemberDeserializer.java @@ -78,11 +78,10 @@ public class MemberDeserializer { context.getNameResolver() ); - List typeParameters = new ArrayList(proto.getTypeParameterCount()); - DeserializationContextWithTypes local = context.childContext(property, proto.getTypeParameterList(), typeParameters); + DeserializationContextWithTypes local = context.childContext(property, proto.getTypeParameterList()); property.setType( local.getTypeDeserializer().type(proto.getReturnType()), - typeParameters, + local.getTypeDeserializer().getOwnTypeParameters(), getDispatchReceiverParameter(), local.getTypeDeserializer().typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null) ); @@ -117,8 +116,7 @@ public class MemberDeserializer { visibility(Flags.VISIBILITY.get(setterFlags)), isNotDefault, !isNotDefault, property.getKind(), null, SourceElement.NO_SOURCE); - DeserializationContextWithTypes setterLocal = local.childContext(setter, Collections.emptyList(), - Collections.emptyList()); + DeserializationContextWithTypes setterLocal = local.childContext(setter, Collections.emptyList()); List valueParameters = setterLocal.getDeserializer().valueParameters(proto, AnnotatedCallableKind.PROPERTY_SETTER); assert valueParameters.size() == 1 : "Property setter should have a single value parameter: " + setter; @@ -157,12 +155,11 @@ public class MemberDeserializer { DeserializedSimpleFunctionDescriptor function = DeserializedSimpleFunctionDescriptor.create( context.getContainingDeclaration(), proto, context.getAnnotationLoader(), context.getNameResolver() ); - List typeParameters = new ArrayList(proto.getTypeParameterCount()); - DeserializationContextWithTypes local = context.childContext(function, proto.getTypeParameterList(), typeParameters); + DeserializationContextWithTypes local = context.childContext(function, proto.getTypeParameterList()); function.initialize( local.getTypeDeserializer().typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null), getDispatchReceiverParameter(), - typeParameters, + local.getTypeDeserializer().getOwnTypeParameters(), local.getDeserializer().valueParameters(proto, AnnotatedCallableKind.FUNCTION), local.getTypeDeserializer().type(proto.getReturnType()), modality(Flags.MODALITY.get(flags)), @@ -186,8 +183,7 @@ public class MemberDeserializer { getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION), // TODO: primary true, SourceElement.NO_SOURCE); - List typeParameters = new ArrayList(proto.getTypeParameterCount()); - DeserializationContextWithTypes local = context.childContext(descriptor, Collections.emptyList(), typeParameters); + DeserializationContextWithTypes local = context.childContext(descriptor, Collections.emptyList()); descriptor.initialize( classDescriptor.getTypeConstructor().getParameters(), local.getDeserializer().valueParameters(proto, AnnotatedCallableKind.FUNCTION), diff --git a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java index 1c3a57b2aac..9b2b13bc107 100644 --- a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java +++ b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java @@ -16,12 +16,10 @@ package org.jetbrains.jet.descriptors.serialization; -import gnu.trove.TIntObjectHashMap; import kotlin.Function0; import kotlin.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.ReadOnly; import org.jetbrains.jet.descriptors.serialization.context.DeserializationContext; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -33,54 +31,28 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.storage.MemoizedFunctionToNullable; import org.jetbrains.jet.storage.NotNullLazyValue; +import org.jetbrains.jet.utils.UtilsPackage; import java.util.ArrayList; -import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import static org.jetbrains.jet.descriptors.serialization.SerializationPackage.variance; public class TypeDeserializer { - - public interface TypeParameterResolver { - TypeParameterResolver NONE = new TypeParameterResolver() { - @NotNull - @Override - public List getTypeParameters(@NotNull TypeDeserializer typeDeserializer) { - return Collections.emptyList(); - } - }; - - @NotNull - @ReadOnly - List getTypeParameters(@NotNull TypeDeserializer typeDeserializer); - } - + private final DeserializationContext context; private final TypeDeserializer parent; - - // never written to after constructor returns - private final TIntObjectHashMap typeParameterDescriptors = new TIntObjectHashMap(); - + private final Map typeParameterDescriptors = new LinkedHashMap(); private final MemoizedFunctionToNullable classDescriptors; private final String debugName; - private final DeserializationContext context; - - public TypeDeserializer( - @NotNull DeserializationContext context, - @Nullable TypeDeserializer parent, - @NotNull String debugName, - @NotNull TypeParameterResolver typeParameterResolver - ) { + public TypeDeserializer(@NotNull DeserializationContext context, @Nullable TypeDeserializer parent, @NotNull String debugName) { this.parent = parent; this.debugName = debugName + (parent == null ? "" : ". Child of " + parent.debugName); this.context = context; - for (DeserializedTypeParameterDescriptor typeParameterDescriptor : typeParameterResolver.getTypeParameters(this)) { - typeParameterDescriptors.put(typeParameterDescriptor.getProtoId(), typeParameterDescriptor); - } - this.classDescriptors = context.getStorageManager().createMemoizedFunctionWithNullableValues( new Function1() { @Override @@ -90,6 +62,15 @@ public class TypeDeserializer { }); } + public void addTypeParameter(@NotNull DeserializedTypeParameterDescriptor typeParameterDescriptor) { + typeParameterDescriptors.put(typeParameterDescriptor.getProtoId(), typeParameterDescriptor); + } + + @NotNull + public List getOwnTypeParameters() { + return UtilsPackage.toReadOnlyList(typeParameterDescriptors.values()); + } + @Nullable public JetType typeOrNull(@Nullable ProtoBuf.Type proto) { if (proto == null) { diff --git a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/context/context.kt b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/context/context.kt index fbb002306ac..0ad81df8fca 100644 --- a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/context/context.kt +++ b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/context/context.kt @@ -25,8 +25,6 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor import org.jetbrains.jet.descriptors.serialization.TypeDeserializer import org.jetbrains.jet.descriptors.serialization.MemberDeserializer import org.jetbrains.jet.descriptors.serialization.ProtoBuf.TypeParameter -import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor -import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor import org.jetbrains.jet.descriptors.serialization.descriptors.ConstantLoader import org.jetbrains.jet.lang.descriptors.ModuleDescriptor import org.jetbrains.jet.lang.descriptors.ClassDescriptor @@ -68,8 +66,7 @@ public open class DeserializationContext( ) : DeserializationGlobalContext(storageManager, moduleDescriptor, classDataFinder, annotationLoader, constantLoader, packageFragmentProvider, flexibleTypeCapabilitiesDeserializer, classDeserializer) { fun withTypes(containingDeclaration: DeclarationDescriptor): DeserializationContextWithTypes { - val typeDeserializer = TypeDeserializer(this, null, "Deserializer for ${containingDeclaration.getName()}", - TypeDeserializer.TypeParameterResolver.NONE) + val typeDeserializer = TypeDeserializer(this, null, "Deserializer for ${containingDeclaration.getName()}") return withTypes(containingDeclaration, typeDeserializer) } @@ -98,24 +95,16 @@ class DeserializationContextWithTypes( constantLoader, packageFragmentProvider, flexibleTypeCapabilitiesDeserializer, classDeserializer, nameResolver) { val deserializer: MemberDeserializer = MemberDeserializer(this) - public fun childContext( - descriptor: DeclarationDescriptor, - typeParameterProtos: List, - typeParameters: MutableList - ): DeserializationContextWithTypes { - val childTypeParameterResolver = object : TypeDeserializer.TypeParameterResolver { - override fun getTypeParameters(typeDeserializer: TypeDeserializer): List { - val childDeserializer = MemberDeserializer(withTypes(descriptor, typeDeserializer)) - val descriptors = childDeserializer.typeParameters(typeParameterProtos, typeDeserializer) - typeParameters.addAll(descriptors) - return descriptors - } - } - val childTypeDeserializer = TypeDeserializer(this, typeDeserializer, "Child deserializer for " + descriptor.getName(), - childTypeParameterResolver) - return withTypes(descriptor, childTypeDeserializer) - } + public fun childContext(descriptor: DeclarationDescriptor, typeParameterProtos: List): DeserializationContextWithTypes { + val childTypeDeserializer = TypeDeserializer(this, typeDeserializer, "Child deserializer for ${descriptor.getName()}") + val childContext = withTypes(descriptor, childTypeDeserializer) + for (typeParameter in childContext.deserializer.typeParameters(typeParameterProtos, childTypeDeserializer)) { + childTypeDeserializer.addTypeParameter(typeParameter) + } + + return childContext + } } fun DeserializationGlobalContext.deserializeClass(classId: ClassId): ClassDescriptor? { diff --git a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.kt b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.kt index 5a735b39924..902733f5ccc 100644 --- a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.kt @@ -51,16 +51,15 @@ public class DeserializedClassDescriptor( private val isInner = Flags.INNER.get(classProto.getFlags()) private val classId = outerContext.nameResolver.getClassId(classProto.getFqName()) - private val typeParameters = ArrayList(classProto.getTypeParameterCount()) - val context = outerContext.withTypes(this).childContext(this, classProto.getTypeParameterList(), typeParameters) + val context = outerContext.withTypes(this).childContext(this, classProto.getTypeParameterList()) private val staticScope = StaticScopeForKotlinClass(this) - private val typeConstructor = DeserializedClassTypeConstructor(typeParameters) + private val typeConstructor = DeserializedClassTypeConstructor() private val memberScope = DeserializedClassMemberScope() private val nestedClasses = NestedClassDescriptors() private val enumEntries = EnumEntryClassDescriptors() - private val containingDeclaration = outerContext.storageManager.createLazyValue { computeContainingDeclaration() } + private val containingDeclaration = context.storageManager.createLazyValue { computeContainingDeclaration() } private val annotations = context.storageManager.createLazyValue { computeAnnotations() } private val primaryConstructor = context.storageManager.createNullableLazyValue { computePrimaryConstructor() } private val classObjectDescriptor = context.storageManager.createNullableLazyValue { computeClassObjectDescriptor() } @@ -151,10 +150,10 @@ public class DeserializedClassDescriptor( override fun getSource() = SourceElement.NO_SOURCE - private inner class DeserializedClassTypeConstructor(private val parameters: List) : AbstractClassTypeConstructor() { + private inner class DeserializedClassTypeConstructor : AbstractClassTypeConstructor() { private val supertypes = computeSuperTypes() - override fun getParameters() = parameters + override fun getParameters() = context.typeDeserializer.getOwnTypeParameters() override fun getSupertypes(): Collection { // We cannot have error supertypes because subclasses inherit error functions from them