Fix getting default sdk for scripts after refactoring

This commit is contained in:
Natalia Selezneva
2020-04-22 16:17:09 +03:00
parent 73760effee
commit 69d86a2972
5 changed files with 38 additions and 42 deletions
@@ -113,7 +113,6 @@ sealed class ScriptDependenciesInfo(override val project: Project) : IdeaModuleI
override val sdk: Sdk? override val sdk: Sdk?
get() { get() {
return ScriptConfigurationManager.getInstance(project).getFirstScriptsSdk() return ScriptConfigurationManager.getInstance(project).getFirstScriptsSdk()
?: ScriptConfigurationManager.getScriptDefaultSdk(project)
} }
override fun contentScope(): GlobalSearchScope { override fun contentScope(): GlobalSearchScope {
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.idea.core.script
import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdkType
import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.ProjectRootManager.*
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
@@ -29,7 +26,6 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.io.URLUtil import com.intellij.util.io.URLUtil
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.caches.project.getAllProjectSdks
import org.jetbrains.kotlin.idea.core.script.configuration.CompositeScriptConfigurationManager import org.jetbrains.kotlin.idea.core.script.configuration.CompositeScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptConfigurationUpdater import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptConfigurationUpdater
import org.jetbrains.kotlin.idea.core.script.configuration.loader.ScriptConfigurationLoader import org.jetbrains.kotlin.idea.core.script.configuration.loader.ScriptConfigurationLoader
@@ -124,29 +120,10 @@ interface ScriptConfigurationManager {
fun getInstance(project: Project): ScriptConfigurationManager = fun getInstance(project: Project): ScriptConfigurationManager =
ServiceManager.getService(project, ScriptConfigurationManager::class.java) ServiceManager.getService(project, ScriptConfigurationManager::class.java)
fun getScriptDefaultSdk(project: Project): Sdk? {
val projectSdk = ProjectRootManager.getInstance(project).projectSdk?.takeIf { it.canBeUsedForScript() }
if (projectSdk != null) return projectSdk
val anyJavaSdk = getAllProjectSdks().find { it.canBeUsedForScript() }
if (anyJavaSdk != null) {
return anyJavaSdk
}
LOG.warn(
"Default Script SDK is null: " +
"projectSdk = ${ProjectRootManager.getInstance(project).projectSdk}, " +
"all sdks = ${getAllProjectSdks().joinToString("\n")}"
)
return null
}
fun toVfsRoots(roots: Iterable<File>): List<VirtualFile> { fun toVfsRoots(roots: Iterable<File>): List<VirtualFile> {
return roots.mapNotNull { it.classpathEntryToVfs() } return roots.mapNotNull { it.classpathEntryToVfs() }
} }
private fun Sdk.canBeUsedForScript() = sdkType is JavaSdkType
private fun File.classpathEntryToVfs(): VirtualFile? { private fun File.classpathEntryToVfs(): VirtualFile? {
val res = when { val res = when {
!exists() -> null !exists() -> null
@@ -28,16 +28,13 @@ internal class DefaultClassRootsCache(
private val scriptsSdksCache: Map<VirtualFile, Sdk?> = private val scriptsSdksCache: Map<VirtualFile, Sdk?> =
ConcurrentFactoryMap.createWeakMap { file -> ConcurrentFactoryMap.createWeakMap { file ->
return@createWeakMap getScriptSdk( return@createWeakMap getScriptSdkOrDefault(all[file]?.javaHome, project)
all[file]?.javaHome
) ?: ScriptConfigurationManager.getScriptDefaultSdk(project)
} }
override fun getScriptSdk(file: VirtualFile): Sdk? = scriptsSdksCache[file] override fun getScriptSdk(file: VirtualFile): Sdk? = scriptsSdksCache[file]
override val firstScriptSdk: Sdk? by lazy { override val firstScriptSdk: Sdk? by lazy {
val firstCachedScript = all.keys.firstOrNull() ?: return@lazy null getScriptSdkOrDefault(all.values.firstOrNull()?.javaHome, project)
return@lazy getScriptSdk(firstCachedScript)
} }
companion object { companion object {
@@ -45,7 +42,7 @@ internal class DefaultClassRootsCache(
project: Project, project: Project,
configuration: ScriptCompilationConfigurationWrapper configuration: ScriptCompilationConfigurationWrapper
): ScriptClassRootsStorage.Companion.ScriptClassRoots { ): ScriptClassRootsStorage.Companion.ScriptClassRoots {
val scriptSdk = getScriptSdk(configuration.javaHome) val scriptSdk = getScriptSdkOrDefault(configuration.javaHome, project)
if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(project)) { if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(project)) {
return ScriptClassRootsStorage.Companion.ScriptClassRoots( return ScriptClassRootsStorage.Companion.ScriptClassRoots(
toStringValues(configuration.dependenciesClassPath), toStringValues(configuration.dependenciesClassPath),
@@ -70,8 +67,7 @@ internal class DefaultClassRootsCache(
val sdks = mutableSetOf<Sdk>() val sdks = mutableSetOf<Sdk>()
for ((_, configuration) in all) { for ((_, configuration) in all) {
val scriptSdk = val scriptSdk = getScriptSdkOrDefault(configuration.javaHome, project)
getScriptSdk(configuration.javaHome)
if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(project)) { if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(project)) {
sdks.add(scriptSdk) sdks.add(scriptSdk)
} }
@@ -7,13 +7,17 @@ package org.jetbrains.kotlin.idea.core.script.configuration.utils
import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdkType
import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.* import com.intellij.openapi.vfs.*
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.NonClasspathDirectoriesScope import com.intellij.psi.search.NonClasspathDirectoriesScope
import com.intellij.util.containers.ConcurrentFactoryMap import com.intellij.util.containers.ConcurrentFactoryMap
import org.jetbrains.kotlin.idea.caches.project.getAllProjectSdks
import org.jetbrains.kotlin.idea.core.script.LOG
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
@@ -100,21 +104,40 @@ abstract class ScriptClassRootsCache(
return prop.mapNotNull { it.absolutePath }.toSet() return prop.mapNotNull { it.absolutePath }.toSet()
} }
fun getScriptSdkOfDefault(javaHomeStr: File?, project: Project): Sdk? { fun getScriptSdkOrDefault(javaHome: File?, project: Project): Sdk? {
return getScriptSdk(javaHomeStr) ?: ScriptConfigurationManager.getScriptDefaultSdk(project) return javaHome?.let { getScriptSdkByJavaHome(it) } ?: getScriptDefaultSdk(project)
} }
fun getScriptSdk(javaHomeStr: File?): Sdk? { private fun getScriptSdkByJavaHome(javaHome: File): Sdk? {
// workaround for mismatched gradle wrapper and plugin version // workaround for mismatched gradle wrapper and plugin version
val javaHome = try { val javaHomeVF = try {
javaHomeStr?.let { VfsUtil.findFileByIoFile(it, true) } VfsUtil.findFileByIoFile(javaHome, true)
} catch (e: Throwable) { } catch (e: Throwable) {
null null
} ?: return null } ?: return null
return getProjectJdkTableSafe().allJdks.find { it.homeDirectory == javaHome } return getProjectJdkTableSafe().allJdks.find { it.homeDirectory == javaHomeVF }
} }
private fun getScriptDefaultSdk(project: Project): Sdk? {
val projectSdk = ProjectRootManager.getInstance(project).projectSdk?.takeIf { it.canBeUsedForScript() }
if (projectSdk != null) return projectSdk
val anyJavaSdk = getAllProjectSdks().find { it.canBeUsedForScript() }
if (anyJavaSdk != null) {
return anyJavaSdk
}
LOG.warn(
"Default Script SDK is null: " +
"projectSdk = ${ProjectRootManager.getInstance(project).projectSdk}, " +
"all sdks = ${getAllProjectSdks().joinToString("\n")}"
)
return null
}
private fun Sdk.canBeUsedForScript() = sdkType is JavaSdkType
fun Sdk.isAlreadyIndexed(project: Project): Boolean { fun Sdk.isAlreadyIndexed(project: Project): Boolean {
return ModuleManager.getInstance(project).modules.any { ModuleRootManager.getInstance(it).sdk == this } return ModuleManager.getInstance(project).modules.any { ModuleRootManager.getInstance(it).sdk == this }
} }
@@ -10,6 +10,7 @@ import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsCache import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsCache
import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsCache.Companion.getScriptSdkOrDefault
import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsStorage import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsStorage
import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsStorage.Companion.ScriptClassRoots import org.jetbrains.kotlin.idea.core.script.configuration.utils.ScriptClassRootsStorage.Companion.ScriptClassRoots
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModel import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModel
@@ -58,7 +59,7 @@ class GradleClassRootsCache(
return firstScriptSdk return firstScriptSdk
} }
override val firstScriptSdk: Sdk? = configuration?.let { getScriptSdk(context.javaHome) } override val firstScriptSdk: Sdk? = getScriptSdkOrDefault(context.javaHome, project)
// called to ensure that configuration for file is loaded // called to ensure that configuration for file is loaded
// as we cannot force loading, we always return true // as we cannot force loading, we always return true
@@ -69,8 +70,8 @@ class GradleClassRootsCache(
if (configuration == null) { if (configuration == null) {
return ScriptClassRootsStorage.EMPTY return ScriptClassRootsStorage.EMPTY
} }
val scriptSdk = getScriptSdk(configuration.context.javaHome) val scriptSdk = getScriptSdkOrDefault(context.javaHome, project)
if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(configuration.context.project)) { if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(project)) {
return ScriptClassRootsStorage.Companion.ScriptClassRoots( return ScriptClassRootsStorage.Companion.ScriptClassRoots(
configuration.classFilePath, configuration.classFilePath,
configuration.sourcePath, configuration.sourcePath,
@@ -80,7 +81,7 @@ class GradleClassRootsCache(
return ScriptClassRoots( return ScriptClassRoots(
configuration.classFilePath, configuration.classFilePath,
configuration.sourcePath, configuration.sourcePath,
getScriptSdk(context.javaHome)?.let { setOf(it) } ?: setOf() getScriptSdkOrDefault(context.javaHome, project)?.let { setOf(it) } ?: setOf()
) )
} }
} }