From b4e5f8cf1c5dd1d63dff2f310654778e9cd1e8c6 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Sat, 13 Jan 2018 17:16:39 +0300 Subject: [PATCH] Optimize collecting module info in IDE The problem was that there is no special entity for libraries in the IntelliJ model, and when we have an element for a library we have to search through all of its dependencies (see getOrderEntriesForFile call in collectInfosByVirtualFile) But for popular library there could be quite a lot of dependencies, while in most cases we need only the first one to obtain module info for library itself (see changed usage in resolverForElement). So it's worth replacing List with Sequence here --- .../caches/resolve/ProjectResolutionFacade.kt | 8 +++--- .../idea/caches/resolve/getModuleInfo.kt | 27 ++++++++++--------- 2 files changed, 19 insertions(+), 16 deletions(-) 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 15dd47a25ea..193e34abbe4 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 @@ -79,9 +79,9 @@ internal class ProjectResolutionFacade( fun resolverForElement(element: PsiElement): ResolverForModule { val infos = element.getModuleInfos() - return infos.firstNotNullResult { resolverForProject.tryGetResolverForModule(it) } - ?: resolverForProject.tryGetResolverForModule(NotUnderContentRootModuleInfo) - ?: resolverForProject.diagnoseUnknownModuleInfo(infos) + return infos.asIterable().firstNotNullResult { resolverForProject.tryGetResolverForModule(it) } + ?: resolverForProject.tryGetResolverForModule(NotUnderContentRootModuleInfo) + ?: resolverForProject.diagnoseUnknownModuleInfo(infos.toList()) } fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = resolverForProject.resolverForModuleDescriptor(moduleDescriptor) @@ -126,4 +126,4 @@ internal class ProjectResolutionFacade( override fun toString(): String { return "$debugString@${Integer.toHexString(hashCode())}" } -} \ No newline at end of file +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/getModuleInfo.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/getModuleInfo.kt index d5f6df5ef1b..8a0fc7de2e9 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/getModuleInfo.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/getModuleInfo.kt @@ -33,12 +33,14 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.script.getScriptDefinition import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.sure +import org.jetbrains.kotlin.utils.yieldIfNotNull +import kotlin.coroutines.experimental.buildSequence fun PsiElement.getModuleInfo(): IdeaModuleInfo = this.collectInfos(ModuleInfoCollector.NotNullTakeFirst) fun PsiElement.getNullableModuleInfo(): IdeaModuleInfo? = this.collectInfos(ModuleInfoCollector.NullableTakeFirst) -fun PsiElement.getModuleInfos(): List = this.collectInfos(ModuleInfoCollector.ToList) +fun PsiElement.getModuleInfos(): Sequence = this.collectInfos(ModuleInfoCollector.ToSequence) fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFile): IdeaModuleInfo? = collectInfosByVirtualFile( project, virtualFile, @@ -80,17 +82,17 @@ private sealed class ModuleInfoCollector( } ) - object ToList : ModuleInfoCollector>( - onResult = { it?.let(::listOf).orEmpty() }, - onFailure = { reason -> - LOG.warn("Could not find correct module information.\nReason: $reason") - emptyList() - }, - virtualFileProcessor = { project, virtualFile, isLibrarySource -> - val result = mutableListOf() - collectInfosByVirtualFile(project, virtualFile, isLibrarySource, { result.addIfNotNull(it) }) - result + object ToSequence : ModuleInfoCollector>( + onResult = { result -> result?.let { sequenceOf(it) } ?: emptySequence() }, + onFailure = { reason -> + LOG.warn("Could not find correct module information.\nReason: $reason") + emptySequence() + }, + virtualFileProcessor = { project, virtualFile, isLibrarySource -> + buildSequence { + collectInfosByVirtualFile(project, virtualFile, isLibrarySource, { yieldIfNotNull(it) }) } + } ) } @@ -212,6 +214,7 @@ private fun OrderEntry.toIdeaModuleInfo( virtualFile: VirtualFile, treatAsLibrarySource: Boolean = false ): IdeaModuleInfo? { + if (this is ModuleOrderEntry) return null if (!isValid) return null when (this) { @@ -230,4 +233,4 @@ private fun OrderEntry.toIdeaModuleInfo( else -> return null } return null -} \ No newline at end of file +}