From 158f7f1cd7b356278fc0e722249ae671d544227e Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Thu, 17 Oct 2019 10:32:56 +0200 Subject: [PATCH] Avoid PsiFile searching when resolving imported scripts descriptors. --- .../scripting/resolve/LazyScriptDescriptor.kt | 44 ++++++++++++------- .../resolve/refineCompilationConfiguration.kt | 11 +++-- .../ScriptsCompilationDependencies.kt | 7 ++- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/LazyScriptDescriptor.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/LazyScriptDescriptor.kt index 0313aca8b94..24fb51ae5b4 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/LazyScriptDescriptor.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/LazyScriptDescriptor.kt @@ -47,6 +47,7 @@ import java.io.File import kotlin.reflect.KClass import kotlin.reflect.KType import kotlin.script.experimental.api.* +import kotlin.script.experimental.host.FileBasedScriptSource import kotlin.script.experimental.host.GetScriptingClass import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.host.getScriptingClass @@ -174,29 +175,40 @@ class LazyScriptDescriptor( override fun computeSupertypes() = listOf(baseClassDescriptor()?.defaultType ?: builtIns.anyType) - // TODO: consider passing ScriptSource to avoid psi file fsearching private inner class ImportedScriptDescriptorsFinder { - val fileManager = VirtualFileManager.getInstance() - val localFS = fileManager.getFileSystem(StandardFileSystems.FILE_PROTOCOL) - val psiManager = PsiManager.getInstance(scriptInfo.script.project) + val localFS by lazy { + val fileManager = VirtualFileManager.getInstance() + fileManager.getFileSystem(StandardFileSystems.FILE_PROTOCOL) + } + val psiManager by lazy { PsiManager.getInstance(scriptInfo.script.project) } - operator fun invoke(importedScriptFile: File): ScriptDescriptor? { + operator fun invoke(importedScript: SourceCode): ScriptDescriptor? { + // Note: is not an error now - if import references other valid source file, it is simply compiled along with script + // TODO: check if this is the behavior we want to have - see #KT-28916 + val ktScript = getKtFile(importedScript)?.declarations?.firstIsInstanceOrNull() + ?: return null + return resolveSession.getScriptDescriptor(ktScript) as ScriptDescriptor + } - fun errorDescriptor(errorDiagnostic: DiagnosticFactory1?): ScriptDescriptor? { - reportErrorString1(errorDiagnostic, importedScriptFile.path) + private fun getKtFile(script: SourceCode): KtFile? { + if (script is KtFileScriptSource) return script.ktFile + + // TODO: support any kind of ScriptSource. + if (script !is FileBasedScriptSource) return null + + fun errorKtFile(errorDiagnostic: DiagnosticFactory1?): KtFile? { + reportErrorString1(errorDiagnostic, script.file.path) return null } - val vfile = localFS.findFileByPath(importedScriptFile.absolutePath) - ?: return errorDescriptor(MISSING_IMPORTED_SCRIPT_FILE) - val psiFile = psiManager.findFile(vfile) - ?: return errorDescriptor(MISSING_IMPORTED_SCRIPT_PSI) - // Note: is not an error now - if import references other valid source file, it is simply compiled along with script - // TODO: check if this is the behavior we want to have - see #KT-28916 - val ktScript = (psiFile as? KtFile)?.declarations?.firstIsInstanceOrNull() - ?: return null - return resolveSession.getScriptDescriptor(ktScript) as ScriptDescriptor + val virtualFile = when (script) { + is VirtualFileScriptSource -> script.virtualFile + else -> localFS.findFileByPath(script.file.absolutePath) ?: return errorKtFile(MISSING_IMPORTED_SCRIPT_FILE) + } + + val psiFile = psiManager.findFile(virtualFile) ?: return errorKtFile(MISSING_IMPORTED_SCRIPT_PSI) + return psiFile as? KtFile } } diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt index 5c9339a2fe5..e06ee476de6 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt @@ -114,7 +114,7 @@ abstract class ScriptCompilationConfigurationWrapper(val script: SourceCode) { abstract val dependenciesSources: List abstract val javaHome: File? abstract val defaultImports: List - abstract val importedScripts: List + abstract val importedScripts: List override fun equals(other: Any?): Boolean = script == (other as? ScriptCompilationConfigurationWrapper)?.script @@ -141,9 +141,8 @@ abstract class ScriptCompilationConfigurationWrapper(val script: SourceCode) { override val defaultImports: List get() = configuration?.get(ScriptCompilationConfiguration.defaultImports).orEmpty() - override val importedScripts: List - get() = configuration?.get(ScriptCompilationConfiguration.importScripts) - ?.mapNotNull { (it as? FileBasedScriptSource)?.file }.orEmpty() + override val importedScripts: List + get() = configuration?.get(ScriptCompilationConfiguration.importScripts).orEmpty() @Suppress("OverridingDeprecatedMember") override val legacyDependencies: ScriptDependencies? @@ -178,8 +177,8 @@ abstract class ScriptCompilationConfigurationWrapper(val script: SourceCode) { override val defaultImports: List get() = legacyDependencies?.imports.orEmpty() - override val importedScripts: List - get() = legacyDependencies?.scripts.orEmpty() + override val importedScripts: List + get() = legacyDependencies?.scripts?.map { FileScriptSource(it) }.orEmpty() override val configuration: ScriptCompilationConfiguration? get() { diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt index 6371f9830c3..01888502958 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider import java.io.File +import kotlin.script.experimental.host.FileBasedScriptSource data class ScriptsCompilationDependencies( val classpath: List, @@ -45,8 +46,10 @@ fun collectScriptsCompilationDependencies( if (refinedConfiguration != null) { collectedClassPath.addAll(refinedConfiguration.dependenciesClassPath) - val sourceDependenciesRoots = refinedConfiguration.importedScripts.map { - KotlinSourceRoot(it.absolutePath, false) + val sourceDependenciesRoots = refinedConfiguration.importedScripts.mapNotNull { + // TODO: support any kind of ScriptSource. + val path = (it as? FileBasedScriptSource)?.file?.path ?: return@mapNotNull null + KotlinSourceRoot(path, false) } val sourceDependencies = createSourceFilesFromSourceRoots(