[IDE] Optimize stdlib cache for non-JVM modules
Consider only dependencies of JVM modules. Cache found/missing stdlib dependencies for modules. As of now, non-JVM platforms use default builtins in IDE. For any non-JVM module indexed stdlib dependency is guaranteed to be missing, searching for it is useless and costly. ^KTIJ-5666 Fixed See also KT-44552
This commit is contained in:
committed by
TeamCityServer
parent
6c11751c55
commit
36bc71121a
+26
-4
@@ -17,11 +17,14 @@ import org.jetbrains.kotlin.idea.configuration.IdeBuiltInsLoadingState
|
|||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.vfilefinder.KotlinStdlibIndex
|
import org.jetbrains.kotlin.idea.vfilefinder.KotlinStdlibIndex
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
// TODO(kirpichenkov): works only for JVM (see KT-44552)
|
||||||
interface KotlinStdlibCache {
|
interface KotlinStdlibCache {
|
||||||
fun isStdlib(libraryInfo: LibraryInfo): Boolean
|
fun isStdlib(libraryInfo: LibraryInfo): Boolean
|
||||||
fun isStdlibDependency(libraryInfo: LibraryInfo): Boolean
|
fun isStdlibDependency(libraryInfo: LibraryInfo): Boolean
|
||||||
|
fun findStdlibInModuleDependencies(module: IdeaModuleInfo): LibraryInfo?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getInstance(project: Project): KotlinStdlibCache =
|
fun getInstance(project: Project): KotlinStdlibCache =
|
||||||
@@ -35,21 +38,30 @@ interface KotlinStdlibCache {
|
|||||||
val Disabled = object : KotlinStdlibCache {
|
val Disabled = object : KotlinStdlibCache {
|
||||||
override fun isStdlib(libraryInfo: LibraryInfo) = false
|
override fun isStdlib(libraryInfo: LibraryInfo) = false
|
||||||
override fun isStdlibDependency(libraryInfo: LibraryInfo) = false
|
override fun isStdlibDependency(libraryInfo: LibraryInfo) = false
|
||||||
|
override fun findStdlibInModuleDependencies(module: IdeaModuleInfo): LibraryInfo? = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinStdlibCacheImpl(val project: Project) : KotlinStdlibCache {
|
class KotlinStdlibCacheImpl(val project: Project) : KotlinStdlibCache {
|
||||||
private val stdlibCache
|
@JvmInline
|
||||||
|
private value class StdlibDependency(val libraryInfo: LibraryInfo?)
|
||||||
|
|
||||||
|
private val isStdlibCache: MutableMap<LibraryInfo, Boolean>
|
||||||
get() = project.cacheInvalidatingOnRootModifications {
|
get() = project.cacheInvalidatingOnRootModifications {
|
||||||
ConcurrentHashMap<LibraryInfo, Boolean>()
|
ConcurrentHashMap<LibraryInfo, Boolean>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val stdlibDependencyCache
|
private val isStdlibDependencyCache: MutableMap<LibraryInfo, Boolean>
|
||||||
get() = project.cacheInvalidatingOnRootModifications {
|
get() = project.cacheInvalidatingOnRootModifications {
|
||||||
ConcurrentHashMap<LibraryInfo, Boolean>()
|
ConcurrentHashMap<LibraryInfo, Boolean>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val moduleStdlibDependencyCache: MutableMap<IdeaModuleInfo, StdlibDependency>
|
||||||
|
get() = project.cacheInvalidatingOnRootModifications {
|
||||||
|
ConcurrentHashMap<IdeaModuleInfo, StdlibDependency>()
|
||||||
|
}
|
||||||
|
|
||||||
private class LibraryScope(
|
private class LibraryScope(
|
||||||
project: Project,
|
project: Project,
|
||||||
private val directories: Set<VirtualFile>
|
private val directories: Set<VirtualFile>
|
||||||
@@ -76,16 +88,26 @@ class KotlinStdlibCacheImpl(val project: Project) : KotlinStdlibCache {
|
|||||||
libraryScopeContainsIndexedFilesForNames(libraryInfo, listOf(name))
|
libraryScopeContainsIndexedFilesForNames(libraryInfo, listOf(name))
|
||||||
|
|
||||||
override fun isStdlib(libraryInfo: LibraryInfo): Boolean {
|
override fun isStdlib(libraryInfo: LibraryInfo): Boolean {
|
||||||
return stdlibCache.getOrPut(libraryInfo) {
|
return isStdlibCache.getOrPut(libraryInfo) {
|
||||||
libraryScopeContainsIndexedFilesForName(libraryInfo, KotlinStdlibIndex.KOTLIN_STDLIB_NAME)
|
libraryScopeContainsIndexedFilesForName(libraryInfo, KotlinStdlibIndex.KOTLIN_STDLIB_NAME)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isStdlibDependency(libraryInfo: LibraryInfo): Boolean {
|
override fun isStdlibDependency(libraryInfo: LibraryInfo): Boolean {
|
||||||
return stdlibDependencyCache.getOrPut(libraryInfo) {
|
return isStdlibDependencyCache.getOrPut(libraryInfo) {
|
||||||
libraryScopeContainsIndexedFilesForNames(libraryInfo, KotlinStdlibIndex.STANDARD_LIBRARY_DEPENDENCY_NAMES)
|
libraryScopeContainsIndexedFilesForNames(libraryInfo, KotlinStdlibIndex.STANDARD_LIBRARY_DEPENDENCY_NAMES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findStdlibInModuleDependencies(module: IdeaModuleInfo): LibraryInfo? {
|
||||||
|
val stdlibDependency = moduleStdlibDependencyCache.getOrPut(module) {
|
||||||
|
module.dependencies().lazyClosure { it.dependencies() }.firstOrNull {
|
||||||
|
it is LibraryInfo && isStdlib(it)
|
||||||
|
}.let { StdlibDependency(it as? LibraryInfo?) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return stdlibDependency.libraryInfo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun LibraryInfo.isCoreKotlinLibrary(project: Project): Boolean =
|
fun LibraryInfo.isCoreKotlinLibrary(project: Project): Boolean =
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ import com.intellij.psi.PsiFile
|
|||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
import org.jetbrains.kotlin.caches.project.cacheByClassInvalidatingOnRootModifications
|
|
||||||
import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications
|
|
||||||
import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration
|
import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration
|
||||||
import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware
|
import org.jetbrains.kotlin.idea.core.isInTestSourceContentKotlinAware
|
||||||
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
||||||
@@ -32,7 +30,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
|||||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||||
import org.jetbrains.kotlin.scripting.definitions.runReadAction
|
import org.jetbrains.kotlin.scripting.definitions.runReadAction
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
|
||||||
import org.jetbrains.kotlin.utils.sure
|
import org.jetbrains.kotlin.utils.sure
|
||||||
import org.jetbrains.kotlin.utils.yieldIfNotNull
|
import org.jetbrains.kotlin.utils.yieldIfNotNull
|
||||||
|
|
||||||
@@ -50,6 +47,12 @@ fun ModuleInfo.findSdkAcrossDependencies(): SdkInfo? {
|
|||||||
return SdkInfoCache.getInstance(project).findOrGetCachedSdk(this)
|
return SdkInfoCache.getInstance(project).findOrGetCachedSdk(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IdeaModuleInfo.findJvmStdlibAcrossDependencies(): LibraryInfo? {
|
||||||
|
val project = project ?: return null
|
||||||
|
|
||||||
|
return KotlinStdlibCache.getInstance(project).findStdlibInModuleDependencies(this)
|
||||||
|
}
|
||||||
|
|
||||||
fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFile): IdeaModuleInfo? =
|
fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFile): IdeaModuleInfo? =
|
||||||
collectInfosByVirtualFile(
|
collectInfosByVirtualFile(
|
||||||
project, virtualFile,
|
project, virtualFile,
|
||||||
|
|||||||
+10
-6
@@ -164,12 +164,16 @@ class IdeaResolverForProject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findStdlibForModulesBuiltins(module: IdeaModuleInfo): LibraryInfo? {
|
private fun findStdlibForModulesBuiltins(module: IdeaModuleInfo): LibraryInfo? {
|
||||||
if (IdeBuiltInsLoadingState.isFromClassLoader)
|
return when (IdeBuiltInsLoadingState.state) {
|
||||||
return null
|
IdeBuiltInsLoadingState.IdeBuiltInsLoading.FROM_CLASSLOADER -> null
|
||||||
|
IdeBuiltInsLoadingState.IdeBuiltInsLoading.FROM_DEPENDENCIES_JVM -> {
|
||||||
return module.dependencies().lazyClosure { it.dependencies() }.firstOrNull {
|
if (module.platform.isJvm()) {
|
||||||
it is LibraryInfo && it.isKotlinStdlib(projectContextFromSdkResolver.project)
|
module.findJvmStdlibAcrossDependencies()
|
||||||
} as? LibraryInfo
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user