FIR LC: do not create light classes for non-source declarations

This commit is contained in:
Ilya Kirillov
2021-10-21 13:34:54 +02:00
parent 55e6df6920
commit 79f30755a5
4 changed files with 30 additions and 15 deletions
@@ -9,6 +9,7 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.assertIsValidAndAccessible
import org.jetbrains.kotlin.analysis.api.components.*
import org.jetbrains.kotlin.analysis.api.fir.components.*
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirOverrideInfoProvider
@@ -9,10 +9,7 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.analysis.api.KtStarProjectionTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.analysis.api.*
import org.jetbrains.kotlin.analysis.api.fir.symbols.*
import org.jetbrains.kotlin.analysis.api.fir.types.*
import org.jetbrains.kotlin.analysis.api.fir.utils.weakRef
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.light.classes.symbol
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClass
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
@@ -23,9 +20,7 @@ import org.jetbrains.kotlin.light.classes.symbol.classes.getOrCreateFirLightFaca
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtScript
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
class IDEKotlinAsJavaFirSupport(private val project: Project) : KotlinAsJavaSupport() {
@@ -84,8 +79,10 @@ class IDEKotlinAsJavaFirSupport(private val project: Project) : KotlinAsJavaSupp
.getKotlinSubPackageFqNames(fqn)
.map { fqn.child(it) }
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? =
getOrCreateFirLightClass(classOrObject)
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? {
if (!classOrObject.isFromSource()) return null
return getOrCreateFirLightClass(classOrObject)
}
override fun getLightClassForScript(script: KtScript): KtLightClass =
error("Should not be called")
@@ -105,21 +102,35 @@ class IDEKotlinAsJavaFirSupport(private val project: Project) : KotlinAsJavaSupp
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> =
project.createDeclarationProvider(scope)
.getFacadeFilesInPackage(packageFqName)
.asSequence()
.filter { it.isFromSource() }
.groupBy { it.javaFileFacadeFqName }
.mapNotNull { getOrCreateFirLightFacade(it.value, it.key) }
override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection<String> =
project.createDeclarationProvider(scope)
.getFacadeFilesInPackage(packageFqName)
.filter { it.isFromSource() }
.mapTo(mutableSetOf()) { it.javaFileFacadeFqName.shortName().asString() }
override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile> =
project.createDeclarationProvider(scope)
override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile> {
return project.createDeclarationProvider(scope)
.findFilesForFacade(facadeFqName)
.filter { it.isFromSource() }
}
override fun getFakeLightClass(classOrObject: KtClassOrObject): KtFakeLightClass =
KtFirBasedFakeLightClass(classOrObject)
override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass =
TODO("Not implemented")
}
private fun KtElement.isFromSource(): Boolean {
if (this is KtFile && isCompiled) {
// small optimisation to not invoke expensive getKtModule
return false
}
return getKtModule(project) is KtSourceModule
}
@@ -40,6 +40,12 @@ class FirLightClassForFacade(
init {
require(files.isNotEmpty())
/*
Actually, here should be the following check
require(files.all { it.getKtModule() is KtSourceModule })
but it is quite expensive
*/
require(files.none { it.isCompiled })
}
private val firstFileInFacade by lazyPub { files.first() }