Preserve order entry to module info mapping in IdeaModelInfosCache

This commit is contained in:
Pavel Kirpichenkov
2020-07-24 15:32:40 +03:00
parent 24d8aee2bb
commit 6abd708d42
@@ -5,12 +5,15 @@
package org.jetbrains.kotlin.idea.caches.project package org.jetbrains.kotlin.idea.caches.project
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.JdkOrderEntry import com.intellij.openapi.roots.JdkOrderEntry
import com.intellij.openapi.roots.LibraryOrderEntry import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.ModuleRootManager 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.caches.project.cacheInvalidatingOnRootModifications
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatform
@@ -21,23 +24,29 @@ import java.util.concurrent.ConcurrentHashMap
/** null-platform means that we should get all modules */ /** null-platform means that we should get all modules */
fun getModuleInfosFromIdeaModel(project: Project, platform: TargetPlatform? = null): List<IdeaModuleInfo> { fun getModuleInfosFromIdeaModel(project: Project, platform: TargetPlatform? = null): List<IdeaModuleInfo> {
val modelInfosCache = project.cacheInvalidatingOnRootModifications { val ideaModelInfosCache = getIdeaModelInfosCache(project)
collectModuleInfosFromIdeaModel(project)
}
return if (platform != null) return if (platform != null)
modelInfosCache.forPlatform(platform) ideaModelInfosCache.forPlatform(platform)
else else
modelInfosCache.allModules() ideaModelInfosCache.allModules()
} }
private class IdeaModelInfosCache( fun getIdeaModelInfosCache(project: Project): IdeaModelInfosCache = project.cacheInvalidatingOnRootModifications {
val moduleSourceInfos: List<ModuleSourceInfo>, collectModuleInfosFromIdeaModel(project)
val libraryInfos: List<LibraryInfo>, }
val sdkInfos: List<SdkInfo>
class IdeaModelInfosCache(
private val moduleSourceInfosByModules: MultiMap<Module, ModuleSourceInfo>,
private val libraryInfosByLibraries: MultiMap<Library, LibraryInfo>,
private val sdkInfosBySdks: Map<Sdk, SdkInfo>,
) { ) {
private val resultByPlatform = ConcurrentHashMap<TargetPlatform, List<IdeaModuleInfo>>() private val resultByPlatform = ConcurrentHashMap<TargetPlatform, List<IdeaModuleInfo>>()
private val moduleSourceInfos = moduleSourceInfosByModules.values().toList()
private val libraryInfos = libraryInfosByLibraries.values().toList()
private val sdkInfos = sdkInfosBySdks.values.toList()
fun forPlatform(platform: TargetPlatform): List<IdeaModuleInfo> { fun forPlatform(platform: TargetPlatform): List<IdeaModuleInfo> {
return resultByPlatform.getOrPut(platform) { return resultByPlatform.getOrPut(platform) {
mergePlatformModules(moduleSourceInfos, platform) + libraryInfos + sdkInfos mergePlatformModules(moduleSourceInfos, platform) + libraryInfos + sdkInfos
@@ -45,8 +54,11 @@ private class IdeaModelInfosCache(
} }
fun allModules(): List<IdeaModuleInfo> = moduleSourceInfos + libraryInfos + sdkInfos fun allModules(): List<IdeaModuleInfo> = moduleSourceInfos + libraryInfos + sdkInfos
}
fun getModuleInfosForModule(module: Module): Collection<ModuleSourceInfo> = moduleSourceInfosByModules[module]
fun getLibraryInfosForLibrary(library: Library): Collection<LibraryInfo> = libraryInfosByLibraries[library]
fun getSdkInfoForSdk(sdk: Sdk): SdkInfo? = sdkInfosBySdks[sdk]
}
private fun collectModuleInfosFromIdeaModel( private fun collectModuleInfosFromIdeaModel(
project: Project project: Project
@@ -67,16 +79,19 @@ private fun collectModuleInfosFromIdeaModel(
} }
return IdeaModelInfosCache( return IdeaModelInfosCache(
moduleSourceInfos = ideaModules.flatMap { moduleSourceInfosByModules = MultiMap.create<Module, ModuleSourceInfo>().also { moduleInfosByModules ->
checkCanceled() for (module in ideaModules) {
it.correspondingModuleInfos() checkCanceled()
moduleInfosByModules.putValues(module, module.correspondingModuleInfos())
}
}, },
libraryInfos = ideaLibraries.flatMap { libraryInfosByLibraries = MultiMap.create<Library, LibraryInfo>().also { libraryInfosByLibraries ->
checkCanceled() for (library in ideaLibraries) {
checkCanceled()
createLibraryInfo(project, it) libraryInfosByLibraries.putValues(library, createLibraryInfo(project, library))
}
}, },
sdkInfos = (sdksFromModulesDependencies + getAllProjectSdks()).filterNotNull().toSet().map { SdkInfo(project, it) } sdkInfosBySdks = (sdksFromModulesDependencies + getAllProjectSdks()).filterNotNull().toSet().associateWith { SdkInfo(project, it) }
) )
} }