From fbe965be9d6af12202f1a3a74029735de2ce8915 Mon Sep 17 00:00:00 2001 From: Natalia Selezneva Date: Tue, 9 Jul 2019 12:49:44 +0300 Subject: [PATCH] Scripts: pass File finding script definition instead of File.name --- .../idea/core/script/ScriptDefinitionsManager.kt | 14 +++++++------- .../MultipleScriptDefinitionsChecker.kt | 3 ++- .../definitions/KotlinScriptDefinitionProvider.kt | 5 +++-- .../definitions/LazyScriptDefinitionProvider.kt | 15 ++++++++++----- .../scripting/definitions/ScriptDefinition.kt | 6 +++--- .../kotlin/scripting/definitions/definitions.kt | 9 +++++---- .../plugin/JvmCliScriptEvaluationExtension.kt | 3 +-- .../compiler/plugin/ScriptProviderTest.kt | 6 +++++- 8 files changed, 36 insertions(+), 25 deletions(-) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt index f089a19a954..fb530f1d47a 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt @@ -68,25 +68,25 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit private val failedContributorsHashes = HashSet() private val scriptDefinitionsCacheLock = ReentrantReadWriteLock() - private val scriptDefinitionsCache = SLRUMap(10, 10) + private val scriptDefinitionsCache = SLRUMap(10, 10) - override fun findDefinition(fileName: String): ScriptDefinition? { - if (nonScriptFileName(fileName)) return null + override fun findDefinition(file: File): ScriptDefinition? { + if (nonScriptFileName(file.name)) return null if (!isReady()) return null - val cached = scriptDefinitionsCacheLock.write { scriptDefinitionsCache.get(fileName) } + val cached = scriptDefinitionsCacheLock.write { scriptDefinitionsCache.get(file) } if (cached != null) return cached - val definition = super.findDefinition(fileName) ?: return null + val definition = super.findDefinition(file) ?: return null scriptDefinitionsCacheLock.write { - scriptDefinitionsCache.put(fileName, definition) + scriptDefinitionsCache.put(file, definition) } return definition } - override fun findScriptDefinition(fileName: String): KotlinScriptDefinition? = findDefinition(fileName)?.legacyDefinition + override fun findScriptDefinition(fileName: String): KotlinScriptDefinition? = findDefinition(File(fileName))?.legacyDefinition fun reloadDefinitionsBy(source: ScriptDefinitionsSource) = lock.write { if (definitions == null) return // not loaded yet diff --git a/idea/src/org/jetbrains/kotlin/idea/script/configuration/MultipleScriptDefinitionsChecker.kt b/idea/src/org/jetbrains/kotlin/idea/script/configuration/MultipleScriptDefinitionsChecker.kt index 0fa943b1269..26ec4563f29 100644 --- a/idea/src/org/jetbrains/kotlin/idea/script/configuration/MultipleScriptDefinitionsChecker.kt +++ b/idea/src/org/jetbrains/kotlin/idea/script/configuration/MultipleScriptDefinitionsChecker.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.parsing.KotlinParserDefinition import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate +import java.io.File class MultipleScriptDefinitionsChecker(private val project: Project) : EditorNotifications.Provider() { @@ -41,7 +42,7 @@ class MultipleScriptDefinitionsChecker(private val project: Project) : EditorNot val allApplicableDefinitions = ScriptDefinitionsManager.getInstance(project) .getAllDefinitions() .filter { - it.asLegacyOrNull() == null && it.isScript(ktFile.name) && + it.asLegacyOrNull() == null && it.isScript(File(file.path)) && KotlinScriptingSettings.getInstance(project).isScriptDefinitionEnabled(it) } .toList() diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/KotlinScriptDefinitionProvider.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/KotlinScriptDefinitionProvider.kt index 3aacba360bb..22464b19a2e 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/KotlinScriptDefinitionProvider.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/KotlinScriptDefinitionProvider.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.scripting.definitions import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project +import java.io.File interface ScriptDefinitionProvider { @Deprecated("Migrating to configuration refinement", level = DeprecationLevel.ERROR) @@ -15,9 +16,9 @@ interface ScriptDefinitionProvider { @Deprecated("Migrating to configuration refinement", level = DeprecationLevel.ERROR) fun getDefaultScriptDefinition(): KotlinScriptDefinition - fun isScript(fileName: String): Boolean + fun isScript(file: File): Boolean - fun findDefinition(fileName: String): ScriptDefinition? + fun findDefinition(file: File): ScriptDefinition? fun getDefaultDefinition(): ScriptDefinition fun getKnownFilenameExtensions(): Sequence diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/LazyScriptDefinitionProvider.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/LazyScriptDefinitionProvider.kt index f3ac8e21376..8bf58115d46 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/LazyScriptDefinitionProvider.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/LazyScriptDefinitionProvider.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.scripting.definitions import com.intellij.ide.highlighter.JavaFileType import org.jetbrains.kotlin.idea.KotlinFileType +import java.io.File import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.read import kotlin.concurrent.write @@ -44,15 +45,19 @@ abstract class LazyScriptDefinitionProvider : ScriptDefinitionProvider { fileName.endsWith(it, ignoreCase = true) } - override fun findDefinition(fileName: String): ScriptDefinition? = - if (nonScriptFileName(fileName)) null + override fun findDefinition(file: File): ScriptDefinition? = + if (nonScriptFileName(file.name)) null else lock.read { - cachedDefinitions.firstOrNull { it.isScript(fileName) } + cachedDefinitions.firstOrNull { it.isScript(file) } } - override fun findScriptDefinition(fileName: String): KotlinScriptDefinition? = findDefinition(fileName)?.legacyDefinition + override fun findScriptDefinition(fileName: String): KotlinScriptDefinition? = + if (nonScriptFileName(fileName)) null + else lock.read { + cachedDefinitions.map { it.legacyDefinition }.firstOrNull { it.isScript(fileName) } + } - override fun isScript(fileName: String) = findDefinition(fileName) != null + override fun isScript(file: File) = findDefinition(file) != null override fun getKnownFilenameExtensions(): Sequence = lock.read { cachedDefinitions.map { it.fileExtension } diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt index e43aaf1bafd..b001b0c5a14 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt @@ -27,7 +27,7 @@ abstract class ScriptDefinition : UserDataHolderBase() { abstract val compilationConfiguration: ScriptCompilationConfiguration abstract val evaluationConfiguration: ScriptEvaluationConfiguration? - abstract fun isScript(fileName: String): Boolean + abstract fun isScript(file: File): Boolean abstract val fileExtension: String abstract val name: String // TODO: used in settings, find out the reason and refactor accordingly @@ -68,7 +68,7 @@ abstract class ScriptDefinition : UserDataHolderBase() { ) } - override fun isScript(fileName: String): Boolean = legacyDefinition.isScript(fileName) + override fun isScript(file: File): Boolean = legacyDefinition.isScript(file.name) override val fileExtension: String get() = legacyDefinition.fileExtension @@ -116,7 +116,7 @@ abstract class ScriptDefinition : UserDataHolderBase() { ) } - override fun isScript(fileName: String): Boolean = fileName.endsWith(".$fileExtension") + override fun isScript(file: File): Boolean = file.name.endsWith(".$fileExtension") override val fileExtension: String get() = compilationConfiguration[ScriptCompilationConfiguration.fileExtension]!! diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/definitions.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/definitions.kt index 0c48623827b..c1aada73ee4 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/definitions.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/definitions.kt @@ -15,6 +15,7 @@ import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.psi.KtFile +import java.io.File inline fun runReadAction(crossinline runnable: () -> T): T { return ApplicationManager.getApplication().runReadAction(Computable { runnable() }) @@ -26,7 +27,7 @@ fun PsiFile.findScriptDefinition(): ScriptDefinition? { val file = virtualFile ?: originalFile.virtualFile ?: return null if (file.isNonScript()) return null - return findScriptDefinitionByFileName(project, file.name) + return findScriptDefinitionByFilePath(project, File(file.path)) } fun VirtualFile.findScriptDefinition(project: Project): ScriptDefinition? { @@ -37,14 +38,14 @@ fun VirtualFile.findScriptDefinition(project: Project): ScriptDefinition? { if (runReadAction { PsiManager.getInstance(project).findFile(this) as? KtFile }/*?.script*/ == null) return null - return findScriptDefinitionByFileName(project, name) + return findScriptDefinitionByFilePath(project, File(path)) } -fun findScriptDefinitionByFileName(project: Project, fileName: String): ScriptDefinition { +fun findScriptDefinitionByFilePath(project: Project, file: File): ScriptDefinition { val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) ?: return null ?: throw IllegalStateException("Unable to get script definition: ScriptDefinitionProvider is not configured.") - return scriptDefinitionProvider.findDefinition(fileName) ?: scriptDefinitionProvider.getDefaultDefinition() + return scriptDefinitionProvider.findDefinition(file) ?: scriptDefinitionProvider.getDefaultDefinition() } internal fun VirtualFile.isNonScript(): Boolean = diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt index b88de350c08..f96c01e6df5 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/JvmCliScriptEvaluationExtension.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionProvider -import org.jetbrains.kotlin.scripting.definitions.StandardScriptDefinition import java.io.File class JvmCliScriptEvaluationExtension : ScriptEvaluationExtension { @@ -47,7 +46,7 @@ class JvmCliScriptEvaluationExtension : ScriptEvaluationExtension { KotlinCoreEnvironment.createForProduction(projectEnvironment, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) val scriptFile = File(sourcePath) - if (scriptFile.isDirectory || !scriptDefinitionProvider.isScript(scriptFile.name)) { + if (scriptFile.isDirectory || !scriptDefinitionProvider.isScript(scriptFile)) { val extensionHint = if (configuration.get(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS)?.let { it.size == 1 && it.first().isDefault } == true) " (.kts)" else "" diff --git a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptProviderTest.kt b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptProviderTest.kt index 857788ab8ac..933bbb4747f 100644 --- a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptProviderTest.kt +++ b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptProviderTest.kt @@ -8,10 +8,12 @@ package org.jetbrains.kotlin.scripting.compiler.plugin import org.jetbrains.kotlin.scripting.compiler.plugin.definitions.CliScriptDefinitionProvider import org.jetbrains.kotlin.scripting.definitions.KotlinScriptDefinition import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionProvider import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionsSource import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase import org.junit.Assert import org.junit.Test +import java.io.File import java.util.concurrent.atomic.AtomicInteger import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.templates.standard.ScriptTemplateWithArgs @@ -64,13 +66,15 @@ class ScriptProviderTest : KtUsefulTestCase() { Assert.assertEquals(2, genDefCounter.get()) } } + + private fun ScriptDefinitionProvider.isScript(fileName: String) = isScript(File(fileName)) } private open class FakeScriptDefinition(val suffix: String = ".kts") : ScriptDefinition.FromLegacy(defaultJvmScriptingHostConfiguration, KotlinScriptDefinition(ScriptTemplateWithArgs::class)) { val matchCounter = AtomicInteger() - override fun isScript(fileName: String): Boolean = fileName.endsWith(suffix).also { + override fun isScript(file: File): Boolean = file.name.endsWith(suffix).also { if (it) matchCounter.incrementAndGet() }