diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/moduleInfosFromIdeaModel.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/moduleInfosFromIdeaModel.kt index 0585bb7247e..f1cdc50b033 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/moduleInfosFromIdeaModel.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/moduleInfosFromIdeaModel.kt @@ -5,12 +5,15 @@ package org.jetbrains.kotlin.idea.caches.project +import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.JdkOrderEntry import com.intellij.openapi.roots.LibraryOrderEntry import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.roots.libraries.Library +import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe import org.jetbrains.kotlin.platform.TargetPlatform @@ -21,23 +24,29 @@ import java.util.concurrent.ConcurrentHashMap /** null-platform means that we should get all modules */ fun getModuleInfosFromIdeaModel(project: Project, platform: TargetPlatform? = null): List { - val modelInfosCache = project.cacheInvalidatingOnRootModifications { - collectModuleInfosFromIdeaModel(project) - } + val ideaModelInfosCache = getIdeaModelInfosCache(project) return if (platform != null) - modelInfosCache.forPlatform(platform) + ideaModelInfosCache.forPlatform(platform) else - modelInfosCache.allModules() + ideaModelInfosCache.allModules() } -private class IdeaModelInfosCache( - val moduleSourceInfos: List, - val libraryInfos: List, - val sdkInfos: List +fun getIdeaModelInfosCache(project: Project): IdeaModelInfosCache = project.cacheInvalidatingOnRootModifications { + collectModuleInfosFromIdeaModel(project) +} + +class IdeaModelInfosCache( + private val moduleSourceInfosByModules: MultiMap, + private val libraryInfosByLibraries: MultiMap, + private val sdkInfosBySdks: Map, ) { private val resultByPlatform = ConcurrentHashMap>() + private val moduleSourceInfos = moduleSourceInfosByModules.values().toList() + private val libraryInfos = libraryInfosByLibraries.values().toList() + private val sdkInfos = sdkInfosBySdks.values.toList() + fun forPlatform(platform: TargetPlatform): List { return resultByPlatform.getOrPut(platform) { mergePlatformModules(moduleSourceInfos, platform) + libraryInfos + sdkInfos @@ -45,8 +54,11 @@ private class IdeaModelInfosCache( } fun allModules(): List = moduleSourceInfos + libraryInfos + sdkInfos -} + fun getModuleInfosForModule(module: Module): Collection = moduleSourceInfosByModules[module] + fun getLibraryInfosForLibrary(library: Library): Collection = libraryInfosByLibraries[library] + fun getSdkInfoForSdk(sdk: Sdk): SdkInfo? = sdkInfosBySdks[sdk] +} private fun collectModuleInfosFromIdeaModel( project: Project @@ -67,16 +79,19 @@ private fun collectModuleInfosFromIdeaModel( } return IdeaModelInfosCache( - moduleSourceInfos = ideaModules.flatMap { - checkCanceled() - it.correspondingModuleInfos() + moduleSourceInfosByModules = MultiMap.create().also { moduleInfosByModules -> + for (module in ideaModules) { + checkCanceled() + moduleInfosByModules.putValues(module, module.correspondingModuleInfos()) + } }, - libraryInfos = ideaLibraries.flatMap { - checkCanceled() - - createLibraryInfo(project, it) + libraryInfosByLibraries = MultiMap.create().also { libraryInfosByLibraries -> + for (library in ideaLibraries) { + checkCanceled() + libraryInfosByLibraries.putValues(library, createLibraryInfo(project, library)) + } }, - sdkInfos = (sdksFromModulesDependencies + getAllProjectSdks()).filterNotNull().toSet().map { SdkInfo(project, it) } + sdkInfosBySdks = (sdksFromModulesDependencies + getAllProjectSdks()).filterNotNull().toSet().associateWith { SdkInfo(project, it) } ) }