FIR: remove extra layers of caching above JavaSymbolProvider

There needs to be exactly one postcompute-aware cache in order to avoid
breaking recursive calls to getClassLikeSymbolByFqName.
This commit is contained in:
pyos
2021-08-26 16:54:06 +02:00
committed by teamcityserver
parent 09c34eaa7b
commit ba1fc81b96
6 changed files with 38 additions and 156 deletions
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -63,14 +62,22 @@ class JavaSymbolProvider(
}
private val classCache =
session.firCachesFactory.createCacheWithPostCompute(
createValue = ::findAndConvertJavaClass,
session.firCachesFactory.createCacheWithPostCompute<ClassId, FirRegularClassSymbol?, Nothing?, JavaClass?>(
createValue = { classId, _ ->
val foundClass = findClass(classId)
if (foundClass == null) {
null to null
} else {
FirRegularClassSymbol(classId) to foundClass
}
},
postCompute = { _, classSymbol, javaClass ->
if (classSymbol != null && javaClass != null) {
convertJavaClassToFir(classSymbol, javaClass)
}
}
)
private val packageCache = session.firCachesFactory.createCache(::findPackage)
private val knownClassNamesInPackage = session.firCachesFactory.createCache<FqName, Set<String>?>(::getKnownClassNames)
@@ -80,10 +87,9 @@ class JavaSymbolProvider(
private val parentClassTypeParameterStackCache = mutableMapOf<FirRegularClassSymbol, JavaTypeParameterStack>()
private val parentClassEffectiveVisibilityCache = mutableMapOf<FirRegularClassSymbol, EffectiveVisibility>()
private fun findClass(
classId: ClassId,
content: KotlinClassFinder.Result.ClassFileContent?,
): JavaClass? = facade.findClass(JavaClassFinder.Request(classId, previouslyFoundClassFileContent = content?.content), searchScope)
private fun findClass(classId: ClassId): JavaClass? =
facade.findClass(JavaClassFinder.Request(classId), searchScope)
?.takeIf { !it.hasDifferentClassId(classId) && !it.hasMetadataAnnotation() }
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
@@ -133,27 +139,10 @@ class JavaSymbolProvider(
}
}
fun getFirJavaClass(classId: ClassId, content: KotlinClassFinder.Result.ClassFileContent? = null): FirRegularClassSymbol? {
private fun getFirJavaClass(classId: ClassId): FirRegularClassSymbol? {
// Enforce loading of outer class first
classId.outerClassId?.let { getFirJavaClass(it) }
return classCache.getValue(classId, content)
}
private fun findAndConvertJavaClass(
classId: ClassId,
content: KotlinClassFinder.Result.ClassFileContent?
): Pair<FirRegularClassSymbol?, JavaClass?> {
val foundClass = findClass(classId, content)
return if (foundClass == null ||
foundClass.hasDifferentClassId(classId) ||
foundClass.hasMetadataAnnotation()
) {
null to null
} else {
val symbol = FirRegularClassSymbol(classId)
symbol to foundClass
}
return classCache.getValue(classId, null)
}
private fun JavaClass.hasDifferentClassId(lookupClassId: ClassId): Boolean =
@@ -42,7 +42,6 @@ open class KotlinDeserializedJvmSymbolsProvider(
kotlinScopeProvider: FirKotlinScopeProvider,
private val packagePartProvider: PackagePartProvider,
private val kotlinClassFinder: KotlinClassFinder,
private val javaSymbolProvider: JavaSymbolProvider,
javaClassFinder: JavaClassFinder,
) : AbstractFirDeserializedSymbolsProvider(session, moduleDataProvider, kotlinScopeProvider) {
private val knownNameInPackageCache = KnownNameInPackageCache(session, javaClassFinder)
@@ -102,9 +101,7 @@ open class KotlinDeserializedJvmSymbolsProvider(
}
val kotlinClass = when (result) {
is KotlinClassFinder.Result.KotlinClass -> result
is KotlinClassFinder.Result.ClassFileContent -> {
return ClassMetadataFindResult.ClassWithoutMetadata(readClassFromClassFile(classId, result))
}
is KotlinClassFinder.Result.ClassFileContent -> return null
null -> return ClassMetadataFindResult.ShouldDeserializeViaParent
}
if (kotlinClass.kotlinJvmBinaryClass.classHeader.kind != KotlinClassHeader.Kind.CLASS) return null
@@ -144,10 +141,6 @@ open class KotlinDeserializedJvmSymbolsProvider(
symbol.fir.replaceDeprecation(symbol.fir.getDeprecationInfos(session.languageVersionSettings.apiVersion))
}
private fun readClassFromClassFile(classId: ClassId, classFile: KotlinClassFinder.Result.ClassFileContent): FirRegularClassSymbol? {
return javaSymbolProvider.getFirJavaClass(classId, classFile)
}
private fun KotlinClassFinder.Result.KotlinClass.extractMetadata(): Pair<NameResolver, ProtoBuf.Class>? {
val data = kotlinJvmBinaryClass.classHeader.data ?: return null
val strings = kotlinJvmBinaryClass.classHeader.strings ?: return null