Change script definition lookup key from File to ScriptSource
to make it more generic and allow easier implementation fo the non-file based scripts.
This commit is contained in:
+3
-3
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.scripting.definitions
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import java.io.File
|
||||
import kotlin.script.experimental.api.SourceCode
|
||||
|
||||
interface ScriptDefinitionProvider {
|
||||
@Deprecated("Migrating to configuration refinement", level = DeprecationLevel.ERROR)
|
||||
@@ -16,9 +16,9 @@ interface ScriptDefinitionProvider {
|
||||
@Deprecated("Migrating to configuration refinement", level = DeprecationLevel.ERROR)
|
||||
fun getDefaultScriptDefinition(): KotlinScriptDefinition
|
||||
|
||||
fun isScript(file: File): Boolean
|
||||
fun isScript(script: SourceCode): Boolean
|
||||
|
||||
fun findDefinition(file: File): ScriptDefinition?
|
||||
fun findDefinition(script: SourceCode): ScriptDefinition?
|
||||
fun getDefaultDefinition(): ScriptDefinition
|
||||
|
||||
fun getKnownFilenameExtensions(): Sequence<String>
|
||||
|
||||
+13
-9
@@ -7,10 +7,11 @@ package org.jetbrains.kotlin.scripting.definitions
|
||||
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
import kotlin.script.experimental.api.SourceCode
|
||||
import kotlin.script.experimental.host.ScriptingHostConfiguration
|
||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||
|
||||
@@ -25,6 +26,8 @@ abstract class LazyScriptDefinitionProvider : ScriptDefinitionProvider {
|
||||
override fun getDefaultDefinition(): ScriptDefinition =
|
||||
ScriptDefinition.getDefault(getScriptingHostConfiguration())
|
||||
|
||||
protected val fixedDefinitions: HashMap<URI, ScriptDefinition> = HashMap()
|
||||
|
||||
private var _cachedDefinitions: Sequence<ScriptDefinition>? = null
|
||||
private val cachedDefinitions: Sequence<ScriptDefinition>
|
||||
get() {
|
||||
@@ -41,23 +44,24 @@ abstract class LazyScriptDefinitionProvider : ScriptDefinitionProvider {
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun nonScriptFileName(fileName: String) = nonScriptFilenameSuffixes.any {
|
||||
fileName.endsWith(it, ignoreCase = true)
|
||||
}
|
||||
protected open fun nonScriptId(locationId: String): Boolean =
|
||||
nonScriptFilenameSuffixes.any {
|
||||
locationId.endsWith(it, ignoreCase = true)
|
||||
}
|
||||
|
||||
override fun findDefinition(file: File): ScriptDefinition? =
|
||||
if (nonScriptFileName(file.name)) null
|
||||
override fun findDefinition(script: SourceCode): ScriptDefinition? =
|
||||
if (script.locationId == null || nonScriptId(script.locationId!!)) null
|
||||
else lock.read {
|
||||
cachedDefinitions.firstOrNull { it.isScript(file) }
|
||||
cachedDefinitions.firstOrNull { it.isScript(script) }
|
||||
}
|
||||
|
||||
override fun findScriptDefinition(fileName: String): KotlinScriptDefinition? =
|
||||
if (nonScriptFileName(fileName)) null
|
||||
if (nonScriptId(fileName)) null
|
||||
else lock.read {
|
||||
cachedDefinitions.map { it.legacyDefinition }.firstOrNull { it.isScript(fileName) }
|
||||
}
|
||||
|
||||
override fun isScript(file: File) = findDefinition(file) != null
|
||||
override fun isScript(script: SourceCode): Boolean = findDefinition(script) != null
|
||||
|
||||
override fun getKnownFilenameExtensions(): Sequence<String> = lock.read {
|
||||
cachedDefinitions.map { it.fileExtension }
|
||||
|
||||
+8
-7
@@ -28,7 +28,7 @@ abstract class ScriptDefinition : UserDataHolderBase() {
|
||||
abstract val compilationConfiguration: ScriptCompilationConfiguration
|
||||
abstract val evaluationConfiguration: ScriptEvaluationConfiguration?
|
||||
|
||||
abstract fun isScript(file: File): Boolean
|
||||
abstract fun isScript(script: SourceCode): Boolean
|
||||
abstract val fileExtension: String
|
||||
abstract val name: String
|
||||
open val defaultClassName: String = "Script"
|
||||
@@ -75,7 +75,7 @@ abstract class ScriptDefinition : UserDataHolderBase() {
|
||||
)
|
||||
}
|
||||
|
||||
override fun isScript(file: File): Boolean = legacyDefinition.isScript(file.name)
|
||||
override fun isScript(script: SourceCode): Boolean = script.name?.let { legacyDefinition.isScript(it) } ?: isDefault
|
||||
|
||||
override val fileExtension: String get() = legacyDefinition.fileExtension
|
||||
|
||||
@@ -130,11 +130,12 @@ abstract class ScriptDefinition : UserDataHolderBase() {
|
||||
compilationConfiguration[ScriptCompilationConfiguration.filePathPattern]?.takeIf { it.isNotBlank() }
|
||||
}
|
||||
|
||||
override fun isScript(file: File): Boolean =
|
||||
file.name.endsWith(".$fileExtension") &&
|
||||
(filePathPattern?.let {
|
||||
Regex(it).matches(FileUtilRt.toSystemIndependentName(file.path))
|
||||
} ?: true)
|
||||
override fun isScript(script: SourceCode): Boolean {
|
||||
val location = script.locationId ?: return false
|
||||
return location.endsWith(".$fileExtension") && filePathPattern?.let {
|
||||
Regex(it).matches(FileUtilRt.toSystemIndependentName(location))
|
||||
} != false
|
||||
}
|
||||
|
||||
override val fileExtension: String get() = compilationConfiguration[ScriptCompilationConfiguration.fileExtension]!!
|
||||
|
||||
|
||||
+7
-5
@@ -16,7 +16,9 @@ import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
import org.jetbrains.kotlin.scripting.resolve.KtFileScriptSource
|
||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||
import kotlin.script.experimental.api.SourceCode
|
||||
|
||||
inline fun <T> runReadAction(crossinline runnable: () -> T): T {
|
||||
return ApplicationManager.getApplication().runReadAction(Computable { runnable() })
|
||||
@@ -29,7 +31,7 @@ fun PsiFile.findScriptDefinition(): ScriptDefinition? {
|
||||
val virtualFile = this.virtualFile ?: this.originalFile.virtualFile ?: return null
|
||||
if (virtualFile.isNonScript()) return null
|
||||
|
||||
return findScriptDefinitionByFilePath(project, File(virtualFile.path))
|
||||
return findScriptDefinition(project, KtFileScriptSource(this))
|
||||
}
|
||||
|
||||
@Deprecated("Use PsiFile.findScriptDefinition() instead")
|
||||
@@ -41,14 +43,14 @@ fun VirtualFile.findScriptDefinition(project: Project): ScriptDefinition? {
|
||||
// TODO: measure performance effect and if necessary consider detecting indexing here or using separate logic for non-IDE operations to speed up filtering
|
||||
if (runReadAction { PsiManager.getInstance(project).findFile(this) as? KtFile }/*?.script*/ == null) return null
|
||||
|
||||
return findScriptDefinitionByFilePath(project, File(path))
|
||||
return findScriptDefinition(project, VirtualFileScriptSource(this))
|
||||
}
|
||||
|
||||
private fun findScriptDefinitionByFilePath(project: Project, file: File): ScriptDefinition {
|
||||
fun findScriptDefinition(project: Project, script: SourceCode): ScriptDefinition? {
|
||||
val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) ?: return null
|
||||
?: throw IllegalStateException("Unable to get script definition: ScriptDefinitionProvider is not configured.")
|
||||
|
||||
return scriptDefinitionProvider.findDefinition(file) ?: scriptDefinitionProvider.getDefaultDefinition()
|
||||
return scriptDefinitionProvider.findDefinition(script) ?: scriptDefinitionProvider.getDefaultDefinition()
|
||||
}
|
||||
|
||||
fun VirtualFile.isNonScript(): Boolean =
|
||||
|
||||
Reference in New Issue
Block a user