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