~
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt
index 164407c..ed7de65 100644
--- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt
+++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt
@@ -26,6 +26,8 @@
return providers.flatMapTo(mutableSetOf()) { it.findPackageParts(packageFqName) }.toList()
}
+ override fun allPackageNames(): List<String> = providers.flatMap { it.allPackageNames() }
+
override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> {
return providers.flatMapTo(mutableSetOf()) { it.getAnnotationsOnBinaryModule(moduleName) }.toList()
}
diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt
index 64eb9cf..8881cd0 100644
--- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt
+++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/KlibBasedSymbolProvider.kt
@@ -97,6 +97,10 @@
}
}
+ override fun computePackageSet(): Set<String> = fragmentNamesInLibraries.keys
+
+ override fun mayHaveTopLevelClass(classId: ClassId) = true
+
@OptIn(SymbolInternals::class)
override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? {
val packageStringName = classId.packageFqName.asString()
diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolProvider.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolProvider.kt
index f3670f9..b60c61c 100644
--- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolProvider.kt
+++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolProvider.kt
@@ -73,6 +73,22 @@
) : FirSymbolProvider(session) {
// ------------------------ Caches ------------------------
+ private val packageNames by lazy {
+ computePackageSet()
+ }
+
+ private val typeAliasesNamesByPackage: FirCache<FqName, Set<Name>, Nothing?> =
+ session.firCachesFactory.createCache { fqName: FqName ->
+ getPackageParts(fqName).flatMapTo(mutableSetOf()) { it.typeAliasNameIndex.keys }
+ }
+
+ private val allNamesByPackage: FirCache<FqName, Set<Name>, Nothing?> =
+ session.firCachesFactory.createCache { fqName: FqName ->
+ getPackageParts(fqName).flatMapTo(mutableSetOf()) {
+ it.topLevelFunctionNameIndex.keys + it.topLevelPropertyNameIndex.keys
+ }
+ }
+
private val packagePartsCache = session.firCachesFactory.createCache(::tryComputePackagePartInfos)
private val typeAliasCache = session.firCachesFactory.createCache(::findAndDeserializeTypeAlias)
private val classCache: FirCache<ClassId, FirRegularClassSymbol?, FirDeserializationContext?> =
@@ -91,6 +107,9 @@
// ------------------------ Abstract members ------------------------
protected abstract fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData>
+ protected abstract fun computePackageSet(): Set<String>
+
+ protected abstract fun mayHaveTopLevelClass(classId: ClassId): Boolean
protected abstract fun extractClassMetadata(
classId: ClassId,
@@ -190,6 +209,10 @@
parentContext: FirDeserializationContext? = null
): FirRegularClassSymbol? {
val parentClassId = classId.outerClassId
+
+ if (parentClassId == null && !mayHaveTopLevelClass(classId)) return null
+ if (parentClassId != null && !mayHaveTopLevelClass(classId.outermostClassId)) return null
+
if (parentContext == null && parentClassId != null) {
val alreadyLoaded = classCache.getValueIfComputed(classId)
if (alreadyLoaded != null) return alreadyLoaded
@@ -200,26 +223,38 @@
return classCache.getValue(classId, parentContext)
}
- private fun getTypeAlias(classId: ClassId): FirTypeAliasSymbol? =
- if (classId.relativeClassName.isOneSegmentFQN()) typeAliasCache.getValue(classId) else null
+ private fun getTypeAlias(classId: ClassId): FirTypeAliasSymbol? {
+ if (!classId.relativeClassName.isOneSegmentFQN()) return null
+ val packageFqName = classId.packageFqName
+ if (packageFqName.asString() !in packageNames) return null
+ if (classId.shortClassName !in typeAliasesNamesByPackage.getValue(packageFqName)) return null
+
+ return typeAliasCache.getValue(classId)
+ }
// ------------------------ SymbolProvider methods ------------------------
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
val callableId = CallableId(packageFqName, name)
- destination += functionCache.getValue(callableId)
- destination += propertyCache.getValue(callableId)
+ destination += functionCache.getCallables(callableId)
+ destination += propertyCache.getCallables(callableId)
+ }
+
+ private fun <C : FirCallableSymbol<*>> FirCache<CallableId, List<C>, Nothing?>.getCallables(id: CallableId): List<C> {
+ if (id.packageName.asString() !in packageNames) return emptyList()
+ if (id.callableName !in allNamesByPackage.getValue(id.packageName)) return emptyList()
+ return getValue(id)
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
- destination += functionCache.getValue(CallableId(packageFqName, name))
+ destination += functionCache.getCallables(CallableId(packageFqName, name))
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
- destination += propertyCache.getValue(CallableId(packageFqName, name))
+ destination += propertyCache.getCallables(CallableId(packageFqName, name))
}
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt
index 4e77418..80321f1 100644
--- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt
+++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt
@@ -27,7 +27,7 @@
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
-import org.jetbrains.kotlin.serialization.deserialization.*
+import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import java.nio.file.Path
import java.nio.file.Paths
@@ -91,6 +91,10 @@
}
}
+ override fun computePackageSet(): Set<String> = packagePartProvider.allPackageNames().toSet()
+
+ override fun mayHaveTopLevelClass(classId: ClassId): Boolean = javaFacade.hasTopLevelClassOf(classId)
+
private val KotlinJvmBinaryClass.incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>?
get() {
// TODO: skipMetadataVersionCheck
diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/OptionalAnnotationClassesProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/OptionalAnnotationClassesProvider.kt
index 0fbdfa7..fb35d2d 100644
--- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/OptionalAnnotationClassesProvider.kt
+++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/OptionalAnnotationClassesProvider.kt
@@ -49,6 +49,10 @@
return emptyList()
}
+ override fun computePackageSet(): Set<String> = emptySet()
+
+ override fun mayHaveTopLevelClass(classId: ClassId): Boolean = true
+
override fun extractClassMetadata(
classId: ClassId,
parentContext: FirDeserializationContext?
@@ -70,4 +74,4 @@
}
override fun getPackage(fqName: FqName): FqName? = if (optionalAnnotationClassesAndPackages.second.contains(fqName)) fqName else null
-}
\ No newline at end of file
+}
diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt
index 90bc4dc..fe94302 100644
--- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt
+++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackagePartProvider.kt
@@ -52,6 +52,12 @@
parent.findPackageParts(packageFqName)).distinct()
}
+ private val allPackageNames_ by lazy {
+ moduleMappings.flatMap { it.packageFqName2Parts.keys } + parent.allPackageNames()
+ }
+
+ override fun allPackageNames() = allPackageNames_
+
override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> {
return parent.getAnnotationsOnBinaryModule(moduleName)
}
diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt
index 262434c..56f2786 100644
--- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt
+++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt
@@ -39,6 +39,11 @@
return result.toList()
}
+ private val allPackageNames_ by lazy {
+ loadedModules.flatMap { it.mapping.packageFqName2Parts.keys }
+ }
+
+ override fun allPackageNames() = allPackageNames_
override fun findMetadataPackageParts(packageFqName: String): List<String> =
getPackageParts(packageFqName).flatMap(PackageParts::metadataParts).distinct()
diff --git a/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/PackagePartProvider.kt b/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/PackagePartProvider.kt
index 2502123..7241161 100644
--- a/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/PackagePartProvider.kt
+++ b/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/PackagePartProvider.kt
@@ -18,6 +18,8 @@
*/
fun findPackageParts(packageFqName: String): List<String>
+ fun allPackageNames(): List<String>
+
fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId>
fun getAllOptionalAnnotationClasses(): List<ClassData>
@@ -28,5 +30,7 @@
override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> = emptyList()
override fun getAllOptionalAnnotationClasses(): List<ClassData> = emptyList()
+
+ override fun allPackageNames(): List<String> = emptyList()
}
}