From b55f36f0fd37b6a595413d65b26b1a57b1fda9d5 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 21 Jul 2022 21:44:43 +0200 Subject: [PATCH] [Analysis API] introduce some basic API to create KtSymbol by Java PSI ^KT-50240 --- .../api/descriptors/KtFe10AnalysisSession.kt | 4 ++ .../KtFe10SymbolProviderByJavaPsi.kt | 28 ++++++++ .../analysis/api/fir/KtFirAnalysisSession.kt | 6 +- .../KtFirAnalysisSessionComponent.kt | 2 + .../KtFirSymbolProviderByJavaPsi.kt | 46 +++++++++++++ .../kotlin/analysis/api/KtAnalysisSession.kt | 13 ++-- .../api/symbols/KtSymbolProviderByJavaPsi.kt | 29 +++++++++ .../api/fir/LLFirResolveSessionDepended.kt | 3 +- .../level/api/fir/api/LLFirResolveSession.kt | 3 +- .../structure/LLFirLibrarySessionFactory.kt | 2 + .../LLFirFirClassByPsiClassProvider.kt | 64 +++++++++++++++++++ .../api/fir/sessions/LLFirSessionFactory.kt | 1 + .../state/LLFirResolvableResolveSession.kt | 4 +- 13 files changed, 196 insertions(+), 9 deletions(-) create mode 100644 analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolProviderByJavaPsi.kt create mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolProviderByJavaPsi.kt create mode 100644 analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProviderByJavaPsi.kt create mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirFirClassByPsiClassProvider.kt diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt index 8afe8cec903..ec5a3eb69a7 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.analysis.api.descriptors +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.components.* import org.jetbrains.kotlin.analysis.api.descriptors.components.* @@ -12,11 +13,13 @@ import org.jetbrains.kotlin.analysis.api.impl.base.components.KtAnalysisScopePro import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProvider +import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProviderByJavaPsi import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.getKtModule import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile +@OptIn(KtAnalysisApiInternals::class) @Suppress("LeakingThis") class KtFe10AnalysisSession( val analysisContext: Fe10AnalysisContext, @@ -59,6 +62,7 @@ class KtFe10AnalysisSession( override val signatureSubstitutorImpl: KtSignatureSubstitutor = KtFe10SignatureSubstitutor(this) override val scopeSubstitutionImpl: KtScopeSubstitution = KtFe10ScopeSubstitution(this) override val substitutorFactoryImpl: KtSubstitutorFactory = KtFe10SubstitutorFactory(this) + override val symbolProviderByJavaPsiImpl: KtSymbolProviderByJavaPsi = KtFe10SymbolProviderByJavaPsi(this) override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession = withValidityAssertion { diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolProviderByJavaPsi.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolProviderByJavaPsi.kt new file mode 100644 index 00000000000..48080ede927 --- /dev/null +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SymbolProviderByJavaPsi.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.descriptors.components + +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiMember +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals +import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession +import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent +import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProviderByJavaPsi + +@OptIn(KtAnalysisApiInternals::class) +internal class KtFe10SymbolProviderByJavaPsi( + override val analysisSession: KtFe10AnalysisSession +) : KtSymbolProviderByJavaPsi(), Fe10KtAnalysisSessionComponent { + override fun getNamedClassSymbol(psiClass: PsiClass): KtNamedClassOrObjectSymbol? { + return null /*TODO*/ + } + + override fun getCallableSymbol(callable: PsiMember): KtCallableSymbol? { + return null /*TODO*/ + } +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt index 9663fd034bc..8d511064bc7 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.api.fir import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.components.* import org.jetbrains.kotlin.analysis.api.fir.components.* @@ -27,10 +28,11 @@ import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile +@OptIn(KtAnalysisApiInternals::class) @Suppress("AnalysisApiMissingLifetimeCheck") internal class KtFirAnalysisSession private constructor( - private val project: Project, + val project: Project, val firResolveSession: LLFirResolveSession, token: KtLifetimeToken, private val mode: AnalysisSessionMode, @@ -109,6 +111,8 @@ private constructor( override val substitutorFactoryImpl: KtSubstitutorFactory = KtFirSubstitutorFactory(this) + override val symbolProviderByJavaPsiImpl = KtFirSymbolProviderByJavaPsi(this) + @Suppress("AnalysisApiMissingLifetimeCheck") override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession { check(mode == AnalysisSessionMode.REGULAR) { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt index 58e22892b04..5ec7dad3747 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.analysis.api.fir.components +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.analysis.api.KtStarProjectionTypeArgument import org.jetbrains.kotlin.analysis.api.KtTypeArgument @@ -39,6 +40,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs internal interface KtFirAnalysisSessionComponent { val analysisSession: KtFirAnalysisSession + val project: Project get() = analysisSession.project val rootModuleSession: FirSession get() = analysisSession.firResolveSession.useSiteFirSession val typeContext: ConeInferenceContext get() = rootModuleSession.typeContext val firSymbolBuilder get() = analysisSession.firSymbolBuilder diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolProviderByJavaPsi.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolProviderByJavaPsi.kt new file mode 100644 index 00000000000..98fcada2e2e --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolProviderByJavaPsi.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.fir.components + +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiField +import com.intellij.psi.PsiMember +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiTypeParameter +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals +import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProviderByJavaPsi +import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.firClassByPsiClassProvider +import org.jetbrains.kotlin.analysis.project.structure.getKtModule +import org.jetbrains.kotlin.name.Name + +@OptIn(KtAnalysisApiInternals::class) +internal class KtFirSymbolProviderByJavaPsi( + override val analysisSession: KtFirAnalysisSession, +) : KtSymbolProviderByJavaPsi(), KtFirAnalysisSessionComponent { + override fun getNamedClassSymbol(psiClass: PsiClass): KtNamedClassOrObjectSymbol? { + if (psiClass.qualifiedName == null) return null + if (psiClass is PsiTypeParameter) return null + val module = psiClass.getKtModule(analysisSession.project) + val provider = firResolveSession.getSessionFor(module).firClassByPsiClassProvider + val firClass = provider.getFirClass(psiClass) ?: return null + return firSymbolBuilder.classifierBuilder.buildNamedClassOrObjectSymbol(firClass) + } + + override fun getCallableSymbol(callable: PsiMember): KtCallableSymbol? { + if (callable !is PsiMethod && callable !is PsiField) return null + val name = callable.name?.let(Name::identifier) ?: return null + val containingClass = callable.containingClass ?: return null + val classSymbol = getNamedClassSymbol(containingClass) ?: return null + return with(analysisSession) { + classSymbol.getDeclaredMemberScope() + .getCallableSymbols { it == name } + .firstOrNull { it.psi == callable } + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt index 2af2293daf0..5ca096677af 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt @@ -8,9 +8,7 @@ package org.jetbrains.kotlin.analysis.api import org.jetbrains.kotlin.analysis.api.components.* import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProvider -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolProviderMixIn +import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.psi.KtElement @@ -28,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtFile * * To create analysis session consider using [analyse] */ +@OptIn(KtAnalysisApiInternals::class) @Suppress("AnalysisApiMissingLifetimeCheck") public abstract class KtAnalysisSession(final override val token: KtLifetimeToken) : KtLifetimeOwner, KtSmartCastProviderMixIn, @@ -59,7 +58,8 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke KtTypeCreatorMixIn, KtAnalysisScopeProviderMixIn, KtSignatureSubstitutorMixIn, - KtScopeSubstitutionMixIn { + KtScopeSubstitutionMixIn, + KtSymbolProviderByJavaPsiMixIn { public abstract val useSiteModule: KtModule @@ -155,6 +155,11 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke public val substitutorFactory: KtSubstitutorFactory get() = substitutorFactoryImpl protected abstract val substitutorFactoryImpl: KtSubstitutorFactory + @KtAnalysisApiInternals + public val symbolProviderByJavaPsi: KtSymbolProviderByJavaPsi get() = symbolProviderByJavaPsiImpl + @KtAnalysisApiInternals + protected abstract val symbolProviderByJavaPsiImpl: KtSymbolProviderByJavaPsi + @PublishedApi internal val typesCreator: KtTypeCreator diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProviderByJavaPsi.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProviderByJavaPsi.kt new file mode 100644 index 00000000000..e4f7962773b --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProviderByJavaPsi.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.symbols + +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiMember +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals +import org.jetbrains.kotlin.analysis.api.components.KtAnalysisSessionComponent +import org.jetbrains.kotlin.analysis.api.components.KtAnalysisSessionMixIn +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion + +@KtAnalysisApiInternals +public abstract class KtSymbolProviderByJavaPsi : KtAnalysisSessionComponent() { + public abstract fun getNamedClassSymbol(psiClass: PsiClass): KtNamedClassOrObjectSymbol? + + public abstract fun getCallableSymbol(callable: PsiMember): KtCallableSymbol? +} + +@KtAnalysisApiInternals +public interface KtSymbolProviderByJavaPsiMixIn : KtAnalysisSessionMixIn { + public fun PsiClass.getNamedClassSymbol(): KtNamedClassOrObjectSymbol? = + withValidityAssertion { analysisSession.symbolProviderByJavaPsi.getNamedClassSymbol(this) } + + public fun PsiMember.getCallableSymbol(): KtCallableSymbol? = + withValidityAssertion { analysisSession.symbolProviderByJavaPsi.getCallableSymbol(this) } +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveSessionDepended.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveSessionDepended.kt index cc2f8beb816..f7e467209f2 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveSessionDepended.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveSessionDepended.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirElementBuilder import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.KtToFirMapping +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableResolveSession import org.jetbrains.kotlin.analysis.low.level.api.fir.state.TowerProviderForElementForState import org.jetbrains.kotlin.analysis.low.level.api.fir.util.LLFirScopeSessionProvider @@ -54,7 +55,7 @@ internal class LLFirResolveSessionDepended( .getScopeSession() } - override fun getSessionFor(module: KtModule): FirSession = + override fun getSessionFor(module: KtModule): LLFirSession = originalFirResolveSession.getSessionFor(module) override fun getOrBuildFirFor(element: KtElement): FirElement? { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt index 438486c5c91..7383e995a24 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.api import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic import org.jetbrains.kotlin.fir.FirElement @@ -30,7 +31,7 @@ abstract class LLFirResolveSession { abstract val useSiteKtModule: KtModule - internal abstract fun getSessionFor(module: KtModule): FirSession + abstract fun getSessionFor(module: KtModule): LLFirSession abstract fun getScopeSessionFor(firSession: FirSession): ScopeSession diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirLibrarySessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirLibrarySessionFactory.kt index f4d28dd78ca..1b955bdac78 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirLibrarySessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirLibrarySessionFactory.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirFirClassByPsiClassProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirLibrarySessionProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibraryLikeSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibrarySession @@ -77,6 +78,7 @@ internal class LLFirLibrarySessionFactory( add(builtinsSession.symbolProvider) } + register(LLFirFirClassByPsiClassProvider::class, LLFirFirClassByPsiClassProvider(this)) register(FirProvider::class, LLFirLibrarySessionProvider(symbolProvider)) register(FirSymbolProvider::class, symbolProvider) register(FirJvmTypeMapper::class, FirJvmTypeMapper(this)) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirFirClassByPsiClassProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirFirClassByPsiClassProvider.kt new file mode 100644 index 00000000000..88af009b63e --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirFirClassByPsiClassProvider.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.low.level.api.fir.providers + +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiJavaFile +import com.intellij.psi.PsiTypeParameter +import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession +import org.jetbrains.kotlin.asJava.KtLightClassMarker +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionComponent +import org.jetbrains.kotlin.fir.java.JavaSymbolProvider +import org.jetbrains.kotlin.fir.psi +import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName + +class LLFirFirClassByPsiClassProvider(private val session: LLFirSession) : FirSessionComponent { + fun getFirClass(psiClass: PsiClass): FirRegularClassSymbol? { + require(psiClass !is PsiTypeParameter) { + "${LLFirFirClassByPsiClassProvider::class.simpleName} can create only regular classes" + } + + require(psiClass !is KtLightClassMarker) { + "${LLFirFirClassByPsiClassProvider::class.simpleName} can create only non-kotlin classes" + } + + if (psiClass.qualifiedName == null) { + return null // not yet supported + } + + val firClassSymbol = createFirClassFromFirProvider(psiClass) + check(firClassSymbol.fir.psi == psiClass) + return firClassSymbol + } + + private fun createFirClassFromFirProvider(psiClass: PsiClass): FirRegularClassSymbol { + val classId = psiClass.classIdIfNonLocal + ?: error("No classId for non-local class") + val provider = session.nullableJavaSymbolProvider ?: session.symbolProvider + val symbol = (provider.getClassLikeSymbolByClassId(classId) + ?: error("No classifier found with $classId")) + return symbol as FirRegularClassSymbol + } +} + +private val FirSession.nullableJavaSymbolProvider: JavaSymbolProvider? by FirSession.nullableSessionComponentAccessor() + + +val LLFirSession.firClassByPsiClassProvider: LLFirFirClassByPsiClassProvider by FirSession.sessionComponentAccessor() + +private val PsiClass.classIdIfNonLocal: ClassId? + get() { + val packageName = (containingFile as? PsiJavaFile)?.packageName ?: return null + val packageFqName = FqName(packageName) + + val classesNames = generateSequence(this) { it.containingClass }.map { it.name }.toList().asReversed() + if (classesNames.any { it == null }) return null + return ClassId(packageFqName, FqName(classesNames.joinToString(separator = ".")), false) + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt index 07d60f4381e..6709b0d823b 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt @@ -150,6 +150,7 @@ internal object LLFirSessionFactory { register(FirDependenciesSymbolProvider::class, dependencyProvider) register(FirJvmTypeMapper::class, FirJvmTypeMapper(this)) + register(LLFirFirClassByPsiClassProvider::class, LLFirFirClassByPsiClassProvider(this)) configureSession?.invoke(this) extensionService.additionalCheckers.forEach(session.checkersComponent::register) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt index 6863b757f8a..a7cabeea1d9 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirResolvableResolveSession.kt @@ -40,8 +40,8 @@ internal abstract class LLFirResolvableResolveSession( final override val useSiteFirSession = sessionProvider.rootModuleSession - override fun getSessionFor(module: KtModule): FirSession = - sessionProvider.getResolvableSession(module) + override fun getSessionFor(module: KtModule): LLFirSession = + sessionProvider.getSession(module) override fun getScopeSessionFor(firSession: FirSession): ScopeSession { requireIsInstance(firSession)