From 2b748ccd9aa61a7cf02bcd7020f3bc0589c509c2 Mon Sep 17 00:00:00 2001 From: Natalia Selezneva Date: Fri, 31 May 2019 15:19:08 +0300 Subject: [PATCH] Scripts: if sdk isn't use for some module in project, PsiElementFinder doesn't return jdk classes For example in Android project all modules can have AndroidSDK, but JavaSDK can be set as ProjectSdk In this case build.gradle.kts couldn't resolve jdk classes --- .../idea/caches/project/ScriptModuleInfos.kt | 3 +- .../core/script/ScriptDependenciesManager.kt | 31 +++++++++++-------- .../ScriptsCompilationConfigurationCache.kt | 27 ++++++++++++---- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/ScriptModuleInfos.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/ScriptModuleInfos.kt index 8a384507a85..2681dd5f174 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/ScriptModuleInfos.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/project/ScriptModuleInfos.kt @@ -90,8 +90,7 @@ sealed class ScriptDependenciesInfo(val project: Project) : IdeaModuleInfo, Bina ) : ScriptDependenciesInfo(project) { override val sdk: Sdk? get() { - return ScriptDependenciesManager.getInstance(project).getScriptSdk(scriptFile) - ?: ScriptDependenciesManager.getScriptDefaultSdk(project) + return ScriptDependenciesManager.getInstance(project).getScriptSdk(scriptFile, project) } override fun contentScope(): GlobalSearchScope { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesManager.kt index 37a58c74c5d..72ec943286c 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesManager.kt @@ -55,7 +55,10 @@ class ScriptDependenciesManager internal constructor( fun getRefinedCompilationConfiguration(file: VirtualFile): ScriptCompilationConfigurationResult? = cacheUpdater.getCurrentCompilationConfiguration(file) - fun getScriptSdk(file: VirtualFile): Sdk? = Companion.getScriptSdk(getRefinedCompilationConfiguration(file)?.valueOrNull()) + fun getScriptSdk(file: VirtualFile, project: Project): Sdk? { + return getScriptSdk(getRefinedCompilationConfiguration(file)?.valueOrNull()) + ?: getScriptDefaultSdk(project) + } fun getScriptDependenciesClassFilesScope(file: VirtualFile) = cache.scriptDependenciesClassFilesScope(file) @@ -83,20 +86,22 @@ class ScriptDependenciesManager internal constructor( return getAllProjectSdks().find { it.homeDirectory == javaHome } } + fun getScriptDefaultSdk(project: Project): Sdk? { + val projectSdk = ProjectRootManager.getInstance(project).projectSdk?.takeIf { it.canBeUsedForScript() } + if (projectSdk != null) return projectSdk - fun getScriptDefaultSdk(project: Project): Sdk? = - getProjectSdk(project) - ?: getAllProjectSdks().find { it.canBeUsedForScript() } - ?: run { - log.warn( - "Default Script SDK is null: " + - "projectSdk = ${ProjectRootManager.getInstance(project).projectSdk}, " + - "all sdks = ${getAllProjectSdks().joinToString("; ")}" - ) - null - } + val anyJavaSdk = getAllProjectSdks().find { it.canBeUsedForScript() } + if (anyJavaSdk != null) { + return anyJavaSdk + } - fun getProjectSdk(project: Project) = ProjectRootManager.getInstance(project).projectSdk?.takeIf { it.canBeUsedForScript() } + log.warn( + "Default Script SDK is null: " + + "projectSdk = ${ProjectRootManager.getInstance(project).projectSdk}, " + + "all sdks = ${getAllProjectSdks().joinToString("\n")}" + ) + return null + } fun toVfsRoots(roots: Iterable): List { return roots.mapNotNull { it.classpathEntryToVfs() } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptsCompilationConfigurationCache.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptsCompilationConfigurationCache.kt index 579895a76c0..0eadd66a807 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptsCompilationConfigurationCache.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptsCompilationConfigurationCache.kt @@ -18,7 +18,10 @@ package org.jetbrains.kotlin.idea.core.script import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project +import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiElementFinder @@ -79,13 +82,19 @@ class ScriptsCompilationConfigurationCache(private val project: Project) { val allSdks by ClearableLazyValue(cacheLock) { scriptDependenciesCache.getAll() - .mapNotNull { ScriptDependenciesManager.getInstance(project).getScriptSdk(it.key) } + .mapNotNull { ScriptDependenciesManager.getInstance(project).getScriptSdk(it.key, project) } + .distinct() + } + + private val allNonIndexedSdks by ClearableLazyValue(cacheLock) { + scriptDependenciesCache.getAll() + .mapNotNull { ScriptDependenciesManager.getInstance(project).getScriptSdk(it.key, project) } + .filterNonModuleSdk() .distinct() } val allDependenciesClassFiles by ClearableLazyValue(cacheLock) { - val sdkFiles = allSdks - .filter { it != ScriptDependenciesManager.getProjectSdk(project) } + val sdkFiles = allNonIndexedSdks .flatMap { it.rootProvider.getFiles(OrderRootType.CLASSES).toList() } val scriptDependenciesClasspath = scriptDependenciesCache.getAll() @@ -95,8 +104,7 @@ class ScriptsCompilationConfigurationCache(private val project: Project) { } val allDependenciesSources by ClearableLazyValue(cacheLock) { - val sdkSources = allSdks - .filter { it != ScriptDependenciesManager.getProjectSdk(project) } + val sdkSources = allNonIndexedSdks .flatMap { it.rootProvider.getFiles(OrderRootType.SOURCES).toList() } val scriptDependenciesSources = scriptDependenciesCache.getAll() @@ -112,8 +120,14 @@ class ScriptsCompilationConfigurationCache(private val project: Project) { NonClasspathDirectoriesScope.compose(allDependenciesSources) } + private fun List.filterNonModuleSdk(): List { + val moduleSdks = ModuleManager.getInstance(project).modules.map { ModuleRootManager.getInstance(it).sdk } + return filterNot { moduleSdks.contains(it) } + } + private fun onChange(files: List) { this::allSdks.clearValue() + this::allNonIndexedSdks.clearValue() this::allDependenciesClassFiles.clearValue() this::allDependenciesClassFilesScope.clearValue() @@ -145,7 +159,8 @@ class ScriptsCompilationConfigurationCache(private val project: Project) { } fun hasNotCachedRoots(compilationConfiguration: ScriptCompilationConfigurationWrapper): Boolean { - return !allSdks.contains(ScriptDependenciesManager.getScriptSdk(compilationConfiguration)) || + val scriptSdk = ScriptDependenciesManager.getScriptSdk(compilationConfiguration) ?: ScriptDependenciesManager.getScriptDefaultSdk(project) + return (scriptSdk != null && !allSdks.contains(scriptSdk)) || !allDependenciesClassFiles.containsAll(ScriptDependenciesManager.toVfsRoots(compilationConfiguration.dependenciesClassPath)) || !allDependenciesSources.containsAll(ScriptDependenciesManager.toVfsRoots(compilationConfiguration.dependenciesSources)) }