[AA] KT-58257 Implement KtStaticModuleDependentsProvider (standalone)
This commit is contained in:
committed by
Space Team
parent
fe3f7feae4
commit
027fd5600f
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.standalone.base.project.structure
|
||||||
|
|
||||||
|
import com.intellij.util.containers.ContainerUtil.createConcurrentSoftMap
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.allDirectDependencies
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.impl.KotlinModuleDependentsProviderBase
|
||||||
|
|
||||||
|
class KtStaticModuleDependentsProvider(private val modules: List<KtModule>) : KotlinModuleDependentsProviderBase() {
|
||||||
|
private val directDependentsByKtModule: Map<KtModule, Set<KtModule>> by lazy {
|
||||||
|
// Direct dependencies should be computed lazily, because the built-ins module will be reachable via module dependencies. Getting
|
||||||
|
// the built-ins module relies on the built-ins session, which may depend on services that are registered after
|
||||||
|
// `KtStaticModuleDependentsProvider`.
|
||||||
|
buildMap<KtModule, MutableSet<KtModule>> {
|
||||||
|
for (module in modules) {
|
||||||
|
for (dependency in module.allDirectDependencies()) {
|
||||||
|
// `module` should not be part of its own dependents, per the contract of `KotlinModuleDependentsProvider`.
|
||||||
|
if (dependency == module) continue
|
||||||
|
|
||||||
|
val dependents = computeIfAbsent(dependency) { mutableSetOf<KtModule>() }
|
||||||
|
dependents.add(module)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val transitiveDependentsByKtModule = createConcurrentSoftMap<KtModule, Set<KtModule>>()
|
||||||
|
|
||||||
|
override fun getDirectDependents(module: KtModule): Set<KtModule> = directDependentsByKtModule[module] ?: emptySet()
|
||||||
|
|
||||||
|
override fun getTransitiveDependents(module: KtModule): Set<KtModule> =
|
||||||
|
transitiveDependentsByKtModule.computeIfAbsent(module) { computeTransitiveDependents(it) }
|
||||||
|
}
|
||||||
+4
-1
@@ -178,10 +178,13 @@ object StandaloneProjectFactory {
|
|||||||
registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver())
|
registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val modules = projectStructureProvider.allKtModules
|
||||||
project.registerService(ProjectStructureProvider::class.java, projectStructureProvider)
|
project.registerService(ProjectStructureProvider::class.java, projectStructureProvider)
|
||||||
|
project.registerService(KotlinModuleDependentsProvider::class.java, KtStaticModuleDependentsProvider(modules))
|
||||||
|
|
||||||
initialiseVirtualFileFinderServices(
|
initialiseVirtualFileFinderServices(
|
||||||
environment,
|
environment,
|
||||||
projectStructureProvider.allKtModules,
|
modules,
|
||||||
projectStructureProvider.allSourceFiles,
|
projectStructureProvider.allSourceFiles,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
jdkHome,
|
jdkHome,
|
||||||
|
|||||||
+10
-5
@@ -14,8 +14,10 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
|||||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider
|
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.references.HLApiReferenceProviderService
|
import org.jetbrains.kotlin.analysis.api.impl.base.references.HLApiReferenceProviderService
|
||||||
import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider
|
import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtStaticModuleDependentsProvider
|
||||||
import org.jetbrains.kotlin.analysis.decompiled.light.classes.ClsJavaStubByVirtualFileCache
|
import org.jetbrains.kotlin.analysis.decompiled.light.classes.ClsJavaStubByVirtualFileCache
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KotlinModuleDependentsProvider
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
|
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
|
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||||
@@ -77,6 +79,7 @@ public fun configureApplicationEnvironment(app: MockApplication) {
|
|||||||
* * [FirSealedClassInheritorsProcessorFactory]
|
* * [FirSealedClassInheritorsProcessorFactory]
|
||||||
* * [KtModuleScopeProvider]
|
* * [KtModuleScopeProvider]
|
||||||
* * [ProjectStructureProvider]
|
* * [ProjectStructureProvider]
|
||||||
|
* * [KotlinModuleDependentsProvider]
|
||||||
* * [KotlinDeclarationProviderFactory]
|
* * [KotlinDeclarationProviderFactory]
|
||||||
* * [KotlinPackageProviderFactory]
|
* * [KotlinPackageProviderFactory]
|
||||||
* * [PackagePartProviderFactory]
|
* * [PackagePartProviderFactory]
|
||||||
@@ -158,14 +161,16 @@ internal fun configureProjectEnvironment(
|
|||||||
KtModuleScopeProviderImpl()
|
KtModuleScopeProviderImpl()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val projectStructureProvider = buildKtModuleProviderByCompilerConfiguration(compilerConfig, project, ktFiles)
|
||||||
project.registerService(
|
project.registerService(
|
||||||
ProjectStructureProvider::class.java,
|
ProjectStructureProvider::class.java,
|
||||||
buildKtModuleProviderByCompilerConfiguration(
|
projectStructureProvider,
|
||||||
compilerConfig,
|
|
||||||
project,
|
|
||||||
ktFiles,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
project.registerService(
|
||||||
|
KotlinModuleDependentsProvider::class.java,
|
||||||
|
KtStaticModuleDependentsProvider(projectStructureProvider.allKtModules),
|
||||||
|
)
|
||||||
|
|
||||||
project.registerService(
|
project.registerService(
|
||||||
KotlinDeclarationProviderFactory::class.java,
|
KotlinDeclarationProviderFactory::class.java,
|
||||||
KotlinStaticDeclarationProviderFactory(project, ktFiles)
|
KotlinStaticDeclarationProviderFactory(project, ktFiles)
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.project.structure.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KotlinModuleDependentsProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
|
|
||||||
|
public abstract class KotlinModuleDependentsProviderBase : KotlinModuleDependentsProvider() {
|
||||||
|
override fun getTransitiveDependents(module: KtModule): Set<KtModule> = computeTransitiveDependents(module)
|
||||||
|
|
||||||
|
protected fun computeTransitiveDependents(module: KtModule): Set<KtModule> = buildSet {
|
||||||
|
// We could use `DFS` from utils, but this implementation has no handler overhead and is simple enough.
|
||||||
|
fun visit(module: KtModule) {
|
||||||
|
if (module in this) return
|
||||||
|
add(module)
|
||||||
|
getDirectDependents(module).forEach(::visit)
|
||||||
|
}
|
||||||
|
visit(module)
|
||||||
|
|
||||||
|
// `module` should not be part of its own dependents, per the contract of `KotlinModuleDependentsProvider`.
|
||||||
|
remove(module)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user