Core interfaces and data structures for Kotlin script compilation, evaluation, and IDE integration
—
Core interfaces and implementations for representing script source code with location information, external source support, and file-based utilities. These types provide the foundation for all script processing operations.
Primary interface for representing script source code with text content and optional metadata.
/**
* Represents script source code with text content and metadata
*/
interface SourceCode {
/** The actual script source text */
val text: String
/** Optional human-readable name for the source */
val name: String?
/** Optional unique identifier for the source location */
val locationId: String?
}Extension of SourceCode for representing scripts loaded from external sources like files or URLs.
/**
* Source code loaded from an external location
*/
interface ExternalSourceCode : SourceCode {
/** External location URL */
val externalLocation: URL
}Nested classes within SourceCode for representing positions and ranges within script text.
/**
* Position within source code
*/
data class Position(
val line: Int,
val col: Int,
val absolutePos: Int? = null
)
/**
* Range within source code
*/
data class Range(
val start: Position,
val end: Position
)
/**
* Location within source code
*/
data class Location(
val start: Position,
val end: Position? = null
)
/**
* Location with source identifier
*/
data class LocationWithId(
val codeLocationId: String,
val locationInText: Location
)Ready-to-use implementations for common source scenarios.
/**
* Abstract base for file-based script sources
*/
abstract class FileBasedScriptSource : ExternalSourceCode {
abstract val file: File
override val text: String get() = file.readText()
override val name: String? get() = file.name
override val locationId: String? get() = file.absolutePath
}
/**
* Script source from a file
*/
class FileScriptSource(
override val file: File,
private val preloadedText: String? = null
) : FileBasedScriptSource() {
override val externalLocation: URL get() = file.toURI().toURL()
override val text: String by lazy { preloadedText ?: file.readText() }
}
/**
* Script source from a URL
*/
class UrlScriptSource(override val externalLocation: URL) : ExternalSourceCode {
override val text: String by lazy { externalLocation.readText() }
override val name: String? get() = externalLocation.file
override val locationId: String? get() = externalLocation.toString()
}
/**
* Script source from a string
*/
class StringScriptSource(
override val text: String,
override val name: String? = null
) : SourceCode {
override val locationId: String? = name
}Convenient extension functions for creating SourceCode instances from common types.
/**
* Convert a File to SourceCode
*/
fun File.toScriptSource(): FileScriptSource
/**
* Convert a String to SourceCode
* @param name Optional name for the source
*/
fun String.toScriptSource(name: String? = null): StringScriptSourceUsage Examples:
import kotlin.script.experimental.host.*
// Create source from string
val stringSource = "println(\"Hello World\")".toScriptSource("hello.kts")
// Create source from file
val fileSource = File("script.kts").toScriptSource()
// Create source from URL
val url = URL("https://example.com/script.kts")
val urlText = url.readText()
val urlSource = UrlScriptSource(url, urlText)
// Access source properties
println("Source name: ${stringSource.name}")
println("Source text: ${stringSource.text}")
println("Location ID: ${stringSource.locationId}")
// Working with external sources
if (fileSource is ExternalSourceCode) {
println("External location: ${fileSource.externalLocation}")
}Support for associating metadata and annotations with source code sections.
/**
* Named fragment within source code
*/
data class ScriptSourceNamedFragment(
val name: String?,
val range: SourceCode.Range
)
/**
* Source annotation with associated data
*/
data class ScriptSourceAnnotation<out A : Annotation>(
val annotation: A,
val location: SourceCode.LocationWithId?
)Helper functions for working with source code positions and ranges.
// Create position
val position = SourceCode.Position(line = 1, col = 10, absolutePos = 10)
// Create range
val range = SourceCode.Range(
start = SourceCode.Position(1, 0),
end = SourceCode.Position(1, 20)
)
// Create location
val location = SourceCode.Location(
start = SourceCode.Position(1, 0),
end = SourceCode.Position(3, 15)
)
// Create location with ID
val locationWithId = SourceCode.LocationWithId(
locationId = "script.kts",
location = location
)Creating custom SourceCode implementations for specialized scenarios:
class DatabaseScriptSource(
private val scriptId: String,
private val database: Database
) : ExternalSourceCode {
override val text: String by lazy { database.getScript(scriptId) }
override val name: String? = "script_$scriptId"
override val locationId: String? = "db:$scriptId"
override val externalLocation: String? = "database://scripts/$scriptId"
}
class MemoryScriptSource(
override val text: String,
override val name: String
) : SourceCode {
override val locationId: String? = "memory:$name"
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-scripting-common