Fix the way how script SDK is found in IDE
This commit is contained in:
@@ -369,7 +369,7 @@ private class LibrarySourceScope(project: Project, private val library: Library)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: (module refactoring) android sdk has modified scope
|
//TODO: (module refactoring) android sdk has modified scope
|
||||||
private class SdkScope(project: Project, private val sdk: Sdk) :
|
private class SdkScope(project: Project, val sdk: Sdk) :
|
||||||
LibraryScopeBase(project, sdk.rootProvider.getFiles(OrderRootType.CLASSES), arrayOf<VirtualFile>()) {
|
LibraryScopeBase(project, sdk.rootProvider.getFiles(OrderRootType.CLASSES), arrayOf<VirtualFile>()) {
|
||||||
|
|
||||||
override fun equals(other: Any?) = other is SdkScope && sdk == other.sdk
|
override fun equals(other: Any?) = other is SdkScope && sdk == other.sdk
|
||||||
|
|||||||
+4
-2
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
|
|||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||||
|
import java.io.File
|
||||||
import kotlin.script.experimental.dependencies.ScriptDependencies
|
import kotlin.script.experimental.dependencies.ScriptDependencies
|
||||||
|
|
||||||
class ScriptModuleSearchScope(val scriptFile: VirtualFile, baseScope: GlobalSearchScope) : DelegatingGlobalSearchScope(baseScope) {
|
class ScriptModuleSearchScope(val scriptFile: VirtualFile, baseScope: GlobalSearchScope) : DelegatingGlobalSearchScope(baseScope) {
|
||||||
@@ -61,8 +62,9 @@ fun findJdk(dependencies: ScriptDependencies?, project: Project): Sdk? {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
return allJdks.find { javaHome != null && it.homePath == javaHome } ?: ProjectRootManager.getInstance(project).projectSdk
|
return allJdks.find { javaHome != null && File(it.homePath).canonicalPath == javaHome }
|
||||||
?: allJdks.firstOrNull()
|
?: ProjectRootManager.getInstance(project).projectSdk
|
||||||
|
?: allJdks.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ScriptDependenciesInfo(val project: Project) : IdeaModuleInfo, BinaryModuleInfo {
|
sealed class ScriptDependenciesInfo(val project: Project) : IdeaModuleInfo, BinaryModuleInfo {
|
||||||
|
|||||||
+20
-3
@@ -24,6 +24,11 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.projectRoots.JavaSdk
|
import com.intellij.openapi.projectRoots.JavaSdk
|
||||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||||
import com.intellij.openapi.projectRoots.ex.PathUtilEx
|
import com.intellij.openapi.projectRoots.ex.PathUtilEx
|
||||||
|
import com.intellij.openapi.roots.ProjectRootManager
|
||||||
|
import com.intellij.openapi.vfs.VfsUtil
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.getScriptRelatedModuleInfo
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||||
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
|
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
|
||||||
@@ -223,7 +228,9 @@ class BundledKotlinScriptDependenciesResolver(private val project: Project) : De
|
|||||||
scriptContents: ScriptContents,
|
scriptContents: ScriptContents,
|
||||||
environment: Environment
|
environment: Environment
|
||||||
): DependenciesResolver.ResolveResult {
|
): DependenciesResolver.ResolveResult {
|
||||||
val javaHome = getScriptSDK(project)
|
val virtualFile = scriptContents.file?.let { VfsUtil.findFileByIoFile(it, true) }
|
||||||
|
|
||||||
|
val javaHome = getScriptSDK(project, virtualFile)
|
||||||
val dependencies = ScriptDependencies(
|
val dependencies = ScriptDependencies(
|
||||||
javaHome = javaHome?.let(::File),
|
javaHome = javaHome?.let(::File),
|
||||||
classpath = with(PathUtil.kotlinPathsForIdeaPlugin) {
|
classpath = with(PathUtil.kotlinPathsForIdeaPlugin) {
|
||||||
@@ -237,8 +244,18 @@ class BundledKotlinScriptDependenciesResolver(private val project: Project) : De
|
|||||||
return dependencies.asSuccess()
|
return dependencies.asSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getScriptSDK(project: Project): String? {
|
private fun getScriptSDK(project: Project, virtualFile: VirtualFile?): String? {
|
||||||
val jdk = ProjectJdkTable.getInstance().allJdks.firstOrNull { sdk -> sdk.sdkType is JavaSdk } ?: PathUtilEx.getAnyJdk(project)
|
if (virtualFile != null) {
|
||||||
|
val dependentModuleSourceInfo = getScriptRelatedModuleInfo(project, virtualFile)
|
||||||
|
val sdk = dependentModuleSourceInfo?.dependencies()?.filterIsInstance<SdkInfo>()?.singleOrNull()?.sdk
|
||||||
|
if (sdk != null) {
|
||||||
|
return sdk.homePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val jdk = ProjectRootManager.getInstance(project).projectSdk
|
||||||
|
?: ProjectJdkTable.getInstance().allJdks.firstOrNull { sdk -> sdk.sdkType is JavaSdk }
|
||||||
|
?: PathUtilEx.getAnyJdk(project)
|
||||||
return jdk?.homePath
|
return jdk?.homePath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,20 +18,29 @@ package org.jetbrains.kotlin.idea.caches.resolve
|
|||||||
|
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.module.StdModuleTypes
|
import com.intellij.openapi.module.StdModuleTypes
|
||||||
|
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||||
import com.intellij.openapi.roots.DependencyScope
|
import com.intellij.openapi.roots.DependencyScope
|
||||||
|
import com.intellij.openapi.roots.ModuleRootManager
|
||||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||||
|
import com.intellij.openapi.roots.ProjectRootManager
|
||||||
import com.intellij.openapi.roots.libraries.Library
|
import com.intellij.openapi.roots.libraries.Library
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem
|
import com.intellij.openapi.vfs.LocalFileSystem
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||||
import com.intellij.testFramework.ModuleTestCase
|
import com.intellij.testFramework.ModuleTestCase
|
||||||
|
import com.intellij.testFramework.PlatformTestCase
|
||||||
import com.intellij.testFramework.PsiTestUtil
|
import com.intellij.testFramework.PsiTestUtil
|
||||||
import com.intellij.testFramework.UsefulTestCase
|
import com.intellij.testFramework.UsefulTestCase
|
||||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||||
import org.jetbrains.kotlin.idea.caches.project.*
|
import org.jetbrains.kotlin.idea.caches.project.*
|
||||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
||||||
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
|
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
|
||||||
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase.*
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.test.util.addDependency
|
import org.jetbrains.kotlin.test.util.addDependency
|
||||||
import org.jetbrains.kotlin.test.util.jarRoot
|
import org.jetbrains.kotlin.test.util.jarRoot
|
||||||
import org.jetbrains.kotlin.test.util.projectLibrary
|
import org.jetbrains.kotlin.test.util.projectLibrary
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
|
|
||||||
class IdeaModuleInfoTest : ModuleTestCase() {
|
class IdeaModuleInfoTest : ModuleTestCase() {
|
||||||
@@ -319,12 +328,108 @@ class IdeaModuleInfoTest : ModuleTestCase() {
|
|||||||
stdlibJs.classes.assertAdditionalLibraryDependencies(stdlibCommon.classes)
|
stdlibJs.classes.assertAdditionalLibraryDependencies(stdlibCommon.classes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testScriptDependenciesForModule() {
|
||||||
|
val a = module("a")
|
||||||
|
val b = module("b")
|
||||||
|
|
||||||
|
with(createFileInModule(a, "script.kts").moduleInfo) {
|
||||||
|
dependencies().contains(a.production)
|
||||||
|
dependencies().contains(a.test)
|
||||||
|
!dependencies().contains(b.production)
|
||||||
|
dependencies().firstIsInstance<ScriptDependenciesInfo.ForFile>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setUp() {
|
||||||
|
super.setUp()
|
||||||
|
VfsRootAccess.allowRootAccess("C:/Work/Projects/kotlin/")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testScriptDependenciesForProject() {
|
||||||
|
val a = module("a")
|
||||||
|
|
||||||
|
val script = createFileInProject("script.kts").moduleInfo
|
||||||
|
|
||||||
|
!script.dependencies().contains(a.production)
|
||||||
|
!script.dependencies().contains(a.test)
|
||||||
|
|
||||||
|
script.dependencies().firstIsInstance<ScriptDependenciesInfo.ForFile>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSdkForScript() {
|
||||||
|
runWriteAction {
|
||||||
|
ProjectJdkTable.getInstance().addJdk(mockJdk6())
|
||||||
|
ProjectJdkTable.getInstance().addJdk(mockJdk9())
|
||||||
|
}
|
||||||
|
|
||||||
|
with(createFileInProject("script.kts").moduleInfo) {
|
||||||
|
dependencies().filterIsInstance<SdkInfo>().single { it.sdk == mockJdk6() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSdkForScriptProjectSdk() {
|
||||||
|
runWriteAction {
|
||||||
|
ProjectJdkTable.getInstance().addJdk(mockJdk6())
|
||||||
|
ProjectJdkTable.getInstance().addJdk(mockJdk9())
|
||||||
|
|
||||||
|
ProjectRootManager.getInstance(project).projectSdk = mockJdk9()
|
||||||
|
}
|
||||||
|
|
||||||
|
with(createFileInProject("script.kts").moduleInfo) {
|
||||||
|
dependencies().filterIsInstance<SdkInfo>().single { it.sdk == mockJdk9() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSdkForScriptModuleSdk() {
|
||||||
|
val a = module("a")
|
||||||
|
|
||||||
|
runWriteAction {
|
||||||
|
ProjectJdkTable.getInstance().addJdk(mockJdk6())
|
||||||
|
ProjectJdkTable.getInstance().addJdk(mockJdk9())
|
||||||
|
|
||||||
|
ProjectRootManager.getInstance(project).projectSdk = mockJdk6()
|
||||||
|
with(ModuleRootManager.getInstance(a).modifiableModel) {
|
||||||
|
sdk = mockJdk9()
|
||||||
|
commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with(createFileInModule(a, "script.kts").moduleInfo) {
|
||||||
|
dependencies().filterIsInstance<SdkInfo>().first { it.sdk == mockJdk9() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFileInModule(module: Module, fileName: String, inTests: Boolean = false): VirtualFile {
|
||||||
|
val fileToCopyIO = createTempFile(fileName, "")
|
||||||
|
|
||||||
|
for (contentEntry in ModuleRootManager.getInstance(module).contentEntries) {
|
||||||
|
for (sourceFolder in contentEntry.sourceFolders) {
|
||||||
|
if (((!inTests && !sourceFolder.isTestSource) || (inTests && sourceFolder.isTestSource)) && sourceFolder.file != null) {
|
||||||
|
return runWriteAction {
|
||||||
|
PlatformTestCase.getVirtualFile(fileToCopyIO).copy(this, sourceFolder.file!!, fileName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error("Couldn't find source folder in ${module.name}")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFileInProject(fileName: String): VirtualFile {
|
||||||
|
return runWriteAction {
|
||||||
|
PlatformTestCase.getVirtualFile(createTempFile(fileName, "")).copy(this, project.baseDir, fileName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun Module.addDependency(
|
private fun Module.addDependency(
|
||||||
other: Module,
|
other: Module,
|
||||||
dependencyScope: DependencyScope = DependencyScope.COMPILE,
|
dependencyScope: DependencyScope = DependencyScope.COMPILE,
|
||||||
exported: Boolean = false
|
exported: Boolean = false
|
||||||
) = ModuleRootModificationUtil.addDependency(this, other, dependencyScope, exported)
|
) = ModuleRootModificationUtil.addDependency(this, other, dependencyScope, exported)
|
||||||
|
|
||||||
|
private val VirtualFile.moduleInfo: IdeaModuleInfo
|
||||||
|
get() = getModuleInfoByVirtualFile(project, this)!!
|
||||||
|
|
||||||
private val Module.production: ModuleProductionSourceInfo
|
private val Module.production: ModuleProductionSourceInfo
|
||||||
get() = productionSourceInfo()!!
|
get() = productionSourceInfo()!!
|
||||||
|
|
||||||
@@ -361,13 +466,23 @@ class IdeaModuleInfoTest : ModuleTestCase() {
|
|||||||
UsefulTestCase.assertSameElements(this.getDependentModules(), expected.toList())
|
UsefulTestCase.assertSameElements(this.getDependentModules(), expected.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stdlibCommon(): Library = projectLibrary("kotlin-stdlib-common",
|
private fun stdlibCommon(): Library = projectLibrary(
|
||||||
ForTestCompileRuntime.stdlibCommonForTests().jarRoot,
|
"kotlin-stdlib-common",
|
||||||
kind = CommonLibraryKind)
|
ForTestCompileRuntime.stdlibCommonForTests().jarRoot,
|
||||||
|
kind = CommonLibraryKind
|
||||||
|
)
|
||||||
|
|
||||||
private fun stdlibJvm(): Library = projectLibrary("kotlin-stdlib", ForTestCompileRuntime.runtimeJarForTests().jarRoot)
|
private fun stdlibJvm(): Library = projectLibrary("kotlin-stdlib", ForTestCompileRuntime.runtimeJarForTests().jarRoot)
|
||||||
|
|
||||||
private fun stdlibJs(): Library = projectLibrary("kotlin-stdlib-js",
|
private fun stdlibJs(): Library = projectLibrary(
|
||||||
ForTestCompileRuntime.runtimeJarForTests().jarRoot,
|
"kotlin-stdlib-js",
|
||||||
kind = JSLibraryKind)
|
ForTestCompileRuntime.runtimeJarForTests().jarRoot,
|
||||||
|
kind = JSLibraryKind
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun tearDown() {
|
||||||
|
clearSdkTable(testRootDisposable)
|
||||||
|
|
||||||
|
super.tearDown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user