Skip to content

Commit fc91e6e

Browse files
feat: implement Language.copy
1 parent e194f0e commit fc91e6e

File tree

7 files changed

+62
-15
lines changed

7 files changed

+62
-15
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ class LanguageTest : FunSpec({
7777
}
7878

7979
test("equals()") {
80-
Language(TreeSitterJava.language()) shouldBe Language(TreeSitterJava.language())
80+
Language(TreeSitterJava.language()) shouldBe language.copy()
8181
}
8282

8383
test("hashCode()") {
8484
language shouldHaveSameHashCodeAs TreeSitterJava.language()
8585
}
8686

8787
test("toString()") {
88-
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-z]+, version=14\)""")
88+
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, version=14\)""")
8989
}
9090
})

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.treesitter.ktreesitter
22

3+
import dalvik.annotation.optimization.CriticalNative
34
import dalvik.annotation.optimization.FastNative
45

56
/**
@@ -41,6 +42,13 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
4142
actual val fieldCount: UInt
4243
@FastNative external get
4344

45+
/**
46+
* Get another reference to the language.
47+
*
48+
* @since 0.24.0
49+
*/
50+
actual fun copy() = Language(copy(self))
51+
4452
/** Get the node type for the given numerical ID. */
4553
@FastNative
4654
@JvmName("symbolName")
@@ -130,6 +138,10 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
130138
private external fun checkVersion()
131139

132140
private companion object {
141+
@JvmStatic
142+
@CriticalNative
143+
private external fun copy(self: Long): Long
144+
133145
init {
134146
System.loadLibrary("ktreesitter")
135147
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ expect class Language @Throws(IllegalArgumentException::class) constructor(langu
2222
/** The number of distinct field names in this language. */
2323
val fieldCount: UInt
2424

25+
/**
26+
* Get another reference to the language.
27+
*
28+
* @since 0.24.0
29+
*/
30+
fun copy(): Language
31+
2532
/** Get the node type for the given numerical ID. */
2633
fun symbolName(symbol: UShort): String?
2734

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@ class LanguageTest : FunSpec({
7474
}
7575

7676
test("equals()") {
77-
Language(TreeSitterJava.language()) shouldBe Language(TreeSitterJava.language())
77+
Language(TreeSitterJava.language()) shouldBe language.copy()
7878
}
7979

8080
test("hashCode()") {
8181
language shouldHaveSameHashCodeAs TreeSitterJava.language()
8282
}
8383

8484
test("toString()") {
85-
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-z]+, version=14\)""")
85+
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, version=14\)""")
8686
}
8787
})

ktreesitter/src/jni/language.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include "utils.h"
22

3+
jlong JNICALL language_copy CRITICAL_ARGS(jlong self) {
4+
return (jlong)ts_language_copy((TSLanguage *)self);
5+
}
6+
37
jint JNICALL language_get_version(JNIEnv *env, jobject this) {
48
TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
59
return (jint)ts_language_version(self);
@@ -88,6 +92,7 @@ void JNICALL language_check_version(JNIEnv *env, jobject this) {
8892
}
8993

9094
const JNINativeMethod Language_methods[] = {
95+
{"copy", "(J)J", (void *)&language_copy},
9196
{"getVersion", "()I", (void *)&language_get_version},
9297
{"getSymbolCount", "()I", (void *)&language_get_symbol_count},
9398
{"getStateCount", "()I", (void *)&language_get_state_count},

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
3939
actual val fieldCount: UInt
4040
external get
4141

42+
/**
43+
* Get another reference to the language.
44+
*
45+
* @since 0.24.0
46+
*/
47+
actual fun copy() = Language(copy(self))
48+
4249
/** Get the node type for the given numerical ID. */
4350
@JvmName("symbolName")
4451
actual external fun symbolName(symbol: UShort): String?
@@ -119,6 +126,9 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
119126
private external fun checkVersion()
120127

121128
private companion object {
129+
@JvmStatic
130+
private external fun copy(self: Long): Long
131+
122132
init {
123133
NativeUtils.loadLibrary()
124134
}

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

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,22 @@ import kotlinx.cinterop.*
99
*
1010
* When a [Language] is generated by the Tree-sitter CLI, it is assigned
1111
* an ABI [version] number that corresponds to the current CLI version.
12-
*
13-
* @constructor Create a new instance from the given language pointer.
14-
* @param language A [CPointer] to a `TSLanguage`.
15-
* @throws [IllegalArgumentException] If the pointer is invalid or the [version] is incompatible.
1612
*/
17-
@OptIn(ExperimentalForeignApi::class)
18-
actual class Language @Throws(IllegalArgumentException::class) actual constructor(language: Any) {
19-
internal val self: CPointer<TSLanguage> =
13+
@OptIn(ExperimentalForeignApi::class) actual class Language internal constructor(
14+
internal val self: CPointer<TSLanguage>
15+
) {
16+
/**
17+
* Create a new instance from the given language pointer.
18+
*
19+
* @param language A [CPointer] to a `TSLanguage`.
20+
* @throws [IllegalArgumentException]
21+
* If the pointer is invalid or the [version] is incompatible.
22+
*/
23+
@Throws(IllegalArgumentException::class)
24+
actual constructor(language: Any) : this(
2025
(language as? CPointer<*>)?.rawValue?.let(::interpretCPointer)
2126
?: throw IllegalArgumentException("Invalid language: $language")
27+
)
2228

2329
/** The ABI version number for this language. */
2430
actual val version: UInt = ts_language_version(self)
@@ -39,6 +45,13 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
3945
/** The number of distinct field names in this language. */
4046
actual val fieldCount: UInt = ts_language_field_count(self)
4147

48+
/**
49+
* Get another reference to the language.
50+
*
51+
* @since 0.24.0
52+
*/
53+
actual fun copy() = Language(ts_language_copy(self)!!)
54+
4255
/** Get the node type for the given numerical ID. */
4356
actual fun symbolName(symbol: UShort) = ts_language_symbol_name(self, symbol)?.toKString()
4457

@@ -93,17 +106,17 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
93106
*
94107
* @throws [IllegalArgumentException] If the state is invalid for this language.
95108
*/
96-
@Throws(IllegalArgumentException::class)
97-
actual fun lookaheadIterator(state: UShort) = LookaheadIterator(this, state)
109+
@Throws(
110+
IllegalArgumentException::class
111+
) actual fun lookaheadIterator(state: UShort) = LookaheadIterator(this, state)
98112

99113
/**
100114
* Create a new [Query] from a string containing one or more S-expression
101115
* [patterns](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax).
102116
*
103117
* @throws [QueryError] If any error occurred while creating the query.
104118
*/
105-
@Throws(QueryError::class)
106-
actual fun query(source: String) = Query(this, source)
119+
@Throws(QueryError::class) actual fun query(source: String) = Query(this, source)
107120

108121
actual override fun equals(other: Any?) =
109122
this === other || (other is Language && self == other.self)

0 commit comments

Comments
 (0)