FIR: deserialize classes lazily from KLib to avoid cycles

the cycle appears e.g. on the Target annotation
This commit is contained in:
Ilya Chernikov
2022-07-14 15:27:56 +02:00
parent e1d19516e8
commit 302ccf12d0
@@ -9,8 +9,10 @@ import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.deserialization.* import org.jetbrains.kotlin.fir.deserialization.*
import org.jetbrains.kotlin.fir.isNewPlaceForBodyGeneration
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.library.metadata.KlibMetadataClassDataFinder import org.jetbrains.kotlin.library.metadata.KlibMetadataClassDataFinder
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -80,6 +82,7 @@ class KlibBasedSymbolProvider(
} }
} }
@OptIn(SymbolInternals::class)
override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? { override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? {
val packageStringName = classId.packageFqName.asString() val packageStringName = classId.packageFqName.asString()
@@ -99,6 +102,9 @@ class KlibBasedSymbolProvider(
val finder = KlibMetadataClassDataFinder(fragment, nameResolver) val finder = KlibMetadataClassDataFinder(fragment, nameResolver)
val classProto = finder.findClassData(classId)?.classProto ?: return@forEach val classProto = finder.findClassData(classId)?.classProto ?: return@forEach
val moduleData = moduleDataProvider.getModuleData(libraryPath) ?: return null
return ClassMetadataFindResult.NoMetadata { symbol ->
val source = object : DeserializedContainerSource { val source = object : DeserializedContainerSource {
override val incompatibility: IncompatibleVersionErrorData<*>? = null override val incompatibility: IncompatibleVersionErrorData<*>? = null
override val isPreReleaseInvisible = override val isPreReleaseInvisible =
@@ -109,14 +115,22 @@ class KlibBasedSymbolProvider(
override fun getContainingFile() = SourceFile.NO_SOURCE_FILE override fun getContainingFile() = SourceFile.NO_SOURCE_FILE
} }
return ClassMetadataFindResult.Metadata( deserializeClassToSymbol(
nameResolver, classId,
classProto, classProto,
symbol,
nameResolver,
session,
moduleData,
annotationDeserializer, annotationDeserializer,
moduleDataProvider.getModuleData(libraryPath), kotlinScopeProvider,
parentContext,
source, source,
classPostProcessor = {} origin = defaultDeserializationOrigin,
deserializeNestedClass = this::getClass,
) )
symbol.fir.isNewPlaceForBodyGeneration = isNewPlaceForBodyGeneration(classProto)
}
} }
return null return null