diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractPsiTypeProviderTest.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractPsiTypeProviderTest.kt index 49802ae1364..cd2d27996de 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractPsiTypeProviderTest.kt +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractPsiTypeProviderTest.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.analysis.api.fir.components +import com.intellij.openapi.project.Project import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiElementVisitor @@ -12,10 +13,11 @@ import org.jetbrains.kotlin.analysis.api.analyse import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService import org.jetbrains.kotlin.analysis.api.impl.barebone.test.expressionMarkerProvider import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleFileTest +import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.elements.KtLightElement -import org.jetbrains.kotlin.light.classes.symbol.classes.getOrCreateFirLightClass -import org.jetbrains.kotlin.light.classes.symbol.classes.getOrCreateFirLightFacade +import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration @@ -24,16 +26,13 @@ import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull abstract class AbstractPsiTypeProviderTest : AbstractHLApiSingleFileTest(FirFrontendApiTestConfiguratorService) { - override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { - val mainKtFileFqName = ktFile.packageFqName.child(Name.identifier(ktFile.name)) val declaration = testServices.expressionMarkerProvider.getElementOfTypAtCaret(ktFile) val containingClass = - declaration.parents.firstOrNull { it is KtClassOrObject }?.let { getOrCreateFirLightClass(it as KtClassOrObject) } - ?: getOrCreateFirLightFacade(listOf(ktFile), mainKtFileFqName) - ?: error("Can't get or create containing KtLightClass for $declaration") + getContainingKtLightClass(declaration, ktFile) val psiContext = containingClass.findLightDeclarationContext(declaration) ?: error("Can't find psi context for $declaration") val actual = buildString { @@ -48,6 +47,34 @@ abstract class AbstractPsiTypeProviderTest : AbstractHLApiSingleFileTest(FirFron testServices.assertions.assertEqualsToFile(testDataFileSibling(".txt"), actual) } + private fun getContainingKtLightClass( + declaration: KtDeclaration, + ktFile: KtFile, + ): KtLightClass { + val project = ktFile.project + return createLightClassByContainingClass(declaration, project) + ?: getFacadeLightClass(ktFile, project) + ?: error("Can't get or create containing KtLightClass for $declaration") + + } + + private fun getFacadeLightClass( + ktFile: KtFile, + project: Project, + ): KtLightClass? { + val mainKtFileFqName = ktFile.packageFqName.child(Name.identifier(ktFile.name)) + return project.getService(SymbolLightClassFacadeCache::class.java) + .getOrCreateSymbolLightFacade(listOf(ktFile), mainKtFileFqName) + } + + private fun createLightClassByContainingClass( + declaration: KtDeclaration, + project: Project + ): KtLightClass? { + val containingClass = declaration.parents.firstIsInstanceOrNull() ?: return null + return project.getService(KotlinAsJavaSupport::class.java).getLightClass(containingClass) + } + private fun KtLightClass.findLightDeclarationContext(ktDeclaration: KtDeclaration): KtLightElement<*, *>? { val selfOrParents = listOf(ktDeclaration) + ktDeclaration.parents.filterIsInstance() var result: KtLightElement<*, *>? = null diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/firLightClassUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/firLightClassUtils.kt index 199721a2df6..7bf1b3741b8 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/firLightClassUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/firLightClassUtils.kt @@ -37,7 +37,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClass import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import java.util.* -fun getOrCreateFirLightClass(classOrObject: KtClassOrObject): KtLightClass? = +internal fun getOrCreateFirLightClass(classOrObject: KtClassOrObject): KtLightClass? = CachedValuesManager.getCachedValue(classOrObject) { CachedValueProvider.Result .create( @@ -47,7 +47,7 @@ fun getOrCreateFirLightClass(classOrObject: KtClassOrObject): KtLightClass? = } @OptIn(HackToForceAllowRunningAnalyzeOnEDT::class) -fun createFirLightClassNoCache(classOrObject: KtClassOrObject): KtLightClass? = hackyAllowRunningOnEdt { +internal fun createFirLightClassNoCache(classOrObject: KtClassOrObject): KtLightClass? = hackyAllowRunningOnEdt { val containingFile = classOrObject.containingFile if (containingFile is KtCodeFragment) {