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
This commit is contained in:
Denis Zharkov
2018-01-13 17:16:39 +03:00
parent d848238a46
commit b4e5f8cf1c
2 changed files with 19 additions and 16 deletions
@@ -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())}"
}
}
}
@@ -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<IdeaModuleInfo> = this.collectInfos(ModuleInfoCollector.ToList)
fun PsiElement.getModuleInfos(): Sequence<IdeaModuleInfo> = this.collectInfos(ModuleInfoCollector.ToSequence)
fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFile): IdeaModuleInfo? = collectInfosByVirtualFile(
project, virtualFile,
@@ -80,17 +82,17 @@ private sealed class ModuleInfoCollector<out T>(
}
)
object ToList : ModuleInfoCollector<List<IdeaModuleInfo>>(
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<IdeaModuleInfo>()
collectInfosByVirtualFile(project, virtualFile, isLibrarySource, { result.addIfNotNull(it) })
result
object ToSequence : ModuleInfoCollector<Sequence<IdeaModuleInfo>>(
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
}
}