Major refactoring of deserialization contexts: merge two into one

This commit is contained in:
Alexander Udalov
2014-11-21 02:32:28 +03:00
parent cb5c21e831
commit 4df7cb4e72
8 changed files with 68 additions and 85 deletions
@@ -111,7 +111,7 @@ public class IncrementalPackageFragmentProvider(
private inner class IncrementalPackageScope(val packageData: PackageData) : DeserializedPackageMemberScope(
this@IncrementalPackageFragment,
packageData.getPackageProto(),
deserializationComponents.createContext(packageData.getNameResolver()),
deserializationComponents.createContext(this@IncrementalPackageFragment, packageData.getNameResolver()),
{ listOf() }
) {
override fun filteredMemberProtos(allMemberProtos: Collection<ProtoBuf.Callable>): Collection<ProtoBuf.Callable> {
@@ -48,7 +48,7 @@ class BuiltinsPackageFragment(storageManager: StorageManager, module: ModuleDesc
DeserializationComponents(
storageManager, module, BuiltInsClassDataFinder(), AnnotationLoader.UNSUPPORTED, // TODO: support annotations
ConstantLoader.UNSUPPORTED, provider, FlexibleTypeCapabilitiesDeserializer.ThrowException
).createContext(nameResolver),
).createContext(this, nameResolver),
{ readClassNames() }
)
@@ -16,30 +16,32 @@
package org.jetbrains.jet.descriptors.serialization
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.jet.lang.resolve.name.ClassId
import org.jetbrains.jet.descriptors.serialization.context.DeserializationComponents
public class ClassDeserializer(private val components: DeserializationComponents) {
private val classes: (ClassKey) -> DeserializedClassDescriptor? = components.storageManager.createMemoizedFunctionWithNullableValues {
(key: ClassKey) ->
val classId = key.classId
val classData = key.classData ?: components.classDataFinder.findClassData(classId)
if (classData != null) {
val outerClassContext =
if (classId.isTopLevelClass()) null
else classes(ClassKey(classId.getOuterClassId(), null))?.context
// TODO: use outerClassContext
DeserializedClassDescriptor(components.createContext(classData.getNameResolver()), classData.getClassProto())
}
else {
null
}
}
private val classes: (ClassKey) -> DeserializedClassDescriptor? =
components.storageManager.createMemoizedFunctionWithNullableValues { key -> createClass(key) }
// Additional ClassData parameter is needed to avoid calling ClassDataFinder#findClassData() if it is already computed at call site
public fun deserializeClass(classId: ClassId, classData: ClassData? = null): ClassDescriptor? = classes(ClassKey(classId, classData))
public fun deserializeClass(classId: ClassId, classData: ClassData? = null): DeserializedClassDescriptor? =
classes(ClassKey(classId, classData))
private fun createClass(key: ClassKey): DeserializedClassDescriptor? {
val classId = key.classId
val classData = key.classData ?: components.classDataFinder.findClassData(classId) ?: return null
val outerContext = if (classId.isTopLevelClass()) {
val fragments = components.packageFragmentProvider.getPackageFragments(classId.getPackageFqName())
assert(fragments.size() == 1) { "There should be exactly one package: $fragments, class id is $classId" }
components.createContext(fragments.single(), classData.getNameResolver())
}
else {
deserializeClass(classId.getOuterClassId())?.context ?: return null
}
return DeserializedClassDescriptor(outerContext, classData.getClassProto(), classData.getNameResolver())
}
private inner class ClassKey(val classId: ClassId, val classData: ClassData?) {
override fun equals(other: Any?): Boolean = other is ClassKey && classId == other.classId
@@ -20,7 +20,7 @@ import kotlin.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.context.DeserializationComponents;
import org.jetbrains.jet.descriptors.serialization.context.DeserializationContextWithTypes;
import org.jetbrains.jet.descriptors.serialization.context.DeserializationContext;
import org.jetbrains.jet.descriptors.serialization.descriptors.*;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
@@ -40,10 +40,9 @@ import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.TypeParameter
import static org.jetbrains.jet.descriptors.serialization.SerializationPackage.*;
public class MemberDeserializer {
private final DeserializationContext context;
private final DeserializationContextWithTypes context;
public MemberDeserializer(@NotNull DeserializationContextWithTypes context) {
public MemberDeserializer(@NotNull DeserializationContext context) {
this.context = context;
}
@@ -69,7 +68,7 @@ public class MemberDeserializer {
@NotNull
private PropertyDescriptor loadProperty(@NotNull final Callable proto) {
final int flags = proto.getFlags();
int flags = proto.getFlags();
DeserializedPropertyDescriptor property = new DeserializedPropertyDescriptor(
context.getContainingDeclaration(),
@@ -84,7 +83,7 @@ public class MemberDeserializer {
context.getNameResolver()
);
DeserializationContextWithTypes local = context.childContext(property, proto.getTypeParameterList());
DeserializationContext local = context.childContext(property, proto.getTypeParameterList());
property.setType(
local.getTypeDeserializer().type(proto.getReturnType()),
local.getTypeDeserializer().getOwnTypeParameters(),
@@ -122,7 +121,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());
DeserializationContext setterLocal = local.childContext(setter, Collections.<TypeParameter>emptyList());
List<ValueParameterDescriptor> valueParameters =
setterLocal.getMemberDeserializer().valueParameters(proto, AnnotatedCallableKind.PROPERTY_SETTER);
assert valueParameters.size() == 1 : "Property setter should have a single value parameter: " + setter;
@@ -161,7 +160,7 @@ public class MemberDeserializer {
DeserializedSimpleFunctionDescriptor function = DeserializedSimpleFunctionDescriptor.create(
context.getContainingDeclaration(), proto, getComponents().getAnnotationLoader(), context.getNameResolver()
);
DeserializationContextWithTypes local = context.childContext(function, proto.getTypeParameterList());
DeserializationContext local = context.childContext(function, proto.getTypeParameterList());
function.initialize(
local.getTypeDeserializer().typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null),
getDispatchReceiverParameter(),
@@ -188,8 +187,9 @@ public class MemberDeserializer {
classDescriptor,
getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION),
// TODO: primary
true, SourceElement.NO_SOURCE);
DeserializationContextWithTypes local = context.childContext(descriptor, Collections.<TypeParameter>emptyList());
true, SourceElement.NO_SOURCE
);
DeserializationContext local = context.childContext(descriptor, Collections.<TypeParameter>emptyList());
descriptor.initialize(
classDescriptor.getTypeConstructor().getParameters(),
local.getMemberDeserializer().valueParameters(proto, AnnotatedCallableKind.FUNCTION),
@@ -18,19 +18,11 @@ package org.jetbrains.jet.descriptors.serialization.context
import org.jetbrains.jet.storage.StorageManager
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationLoader
import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider
import org.jetbrains.jet.descriptors.serialization.ClassDataFinder
import org.jetbrains.jet.descriptors.serialization.NameResolver
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.lang.descriptors.*
import org.jetbrains.jet.descriptors.serialization.*
import org.jetbrains.jet.descriptors.serialization.ProtoBuf.TypeParameter
import org.jetbrains.jet.descriptors.serialization.descriptors.ConstantLoader
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.resolve.name.ClassId
import org.jetbrains.jet.descriptors.serialization.ClassDeserializer
import org.jetbrains.jet.descriptors.serialization.FlexibleTypeCapabilitiesDeserializer
public class DeserializationComponents(
public val storageManager: StorageManager,
@@ -45,31 +37,32 @@ public class DeserializationComponents(
public fun deserializeClass(classId: ClassId): ClassDescriptor? = classDeserializer.deserializeClass(classId)
public fun createContext(nameResolver: NameResolver): DeserializationContext = DeserializationContext(this, nameResolver)
public fun createContext(descriptor: PackageFragmentDescriptor, nameResolver: NameResolver): DeserializationContext =
DeserializationContext(this, nameResolver, descriptor, parentTypeDeserializer = null)
}
public open class DeserializationContext(
public class DeserializationContext(
public val components: DeserializationComponents,
public val nameResolver: NameResolver
public val nameResolver: NameResolver,
public val containingDeclaration: DeclarationDescriptor,
parentTypeDeserializer: TypeDeserializer?
) {
fun withTypes(containingDeclaration: DeclarationDescriptor, parent: TypeDeserializer? = null): DeserializationContextWithTypes {
val typeDeserializer = TypeDeserializer(this, parent, "Deserializer for ${containingDeclaration.getName()}")
return DeserializationContextWithTypes(components, nameResolver, containingDeclaration, typeDeserializer)
}
}
val typeDeserializer: TypeDeserializer =
TypeDeserializer(this, parentTypeDeserializer, "Deserializer for ${containingDeclaration.getName()}")
class DeserializationContextWithTypes(
components: DeserializationComponents,
nameResolver: NameResolver,
val containingDeclaration: DeclarationDescriptor,
val typeDeserializer: TypeDeserializer
) : DeserializationContext(components, nameResolver) {
val memberDeserializer: MemberDeserializer = MemberDeserializer(this)
fun childContext(descriptor: DeclarationDescriptor, typeParameterProtos: List<TypeParameter>): DeserializationContextWithTypes {
val child = this.withTypes(descriptor, parent = this.typeDeserializer)
// Not using default arguments here because Java code calls this function
fun childContext(descriptor: DeclarationDescriptor, typeParameterProtos: List<TypeParameter>): DeserializationContext =
childContext(descriptor, typeParameterProtos, this.nameResolver)
fun childContext(
descriptor: DeclarationDescriptor,
typeParameterProtos: List<TypeParameter>,
nameResolver: NameResolver
): DeserializationContext {
val child = DeserializationContext(components, nameResolver, descriptor, parentTypeDeserializer = this.typeDeserializer)
for (typeParameter in child.memberDeserializer.typeParameters(typeParameterProtos)) {
child.typeDeserializer.addTypeParameter(typeParameter)
@@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.resolve.OverridingUtil
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.scopes.StaticScopeForKotlinClass
import org.jetbrains.jet.lang.types.AbstractClassTypeConstructor
import org.jetbrains.jet.lang.types.ErrorUtils
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.descriptors.serialization
import org.jetbrains.jet.lang.resolve.name.SpecialNames.getClassObjectName
@@ -37,47 +36,38 @@ import org.jetbrains.jet.utils.addIfNotNull
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.resolve.scopes.DescriptorKindFilter
import java.util.*
import org.jetbrains.jet.descriptors.serialization.NameResolver
public class DeserializedClassDescriptor(
outerContext: DeserializationContext,
private val classProto: ProtoBuf.Class
private val classProto: ProtoBuf.Class,
nameResolver: NameResolver
) : ClassDescriptor, AbstractClassDescriptor(
outerContext.components.storageManager,
outerContext.nameResolver.getClassId(classProto.getFqName()).getRelativeClassName().shortName()
nameResolver.getClassId(classProto.getFqName()).getRelativeClassName().shortName()
) {
private val modality = serialization.modality(Flags.MODALITY.get(classProto.getFlags()))
private val visibility = serialization.visibility(Flags.VISIBILITY.get(classProto.getFlags()))
private val kind = classKind(Flags.CLASS_KIND.get(classProto.getFlags()))
private val isInner = Flags.INNER.get(classProto.getFlags())
private val classId = outerContext.nameResolver.getClassId(classProto.getFqName())
val context = outerContext.withTypes(this).childContext(this, classProto.getTypeParameterList())
val context = outerContext.childContext(this, classProto.getTypeParameterList(), nameResolver)
private val components: DeserializationComponents get() = context.components
private val classId = nameResolver.getClassId(classProto.getFqName())
private val staticScope = StaticScopeForKotlinClass(this)
private val typeConstructor = DeserializedClassTypeConstructor()
private val memberScope = DeserializedClassMemberScope()
private val nestedClasses = NestedClassDescriptors()
private val enumEntries = EnumEntryClassDescriptors()
private val containingDeclaration = components.storageManager.createLazyValue { computeContainingDeclaration() }
private val containingDeclaration = outerContext.containingDeclaration
private val annotations = components.storageManager.createLazyValue { computeAnnotations() }
private val primaryConstructor = components.storageManager.createNullableLazyValue { computePrimaryConstructor() }
private val classObjectDescriptor = components.storageManager.createNullableLazyValue { computeClassObjectDescriptor() }
override fun getContainingDeclaration(): DeclarationDescriptor = containingDeclaration()
private fun computeContainingDeclaration(): DeclarationDescriptor {
if (classId.isTopLevelClass()) {
val fragments = components.packageFragmentProvider.getPackageFragments(classId.getPackageFqName())
assert(fragments.size() == 1) { "there should be exactly one package: $fragments, class id is $classId" }
return fragments.single()
}
else {
return components.deserializeClass(classId.getOuterClassId()) ?: ErrorUtils.getErrorModule()
}
}
override fun getContainingDeclaration(): DeclarationDescriptor = containingDeclaration
override fun getTypeConstructor() = typeConstructor
@@ -132,7 +122,7 @@ public class DeserializedClassDescriptor(
throw IllegalStateException("Object should have a serialized class object: $classId")
}
return DeserializedClassDescriptor(context, classObjectProto.getData())
return DeserializedClassDescriptor(context, classObjectProto.getData(), context.nameResolver)
}
return components.deserializeClass(classId.createNestedClassId(getClassObjectName(getName())))
@@ -18,19 +18,18 @@ package org.jetbrains.jet.descriptors.serialization.descriptors
import org.jetbrains.jet.descriptors.serialization.Flags
import org.jetbrains.jet.descriptors.serialization.ProtoBuf
import org.jetbrains.jet.descriptors.serialization.context.DeserializationContextWithTypes
import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.utils.Printer
import java.util.*
import org.jetbrains.jet.utils.toReadOnlyList
import org.jetbrains.jet.lang.resolve.scopes.DescriptorKindFilter
import org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.CallableKind
import org.jetbrains.jet.descriptors.serialization.context.DeserializationContext
import java.util.*
public abstract class DeserializedMemberScope protected(
private val context: DeserializationContextWithTypes,
protected val context: DeserializationContext,
membersList: Collection<ProtoBuf.Callable>)
: JetScope {
@@ -27,7 +27,6 @@ import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.utils.addIfNotNull
import org.jetbrains.jet.lang.resolve.scopes.DescriptorKindFilter
public fun DeserializedPackageMemberScope(
packageDescriptor: PackageFragmentDescriptor,
packageData: PackageData,
@@ -36,16 +35,16 @@ public fun DeserializedPackageMemberScope(
): DeserializedPackageMemberScope = DeserializedPackageMemberScope(
packageDescriptor,
packageData.getPackageProto(),
components.createContext(packageData.getNameResolver()),
components.createContext(packageDescriptor, packageData.getNameResolver()),
classNames
)
public open class DeserializedPackageMemberScope(
packageDescriptor: PackageFragmentDescriptor,
proto: ProtoBuf.Package,
private val context: DeserializationContext,
classNames: () -> Collection<Name>)
: DeserializedMemberScope(context.withTypes(packageDescriptor), proto.getMemberList()) {
outerContext: DeserializationContext,
classNames: () -> Collection<Name>
) : DeserializedMemberScope(outerContext.childContext(packageDescriptor, listOf()), proto.getMemberList()) {
private val packageFqName = packageDescriptor.fqName
private val classNames = context.components.storageManager.createLazyValue(classNames)