scripting, sdk cache: same key for locating sdk

This commit is contained in:
Sergey Rostov
2020-05-26 12:21:10 +03:00
parent 8d00ec1933
commit e3ed8870dd
5 changed files with 65 additions and 15 deletions
@@ -59,6 +59,7 @@ class ScriptClassRootsBuilder(
classes.addAll(classesRoots) classes.addAll(classesRoots)
} }
@Deprecated("Don't use, used only from DefaultScriptingSupport for saving to storage")
fun add(other: ScriptClassRootsBuilder) { fun add(other: ScriptClassRootsBuilder) {
classes.addAll(other.classes) classes.addAll(other.classes)
sources.addAll(other.sources) sources.addAll(other.sources)
@@ -68,7 +68,7 @@ class ScriptClassRootsCache(
val configuration = lightScriptInfo.buildConfiguration() ?: return null val configuration = lightScriptInfo.buildConfiguration() ?: return null
val roots = configuration.dependenciesClassPath val roots = configuration.dependenciesClassPath
val sdk = sdks[configuration.javaHome?.canonicalPath] val sdk = sdks[SdkId(configuration.javaHome)]
return if (sdk == null) { return if (sdk == null) {
HeavyScriptInfo(configuration, compose(toVfsRoots(roots)), null) HeavyScriptInfo(configuration, compose(toVfsRoots(roots)), null)
@@ -12,15 +12,12 @@ import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import java.io.File
class ScriptSdks(val project: Project, private val sdks: Map<String?, Sdk?>) { class ScriptSdks(val project: Project, private val sdks: Map<SdkId, Sdk?>) {
fun rebuild(remove: Sdk?): ScriptSdks { fun rebuild(remove: Sdk?): ScriptSdks {
val builder = ScriptSdksBuilder(project, remove = remove) val builder = ScriptSdksBuilder(project, remove = remove)
sdks.keys.forEach { home -> sdks.keys.forEach { id ->
if (home != null) { builder.addSdk(id)
builder.addSdk(File(home))
}
} }
return builder.build() return builder.build()
} }
@@ -29,7 +26,8 @@ class ScriptSdks(val project: Project, private val sdks: Map<String?, Sdk?>) {
val nonIndexedSourceRoots = mutableSetOf<VirtualFile>() val nonIndexedSourceRoots = mutableSetOf<VirtualFile>()
val first: Sdk? = sdks.values.firstOrNull() val first: Sdk? = sdks.values.firstOrNull()
operator fun get(sdkHome: String?) = sdks[sdkHome]
operator fun get(sdkId: SdkId) = sdks[sdkId]
init { init {
val nonIndexedSdks = sdks.values.filterNotNullTo(mutableSetOf()) val nonIndexedSdks = sdks.values.filterNotNullTo(mutableSetOf())
@@ -9,7 +9,6 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdkType 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.io.FileUtil
import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtil
import org.jetbrains.kotlin.idea.caches.project.getAllProjectSdks import org.jetbrains.kotlin.idea.caches.project.getAllProjectSdks
import org.jetbrains.kotlin.idea.core.script.LOG import org.jetbrains.kotlin.idea.core.script.LOG
@@ -19,22 +18,28 @@ import java.io.File
class ScriptSdksBuilder( class ScriptSdksBuilder(
val project: Project, val project: Project,
private val sdks: MutableMap<String?, Sdk?> = mutableMapOf(), private val sdks: MutableMap<SdkId, Sdk?> = mutableMapOf(),
private val remove: Sdk? = null private val remove: Sdk? = null
) { ) {
private val defaultSdk by lazy { getScriptDefaultSdk() } private val defaultSdk by lazy { getScriptDefaultSdk() }
fun build() = ScriptSdks(project, sdks) fun build() = ScriptSdks(project, sdks)
@Deprecated("Don't use, used only from DefaultScriptingSupport for saving to storage")
fun addAll(other: ScriptSdksBuilder) { fun addAll(other: ScriptSdksBuilder) {
sdks.putAll(other.sdks) sdks.putAll(other.sdks)
} }
// add sdk by home path with checking for removed sdk
fun addSdk(sdkId: SdkId): Sdk? {
val canonicalPath = sdkId.homeDirectory ?: return addDefaultSdk()
return addSdk(File(canonicalPath))
}
fun addSdk(javaHome: File?): Sdk? { fun addSdk(javaHome: File?): Sdk? {
if (javaHome == null) return addDefaultSdk() if (javaHome == null) return addDefaultSdk()
val canonicalPath = FileUtil.toSystemIndependentName(javaHome.canonicalPath) return sdks.getOrPut(SdkId(javaHome)) {
return sdks.getOrPut(canonicalPath) {
getScriptSdkByJavaHome(javaHome) ?: defaultSdk getScriptSdkByJavaHome(javaHome) ?: defaultSdk
} }
} }
@@ -52,7 +57,7 @@ class ScriptSdksBuilder(
} }
fun addDefaultSdk(): Sdk? = fun addDefaultSdk(): Sdk? =
sdks.getOrPut(null) { defaultSdk } sdks.getOrPut(SdkId.default) { defaultSdk }
fun addSdkByName(sdkName: String) { fun addSdkByName(sdkName: String) {
val sdk = getProjectJdkTableSafe().allJdks val sdk = getProjectJdkTableSafe().allJdks
@@ -60,7 +65,7 @@ class ScriptSdksBuilder(
?.takeIf { it.canBeUsedForScript() } ?.takeIf { it.canBeUsedForScript() }
?: defaultSdk ?: return ?: defaultSdk ?: return
val homePath = sdk.homePath ?: return val homePath = sdk.homePath ?: return
sdks[homePath] = sdk sdks[SdkId(homePath)] = sdk
} }
private fun getScriptDefaultSdk(): Sdk? { private fun getScriptDefaultSdk(): Sdk? {
@@ -85,7 +90,7 @@ class ScriptSdksBuilder(
fun toStorage(storage: ScriptClassRootsStorage) { fun toStorage(storage: ScriptClassRootsStorage) {
storage.sdks = sdks.values.mapNotNullTo(mutableSetOf()) { it?.name } storage.sdks = sdks.values.mapNotNullTo(mutableSetOf()) { it?.name }
storage.defaultSdkUsed = sdks.containsKey(null) storage.defaultSdkUsed = sdks.containsKey(SdkId.default)
} }
fun fromStorage(storage: ScriptClassRootsStorage) { fun fromStorage(storage: ScriptClassRootsStorage) {
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.core.script.ucache
import com.intellij.openapi.util.io.FileUtil
import java.io.File
/**
* Safe key for locating sdk in intellij project jdk table
*
* null means default sdk
*/
class SdkId private constructor(val homeDirectory: String?) {
companion object {
val default = SdkId(null as String?)
operator fun invoke(homeDirectory: File?): SdkId {
if (homeDirectory == null) return default
val canonicalPath = FileUtil.toSystemIndependentName(homeDirectory.canonicalPath)
return SdkId(canonicalPath)
}
operator fun invoke(homeDirectory: String?): SdkId {
if (homeDirectory == null) return default
return invoke(File(homeDirectory))
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as SdkId
if (homeDirectory != other.homeDirectory) return false
return true
}
override fun hashCode(): Int {
return homeDirectory?.hashCode() ?: 0
}
}