Untangle circular dependency of TypeDeserializer and context

This commit is contained in:
Alexander Udalov
2014-11-19 21:00:09 +03:00
parent ea3778d5be
commit eadf9a13b9
4 changed files with 36 additions and 71 deletions
@@ -78,11 +78,10 @@ public class MemberDeserializer {
context.getNameResolver()
);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(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.<TypeParameter>emptyList(),
Collections.<TypeParameterDescriptor>emptyList());
DeserializationContextWithTypes setterLocal = local.childContext(setter, Collections.<TypeParameter>emptyList());
List<ValueParameterDescriptor> 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<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(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<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
DeserializationContextWithTypes local = context.childContext(descriptor, Collections.<TypeParameter>emptyList(), typeParameters);
DeserializationContextWithTypes local = context.childContext(descriptor, Collections.<TypeParameter>emptyList());
descriptor.initialize(
classDescriptor.getTypeConstructor().getParameters(),
local.getDeserializer().valueParameters(proto, AnnotatedCallableKind.FUNCTION),
@@ -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<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer) {
return Collections.emptyList();
}
};
@NotNull
@ReadOnly
List<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer);
}
private final DeserializationContext context;
private final TypeDeserializer parent;
// never written to after constructor returns
private final TIntObjectHashMap<TypeParameterDescriptor> typeParameterDescriptors = new TIntObjectHashMap<TypeParameterDescriptor>();
private final Map<Integer, TypeParameterDescriptor> typeParameterDescriptors = new LinkedHashMap<Integer, TypeParameterDescriptor>();
private final MemoizedFunctionToNullable<Integer, ClassDescriptor> 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<Integer, ClassDescriptor>() {
@Override
@@ -90,6 +62,15 @@ public class TypeDeserializer {
});
}
public void addTypeParameter(@NotNull DeserializedTypeParameterDescriptor typeParameterDescriptor) {
typeParameterDescriptors.put(typeParameterDescriptor.getProtoId(), typeParameterDescriptor);
}
@NotNull
public List<TypeParameterDescriptor> getOwnTypeParameters() {
return UtilsPackage.toReadOnlyList(typeParameterDescriptors.values());
}
@Nullable
public JetType typeOrNull(@Nullable ProtoBuf.Type proto) {
if (proto == null) {
@@ -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<TypeParameter>,
typeParameters: MutableList<TypeParameterDescriptor>
): DeserializationContextWithTypes {
val childTypeParameterResolver = object : TypeDeserializer.TypeParameterResolver {
override fun getTypeParameters(typeDeserializer: TypeDeserializer): List<DeserializedTypeParameterDescriptor> {
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<TypeParameter>): 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? {
@@ -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<TypeParameterDescriptor>(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<TypeParameterDescriptor>) : AbstractClassTypeConstructor() {
private inner class DeserializedClassTypeConstructor : AbstractClassTypeConstructor() {
private val supertypes = computeSuperTypes()
override fun getParameters() = parameters
override fun getParameters() = context.typeDeserializer.getOwnTypeParameters()
override fun getSupertypes(): Collection<JetType> {
// We cannot have error supertypes because subclasses inherit error functions from them