Skip to content

Commit e3e6c90

Browse files
feat!: update API to 0.25
1 parent 5722cf0 commit e3e6c90

File tree

30 files changed

+763
-191
lines changed

30 files changed

+763
-191
lines changed

ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/LanguageTest.kt

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package io.github.treesitter.ktreesitter
22

33
import br.com.colman.kotest.KotestRunnerAndroid
44
import io.github.treesitter.ktreesitter.java.TreeSitterJava
5-
import io.kotest.assertions.throwables.shouldNotThrowAny
65
import io.kotest.core.spec.style.FunSpec
76
import io.kotest.matchers.*
7+
import io.kotest.matchers.collections.shouldBeEmpty
88
import io.kotest.matchers.comparables.*
99
import io.kotest.matchers.nulls.*
1010
import io.kotest.matchers.string.*
@@ -15,8 +15,8 @@ import org.junit.runner.RunWith
1515
class LanguageTest : FunSpec({
1616
val language = Language(TreeSitterJava.language())
1717

18-
test("version") {
19-
language.version shouldBe 14U
18+
test("abiVersion") {
19+
language.abiVersion shouldBe 14U
2020
}
2121

2222
test("symbolCount") {
@@ -31,6 +31,19 @@ class LanguageTest : FunSpec({
3131
language.fieldCount shouldBeGreaterThan 1U
3232
}
3333

34+
test("name") {
35+
language.name.shouldBeNull()
36+
}
37+
38+
test("metadata") {
39+
language.metadata.shouldBeNull()
40+
}
41+
42+
@OptIn(ExperimentalUnsignedTypes::class)
43+
test("supertypes") {
44+
language.supertypes.shouldBeEmpty()
45+
}
46+
3447
test("symbolName()") {
3548
language.symbolName(1U) shouldBe "identifier"
3649
}
@@ -40,6 +53,11 @@ class LanguageTest : FunSpec({
4053
language.symbolForName("program", true) shouldBeGreaterThan 0U
4154
}
4255

56+
@OptIn(ExperimentalUnsignedTypes::class)
57+
test("subtypes") {
58+
language.subtypes(1U).shouldBeEmpty()
59+
}
60+
4361
test("isNamed()") {
4462
language.isNamed(1U) shouldBe true
4563
}
@@ -72,10 +90,6 @@ class LanguageTest : FunSpec({
7290
lookahead.language shouldBe language
7391
}
7492

75-
test("query()") {
76-
shouldNotThrowAny { language.query("(program) @root") }
77-
}
78-
7993
test("equals()") {
8094
Language(TreeSitterJava.language()) shouldBe language.copy()
8195
}
@@ -85,6 +99,6 @@ class LanguageTest : FunSpec({
8599
}
86100

87101
test("toString()") {
88-
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, version=14\)""")
102+
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, abiVersion=14\)""")
89103
}
90104
})

ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/NodeTest.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ class NodeTest : FunSpec({
149149
shouldThrow<IndexOutOfBoundsException> { rootNode.namedChild(1U) }
150150
}
151151

152+
test("firstChildForByte()") {
153+
rootNode.firstChildForByte(10U)!!.type shouldBe "class_declaration"
154+
}
155+
156+
test("firstNamedChildForByte()") {
157+
rootNode.firstNamedChildForByte(10U)!!.type shouldBe "class_declaration"
158+
}
159+
152160
test("childByFieldId()") {
153161
rootNode.childByFieldId(0U).shouldBeNull()
154162
}
@@ -177,13 +185,6 @@ class NodeTest : FunSpec({
177185
rootNode.child(0U)!!.fieldNameForNamedChild(2U).shouldBeNull()
178186
}
179187

180-
@Suppress("DEPRECATION")
181-
test("childContainingDescendant()") {
182-
val descendant = rootNode.child(0U)!!.child(0U)!!
183-
val child = rootNode.childContainingDescendant(descendant)
184-
child?.type shouldBe "class_declaration"
185-
}
186-
187188
test("childWithDescendant()") {
188189
val descendant = rootNode.child(0U)!!
189190
val child = rootNode.childWithDescendant(descendant)

ktreesitter/src/androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter/ParserTest.kt

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ class ParserTest : FunSpec({
3030
parser.includedRanges shouldHaveSingleElement range
3131
}
3232

33-
test("timeoutMicros") {
34-
parser.timeoutMicros shouldBe 0UL
35-
parser.timeoutMicros = 10000UL
36-
parser.timeoutMicros shouldBe 10000UL
37-
}
38-
3933
test("logger") {
4034
shouldNotThrowAnyUnit {
4135
parser.logger = { _, _ ->
@@ -61,12 +55,12 @@ class ParserTest : FunSpec({
6155
}
6256

6357
// UTF-16
64-
source = "var java = \"💩\""
65-
tree = parser.parse(source)
66-
tree.text()?.subSequence(12, 14) shouldBe "\uD83D\uDCA9"
58+
source = "\uFEFFvar java = \"💩\""
59+
tree = parser.parse(source, encoding = InputEncoding.UTF_16BE)
60+
tree.text()?.subSequence(13, 15) shouldBe "\uD83D\uDCA9"
6761
}
6862

69-
test("parse(callback)") {
63+
test("parse(readCallback)") {
7064
val source = "class Foo {}"
7165
val tree = parser.parse { byte, _ ->
7266
val end = minOf(byte.toInt() * 2, source.length)
@@ -79,7 +73,6 @@ class ParserTest : FunSpec({
7973
afterTest { (test, _) ->
8074
when (test.name.testName) {
8175
"includedRanges" -> parser.includedRanges = emptyList()
82-
"timeoutMicros" -> parser.timeoutMicros = 0UL
8376
"logger" -> parser.logger = null
8477
}
8578
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.github.treesitter.ktreesitter
2+
3+
import java.nio.charset.Charset
4+
5+
/**
6+
* The encoding of the input text.
7+
*
8+
* @since 0.25.0
9+
*/
10+
actual enum class InputEncoding(val charset: Charset) {
11+
UTF_8(Charsets.UTF_8),
12+
UTF_16LE(Charsets.UTF_16LE),
13+
UTF_16BE(Charsets.UTF_16BE)
14+
}

ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Language.kt

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import dalvik.annotation.optimization.FastNative
66
/**
77
* A class that defines how to parse a particular language.
88
*
9-
* When a [Language] is generated by the Tree-sitter CLI, it is assigned
10-
* an ABI [version] number that corresponds to the current CLI version.
9+
* When a [Language] is generated by the Tree-sitter CLI, it is assigned an
10+
* [ABI version][abiVersion] number that corresponds to the current CLI version.
1111
*
1212
* @constructor Create a new instance from the given language pointer.
1313
* @param language A pointer to a `TSLanguage` cast to [Long].
14-
* @throws [IllegalArgumentException] If the pointer is invalid or the [version] is incompatible.
14+
* @throws [IllegalArgumentException]
15+
* If the pointer is invalid or the [version][abiVersion] is incompatible.
1516
*/
1617
actual class Language @Throws(IllegalArgumentException::class) actual constructor(language: Any) {
1718
@JvmField
@@ -22,7 +23,17 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
2223
checkVersion()
2324
}
2425

26+
/**
27+
* The ABI version number for this language.
28+
*
29+
* @since 0.25.0
30+
*/
31+
@get:JvmName("getAbiVersion")
32+
actual val abiVersion: UInt
33+
@FastNative external get
34+
2535
/** The ABI version number for this language. */
36+
@Deprecated("version is deprecated", ReplaceWith("abiVersion"), DeprecationLevel.ERROR)
2637
@get:JvmName("getVersion")
2738
actual val version: UInt
2839
@FastNative external get
@@ -42,6 +53,32 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
4253
actual val fieldCount: UInt
4354
@FastNative external get
4455

56+
/**
57+
* The name of the language, if available.
58+
*
59+
* @since 0.25.0
60+
*/
61+
actual val name: String?
62+
@FastNative external get
63+
64+
/**
65+
* The metadata of the language, if available.
66+
*
67+
* @since 0.25.0
68+
*/
69+
actual val metadata: Metadata?
70+
@FastNative external get
71+
72+
/**
73+
* The supertype symbols of the language.
74+
*
75+
* @since 0.25.0
76+
*/
77+
@OptIn(ExperimentalUnsignedTypes::class)
78+
@get:JvmName("getSupertypes")
79+
actual val supertypes: UShortArray
80+
@FastNative external get
81+
4582
/**
4683
* Get another reference to the language.
4784
*
@@ -59,6 +96,17 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
5996
@JvmName("symbolForName")
6097
actual external fun symbolForName(name: String, isNamed: Boolean): UShort
6198

99+
/**
100+
* Get the subtype symbols for the given supertype symbol
101+
*
102+
* @since 0.25.0
103+
* @see supertypes
104+
*/
105+
@FastNative
106+
@JvmName("subtypes")
107+
@OptIn(ExperimentalUnsignedTypes::class)
108+
actual external fun subtypes(supertype: UShort): UShortArray
109+
62110
/**
63111
* Check if the node for the given numerical ID is named
64112
*
@@ -119,24 +167,46 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
119167

120168
/**
121169
* Create a new [Query] from a string containing one or more S-expression
122-
* [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax).
170+
* [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html).
123171
*
124172
* @throws [QueryError] If any error occurred while creating the query.
125173
*/
126174
@Throws(QueryError::class)
175+
@Deprecated("Use the Query constructor instead")
127176
actual fun query(source: String) = Query(this, source)
128177

129178
actual override fun equals(other: Any?) =
130179
this === other || (other is Language && self == other.self)
131180

132181
actual override fun hashCode() = self.hashCode()
133182

134-
override fun toString() = "Language(id=0x${self.toString(16)}, version=$version)"
183+
override fun toString() = "Language(id=0x${self.toString(16)}, abiVersion=$abiVersion)"
135184

136185
@FastNative
137186
@Throws(IllegalArgumentException::class)
138187
private external fun checkVersion()
139188

189+
/**
190+
* A class containing the [Language] metadata.
191+
*
192+
* @property semanticVersion The [Semantic Version](https://semver.org/) of the [Language].
193+
*/
194+
@ConsistentCopyVisibility
195+
actual data class Metadata internal actual constructor(
196+
@get:JvmName("getSemanticVersion")
197+
actual val semanticVersion: Triple<UShort, UShort, UShort>
198+
) {
199+
actual override fun toString() = buildString {
200+
append("Metadata(semanticVersion=\"")
201+
append(semanticVersion.first)
202+
append('.')
203+
append(semanticVersion.second)
204+
append('.')
205+
append(semanticVersion.third)
206+
append("\")")
207+
}
208+
}
209+
140210
private companion object {
141211
@JvmStatic
142212
@CriticalNative

ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Node.kt

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,26 @@ actual class Node internal constructor(
207207
@Throws(IndexOutOfBoundsException::class)
208208
actual external fun namedChild(index: UInt): Node?
209209

210+
/**
211+
* Get the node's first child that contains
212+
* or starts after the given byte offset.
213+
*
214+
* @since 0.25.0
215+
*/
216+
@FastNative
217+
@JvmName("firstChildForByte")
218+
actual external fun firstChildForByte(byte: UInt): Node?
219+
220+
/**
221+
* Get the node's first _named_ child that contains
222+
* or starts after the given byte offset.
223+
*
224+
* @since 0.25.0
225+
*/
226+
@FastNative
227+
@JvmName("firstNamedChildForByte")
228+
actual external fun firstNamedChildForByte(byte: UInt): Node?
229+
210230
/**
211231
* Get the node's child with the given field ID, if any.
212232
*
@@ -249,14 +269,6 @@ actual class Node internal constructor(
249269
@Throws(IndexOutOfBoundsException::class)
250270
actual external fun fieldNameForNamedChild(index: UInt): String?
251271

252-
/** Get the child of the node that contains the given descendant, if any. */
253-
@FastNative
254-
@Deprecated(
255-
"This method will not return a direct descendant",
256-
ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
257-
)
258-
actual external fun childContainingDescendant(descendant: Node): Node?
259-
260272
/**
261273
* Get the node that contains the given descendant, if any.
262274
*

ktreesitter/src/androidMain/kotlin/io/github/treesitter/ktreesitter/Parser.kt

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ actual class Parser actual constructor() : AutoCloseable {
5050
*/
5151
@get:JvmName("getTimeoutMicros")
5252
@set:JvmName("setTimeoutMicros")
53+
@Deprecated("Use the progressCallback in parse()")
5354
actual var timeoutMicros: ULong
5455
@FastNative external get
5556

@@ -82,11 +83,10 @@ actual class Parser actual constructor() : AutoCloseable {
8283
* [Tree.edit] method in a way that exactly matches the source code changes.
8384
*
8485
* @throws [IllegalStateException]
85-
* If the parser does not have a [language] assigned or
86-
* if parsing was cancelled due to a [timeout][timeoutMicros].
86+
* If the parser does not have a [language] assigned or if parsing was halted.
8787
*/
8888
@Throws(IllegalStateException::class)
89-
actual external fun parse(source: String, oldTree: Tree?): Tree
89+
actual external fun parse(source: String, encoding: InputEncoding, oldTree: Tree?): Tree
9090

9191
/**
9292
* Parse source code from a callback and create a syntax tree.
@@ -98,19 +98,22 @@ actual class Parser actual constructor() : AutoCloseable {
9898
* [Tree.edit] method in a way that exactly matches the source code changes.
9999
*
100100
* @throws [IllegalStateException]
101-
* If the parser does not have a [language] assigned or
102-
* if parsing was cancelled due to a [timeout][timeoutMicros].
101+
* If the parser does not have a [language] assigned or if parsing was halted.
103102
*/
104103
@Throws(IllegalStateException::class)
105-
actual external fun parse(oldTree: Tree?, callback: ParseCallback): Tree
104+
actual external fun parse(
105+
encoding: InputEncoding,
106+
oldTree: Tree?,
107+
progressCallback: ParseProgressCallback?,
108+
readCallback: ParseReadCallback
109+
): Tree
106110

107111
/**
108112
* Instruct the parser to start the next [parse] from the beginning.
109113
*
110-
* If the parser previously failed because of a [timeout][timeoutMicros],
111-
* then by default, it will resume where it left off. If you don't
112-
* want to resume, and instead intend to use this parser to parse
113-
* some other document, you must call this method first.
114+
* If parsing was previously halted, then by default, it will resume where
115+
* it left off. If you don't want to resume, and instead intend to use this
116+
* parser to parse some other document, you must call this method first.
114117
*/
115118
@FastNative
116119
actual external fun reset()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.github.treesitter.ktreesitter
2+
3+
/**
4+
* The encoding of the input text.
5+
*
6+
* @since 0.25.0
7+
*/
8+
expect enum class InputEncoding { UTF_8, UTF_16LE, UTF_16BE }

0 commit comments

Comments
 (0)