From 0f9d54c4dc4c492ee539ffb6dec3eee7a0ea3869 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Mon, 25 Mar 2019 18:08:11 +0300 Subject: [PATCH] FIR: Support deserialization of nested classes --- .../deserialization/ClassDeserialization.kt | 32 +++++----- .../deserialization/FirMemberDeserializer.kt | 58 +++++++++++-------- .../impl/FirLibrarySymbolProviderImpl.kt | 16 ++++- .../testData/builtIns/kotlin-collections.txt | 8 +++ .../testData/builtIns/kotlin-ranges.txt | 24 ++++++++ .../fir/resolve/testData/builtIns/kotlin.txt | 30 ++++++++++ 6 files changed, 125 insertions(+), 43 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt index 5d3b17b9850..92c54479df4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt @@ -27,7 +27,9 @@ fun deserializeClassToSymbol( classProto: ProtoBuf.Class, symbol: FirClassSymbol, nameResolver: NameResolver, - session: FirSession + session: FirSession, + parentContext: FirDeserializationContext? = null, + deserializeNestedClass: (ClassId, FirDeserializationContext) -> FirClassSymbol? ) { val flags = classProto.flags val kind = Flags.CLASS_KIND.get(flags) @@ -47,15 +49,15 @@ fun deserializeClassToSymbol( } //addAnnotationsFrom(classProto) ? TODO - val typeTable = TypeTable(classProto.typeTable) - val typeDeserializer = FirTypeDeserializer( - nameResolver, - typeTable, - classProto.typeParameterList, - null - ) + val context = + parentContext?.childContext(classProto.typeParameterList, nameResolver, TypeTable(classProto.typeTable)) + ?: FirDeserializationContext + .createForClass(classId, classProto, nameResolver, session) - val superTypesDeserialized = classProto.supertypes(typeTable).map { supertypeProto -> + val typeDeserializer = context.typeDeserializer + val classDeserializer = context.memberDeserializer + + val superTypesDeserialized = classProto.supertypes(context.typeTable).map { supertypeProto -> typeDeserializer.simpleType(supertypeProto) }// TODO: + c.components.additionalClassPartsProvider.getSupertypes(this@DeserializedClassDescriptor) @@ -64,13 +66,13 @@ fun deserializeClassToSymbol( FirResolvedTypeRefImpl(session, null, it, false, emptyList()) } - val classDeserializer = - FirDeserializationContext - .createForClass(classId, classProto, nameResolver, session) - .memberDeserializer - - // TODO: properties + nested classes + // TODO: properties declarations += classProto.functionList.map(classDeserializer::loadFunction) + + declarations += classProto.nestedClassNameList.mapNotNull { nestedNameId -> + val nestedClassId = classId.createNestedClassId(Name.identifier(nameResolver.getString(nestedNameId))) + deserializeNestedClass(nestedClassId, context)?.fir + } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index a8987cacaf5..c4669792304 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -41,7 +41,9 @@ class FirDeserializationContext( val components: FirDeserializationComponents ) { fun childContext( - typeParameterProtos: List + typeParameterProtos: List, + nameResolver: NameResolver = this.nameResolver, + typeTable: TypeTable = this.typeTable ): FirDeserializationContext = FirDeserializationContext( nameResolver, typeTable, versionRequirementTable, session, packageFqName, relativeClassName, FirTypeDeserializer( @@ -55,44 +57,50 @@ class FirDeserializationContext( companion object { fun createForPackage( fqName: FqName, - packageProto: ProtoBuf.PackageFragment, + packageProto: ProtoBuf.Package, nameResolver: NameResolver, session: FirSession - ): FirDeserializationContext { - val typeTable = TypeTable(packageProto.`package`.typeTable) - return FirDeserializationContext( - nameResolver, typeTable, - VersionRequirementTable.EMPTY, // TODO: - session, - fqName, - null, - FirTypeDeserializer( - nameResolver, - typeTable, - emptyList(), - null - ), - FirDeserializationComponents() - ) - } + ) = createRootContext( + nameResolver, + TypeTable(packageProto.typeTable), + session, + fqName, + relativeClassName = null, + typeParameterProtos = emptyList() + ) fun createForClass( classId: ClassId, classProto: ProtoBuf.Class, nameResolver: NameResolver, session: FirSession + ) = createRootContext( + nameResolver, + TypeTable(classProto.typeTable), + session, + classId.packageFqName, + classId.relativeClassName, + classProto.typeParameterList + ) + + private fun createRootContext( + nameResolver: NameResolver, + typeTable: TypeTable, + session: FirSession, + packageFqName: FqName, + relativeClassName: FqName?, + typeParameterProtos: List ): FirDeserializationContext { - val classTypeTable = TypeTable(classProto.typeTable) return FirDeserializationContext( - nameResolver, classTypeTable, + nameResolver, typeTable, VersionRequirementTable.EMPTY, // TODO: session, - classId.packageFqName, - classId.relativeClassName, + packageFqName, + relativeClassName, FirTypeDeserializer( nameResolver, - classTypeTable, - classProto.typeParameterList, + typeTable, + typeParameterProtos, null ), FirDeserializationComponents() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt index 210c6bdfb5c..30fa6bf0f64 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirLibrarySymbolProviderImpl.kt @@ -62,15 +62,25 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider FirDeserializationContext.createForPackage(fqName, packageProto, nameResolver, session).memberDeserializer } - val lookup = mutableMapOf() + val lookup = mutableMapOf() - fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? { + fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? = + findAndDeserializeClass(classId) + + private fun findAndDeserializeClass( + classId: ClassId, + parentContext: FirDeserializationContext? = null + ): FirClassSymbol? { if (classId !in classDataFinder.allClassIds) return null return lookup.getOrPut(classId, { FirClassSymbol(classId) }) { symbol -> val classData = classDataFinder.findClassData(classId)!! val classProto = classData.classProto - deserializeClassToSymbol(classId, classProto, symbol, nameResolver, session) + deserializeClassToSymbol( + classId, classProto, symbol, nameResolver, session, + parentContext, + this::findAndDeserializeClass + ) } } diff --git a/compiler/fir/resolve/testData/builtIns/kotlin-collections.txt b/compiler/fir/resolve/testData/builtIns/kotlin-collections.txt index b63fe322927..fd5298fbfd4 100644 --- a/compiler/fir/resolve/testData/builtIns/kotlin-collections.txt +++ b/compiler/fir/resolve/testData/builtIns/kotlin-collections.txt @@ -119,6 +119,9 @@ public abstract class LongIterator : R|kotlin/collections/Iterator| public abstract fun isEmpty(): R|kotlin/Boolean| + public abstract interface Entry : R|kotlin/Any| { + } + } public abstract interface MutableCollection : R|kotlin/collections/Collection|, R|kotlin/collections/MutableIterable| { @@ -201,6 +204,11 @@ public abstract class LongIterator : R|kotlin/collections/Iterator| public open fun remove(key: R|K|, value: R|V|): R|kotlin/Boolean| + public abstract interface MutableEntry : R|kotlin/collections/Map.Entry| { + public abstract fun setValue(newValue: R|V|): R|V| + + } + } public abstract interface MutableSet : R|kotlin/collections/Set|, R|kotlin/collections/MutableCollection| { diff --git a/compiler/fir/resolve/testData/builtIns/kotlin-ranges.txt b/compiler/fir/resolve/testData/builtIns/kotlin-ranges.txt index c673160c4e4..a9c9cf82c2f 100644 --- a/compiler/fir/resolve/testData/builtIns/kotlin-ranges.txt +++ b/compiler/fir/resolve/testData/builtIns/kotlin-ranges.txt @@ -9,6 +9,11 @@ public open class CharProgression : R|kotlin/collections/Iterable| public open fun toString(): R|kotlin/String| + public final companion object Companion : R|kotlin/Any| { + public final fun fromClosedRange(rangeStart: R|kotlin/Char|, rangeEnd: R|kotlin/Char|, step: R|kotlin/Int|): R|kotlin/ranges/CharProgression| + + } + } internal final class CharProgressionIterator : R|kotlin/collections/CharIterator| { @@ -29,6 +34,9 @@ public final class CharRange : R|kotlin/ranges/CharProgression|, R|kotlin/ranges public open fun toString(): R|kotlin/String| + public final companion object Companion : R|kotlin/Any| { + } + } public abstract interface ClosedRange : R|kotlin/Any| { @@ -49,6 +57,11 @@ public open class IntProgression : R|kotlin/collections/Iterable| { public open fun toString(): R|kotlin/String| + public final companion object Companion : R|kotlin/Any| { + public final fun fromClosedRange(rangeStart: R|kotlin/Int|, rangeEnd: R|kotlin/Int|, step: R|kotlin/Int|): R|kotlin/ranges/IntProgression| + + } + } internal final class IntProgressionIterator : R|kotlin/collections/IntIterator| { @@ -69,6 +82,9 @@ public final class IntRange : R|kotlin/ranges/IntProgression|, R|kotlin/ranges/C public open fun toString(): R|kotlin/String| + public final companion object Companion : R|kotlin/Any| { + } + } public open class LongProgression : R|kotlin/collections/Iterable| { @@ -82,6 +98,11 @@ public open class LongProgression : R|kotlin/collections/Iterable| public open fun toString(): R|kotlin/String| + public final companion object Companion : R|kotlin/Any| { + public final fun fromClosedRange(rangeStart: R|kotlin/Long|, rangeEnd: R|kotlin/Long|, step: R|kotlin/Long|): R|kotlin/ranges/LongProgression| + + } + } internal final class LongProgressionIterator : R|kotlin/collections/LongIterator| { @@ -102,5 +123,8 @@ public final class LongRange : R|kotlin/ranges/LongProgression|, R|kotlin/ranges public open fun toString(): R|kotlin/String| + public final companion object Companion : R|kotlin/Any| { + } + } diff --git a/compiler/fir/resolve/testData/builtIns/kotlin.txt b/compiler/fir/resolve/testData/builtIns/kotlin.txt index 1b8aed395d1..8dcc3195025 100644 --- a/compiler/fir/resolve/testData/builtIns/kotlin.txt +++ b/compiler/fir/resolve/testData/builtIns/kotlin.txt @@ -60,6 +60,9 @@ public final class Boolean : R|kotlin/Comparable| { public final infix fun xor(other: R|kotlin/Boolean|): R|kotlin/Boolean| + public final companion object Companion : R|kotlin/Any| { + } + } public final class BooleanArray : R|kotlin/Any| { @@ -186,6 +189,9 @@ public final class Byte : R|kotlin/Number|, R|kotlin/Comparable| { public final operator fun unaryPlus(): R|kotlin/Int| + public final companion object Companion : R|kotlin/Any| { + } + } public final class ByteArray : R|kotlin/Any| { @@ -226,6 +232,9 @@ public final class Char : R|kotlin/Comparable| { public final fun toShort(): R|kotlin/Short| + public final companion object Companion : R|kotlin/Any| { + } + } public final class CharArray : R|kotlin/Any| { @@ -367,6 +376,9 @@ public final class Double : R|kotlin/Number|, R|kotlin/Comparable public final operator fun unaryPlus(): R|kotlin/Double| + public final companion object Companion : R|kotlin/Any| { + } + } public final class DoubleArray : R|kotlin/Any| { @@ -392,6 +404,9 @@ public final annotation class DslMarker : R|kotlin/Annotation| { public open fun toString(): R|kotlin/String| + public final companion object Companion : R|kotlin/Any| { + } + } public final annotation class ExtensionFunctionType : R|kotlin/Annotation| { @@ -504,6 +519,9 @@ public final class Float : R|kotlin/Number|, R|kotlin/Comparable| public final operator fun unaryPlus(): R|kotlin/Float| + public final companion object Companion : R|kotlin/Any| { + } + } public final class FloatArray : R|kotlin/Any| { @@ -647,6 +665,9 @@ public final class Int : R|kotlin/Number|, R|kotlin/Comparable| { public final infix fun xor(other: R|kotlin/Int|): R|kotlin/Int| + public final companion object Companion : R|kotlin/Any| { + } + } public final class IntArray : R|kotlin/Any| { @@ -787,6 +808,9 @@ public final class Long : R|kotlin/Number|, R|kotlin/Comparable| { public final infix fun xor(other: R|kotlin/Long|): R|kotlin/Long| + public final companion object Companion : R|kotlin/Any| { + } + } public final class LongArray : R|kotlin/Any| { @@ -942,6 +966,9 @@ public final class Short : R|kotlin/Number|, R|kotlin/Comparable| public final operator fun unaryPlus(): R|kotlin/Int| + public final companion object Companion : R|kotlin/Any| { + } + } public final class ShortArray : R|kotlin/Any| { @@ -965,6 +992,9 @@ public final class String : R|kotlin/Comparable|, R|kotlin/CharSe public open fun subSequence(startIndex: R|kotlin/Int|, endIndex: R|kotlin/Int|): R|kotlin/CharSequence| + public final companion object Companion : R|kotlin/Any| { + } + } public final annotation class Suppress : R|kotlin/Annotation| {