Skip to content

Commit

Permalink
feat: implement Language.copy
Browse files Browse the repository at this point in the history
  • Loading branch information
ObserverOfTime committed Nov 3, 2024
1 parent e194f0e commit fc91e6e
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ class LanguageTest : FunSpec({
}

test("equals()") {
Language(TreeSitterJava.language()) shouldBe Language(TreeSitterJava.language())
Language(TreeSitterJava.language()) shouldBe language.copy()
}

test("hashCode()") {
language shouldHaveSameHashCodeAs TreeSitterJava.language()
}

test("toString()") {
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-z]+, version=14\)""")
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, version=14\)""")
}
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.treesitter.ktreesitter

import dalvik.annotation.optimization.CriticalNative
import dalvik.annotation.optimization.FastNative

/**
Expand Down Expand Up @@ -41,6 +42,13 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
actual val fieldCount: UInt
@FastNative external get

/**
* Get another reference to the language.
*
* @since 0.24.0
*/
actual fun copy() = Language(copy(self))

/** Get the node type for the given numerical ID. */
@FastNative
@JvmName("symbolName")
Expand Down Expand Up @@ -130,6 +138,10 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
private external fun checkVersion()

private companion object {
@JvmStatic
@CriticalNative
private external fun copy(self: Long): Long

init {
System.loadLibrary("ktreesitter")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ expect class Language @Throws(IllegalArgumentException::class) constructor(langu
/** The number of distinct field names in this language. */
val fieldCount: UInt

/**
* Get another reference to the language.
*
* @since 0.24.0
*/
fun copy(): Language

/** Get the node type for the given numerical ID. */
fun symbolName(symbol: UShort): String?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ class LanguageTest : FunSpec({
}

test("equals()") {
Language(TreeSitterJava.language()) shouldBe Language(TreeSitterJava.language())
Language(TreeSitterJava.language()) shouldBe language.copy()
}

test("hashCode()") {
language shouldHaveSameHashCodeAs TreeSitterJava.language()
}

test("toString()") {
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-z]+, version=14\)""")
language.toString() shouldMatch Regex("""Language\(id=0x[0-9a-f]+, version=14\)""")
}
})
5 changes: 5 additions & 0 deletions ktreesitter/src/jni/language.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "utils.h"

jlong JNICALL language_copy CRITICAL_ARGS(jlong self) {
return (jlong)ts_language_copy((TSLanguage *)self);
}

jint JNICALL language_get_version(JNIEnv *env, jobject this) {
TSLanguage *self = GET_POINTER(TSLanguage, this, Language_self);
return (jint)ts_language_version(self);
Expand Down Expand Up @@ -88,6 +92,7 @@ void JNICALL language_check_version(JNIEnv *env, jobject this) {
}

const JNINativeMethod Language_methods[] = {
{"copy", "(J)J", (void *)&language_copy},
{"getVersion", "()I", (void *)&language_get_version},
{"getSymbolCount", "()I", (void *)&language_get_symbol_count},
{"getStateCount", "()I", (void *)&language_get_state_count},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
actual val fieldCount: UInt
external get

/**
* Get another reference to the language.
*
* @since 0.24.0
*/
actual fun copy() = Language(copy(self))

/** Get the node type for the given numerical ID. */
@JvmName("symbolName")
actual external fun symbolName(symbol: UShort): String?
Expand Down Expand Up @@ -119,6 +126,9 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
private external fun checkVersion()

private companion object {
@JvmStatic
private external fun copy(self: Long): Long

init {
NativeUtils.loadLibrary()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@ import kotlinx.cinterop.*
*
* When a [Language] is generated by the Tree-sitter CLI, it is assigned
* an ABI [version] number that corresponds to the current CLI version.
*
* @constructor Create a new instance from the given language pointer.
* @param language A [CPointer] to a `TSLanguage`.
* @throws [IllegalArgumentException] If the pointer is invalid or the [version] is incompatible.
*/
@OptIn(ExperimentalForeignApi::class)
actual class Language @Throws(IllegalArgumentException::class) actual constructor(language: Any) {
internal val self: CPointer<TSLanguage> =
@OptIn(ExperimentalForeignApi::class) actual class Language internal constructor(
internal val self: CPointer<TSLanguage>
) {
/**
* Create a new instance from the given language pointer.
*
* @param language A [CPointer] to a `TSLanguage`.
* @throws [IllegalArgumentException]
* If the pointer is invalid or the [version] is incompatible.
*/
@Throws(IllegalArgumentException::class)
actual constructor(language: Any) : this(
(language as? CPointer<*>)?.rawValue?.let(::interpretCPointer)
?: throw IllegalArgumentException("Invalid language: $language")
)

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

/**
* Get another reference to the language.
*
* @since 0.24.0
*/
actual fun copy() = Language(ts_language_copy(self)!!)

/** Get the node type for the given numerical ID. */
actual fun symbolName(symbol: UShort) = ts_language_symbol_name(self, symbol)?.toKString()

Expand Down Expand Up @@ -93,17 +106,17 @@ actual class Language @Throws(IllegalArgumentException::class) actual constructo
*
* @throws [IllegalArgumentException] If the state is invalid for this language.
*/
@Throws(IllegalArgumentException::class)
actual fun lookaheadIterator(state: UShort) = LookaheadIterator(this, state)
@Throws(
IllegalArgumentException::class
) actual fun lookaheadIterator(state: UShort) = LookaheadIterator(this, state)

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

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

0 comments on commit fc91e6e

Please sign in to comment.