[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.LLFirStandaloneLibrarySymbolProviderFactory
|
||||
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.project.structure.KtSourceModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleProviderBuilder
|
||||
@@ -140,9 +140,9 @@ public class StandaloneAnalysisAPISessionBuilder(
|
||||
registerService(KotlinPackageProviderMerger::class.java, KotlinStaticPackageProviderMerger(this))
|
||||
|
||||
registerService(
|
||||
FirSealedClassInheritorsProcessorFactory::class.java,
|
||||
object : FirSealedClassInheritorsProcessorFactory() {
|
||||
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
LLSealedInheritorsProviderFactory::class.java,
|
||||
object : LLSealedInheritorsProviderFactory {
|
||||
override fun createSealedInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
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
|
||||
|
||||
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.low.level.api.fir.IdeSessionComponents
|
||||
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) {
|
||||
register(IdeSessionComponents::class, IdeSessionComponents.create())
|
||||
register(FirCachesFactory::class, FirThreadSafeCachesFactory)
|
||||
register(SealedClassInheritorsProvider::class, project.createSealedInheritorsProvider())
|
||||
register(SealedClassInheritorsProvider::class, createSealedInheritorsProvider(project))
|
||||
register(FirExceptionHandler::class, LLFirExceptionHandler)
|
||||
register(CodeFragmentScopeProvider::class, CodeFragmentScopeProvider(this))
|
||||
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.api.LLFirResolveSession
|
||||
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.services.LLFirSealedClassInheritorsProcessorFactoryForTests
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.LLSealedInheritorsProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.LLSealedInheritorsProviderFactoryForTests
|
||||
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.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.symbols.lazyResolveToPhaseRecursively
|
||||
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.SimpleDirectivesContainer
|
||||
import org.jetbrains.kotlin.test.services.PreAnalysisHandler
|
||||
@@ -55,8 +54,7 @@ class SealedClassesInheritorsCaclulatorPreAnalysisHandler(
|
||||
val tmpFirResolveSession = LLFirResolveSessionService.getInstance(project).getFirResolveSessionNoCaching(ktModule)
|
||||
val firFiles = ktFiles.map { it.getOrBuildFirFile(tmpFirResolveSession) }
|
||||
val sealedInheritors = collectSealedClassInheritors(firFiles, tmpFirResolveSession)
|
||||
val provider =
|
||||
project.getService(FirSealedClassInheritorsProcessorFactory::class.java) as LLFirSealedClassInheritorsProcessorFactoryForTests
|
||||
val provider = project.getService(LLSealedInheritorsProviderFactory::class.java) as LLSealedInheritorsProviderFactoryForTests
|
||||
provider.registerInheritors(ktModule, sealedInheritors)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@
|
||||
|
||||
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.project.structure.KtDanglingFileModule
|
||||
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.name.ClassId
|
||||
|
||||
internal class LLFirSealedClassInheritorsProcessorFactoryForTests : FirSealedClassInheritorsProcessorFactory() {
|
||||
internal class LLSealedInheritorsProviderFactoryForTests : LLSealedInheritorsProviderFactory {
|
||||
private val inheritorsByModule = mutableMapOf<KtModule, Map<ClassId, List<ClassId>>>()
|
||||
|
||||
fun registerInheritors(ktModule: KtModule, inheritors: Map<ClassId, List<ClassId>>) {
|
||||
inheritorsByModule[ktModule] = inheritors
|
||||
}
|
||||
|
||||
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
override fun createSealedInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
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.MockProject
|
||||
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.services.LLFirSealedClassInheritorsProcessorFactoryForTests
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.LLSealedInheritorsProviderFactory
|
||||
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.PackagePartProviderTestImpl
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtCompilerPluginsProvider
|
||||
@@ -28,7 +28,7 @@ object AnalysisApiFirTestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
||||
project.apply {
|
||||
FirStandaloneServiceRegistrar.registerProjectServices(project)
|
||||
|
||||
registerService(FirSealedClassInheritorsProcessorFactory::class.java, LLFirSealedClassInheritorsProcessorFactoryForTests())
|
||||
registerService(LLSealedInheritorsProviderFactory::class.java, LLSealedInheritorsProviderFactoryForTests())
|
||||
registerService(PackagePartProviderFactory::class.java, PackagePartProviderTestImpl(testServices))
|
||||
registerService(KtCompilerPluginsProvider::class.java, NoOpKtCompilerPluginsProvider)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user