[AA] Add KtClass-based KotlinSealedInheritorsProvider
- The compiler's `SealedClassInheritorsProvider` should not be exposed outside LL FIR, as it is an internal compiler component and also exposes `FirRegularClass`. `KotlinSealedInheritorsProvider` is an Analysis API provider for sealed inheritors that accepts a `KtClass` instead. ^KT-64718 fixed
This commit is contained in:
committed by
Space Team
parent
e001fa4e72
commit
9a4bf0601e
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 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.providers
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [KotlinSealedInheritorsProvider] provides a list of direct inheritors for sealed [KtClass]es (which may be a class or an interface). It
|
||||||
|
* may be created with [KotlinSealedInheritorsProviderFactory].
|
||||||
|
*
|
||||||
|
* Implementations of this service should consider caching the results. The [KotlinSealedInheritorsProvider] is tied to the lifetime of its
|
||||||
|
* owning session, so it will be invalidated automatically with the session.
|
||||||
|
*/
|
||||||
|
public interface KotlinSealedInheritorsProvider {
|
||||||
|
/**
|
||||||
|
* Returns the sealed inheritors of [ktClass], which may be a class or an interface. [ktClass] is guaranteed to be sealed.
|
||||||
|
*/
|
||||||
|
public fun getSealedInheritors(ktClass: KtClass): List<ClassId>
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface KotlinSealedInheritorsProviderFactory {
|
||||||
|
/**
|
||||||
|
* Creates a [KotlinSealedInheritorsProvider] for a session.
|
||||||
|
*/
|
||||||
|
public fun createSealedInheritorsProvider(): KotlinSealedInheritorsProvider
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
public fun getInstance(project: Project): KotlinSealedInheritorsProviderFactory? =
|
||||||
|
project.getService(KotlinSealedInheritorsProviderFactory::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-4
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.FirSt
|
|||||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtStaticProjectStructureProvider
|
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtStaticProjectStructureProvider
|
||||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.LLFirStandaloneLibrarySymbolProviderFactory
|
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.LLFirStandaloneLibrarySymbolProviderFactory
|
||||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory
|
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.LLSealedInheritorsProviderFactory
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySymbolProviderFactory
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySymbolProviderFactory
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleProviderBuilder
|
import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleProviderBuilder
|
||||||
@@ -140,9 +140,9 @@ public class StandaloneAnalysisAPISessionBuilder(
|
|||||||
registerService(KotlinPackageProviderMerger::class.java, KotlinStaticPackageProviderMerger(this))
|
registerService(KotlinPackageProviderMerger::class.java, KotlinStaticPackageProviderMerger(this))
|
||||||
|
|
||||||
registerService(
|
registerService(
|
||||||
FirSealedClassInheritorsProcessorFactory::class.java,
|
LLSealedInheritorsProviderFactory::class.java,
|
||||||
object : FirSealedClassInheritorsProcessorFactory() {
|
object : LLSealedInheritorsProviderFactory {
|
||||||
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
|
override fun createSealedInheritorsProvider(): SealedClassInheritorsProvider {
|
||||||
return SealedClassInheritorsProviderImpl
|
return SealedClassInheritorsProviderImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.api.services
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.analysis.providers.KotlinSealedInheritorsProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.providers.KotlinSealedInheritorsProviderFactory
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||||
|
import org.jetbrains.kotlin.fir.psi
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
|
|
||||||
|
interface LLSealedInheritorsProviderFactory {
|
||||||
|
/**
|
||||||
|
* Creates a [SealedClassInheritorsProvider] for a session. A new [SealedClassInheritorsProvider] instance should be created on every
|
||||||
|
* call.
|
||||||
|
*/
|
||||||
|
fun createSealedInheritorsProvider(): SealedClassInheritorsProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a [SealedClassInheritorsProvider] for a session.
|
||||||
|
*
|
||||||
|
* Requires either [LLSealedInheritorsProviderFactory] or [KotlinSealedInheritorsProviderFactory] to be registered as a project service.
|
||||||
|
*/
|
||||||
|
internal fun createSealedInheritorsProvider(project: Project): SealedClassInheritorsProvider =
|
||||||
|
createFromLLProvider(project)
|
||||||
|
?: createFromAnalysisApiProvider(project)
|
||||||
|
?: error(
|
||||||
|
"""
|
||||||
|
Expected one of the following services to be registered with $project:
|
||||||
|
- ${LLSealedInheritorsProviderFactory::class.simpleName}
|
||||||
|
- ${KotlinSealedInheritorsProviderFactory::class.simpleName}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun createFromLLProvider(project: Project): SealedClassInheritorsProvider? =
|
||||||
|
project.getService(LLSealedInheritorsProviderFactory::class.java)?.createSealedInheritorsProvider()
|
||||||
|
|
||||||
|
private fun createFromAnalysisApiProvider(project: Project): SealedClassInheritorsProvider? =
|
||||||
|
KotlinSealedInheritorsProviderFactory.getInstance(project)
|
||||||
|
?.createSealedInheritorsProvider()
|
||||||
|
?.let(::LLSealedInheritorsProviderByAnalysisApiProvider)
|
||||||
|
|
||||||
|
private class LLSealedInheritorsProviderByAnalysisApiProvider(
|
||||||
|
private val provider: KotlinSealedInheritorsProvider,
|
||||||
|
) : SealedClassInheritorsProvider() {
|
||||||
|
override fun getSealedClassInheritors(firClass: FirRegularClass): List<ClassId> {
|
||||||
|
val ktClass = firClass.psi as? KtClass ?: return emptyList()
|
||||||
|
return provider.getSealedInheritors(ktClass)
|
||||||
|
}
|
||||||
|
}
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2021 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.api.services
|
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
|
||||||
|
|
||||||
abstract class FirSealedClassInheritorsProcessorFactory {
|
|
||||||
/**
|
|
||||||
* Creates [SealedClassInheritorsProvider] for a module.
|
|
||||||
* This function should crate a new [SealedClassInheritorsProvider] instance on every call.
|
|
||||||
*/
|
|
||||||
abstract fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates [SealedClassInheritorsProvider] for a module.
|
|
||||||
* This function should crate a new [SealedClassInheritorsProvider] instance on every call.
|
|
||||||
*/
|
|
||||||
internal fun Project.createSealedInheritorsProvider(): SealedClassInheritorsProvider =
|
|
||||||
getService(FirSealedClassInheritorsProcessorFactory::class.java).createSealedClassInheritorsProvider()
|
|
||||||
+1
-2
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
|
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeSessionComponents
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeSessionComponents
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createSealedInheritorsProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createSealedInheritorsProvider
|
||||||
@@ -39,7 +38,7 @@ import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
|
|||||||
internal fun LLFirSession.registerIdeComponents(project: Project) {
|
internal fun LLFirSession.registerIdeComponents(project: Project) {
|
||||||
register(IdeSessionComponents::class, IdeSessionComponents.create())
|
register(IdeSessionComponents::class, IdeSessionComponents.create())
|
||||||
register(FirCachesFactory::class, FirThreadSafeCachesFactory)
|
register(FirCachesFactory::class, FirThreadSafeCachesFactory)
|
||||||
register(SealedClassInheritorsProvider::class, project.createSealedInheritorsProvider())
|
register(SealedClassInheritorsProvider::class, createSealedInheritorsProvider(project))
|
||||||
register(FirExceptionHandler::class, LLFirExceptionHandler)
|
register(FirExceptionHandler::class, LLFirExceptionHandler)
|
||||||
register(CodeFragmentScopeProvider::class, CodeFragmentScopeProvider(this))
|
register(CodeFragmentScopeProvider::class, CodeFragmentScopeProvider(this))
|
||||||
createResolveExtensionTool()?.let {
|
createResolveExtensionTool()?.let {
|
||||||
|
|||||||
+3
-5
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionService
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionService
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.LLSealedInheritorsProviderFactory
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.LLFirSealedClassInheritorsProcessorFactoryForTests
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.LLSealedInheritorsProviderFactoryForTests
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.getKtFiles
|
import org.jetbrains.kotlin.analysis.test.framework.project.structure.getKtFiles
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||||
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
|||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseRecursively
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
|
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
|
||||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||||
import org.jetbrains.kotlin.test.services.PreAnalysisHandler
|
import org.jetbrains.kotlin.test.services.PreAnalysisHandler
|
||||||
@@ -55,8 +54,7 @@ class SealedClassesInheritorsCaclulatorPreAnalysisHandler(
|
|||||||
val tmpFirResolveSession = LLFirResolveSessionService.getInstance(project).getFirResolveSessionNoCaching(ktModule)
|
val tmpFirResolveSession = LLFirResolveSessionService.getInstance(project).getFirResolveSessionNoCaching(ktModule)
|
||||||
val firFiles = ktFiles.map { it.getOrBuildFirFile(tmpFirResolveSession) }
|
val firFiles = ktFiles.map { it.getOrBuildFirFile(tmpFirResolveSession) }
|
||||||
val sealedInheritors = collectSealedClassInheritors(firFiles, tmpFirResolveSession)
|
val sealedInheritors = collectSealedClassInheritors(firFiles, tmpFirResolveSession)
|
||||||
val provider =
|
val provider = project.getService(LLSealedInheritorsProviderFactory::class.java) as LLSealedInheritorsProviderFactoryForTests
|
||||||
project.getService(FirSealedClassInheritorsProcessorFactory::class.java) as LLFirSealedClassInheritorsProcessorFactoryForTests
|
|
||||||
provider.registerInheritors(ktModule, sealedInheritors)
|
provider.registerInheritors(ktModule, sealedInheritors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.services
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.services
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.LLSealedInheritorsProviderFactory
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtDanglingFileModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtDanglingFileModule
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
@@ -16,14 +16,14 @@ import org.jetbrains.kotlin.fir.declarations.sealedInheritorsAttr
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
internal class LLFirSealedClassInheritorsProcessorFactoryForTests : FirSealedClassInheritorsProcessorFactory() {
|
internal class LLSealedInheritorsProviderFactoryForTests : LLSealedInheritorsProviderFactory {
|
||||||
private val inheritorsByModule = mutableMapOf<KtModule, Map<ClassId, List<ClassId>>>()
|
private val inheritorsByModule = mutableMapOf<KtModule, Map<ClassId, List<ClassId>>>()
|
||||||
|
|
||||||
fun registerInheritors(ktModule: KtModule, inheritors: Map<ClassId, List<ClassId>>) {
|
fun registerInheritors(ktModule: KtModule, inheritors: Map<ClassId, List<ClassId>>) {
|
||||||
inheritorsByModule[ktModule] = inheritors
|
inheritorsByModule[ktModule] = inheritors
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
|
override fun createSealedInheritorsProvider(): SealedClassInheritorsProvider {
|
||||||
return SealedClassInheritorsProviderForTests(inheritorsByModule)
|
return SealedClassInheritorsProviderForTests(inheritorsByModule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.test.base
|
|||||||
import com.intellij.mock.MockApplication
|
import com.intellij.mock.MockApplication
|
||||||
import com.intellij.mock.MockProject
|
import com.intellij.mock.MockProject
|
||||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.FirStandaloneServiceRegistrar
|
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.FirStandaloneServiceRegistrar
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.LLSealedInheritorsProviderFactory
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.LLFirSealedClassInheritorsProcessorFactoryForTests
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.LLSealedInheritorsProviderFactoryForTests
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.NoOpKtCompilerPluginsProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.NoOpKtCompilerPluginsProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.PackagePartProviderTestImpl
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.PackagePartProviderTestImpl
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtCompilerPluginsProvider
|
import org.jetbrains.kotlin.analysis.project.structure.KtCompilerPluginsProvider
|
||||||
@@ -28,7 +28,7 @@ object AnalysisApiFirTestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
|||||||
project.apply {
|
project.apply {
|
||||||
FirStandaloneServiceRegistrar.registerProjectServices(project)
|
FirStandaloneServiceRegistrar.registerProjectServices(project)
|
||||||
|
|
||||||
registerService(FirSealedClassInheritorsProcessorFactory::class.java, LLFirSealedClassInheritorsProcessorFactoryForTests())
|
registerService(LLSealedInheritorsProviderFactory::class.java, LLSealedInheritorsProviderFactoryForTests())
|
||||||
registerService(PackagePartProviderFactory::class.java, PackagePartProviderTestImpl(testServices))
|
registerService(PackagePartProviderFactory::class.java, PackagePartProviderTestImpl(testServices))
|
||||||
registerService(KtCompilerPluginsProvider::class.java, NoOpKtCompilerPluginsProvider)
|
registerService(KtCompilerPluginsProvider::class.java, NoOpKtCompilerPluginsProvider)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user