Scripting: avoid creating multiple PSIs for every imported script
#KT-53009 fixed #KT-42810 should be possible now too, but more testing is needed #KT-42101 can also be addressed now, but first the serialization of the imported scripts property should be solved
This commit is contained in:
+6
-5
@@ -10,10 +10,7 @@ import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.resolve.KtFileScriptSource
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptReportSink
|
||||
import org.jetbrains.kotlin.scripting.resolve.refineScriptCompilationConfiguration
|
||||
import org.jetbrains.kotlin.scripting.resolve.*
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
@@ -22,6 +19,7 @@ import kotlin.script.experimental.api.ScriptCompilationConfiguration
|
||||
class CliScriptDependenciesProvider(project: Project) : ScriptDependenciesProvider(project) {
|
||||
private val cacheLock = ReentrantReadWriteLock()
|
||||
private val cache = hashMapOf<String, ScriptCompilationConfigurationResult?>()
|
||||
private val knownVirtualFileSources = mutableMapOf<String, VirtualFileScriptSource>()
|
||||
|
||||
override fun getScriptConfigurationResult(file: KtFile): ScriptCompilationConfigurationResult? = cacheLock.read {
|
||||
calculateRefinedConfiguration(file, null)
|
||||
@@ -43,7 +41,10 @@ class CliScriptDependenciesProvider(project: Project) : ScriptDependenciesProvid
|
||||
else {
|
||||
val scriptDef = file.findScriptDefinition()
|
||||
if (scriptDef != null) {
|
||||
val result = refineScriptCompilationConfiguration(KtFileScriptSource(file), scriptDef, project, providedConfiguration)
|
||||
val result =
|
||||
refineScriptCompilationConfiguration(
|
||||
KtFileScriptSource(file), scriptDef, project, providedConfiguration, knownVirtualFileSources
|
||||
)
|
||||
|
||||
ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file.virtualFile, result.reports)
|
||||
|
||||
|
||||
+22
-10
@@ -6,12 +6,17 @@
|
||||
package org.jetbrains.kotlin.scripting.compiler.plugin.dependencies
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.createSourceFilesFromSourceRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.report
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
|
||||
import org.jetbrains.kotlin.scripting.resolve.KtFileScriptSource
|
||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||
import java.io.File
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.api.ScriptCompilationConfiguration
|
||||
@@ -42,6 +47,7 @@ fun collectScriptsCompilationDependencies(
|
||||
var remainingSources = initialSources
|
||||
val knownSourcePaths = initialSources.mapNotNullTo(HashSet()) { it.virtualFile?.path }
|
||||
val importsProvider = ScriptDependenciesProvider.getInstance(project)
|
||||
val psiManager by lazy(LazyThreadSafetyMode.NONE) { PsiManager.getInstance(project) }
|
||||
if (importsProvider != null) {
|
||||
while (true) {
|
||||
val newRemainingSources = ArrayList<KtFile>()
|
||||
@@ -54,17 +60,23 @@ fun collectScriptsCompilationDependencies(
|
||||
is ResultWithDiagnostics.Success -> {
|
||||
collectedClassPath.addAll(refinedConfiguration.value.dependenciesClassPath)
|
||||
|
||||
val sourceDependenciesRoots = refinedConfiguration.value.importedScripts.mapNotNull {
|
||||
// TODO: support any kind of ScriptSource.
|
||||
val path = (it as? FileBasedScriptSource)?.file?.absolutePath ?: return@mapNotNull null
|
||||
KotlinSourceRoot(path, false)
|
||||
val sourceDependencies = refinedConfiguration.value.importedScripts.mapNotNull {
|
||||
if (it is KtFileScriptSource) it.ktFile
|
||||
else {
|
||||
val virtualFileSource = (it as? VirtualFileScriptSource)
|
||||
?: error("expecting script sources resolved to virtual files here")
|
||||
(psiManager.findFile(virtualFileSource.virtualFile) as? KtFile).also {
|
||||
if (it == null) {
|
||||
configuration.report(
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"imported file is not kotlin source: ${virtualFileSource.virtualFile.path}",
|
||||
// TODO: consider receiving and using precise location from the resolver in the future
|
||||
CompilerMessageLocation.create(source.virtualFile.path)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val sourceDependencies =
|
||||
createSourceFilesFromSourceRoots(
|
||||
configuration, project, sourceDependenciesRoots,
|
||||
// TODO: consider receiving and using precise location from the resolver in the future
|
||||
source.virtualFile?.path?.let { CompilerMessageLocation.create(it) }
|
||||
)
|
||||
if (sourceDependencies.isNotEmpty()) {
|
||||
collectedSourceDependencies.add(
|
||||
ScriptsCompilationDependencies.SourceDependencies(
|
||||
|
||||
Reference in New Issue
Block a user