[Analysis API] introduce some basic API to create KtSymbol by Java PSI

^KT-50240
This commit is contained in:
Ilya Kirillov
2022-07-21 21:44:43 +02:00
parent e4d00eea0f
commit b55f36f0fd
13 changed files with 196 additions and 9 deletions
@@ -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) {
@@ -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
@@ -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 }
}
}
}