From 607fab994c8f86e25ee300ec07b2befac2fc5b18 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Fri, 27 Apr 2018 17:05:33 +0200 Subject: [PATCH] Cache result of collectModulesFromIdeaModel Cache base module infos from idea model until next root modification Calculate platform specific module infos (see PlatformModuleInfo) on demand based on cached module infos from idea model #KT-24144 Fixed --- .../idea/caches/project/IdeaModuleInfos.kt | 4 -- .../kotlin/idea/caches/project/cacheUtil.kt | 19 +++++++ .../project/moduleInfosFromIdeaModel.kt | 49 +++++++++++++------ .../caches/resolve/ProjectResolutionFacade.kt | 2 +- 4 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/cacheUtil.kt diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt index 7163fc0c674..11c83f67ffa 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/IdeaModuleInfos.kt @@ -94,10 +94,6 @@ private fun orderEntryToModuleInfo(project: Project, orderEntry: OrderEntry, for } } -fun Module.cached(provider: CachedValueProvider): T { - return CachedValuesManager.getManager(project).getCachedValue(this, provider) -} - private fun OrderEntry.acceptAsDependency(forProduction: Boolean): Boolean { return this !is ExportableOrderEntry || !forProduction diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/cacheUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/cacheUtil.kt new file mode 100644 index 00000000000..a59649368c8 --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/cacheUtil.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.idea.caches.project + +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager + +fun Module.cached(provider: CachedValueProvider): T { + return CachedValuesManager.getManager(project).getCachedValue(this, provider) +} + +fun Project.cached(provider: CachedValueProvider): T { + return CachedValuesManager.getManager(this).getCachedValue(this, provider) +} 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 9d3a1993c4c..774ea606d7a 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 @@ -13,11 +13,37 @@ 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.ProjectRootModificationTracker +import com.intellij.psi.util.CachedValueProvider import org.jetbrains.kotlin.resolve.TargetPlatform +import java.util.concurrent.ConcurrentHashMap -fun collectAllModuleInfosFromIdeaModel(project: Project, platform: TargetPlatform): List { +fun getModuleInfosFromIdeaModel(project: Project, platform: TargetPlatform): List { + val modelInfosCache = project.cached(CachedValueProvider { + CachedValueProvider.Result(collectModuleInfosFromIdeaModel(project), ProjectRootModificationTracker.getInstance(project)) + }) + return modelInfosCache.forPlatform(platform) +} + +private class IdeaModelInfosCache( + val moduleSourceInfos: List, + val libraryInfos: List, + val sdkInfos: List +) { + private val resultByPlatform = ConcurrentHashMap>() + + fun forPlatform(platform: TargetPlatform): List { + return resultByPlatform.getOrPut(platform) { + mergePlatformModules(moduleSourceInfos, platform) + libraryInfos + sdkInfos + } + } +} + + +private fun collectModuleInfosFromIdeaModel( + project: Project +): IdeaModelInfosCache { val ideaModules = ModuleManager.getInstance(project).modules.toList() - val modulesSourcesInfos = ideaModules.flatMap(Module::correspondingModuleInfos) //TODO: (module refactoring) include libraries that are not among dependencies of any module val ideaLibraries = ideaModules.flatMap { @@ -26,33 +52,28 @@ fun collectAllModuleInfosFromIdeaModel(project: Project, platform: TargetPlatfor } }.filterNotNull().toSet() - val librariesInfos = ideaLibraries.map { LibraryInfo(project, it) } - val sdksFromModulesDependencies = ideaModules.flatMap { ModuleRootManager.getInstance(it).orderEntries.filterIsInstance().map { it.jdk } } - val sdksInfos = (sdksFromModulesDependencies + getAllProjectSdks()).filterNotNull().toSet().map { - SdkInfo( - project, - it - ) - } - - return mergePlatformModules(modulesSourcesInfos, platform) + librariesInfos + sdksInfos + return IdeaModelInfosCache( + moduleSourceInfos = ideaModules.flatMap(Module::correspondingModuleInfos), + libraryInfos = ideaLibraries.map { LibraryInfo(project, it) }, + sdkInfos = (sdksFromModulesDependencies + getAllProjectSdks()).filterNotNull().toSet().map { SdkInfo(project, it) } + ) } private fun mergePlatformModules( - allModules: List, + allModules: List, platform: TargetPlatform ): List { if (platform == TargetPlatform.Common) return allModules val platformModules = allModules.flatMap { module -> - if (module is ModuleSourceInfo && module.platform == platform && module.expectedBy.isNotEmpty()) + if (module.platform == platform && module.expectedBy.isNotEmpty()) listOf(module to module.expectedBy) else emptyList() }.map { (module, expectedBys) -> diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ProjectResolutionFacade.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ProjectResolutionFacade.kt index b0176d3a9bd..07af168b025 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ProjectResolutionFacade.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ProjectResolutionFacade.kt @@ -104,7 +104,7 @@ internal class ProjectResolutionFacade( globalContext ) - val allModuleInfos = (allModules ?: collectAllModuleInfosFromIdeaModel(project, settings.platform)).toMutableSet() + val allModuleInfos = (allModules ?: getModuleInfosFromIdeaModel(project, settings.platform)).toMutableSet() val syntheticFilesByModule = syntheticFiles.groupBy(KtFile::getModuleInfo) val syntheticFilesModules = syntheticFilesByModule.keys