[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.vfilefinder.KotlinStdlibIndex
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
// TODO(kirpichenkov): works only for JVM (see KT-44552)
|
||||
interface KotlinStdlibCache {
|
||||
fun isStdlib(libraryInfo: LibraryInfo): Boolean
|
||||
fun isStdlibDependency(libraryInfo: LibraryInfo): Boolean
|
||||
fun findStdlibInModuleDependencies(module: IdeaModuleInfo): LibraryInfo?
|
||||
|
||||
companion object {
|
||||
fun getInstance(project: Project): KotlinStdlibCache =
|
||||
@@ -35,21 +38,30 @@ interface KotlinStdlibCache {
|
||||
val Disabled = object : KotlinStdlibCache {
|
||||
override fun isStdlib(libraryInfo: LibraryInfo) = false
|
||||
override fun isStdlibDependency(libraryInfo: LibraryInfo) = false
|
||||
override fun findStdlibInModuleDependencies(module: IdeaModuleInfo): LibraryInfo? = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
ConcurrentHashMap<LibraryInfo, Boolean>()
|
||||
}
|
||||
|
||||
private val stdlibDependencyCache
|
||||
private val isStdlibDependencyCache: MutableMap<LibraryInfo, Boolean>
|
||||
get() = project.cacheInvalidatingOnRootModifications {
|
||||
ConcurrentHashMap<LibraryInfo, Boolean>()
|
||||
}
|
||||
|
||||
private val moduleStdlibDependencyCache: MutableMap<IdeaModuleInfo, StdlibDependency>
|
||||
get() = project.cacheInvalidatingOnRootModifications {
|
||||
ConcurrentHashMap<IdeaModuleInfo, StdlibDependency>()
|
||||
}
|
||||
|
||||
private class LibraryScope(
|
||||
project: Project,
|
||||
private val directories: Set<VirtualFile>
|
||||
@@ -76,16 +88,26 @@ class KotlinStdlibCacheImpl(val project: Project) : KotlinStdlibCache {
|
||||
libraryScopeContainsIndexedFilesForNames(libraryInfo, listOf(name))
|
||||
|
||||
override fun isStdlib(libraryInfo: LibraryInfo): Boolean {
|
||||
return stdlibCache.getOrPut(libraryInfo) {
|
||||
return isStdlibCache.getOrPut(libraryInfo) {
|
||||
libraryScopeContainsIndexedFilesForName(libraryInfo, KotlinStdlibIndex.KOTLIN_STDLIB_NAME)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isStdlibDependency(libraryInfo: LibraryInfo): Boolean {
|
||||
return stdlibDependencyCache.getOrPut(libraryInfo) {
|
||||
return isStdlibDependencyCache.getOrPut(libraryInfo) {
|
||||
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 =
|
||||
|
||||
@@ -17,8 +17,6 @@ import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
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.core.isInTestSourceContentKotlinAware
|
||||
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.runReadAction
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.kotlin.utils.yieldIfNotNull
|
||||
|
||||
@@ -50,6 +47,12 @@ fun ModuleInfo.findSdkAcrossDependencies(): SdkInfo? {
|
||||
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? =
|
||||
collectInfosByVirtualFile(
|
||||
project, virtualFile,
|
||||
|
||||
+10
-6
@@ -164,12 +164,16 @@ class IdeaResolverForProject(
|
||||
}
|
||||
|
||||
private fun findStdlibForModulesBuiltins(module: IdeaModuleInfo): LibraryInfo? {
|
||||
if (IdeBuiltInsLoadingState.isFromClassLoader)
|
||||
return null
|
||||
|
||||
return module.dependencies().lazyClosure { it.dependencies() }.firstOrNull {
|
||||
it is LibraryInfo && it.isKotlinStdlib(projectContextFromSdkResolver.project)
|
||||
} as? LibraryInfo
|
||||
return when (IdeBuiltInsLoadingState.state) {
|
||||
IdeBuiltInsLoadingState.IdeBuiltInsLoading.FROM_CLASSLOADER -> null
|
||||
IdeBuiltInsLoadingState.IdeBuiltInsLoading.FROM_DEPENDENCIES_JVM -> {
|
||||
if (module.platform.isJvm()) {
|
||||
module.findJvmStdlibAcrossDependencies()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user