Use outer class context in ClassDeserializer

This commit is contained in:
Alexander Udalov
2014-11-19 18:26:49 +03:00
parent 8f26bc646e
commit ea3778d5be
4 changed files with 35 additions and 42 deletions
@@ -54,7 +54,7 @@ public final class DeserializedDescriptorResolver {
public ClassDescriptor resolveClass(@NotNull KotlinJvmBinaryClass kotlinClass) { public ClassDescriptor resolveClass(@NotNull KotlinJvmBinaryClass kotlinClass) {
String[] data = readData(kotlinClass, CLASS); String[] data = readData(kotlinClass, CLASS);
if (data != null) { if (data != null) {
return context.getClassDeserializer().deserializeClass(JavaProtoBufUtil.readClassDataFrom(data)); return context.getClassDeserializer().deserializeClass(kotlinClass.getClassId(), JavaProtoBufUtil.readClassDataFrom(data));
} }
return null; return null;
} }
@@ -64,13 +64,14 @@ public final class DeserializedDescriptorResolver {
String[] data = readData(kotlinClass, PACKAGE_FACADE); String[] data = readData(kotlinClass, PACKAGE_FACADE);
if (data != null) { if (data != null) {
//all classes are included in java scope //all classes are included in java scope
return DescriptorsPackage.DeserializedPackageMemberScope(descriptor, JavaProtoBufUtil.readPackageDataFrom(data), context, return DescriptorsPackage.DeserializedPackageMemberScope(
new Function0<Collection<Name>>() { descriptor, JavaProtoBufUtil.readPackageDataFrom(data), context,
@Override new Function0<Collection<Name>>() {
public Collection<Name> invoke() { @Override
return Collections.emptyList(); public Collection<Name> invoke() {
} return Collections.emptyList();
}); }
});
} }
return null; return null;
} }
@@ -24,35 +24,30 @@ import kotlin.properties.Delegates
import org.jetbrains.jet.lang.resolve.name.ClassId import org.jetbrains.jet.lang.resolve.name.ClassId
public class ClassDeserializer(val storageManager: StorageManager, val classDataFinder: ClassDataFinder) { public class ClassDeserializer(val storageManager: StorageManager, val classDataFinder: ClassDataFinder) {
private val classes = storageManager.createMemoizedFunctionWithNullableValues { var globalContext: DeserializationGlobalContext by Delegates.notNull()
private val classes: (ClassKey) -> DeserializedClassDescriptor? = storageManager.createMemoizedFunctionWithNullableValues {
(key: ClassKey) -> (key: ClassKey) ->
val classData = key.classData ?: classDataFinder.findClassData(key.classId) val classId = key.classId
val classData = key.classData ?: classDataFinder.findClassData(classId)
if (classData != null) { if (classData != null) {
DeserializedClassDescriptor(context, classData) val outerClassContext =
if (classId.isTopLevelClass()) null
else classes(ClassKey(classId.getOuterClassId(), null))?.context
val context = outerClassContext ?: globalContext
DeserializedClassDescriptor(context.withNameResolver(classData.getNameResolver()), classData.getClassProto())
} }
else { else {
null null
} }
} }
var context: DeserializationGlobalContext by Delegates.notNull() // 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): ClassDescriptor? = classes(ClassKey(classId, null))
//needed to avoid calling ClassDataFinder#findClassData() if it is already computed at call site
public fun deserializeClass(classData: ClassData): ClassDescriptor? = classes(ClassKey(classData.readId(), classData))
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 { override fun equals(other: Any?): Boolean = other is ClassKey && classId == other.classId
return other is ClassKey && classId == other.classId override fun hashCode(): Int = classId.hashCode()
} override fun toString(): String = classId.toString()
override fun hashCode(): Int {
return classId.hashCode()
}
}
private fun ClassData.readId(): ClassId {
return getNameResolver().getClassId(getClassProto().getFqName())
} }
} }
@@ -45,7 +45,7 @@ public open class DeserializationGlobalContext(
public val classDeserializer: ClassDeserializer = ClassDeserializer(storageManager, classDataFinder) public val classDeserializer: ClassDeserializer = ClassDeserializer(storageManager, classDataFinder)
) { ) {
{ {
classDeserializer.context = this classDeserializer.globalContext = this
} }
public fun withNameResolver(nameResolver: NameResolver): DeserializationContext { public fun withNameResolver(nameResolver: NameResolver): DeserializationContext {
@@ -16,7 +16,6 @@
package org.jetbrains.jet.descriptors.serialization.descriptors package org.jetbrains.jet.descriptors.serialization.descriptors
import org.jetbrains.jet.descriptors.serialization.ClassData
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.* import org.jetbrains.jet.descriptors.serialization.context.*
@@ -31,23 +30,21 @@ 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.ErrorUtils
import org.jetbrains.jet.lang.types.JetType import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.storage.MemoizedFunctionToNullable
import java.util.*
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
import org.jetbrains.jet.descriptors.serialization.classKind import org.jetbrains.jet.descriptors.serialization.classKind
import org.jetbrains.jet.utils.addIfNotNull 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.*
public fun DeserializedClassDescriptor(globalContext: DeserializationGlobalContext, classData: ClassData): DeserializedClassDescriptor public class DeserializedClassDescriptor(
= DeserializedClassDescriptor(globalContext.withNameResolver(classData.getNameResolver()), classData.getClassProto()) outerContext: DeserializationContext,
private val classProto: ProtoBuf.Class
public class DeserializedClassDescriptor(outerContext: DeserializationContext, private val classProto: ProtoBuf.Class) ) : ClassDescriptor, AbstractClassDescriptor(
: AbstractClassDescriptor(outerContext.storageManager, outerContext.nameResolver.getClassId(classProto.getFqName()).getRelativeClassName().shortName()), ClassDescriptor { outerContext.storageManager,
outerContext.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()))
@@ -55,7 +52,7 @@ public class DeserializedClassDescriptor(outerContext: DeserializationContext, p
private val classId = outerContext.nameResolver.getClassId(classProto.getFqName()) private val classId = outerContext.nameResolver.getClassId(classProto.getFqName())
private val typeParameters = ArrayList<TypeParameterDescriptor>(classProto.getTypeParameterCount()) private val typeParameters = ArrayList<TypeParameterDescriptor>(classProto.getTypeParameterCount())
private val context = outerContext.withTypes(this).childContext(this, classProto.getTypeParameterList(), typeParameters) val context = outerContext.withTypes(this).childContext(this, classProto.getTypeParameterList(), typeParameters)
private val staticScope = StaticScopeForKotlinClass(this) private val staticScope = StaticScopeForKotlinClass(this)
private val typeConstructor = DeserializedClassTypeConstructor(typeParameters) private val typeConstructor = DeserializedClassTypeConstructor(typeParameters)