[FIR] Handle non-kotlin class results from findKotlinClassOrContent

This commit is contained in:
Simon Ogorodnik
2019-06-14 19:54:16 +03:00
committed by Mikhail Glukhikh
parent 2f53bd24dd
commit 2c5bd46a97
3 changed files with 28 additions and 8 deletions
@@ -59,16 +59,19 @@ class FirLibrarySession private constructor(
init { init {
sessionProvider.sessionCache[moduleInfo] = this sessionProvider.sessionCache[moduleInfo] = this
val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, scope)
_firSymbolProvider = _firSymbolProvider =
FirCompositeSymbolProvider( FirCompositeSymbolProvider(
listOf( listOf(
FirLibrarySymbolProviderImpl(this), FirLibrarySymbolProviderImpl(this),
KotlinDeserializedJvmSymbolsProvider( KotlinDeserializedJvmSymbolsProvider(
this, sessionProvider.project, this, sessionProvider.project,
packagePartProvider, kotlinClassFinder, packagePartProvider,
javaSymbolProvider,
kotlinClassFinder,
javaClassFinder javaClassFinder
), ),
JavaSymbolProvider(this, sessionProvider.project, scope), javaSymbolProvider,
FirDependenciesSymbolProviderImpl(this) FirDependenciesSymbolProviderImpl(this)
) )
) )
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -53,7 +54,10 @@ class JavaSymbolProvider(
private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project) private val facade: KotlinJavaPsiFacade get() = KotlinJavaPsiFacade.getInstance(project)
private fun findClass(classId: ClassId): JavaClass? = facade.findClass(JavaClassFinder.Request(classId), searchScope) private fun findClass(
classId: ClassId,
content: KotlinClassFinder.Result.ClassFileContent?
): JavaClass? = facade.findClass(JavaClassFinder.Request(classId, previouslyFoundClassFileContent = content?.content), searchScope)
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<ConeCallableSymbol> = override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<ConeCallableSymbol> =
emptyList() emptyList()
@@ -136,10 +140,12 @@ class JavaSymbolProvider(
} }
} }
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? { override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? = getFirJavaClass(classId)
fun getFirJavaClass(classId: ClassId, content: KotlinClassFinder.Result.ClassFileContent? = null): ConeClassLikeSymbol? {
if (!hasTopLevelClassOf(classId)) return null if (!hasTopLevelClassOf(classId)) return null
return classCache.lookupCacheOrCalculateWithPostCompute(classId, { return classCache.lookupCacheOrCalculateWithPostCompute(classId, {
val foundClass = findClass(classId) val foundClass = findClass(classId, content)
if (foundClass == null || foundClass.annotations.any { it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME }) { if (foundClass == null || foundClass.annotations.any { it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME }) {
null to null null to null
} else { } else {
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.java.createConstant import org.jetbrains.kotlin.fir.java.createConstant
import org.jetbrains.kotlin.fir.java.topLevelName import org.jetbrains.kotlin.fir.java.topLevelName
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
@@ -61,6 +62,7 @@ class KotlinDeserializedJvmSymbolsProvider(
val session: FirSession, val session: FirSession,
val project: Project, val project: Project,
private val packagePartProvider: PackagePartProvider, private val packagePartProvider: PackagePartProvider,
private val javaSymbolProvider: JavaSymbolProvider,
private val kotlinClassFinder: KotlinClassFinder, private val kotlinClassFinder: KotlinClassFinder,
private val javaClassFinder: JavaClassFinder private val javaClassFinder: JavaClassFinder
) : AbstractFirSymbolProvider() { ) : AbstractFirSymbolProvider() {
@@ -68,6 +70,8 @@ class KotlinDeserializedJvmSymbolsProvider(
private val typeAliasCache = HashMap<ClassId, FirTypeAliasSymbol?>() private val typeAliasCache = HashMap<ClassId, FirTypeAliasSymbol?>()
private val packagePartsCache = HashMap<FqName, Collection<PackagePartsCacheData>>() private val packagePartsCache = HashMap<FqName, Collection<PackagePartsCacheData>>()
private val handledByJava = HashSet<ClassId>()
private class PackagePartsCacheData( private class PackagePartsCacheData(
val proto: ProtoBuf.Package, val proto: ProtoBuf.Package,
val context: FirDeserializationContext, val context: FirDeserializationContext,
@@ -313,10 +317,17 @@ class KotlinDeserializedJvmSymbolsProvider(
if (!hasTopLevelClassOf(classId)) return null if (!hasTopLevelClassOf(classId)) return null
if (classesCache.containsKey(classId)) return classesCache[classId] if (classesCache.containsKey(classId)) return classesCache[classId]
if (classId in handledByJava) return null
// return classesCache.getOrPut(classId) { val result = kotlinClassFinder.findKotlinClassOrContent(classId)
//return null val kotlinJvmBinaryClass = when (result) {
val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) is KotlinClassFinder.Result.KotlinClass -> result.kotlinJvmBinaryClass
is KotlinClassFinder.Result.ClassFileContent -> {
handledByJava.add(classId)
return javaSymbolProvider.getFirJavaClass(classId, result) as FirClassSymbol?
}
null -> null
}
if (kotlinJvmBinaryClass == null) { if (kotlinJvmBinaryClass == null) {
val outerClassId = classId.outerClassId ?: return null val outerClassId = classId.outerClassId ?: return null
val outerJvmBinaryClass = kotlinClassFinder.findKotlinClass(outerClassId) ?: return null val outerJvmBinaryClass = kotlinClassFinder.findKotlinClass(outerClassId) ?: return null