[Analysis API] introduce some basic API to create KtSymbol by Java PSI
^KT-50240
This commit is contained in:
+4
@@ -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 {
|
||||
|
||||
+28
@@ -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*/
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -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) {
|
||||
|
||||
+2
@@ -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
|
||||
|
||||
+46
@@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
+29
@@ -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) }
|
||||
}
|
||||
+2
-1
@@ -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? {
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
|
||||
+2
@@ -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))
|
||||
|
||||
+64
@@ -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)
|
||||
}
|
||||
+1
@@ -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)
|
||||
|
||||
+2
-2
@@ -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<LLFirSession>(firSession)
|
||||
|
||||
Reference in New Issue
Block a user