[FIR] Provide compiler light classes from all source modules

This commit is contained in:
Dmitriy Novozhilov
2021-05-31 17:46:27 +03:00
committed by teamcityserver
parent 8729421e7a
commit 3991383853
@@ -22,13 +22,16 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.resolveSupertypesInTheAir
import org.jetbrains.kotlin.name.StandardClassIds
@@ -45,17 +48,23 @@ class FirJavaElementFinder(
project: Project
) : PsiElementFinder(), KotlinFinderMarker {
private val psiManager = PsiManager.getInstance(project)
private val firProvider = session.firProvider
@OptIn(ExperimentalStdlibApi::class)
private val firProviders: List<FirProvider> = buildList {
add(session.firProvider)
session.collectAllDependentSourceSessions().mapTo(this) { it.firProvider }
}
override fun findPackage(qualifiedName: String): PsiPackage? {
if (firProvider.symbolProvider.getPackage(FqName(qualifiedName)) == null) return null
if (firProviders.none { it.symbolProvider.getPackage(FqName(qualifiedName)) != null }) return null
return PsiPackageImpl(psiManager, qualifiedName)
}
override fun getClasses(psiPackage: PsiPackage, scope: GlobalSearchScope): Array<PsiClass> {
return firProvider.getClassNamesInPackage(FqName(psiPackage.qualifiedName))
.mapNotNull { findClass(psiPackage.qualifiedName + "." + it.identifier, scope) }
.toTypedArray()
return firProviders.flatMap { firProvider ->
firProvider.getClassNamesInPackage(FqName(psiPackage.qualifiedName))
.mapNotNull { findClass(psiPackage.qualifiedName + "." + it.identifier, scope) }
}.toTypedArray()
}
override fun findClasses(qualifiedName: String, scope: GlobalSearchScope): Array<PsiClass> {
@@ -66,9 +75,7 @@ class FirJavaElementFinder(
if (qualifiedName.endsWith(".")) return null
val classId = ClassId.topLevel(FqName(qualifiedName))
val firClass =
firProvider.getFirClassifierByFqName(classId) as? FirRegularClass
?: return null
val firClass = firProviders.firstNotNullOfOrNull { it.getFirClassifierByFqName(classId) as? FirRegularClass } ?: return null
val fileStub = createJavaFileStub(classId.packageFqName, psiManager)
@@ -111,6 +118,28 @@ class FirJavaElementFinder(
}
private fun FirSession.collectAllDependentSourceSessions(): List<FirSession> {
val result = mutableListOf<FirSession>()
collectAllDependentSourceSessionsTo(result)
return result
}
private fun FirSession.collectAllDependentSourceSessionsTo(destination: MutableList<FirSession>) {
val moduleData = moduleData
collectAllDependentSourceSessionsTo(destination, moduleData.dependencies)
collectAllDependentSourceSessionsTo(destination, moduleData.friendDependencies)
collectAllDependentSourceSessionsTo(destination, moduleData.dependsOnDependencies)
}
private fun collectAllDependentSourceSessionsTo(destination: MutableList<FirSession>, dependencies: Collection<FirModuleData>) {
for (dependency in dependencies) {
val dependencySession = dependency.session
if (dependencySession.kind != FirSession.Kind.Source) continue
destination += dependencySession
dependencySession.collectAllDependentSourceSessionsTo(destination)
}
}
private fun FirRegularClass.packFlags(): Int {
var flags = when (visibility) {
Visibilities.Private -> ModifierFlags.PRIVATE_MASK