FIR: hide construction of JavaSymbolProvider
This commit is contained in:
@@ -6,8 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.java
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
@@ -42,16 +40,16 @@ 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.java.structure.impl.JavaPackageImpl
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
import org.jetbrains.kotlin.types.Variance.INVARIANT
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class JavaSymbolProviderWrapper(session: FirSession, private val javaSymbolProvider: JavaSymbolProvider) : FirSymbolProvider(session) {
|
||||
class JavaSymbolProviderWrapper(session: FirSession, baseModuleData: FirModuleData, facade: JavaClassFinder) : FirSymbolProvider(session) {
|
||||
private val javaSymbolProvider = JavaSymbolProvider(session, baseModuleData, facade)
|
||||
|
||||
private val classCache =
|
||||
session.firCachesFactory.createCacheWithPostCompute(
|
||||
createValue = { classId: ClassId, parentClassSymbol: FirRegularClassSymbol? ->
|
||||
@@ -68,14 +66,12 @@ class JavaSymbolProviderWrapper(session: FirSession, private val javaSymbolProvi
|
||||
override fun getPackage(fqName: FqName): FqName? =
|
||||
javaSymbolProvider.getPackage(fqName)
|
||||
|
||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? {
|
||||
return try {
|
||||
if (!javaSymbolProvider.hasTopLevelClassOf(classId)) return null
|
||||
getFirJavaClass(classId)
|
||||
override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? =
|
||||
try {
|
||||
if (javaSymbolProvider.hasTopLevelClassOf(classId)) getFirJavaClass(classId) else null
|
||||
} catch (e: ProcessCanceledException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFirJavaClass(classId: ClassId): FirRegularClassSymbol? =
|
||||
classCache.getValue(classId, classId.outerClassId?.let { getFirJavaClass(it) })
|
||||
@@ -93,25 +89,35 @@ class JavaSymbolProviderWrapper(session: FirSession, private val javaSymbolProvi
|
||||
@ThreadSafeMutableState
|
||||
class JavaSymbolProvider(
|
||||
private val session: FirSession,
|
||||
val baseModuleData: FirModuleData,
|
||||
val project: Project,
|
||||
private val searchScope: GlobalSearchScope,
|
||||
private val baseModuleData: FirModuleData,
|
||||
private val facade: JavaClassFinder
|
||||
) {
|
||||
companion object {
|
||||
val VALUE_METHOD_NAME = Name.identifier("value")
|
||||
}
|
||||
|
||||
private val packageCache = session.firCachesFactory.createCache(::findPackage)
|
||||
private val knownClassNamesInPackage = session.firCachesFactory.createCache<FqName, Set<String>?>(::getKnownClassNames)
|
||||
private val packageCache = session.firCachesFactory.createCache(facade::findPackage)
|
||||
private val knownClassNamesInPackage = session.firCachesFactory.createCache(facade::knownClassNamesInPackage)
|
||||
|
||||
private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project)
|
||||
private val parentClassTypeParameterStackCache = mutableMapOf<FirRegularClassSymbol, JavaTypeParameterStack>()
|
||||
private val parentClassEffectiveVisibilityCache = mutableMapOf<FirRegularClassSymbol, EffectiveVisibility>()
|
||||
|
||||
fun findClass(classId: ClassId, knownContent: ByteArray? = null): JavaClass? =
|
||||
facade.findClass(JavaClassFinder.Request(classId, knownContent), searchScope)
|
||||
facade.findClass(JavaClassFinder.Request(classId, knownContent))
|
||||
?.takeIf { !it.hasDifferentClassId(classId) && !it.hasMetadataAnnotation() }
|
||||
|
||||
fun getPackage(fqName: FqName): FqName? =
|
||||
try {
|
||||
packageCache.getValue(fqName)?.fqName
|
||||
} catch (e: ProcessCanceledException) {
|
||||
null
|
||||
}
|
||||
|
||||
fun hasTopLevelClassOf(classId: ClassId): Boolean {
|
||||
val knownNames = knownClassNamesInPackage.getValue(classId.packageFqName) ?: return true
|
||||
return classId.relativeClassName.topLevelName() in knownNames
|
||||
}
|
||||
|
||||
private fun JavaTypeParameter.toFirTypeParameter(javaTypeParameterStack: JavaTypeParameterStack): FirTypeParameter {
|
||||
return buildTypeParameter {
|
||||
moduleData = this@JavaSymbolProvider.baseModuleData
|
||||
@@ -139,10 +145,6 @@ class JavaSymbolProvider(
|
||||
private fun List<JavaTypeParameter>.convertTypeParameters(stack: JavaTypeParameterStack): List<FirTypeParameter> =
|
||||
map { it.toFirTypeParameter(stack) }
|
||||
|
||||
fun getPackage(fqName: FqName): FqName? {
|
||||
return packageCache.getValue(fqName)?.fqName
|
||||
}
|
||||
|
||||
private fun JavaClass.hasDifferentClassId(lookupClassId: ClassId): Boolean =
|
||||
classId != lookupClassId
|
||||
|
||||
@@ -550,24 +552,6 @@ class JavaSymbolProvider(
|
||||
isNullable = false,
|
||||
)
|
||||
|
||||
private fun findPackage(fqName: FqName): JavaPackage? {
|
||||
return try {
|
||||
val facade = KotlinJavaPsiFacade.getInstance(project)
|
||||
val javaPackage = facade.findPackage(fqName.asString(), searchScope) ?: return null
|
||||
JavaPackageImpl(javaPackage, searchScope)
|
||||
} catch (e: ProcessCanceledException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun hasTopLevelClassOf(classId: ClassId): Boolean {
|
||||
val knownNames = knownClassNamesInPackage.getValue(classId.packageFqName) ?: return true
|
||||
return classId.relativeClassName.topLevelName() in knownNames
|
||||
}
|
||||
|
||||
private fun getKnownClassNames(packageFqName: FqName): MutableSet<String>? =
|
||||
facade.knownClassNamesInPackage(packageFqName, searchScope)
|
||||
private fun FqName.topLevelName() =
|
||||
asString().substringBefore(".")
|
||||
}
|
||||
|
||||
fun FqName.topLevelName() =
|
||||
asString().substringBefore(".")
|
||||
|
||||
+9
-26
@@ -9,14 +9,10 @@ import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.ThreadSafeMutableState
|
||||
import org.jetbrains.kotlin.fir.caches.createCache
|
||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||
import org.jetbrains.kotlin.fir.caches.getValue
|
||||
import org.jetbrains.kotlin.fir.declarations.getDeprecationInfos
|
||||
import org.jetbrains.kotlin.fir.deserialization.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.topLevelName
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
@@ -42,16 +38,15 @@ open class KotlinDeserializedJvmSymbolsProvider(
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
private val packagePartProvider: PackagePartProvider,
|
||||
private val kotlinClassFinder: KotlinClassFinder,
|
||||
javaClassFinder: JavaClassFinder,
|
||||
private val javaSymbolProvider: JavaSymbolProvider
|
||||
javaClassFinder: JavaClassFinder
|
||||
) : AbstractFirDeserializedSymbolsProvider(session, moduleDataProvider, kotlinScopeProvider) {
|
||||
private val knownNameInPackageCache = KnownNameInPackageCache(session, javaClassFinder)
|
||||
private val javaSymbolProvider = JavaSymbolProvider(session, moduleDataProvider.allModuleData.last(), javaClassFinder)
|
||||
private val annotationsLoader = AnnotationsLoader(session, kotlinClassFinder)
|
||||
|
||||
override fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
|
||||
return packagePartProvider.findPackageParts(packageFqName.asString()).mapNotNull { partName ->
|
||||
val classId = ClassId.topLevel(JvmClassName.byInternalName(partName).fqNameForTopLevelClassMaybeWithDollars)
|
||||
if (knownNameInPackageCache.hasNoTopLevelClassOf(classId)) return@mapNotNull null
|
||||
if (!javaSymbolProvider.hasTopLevelClassOf(classId)) return@mapNotNull null
|
||||
val (kotlinJvmBinaryClass, byteContent) =
|
||||
kotlinClassFinder.findKotlinClassOrContent(classId) as? KotlinClassFinder.Result.KotlinClass ?: return@mapNotNull null
|
||||
|
||||
@@ -97,7 +92,7 @@ open class KotlinDeserializedJvmSymbolsProvider(
|
||||
javaSymbolProvider.hasTopLevelClassOf(classId)
|
||||
|
||||
override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? {
|
||||
if (knownNameInPackageCache.hasNoTopLevelClassOf(classId)) return null
|
||||
if (!javaSymbolProvider.hasTopLevelClassOf(classId)) return null
|
||||
val result = try {
|
||||
kotlinClassFinder.findKotlinClassOrContent(classId)
|
||||
} catch (e: ProcessCanceledException) {
|
||||
@@ -106,7 +101,11 @@ open class KotlinDeserializedJvmSymbolsProvider(
|
||||
val kotlinClass = when (result) {
|
||||
is KotlinClassFinder.Result.KotlinClass -> result
|
||||
is KotlinClassFinder.Result.ClassFileContent -> {
|
||||
val javaClass = javaSymbolProvider.findClass(classId, result.content) ?: return null
|
||||
val javaClass = try {
|
||||
javaSymbolProvider.findClass(classId, result.content) ?: return null
|
||||
} catch (e: ProcessCanceledException) {
|
||||
return null
|
||||
}
|
||||
return ClassMetadataFindResult.NoMetadata { symbol ->
|
||||
javaSymbolProvider.convertJavaClassToFir(symbol, classId.outerClassId?.let(::getClass), javaClass)
|
||||
}
|
||||
@@ -159,22 +158,6 @@ open class KotlinDeserializedJvmSymbolsProvider(
|
||||
return JvmProtoBufUtil.readClassDataFrom(data, strings)
|
||||
}
|
||||
|
||||
private class KnownNameInPackageCache(
|
||||
session: FirSession,
|
||||
private val javaClassFinder: JavaClassFinder
|
||||
) {
|
||||
private val knownClassNamesInPackage = session.firCachesFactory.createCache(javaClassFinder::knownClassNamesInPackage)
|
||||
|
||||
/**
|
||||
* This function returns true if we are sure that no top-level class with this id is available
|
||||
* If it returns false, it means we can say nothing about this id
|
||||
*/
|
||||
fun hasNoTopLevelClassOf(classId: ClassId): Boolean {
|
||||
val knownNames = knownClassNamesInPackage.getValue(classId.packageFqName) ?: return false
|
||||
return classId.relativeClassName.topLevelName() !in knownNames
|
||||
}
|
||||
}
|
||||
|
||||
private fun String?.toPath(): Path? {
|
||||
return this?.let { Paths.get(it).normalize() }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user