[FIR] Add MetadataSymbolProvider

Extract common code from K1 to MetadataUtil
This commit is contained in:
Ivan Kochurkin
2023-01-16 23:24:23 +01:00
committed by Space Team
parent c103da98dd
commit e22359cc10
9 changed files with 166 additions and 36 deletions
@@ -34,12 +34,6 @@ import org.jetbrains.kotlin.utils.toMetadataVersion
import java.nio.file.Path
import java.nio.file.Paths
/**
* Any top level declarations in core/builtins/src are also available from FirBuiltinSymbolProvider (or FirIdeBuiltinSymbolProvider) for IDE
* so we filter them out to avoid providing the "same" symbols twice.
*/
private val kotlinBuiltins = setOf("kotlin/ArrayIntrinsicsKt", "kotlin/internal/ProgressionUtilKt")
// This symbol provider loads JVM classes, reading extra info from Kotlin `@Metadata` annotations
// if present. Use it for library and incremental compilation sessions. For source sessions use
// `JavaSymbolProvider`, as Kotlin classes should be parsed first.
@@ -59,7 +53,7 @@ class JvmClassFileBasedSymbolProvider(
override fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
return packagePartProvider.findPackageParts(packageFqName.asString()).mapNotNull { partName ->
if (partName in kotlinBuiltins) return@mapNotNull null
if (partName in KotlinBuiltins) return@mapNotNull null
val classId = ClassId.topLevel(JvmClassName.byInternalName(partName).fqNameForTopLevelClassMaybeWithDollars)
if (!javaFacade.hasTopLevelClassOf(classId)) return@mapNotNull null
val jvmMetadataVersion = session.languageVersionSettings.languageVersion.toMetadataVersion()
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.java.deserialization
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.ThreadSafeMutableState
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.deserialization.*
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.KotlinMetadataFinder
import org.jetbrains.kotlin.serialization.deserialization.MetadataClassDataFinder
import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.serialization.deserialization.readProto
@ThreadSafeMutableState
class MetadataSymbolProvider(
session: FirSession,
moduleDataProvider: ModuleDataProvider,
kotlinScopeProvider: FirKotlinScopeProvider,
private val packagePartProvider: PackagePartProvider,
private val kotlinClassFinder: KotlinMetadataFinder,
defaultDeserializationOrigin: FirDeclarationOrigin = FirDeclarationOrigin.Library
) : AbstractFirDeserializedSymbolProvider(
session, moduleDataProvider, kotlinScopeProvider, defaultDeserializationOrigin, BuiltInSerializerProtocol
) {
private val metadataPartProvider = packagePartProvider as MetadataPartProvider
private val classDataFinder = MetadataClassDataFinder(kotlinClassFinder)
private val annotationDeserializer = FirBuiltinAnnotationDeserializer(session)
private val constDeserializer = FirConstDeserializer(session, BuiltInSerializerProtocol)
override fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
return metadataPartProvider.findMetadataPackageParts(packageFqName.asString()).mapNotNull { partName ->
if (partName in KotlinBuiltins) return@mapNotNull null
val classId = ClassId(packageFqName, Name.identifier(partName))
val stream = kotlinClassFinder.findMetadata(classId) ?: return@mapNotNull null
val (proto, nameResolver, _) = readProto(stream)
val context = FirDeserializationContext.createForPackage(
packageFqName,
proto.`package`,
nameResolver,
moduleDataProvider.allModuleData.last(),
annotationDeserializer = annotationDeserializer,
constDeserializer = constDeserializer,
containerSource = null
)
return@mapNotNull PackagePartsCacheData(proto.`package`, context)
}
}
override fun computePackageSetWithNonClassDeclarations() = packagePartProvider.computePackageSetWithNonClassDeclarations()
override fun knownTopLevelClassesInPackage(packageFqName: FqName) = kotlinClassFinder.findMetadataTopLevelClassesInPackage(packageFqName)
override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? {
val classData = classDataFinder.findClassData(classId) ?: return null
return ClassMetadataFindResult.Metadata(
classData.nameResolver,
classData.classProto,
annotationDeserializer = null,
moduleDataProvider.allModuleData.last(),
sourceElement = null,
classPostProcessor = null
)
}
override fun isNewPlaceForBodyGeneration(classProto: ProtoBuf.Class) = false
override fun getPackage(fqName: FqName) = null
}
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.java.deserialization
/**
* Any top level declarations in core/builtins/src are also available from FirBuiltinSymbolProvider (or FirIdeBuiltinSymbolProvider) for IDE
* so we filter them out to avoid providing the "same" symbols twice.
*/
val KotlinBuiltins = setOf("kotlin/ArrayIntrinsicsKt", "kotlin/internal/ProgressionUtilKt")