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?
get() {
return ScriptConfigurationManager.getInstance(project).getFirstScriptsSdk()
?: ScriptConfigurationManager.getScriptDefaultSdk(project)
}
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.project.Project
import com.intellij.openapi.projectRoots.JavaSdkType
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.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFile
@@ -29,7 +26,6 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.io.URLUtil
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.listener.ScriptConfigurationUpdater
import org.jetbrains.kotlin.idea.core.script.configuration.loader.ScriptConfigurationLoader
@@ -124,29 +120,10 @@ interface ScriptConfigurationManager {
fun getInstance(project: Project): ScriptConfigurationManager =
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> {
return roots.mapNotNull { it.classpathEntryToVfs() }
}
private fun Sdk.canBeUsedForScript() = sdkType is JavaSdkType
private fun File.classpathEntryToVfs(): VirtualFile? {
val res = when {
!exists() -> null
@@ -28,16 +28,13 @@ internal class DefaultClassRootsCache(
private val scriptsSdksCache: Map<VirtualFile, Sdk?> =
ConcurrentFactoryMap.createWeakMap { file ->
return@createWeakMap getScriptSdk(
all[file]?.javaHome
) ?: ScriptConfigurationManager.getScriptDefaultSdk(project)
return@createWeakMap getScriptSdkOrDefault(all[file]?.javaHome, project)
}
override fun getScriptSdk(file: VirtualFile): Sdk? = scriptsSdksCache[file]
override val firstScriptSdk: Sdk? by lazy {
val firstCachedScript = all.keys.firstOrNull() ?: return@lazy null
return@lazy getScriptSdk(firstCachedScript)
getScriptSdkOrDefault(all.values.firstOrNull()?.javaHome, project)
}
companion object {
@@ -45,7 +42,7 @@ internal class DefaultClassRootsCache(
project: Project,
configuration: ScriptCompilationConfigurationWrapper
): ScriptClassRootsStorage.Companion.ScriptClassRoots {
val scriptSdk = getScriptSdk(configuration.javaHome)
val scriptSdk = getScriptSdkOrDefault(configuration.javaHome, project)
if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(project)) {
return ScriptClassRootsStorage.Companion.ScriptClassRoots(
toStringValues(configuration.dependenciesClassPath),
@@ -70,8 +67,7 @@ internal class DefaultClassRootsCache(
val sdks = mutableSetOf<Sdk>()
for ((_, configuration) in all) {
val scriptSdk =
getScriptSdk(configuration.javaHome)
val scriptSdk = getScriptSdkOrDefault(configuration.javaHome, project)
if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(project)) {
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.project.Project
import com.intellij.openapi.projectRoots.JavaSdkType
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.*
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.NonClasspathDirectoriesScope
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.util.getProjectJdkTableSafe
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
@@ -100,21 +104,40 @@ abstract class ScriptClassRootsCache(
return prop.mapNotNull { it.absolutePath }.toSet()
}
fun getScriptSdkOfDefault(javaHomeStr: File?, project: Project): Sdk? {
return getScriptSdk(javaHomeStr) ?: ScriptConfigurationManager.getScriptDefaultSdk(project)
fun getScriptSdkOrDefault(javaHome: File?, project: Project): Sdk? {
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
val javaHome = try {
javaHomeStr?.let { VfsUtil.findFileByIoFile(it, true) }
val javaHomeVF = try {
VfsUtil.findFileByIoFile(javaHome, true)
} catch (e: Throwable) {
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 {
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.VirtualFile
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.Companion.ScriptClassRoots
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModel
@@ -58,7 +59,7 @@ class GradleClassRootsCache(
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
// as we cannot force loading, we always return true
@@ -69,8 +70,8 @@ class GradleClassRootsCache(
if (configuration == null) {
return ScriptClassRootsStorage.EMPTY
}
val scriptSdk = getScriptSdk(configuration.context.javaHome)
if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(configuration.context.project)) {
val scriptSdk = getScriptSdkOrDefault(context.javaHome, project)
if (scriptSdk != null && !scriptSdk.isAlreadyIndexed(project)) {
return ScriptClassRootsStorage.Companion.ScriptClassRoots(
configuration.classFilePath,
configuration.sourcePath,
@@ -80,7 +81,7 @@ class GradleClassRootsCache(
return ScriptClassRoots(
configuration.classFilePath,
configuration.sourcePath,
getScriptSdk(context.javaHome)?.let { setOf(it) } ?: setOf()
getScriptSdkOrDefault(context.javaHome, project)?.let { setOf(it) } ?: setOf()
)
}
}