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
This commit is contained in:
Natalia Selezneva
2019-05-31 15:19:08 +03:00
parent a69b5345d5
commit 2b748ccd9a
3 changed files with 40 additions and 21 deletions
@@ -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 {
@@ -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<File>): List<VirtualFile> {
return roots.mapNotNull { it.classpathEntryToVfs() }
@@ -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<Sdk>.filterNonModuleSdk(): List<Sdk> {
val moduleSdks = ModuleManager.getInstance(project).modules.map { ModuleRootManager.getInstance(it).sdk }
return filterNot { moduleSdks.contains(it) }
}
private fun onChange(files: List<VirtualFile>) {
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))
}