0
# Source Code Representation
1
2
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.
3
4
## Capabilities
5
6
### SourceCode Interface
7
8
Primary interface for representing script source code with text content and optional metadata.
9
10
```kotlin { .api }
11
/**
12
* Represents script source code with text content and metadata
13
*/
14
interface SourceCode {
15
/** The actual script source text */
16
val text: String
17
/** Optional human-readable name for the source */
18
val name: String?
19
/** Optional unique identifier for the source location */
20
val locationId: String?
21
}
22
```
23
24
### ExternalSourceCode Interface
25
26
Extension of SourceCode for representing scripts loaded from external sources like files or URLs.
27
28
```kotlin { .api }
29
/**
30
* Source code loaded from an external location
31
*/
32
interface ExternalSourceCode : SourceCode {
33
/** External location URL */
34
val externalLocation: URL
35
}
36
```
37
38
### Source Code Location Types
39
40
Nested classes within SourceCode for representing positions and ranges within script text.
41
42
```kotlin { .api }
43
/**
44
* Position within source code
45
*/
46
data class Position(
47
val line: Int,
48
val col: Int,
49
val absolutePos: Int? = null
50
)
51
52
/**
53
* Range within source code
54
*/
55
data class Range(
56
val start: Position,
57
val end: Position
58
)
59
60
/**
61
* Location within source code
62
*/
63
data class Location(
64
val start: Position,
65
val end: Position? = null
66
)
67
68
/**
69
* Location with source identifier
70
*/
71
data class LocationWithId(
72
val codeLocationId: String,
73
val locationInText: Location
74
)
75
```
76
77
### Built-in Source Code Implementations
78
79
Ready-to-use implementations for common source scenarios.
80
81
```kotlin { .api }
82
/**
83
* Abstract base for file-based script sources
84
*/
85
abstract class FileBasedScriptSource : ExternalSourceCode {
86
abstract val file: File
87
override val text: String get() = file.readText()
88
override val name: String? get() = file.name
89
override val locationId: String? get() = file.absolutePath
90
}
91
92
/**
93
* Script source from a file
94
*/
95
class FileScriptSource(
96
override val file: File,
97
private val preloadedText: String? = null
98
) : FileBasedScriptSource() {
99
override val externalLocation: URL get() = file.toURI().toURL()
100
override val text: String by lazy { preloadedText ?: file.readText() }
101
}
102
103
/**
104
* Script source from a URL
105
*/
106
class UrlScriptSource(override val externalLocation: URL) : ExternalSourceCode {
107
override val text: String by lazy { externalLocation.readText() }
108
override val name: String? get() = externalLocation.file
109
override val locationId: String? get() = externalLocation.toString()
110
}
111
112
/**
113
* Script source from a string
114
*/
115
class StringScriptSource(
116
override val text: String,
117
override val name: String? = null
118
) : SourceCode {
119
override val locationId: String? = name
120
}
121
```
122
123
### Extension Functions
124
125
Convenient extension functions for creating SourceCode instances from common types.
126
127
```kotlin { .api }
128
/**
129
* Convert a File to SourceCode
130
*/
131
fun File.toScriptSource(): FileScriptSource
132
133
/**
134
* Convert a String to SourceCode
135
* @param name Optional name for the source
136
*/
137
fun String.toScriptSource(name: String? = null): StringScriptSource
138
```
139
140
**Usage Examples:**
141
142
```kotlin
143
import kotlin.script.experimental.host.*
144
145
// Create source from string
146
val stringSource = "println(\"Hello World\")".toScriptSource("hello.kts")
147
148
// Create source from file
149
val fileSource = File("script.kts").toScriptSource()
150
151
// Create source from URL
152
val url = URL("https://example.com/script.kts")
153
val urlText = url.readText()
154
val urlSource = UrlScriptSource(url, urlText)
155
156
// Access source properties
157
println("Source name: ${stringSource.name}")
158
println("Source text: ${stringSource.text}")
159
println("Location ID: ${stringSource.locationId}")
160
161
// Working with external sources
162
if (fileSource is ExternalSourceCode) {
163
println("External location: ${fileSource.externalLocation}")
164
}
165
```
166
167
### Source Code Fragments and Annotations
168
169
Support for associating metadata and annotations with source code sections.
170
171
```kotlin { .api }
172
/**
173
* Named fragment within source code
174
*/
175
data class ScriptSourceNamedFragment(
176
val name: String?,
177
val range: SourceCode.Range
178
)
179
180
/**
181
* Source annotation with associated data
182
*/
183
data class ScriptSourceAnnotation<out A : Annotation>(
184
val annotation: A,
185
val location: SourceCode.LocationWithId?
186
)
187
```
188
189
### Location Utilities
190
191
Helper functions for working with source code positions and ranges.
192
193
```kotlin
194
// Create position
195
val position = SourceCode.Position(line = 1, col = 10, absolutePos = 10)
196
197
// Create range
198
val range = SourceCode.Range(
199
start = SourceCode.Position(1, 0),
200
end = SourceCode.Position(1, 20)
201
)
202
203
// Create location
204
val location = SourceCode.Location(
205
start = SourceCode.Position(1, 0),
206
end = SourceCode.Position(3, 15)
207
)
208
209
// Create location with ID
210
val locationWithId = SourceCode.LocationWithId(
211
locationId = "script.kts",
212
location = location
213
)
214
```
215
216
### Custom Source Implementations
217
218
Creating custom SourceCode implementations for specialized scenarios:
219
220
```kotlin
221
class DatabaseScriptSource(
222
private val scriptId: String,
223
private val database: Database
224
) : ExternalSourceCode {
225
override val text: String by lazy { database.getScript(scriptId) }
226
override val name: String? = "script_$scriptId"
227
override val locationId: String? = "db:$scriptId"
228
override val externalLocation: String? = "database://scripts/$scriptId"
229
}
230
231
class MemoryScriptSource(
232
override val text: String,
233
override val name: String
234
) : SourceCode {
235
override val locationId: String? = "memory:$name"
236
}
237
```