diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/KotlinStdlibCache.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/KotlinStdlibCache.kt index da61c5691c5..09e8bd77963 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/KotlinStdlibCache.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/KotlinStdlibCache.kt @@ -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 get() = project.cacheInvalidatingOnRootModifications { ConcurrentHashMap() } - private val stdlibDependencyCache + private val isStdlibDependencyCache: MutableMap get() = project.cacheInvalidatingOnRootModifications { ConcurrentHashMap() } + private val moduleStdlibDependencyCache: MutableMap + get() = project.cacheInvalidatingOnRootModifications { + ConcurrentHashMap() + } + private class LibraryScope( project: Project, private val directories: Set @@ -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 = diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt index 7fae48d0f97..1bfec3e916b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/getModuleInfo.kt @@ -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, diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt index 265c9f7a28b..7d6e8b36799 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt @@ -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 + } + } + } } }