Support extra imports configuration for scripts (only classpath so far)
This commit is contained in:
+12
-11
@@ -17,16 +17,13 @@
|
||||
package org.jetbrains.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.module.impl.scopes.LibraryScopeBase
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.*
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryImpl
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable
|
||||
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -291,7 +288,8 @@ internal object NotUnderContentRootModuleInfo : IdeaModuleInfo {
|
||||
override fun dependencies(): List<IdeaModuleInfo> = listOf(this)
|
||||
}
|
||||
|
||||
internal data class CustomizedScriptModuleInfo(val project: Project, val module: Module?, val virtualFile: VirtualFile, val scriptDefinition: KotlinScriptDefinition) : IdeaModuleInfo {
|
||||
internal data class CustomizedScriptModuleInfo(val project: Project, val module: Module?, val virtualFile: VirtualFile,
|
||||
val scriptDefinition: KotlinScriptDefinition) : IdeaModuleInfo {
|
||||
override val moduleOrigin: ModuleOrigin
|
||||
get() = ModuleOrigin.OTHER
|
||||
|
||||
@@ -300,15 +298,18 @@ internal data class CustomizedScriptModuleInfo(val project: Project, val module:
|
||||
override fun contentScope() = GlobalSearchScope.union(dependenciesRoots().map { FileLibraryScope(project, it) }.toTypedArray())
|
||||
|
||||
private fun dependenciesRoots(): List<VirtualFile> {
|
||||
// TODO: find out whether it should be cashed
|
||||
// TODO: find out whether it should be cashed (some changes listener should be implemented for the cached roots)
|
||||
val virtualFileManager = VirtualFileManager.getInstance()
|
||||
val jarfs = StandardFileSystems.jar()
|
||||
return scriptDefinition.getScriptDependenciesClasspath().map {
|
||||
if (File(it).isFile)
|
||||
jarfs.findFileByPath(it + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: $it")
|
||||
else
|
||||
virtualFileManager.findFileByUrl("file://$it") ?: throw FileNotFoundException("Classpath entry points to a non-existent location: $it")
|
||||
}
|
||||
return (scriptDefinition.getScriptDependenciesClasspath())
|
||||
.map { File(it).canonicalFile }
|
||||
.distinct()
|
||||
.map {
|
||||
if (it.isFile)
|
||||
jarfs.findFileByPath(it.absolutePath + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: ${it.canonicalPath}")
|
||||
else
|
||||
virtualFileManager.findFileByUrl("file://${it.absolutePath}") ?: throw FileNotFoundException("Classpath entry points to a non-existent location: ${it.canonicalPath}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun dependencies() =
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider
|
||||
import org.jetbrains.kotlin.script.getScriptDefinition
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
fun PsiElement.getModuleInfo(): IdeaModuleInfo = this.getModuleInfo { reason ->
|
||||
@@ -122,7 +123,7 @@ private fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFil
|
||||
}
|
||||
}
|
||||
|
||||
val scriptDefinition = KotlinScriptDefinitionProvider.getInstance(project).findScriptDefinition(virtualFile)
|
||||
val scriptDefinition = getScriptDefinition(virtualFile, project)
|
||||
if (scriptDefinition != null)
|
||||
return CustomizedScriptModuleInfo(project, module, virtualFile, scriptDefinition)
|
||||
|
||||
|
||||
@@ -248,6 +248,9 @@
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider"
|
||||
serviceImplementation="org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.script.KotlinScriptExtraImportsProvider"
|
||||
serviceImplementation="org.jetbrains.kotlin.script.KotlinScriptExtraImportsProvider"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder"/>
|
||||
|
||||
|
||||
@@ -22,25 +22,33 @@ import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
import org.jetbrains.kotlin.script.*
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
|
||||
@Suppress("unused") // project component
|
||||
class KotlinScriptConfigurationManager(private val project: Project, private val scriptDefinitionProvider: KotlinScriptDefinitionProvider) : AbstractProjectComponent(project) {
|
||||
class KotlinScriptConfigurationManager(project: Project,
|
||||
private val scriptDefinitionProvider: KotlinScriptDefinitionProvider,
|
||||
private val scriptExtraImportsProvider: KotlinScriptExtraImportsProvider
|
||||
) : AbstractProjectComponent(project) {
|
||||
|
||||
private val kotlinEnvVars: Map<String, List<String>> by lazy {
|
||||
val paths = PathUtil.getKotlinPathsForIdeaPlugin()
|
||||
mapOf("kotlin-runtime" to listOf(paths.runtimePath.canonicalPath),
|
||||
"project-root" to listOf(project.basePath ?: "."),
|
||||
"jdk" to PathUtil.getJdkClassesRoots().map { it.canonicalPath })
|
||||
}
|
||||
private val kotlinEnvVars: Map<String, List<String>> by lazy { generateKotlinScriptClasspathEnvVarsForIdea(myProject) }
|
||||
|
||||
init {
|
||||
reloadScriptDefinitions()
|
||||
val conn = project.messageBus.connect()
|
||||
val conn = myProject.messageBus.connect()
|
||||
conn.subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
|
||||
override fun after(events: List<VFileEvent>) {
|
||||
events.firstOrNull { it is VFileEvent && isScriptDefinitionConfigFile(File(it.path)) }?.let {
|
||||
var anyScriptDefinitionChanged = false
|
||||
events.filter { it is VFileEvent }.forEach {
|
||||
it.file?.let {
|
||||
if (!anyScriptDefinitionChanged && isScriptDefinitionConfigFile(it)) {
|
||||
anyScriptDefinitionChanged = true
|
||||
}
|
||||
if (scriptExtraImportsProvider.isExtraImportsConfig(it)) {
|
||||
scriptExtraImportsProvider.invalidateExtraImports(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (anyScriptDefinitionChanged) {
|
||||
reloadScriptDefinitions()
|
||||
}
|
||||
}
|
||||
@@ -48,7 +56,7 @@ class KotlinScriptConfigurationManager(private val project: Project, private val
|
||||
}
|
||||
|
||||
private fun reloadScriptDefinitions() {
|
||||
loadScriptConfigsFromProjectRoot(File(project.basePath ?: ".")).let {
|
||||
loadScriptConfigsFromProjectRoot(File(myProject.basePath ?: ".")).let {
|
||||
if (it.isNotEmpty()) {
|
||||
scriptDefinitionProvider.scriptDefinitions =
|
||||
it.map { KotlinConfigurableScriptDefinition(it, kotlinEnvVars) } + StandardScriptDefinition
|
||||
@@ -57,3 +65,4 @@ class KotlinScriptConfigurationManager(private val project: Project, private val
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user