Skip to content

Commit 0349739

Browse files
feat: implement Node.childWithDescendant
and deprecate Node.childContainingDescendant
1 parent 3909ebc commit 0349739

File tree

7 files changed

+72
-0
lines changed
  • ktreesitter/src
    • androidInstrumentedTest/kotlin/io/github/treesitter/ktreesitter
    • androidMain/kotlin/io/github/treesitter/ktreesitter
    • commonMain/kotlin/io/github/treesitter/ktreesitter
    • commonTest/kotlin/io/github/treesitter/ktreesitter
    • jni
    • jvmMain/kotlin/io/github/treesitter/ktreesitter
    • nativeMain/kotlin/io/github/treesitter/ktreesitter

7 files changed

+72
-0
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,19 @@ class NodeTest : FunSpec({
177177
rootNode.child(0U)!!.fieldNameForNamedChild(2U).shouldBeNull()
178178
}
179179

180+
@Suppress("DEPRECATION")
180181
test("childContainingDescendant()") {
181182
val descendant = rootNode.child(0U)!!.child(0U)!!
182183
val child = rootNode.childContainingDescendant(descendant)
183184
child?.type shouldBe "class_declaration"
184185
}
185186

187+
test("childWithDescendant()") {
188+
val descendant = rootNode.child(0U)!!
189+
val child = rootNode.childWithDescendant(descendant)
190+
child?.type shouldBe "class_declaration"
191+
}
192+
186193
test("descendant()") {
187194
rootNode.descendant(0U, 5U)?.type shouldBe "class"
188195
rootNode.descendant(Point(0U, 10U), Point(0U, 12U))?.type shouldBe "class_body"

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,20 @@ actual class Node internal constructor(
251251

252252
/** Get the child of the node that contains the given descendant, if any. */
253253
@FastNative
254+
@Deprecated(
255+
"This method will not return a direct descendant",
256+
ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
257+
)
254258
actual external fun childContainingDescendant(descendant: Node): Node?
255259

260+
/**
261+
* Get the node that contains the given descendant, if any.
262+
*
263+
* @since 0.24.0
264+
*/
265+
@FastNative
266+
actual external fun childWithDescendant(descendant: Node): Node?
267+
256268
/**
257269
* Get the smallest node within this node
258270
* that spans the given byte range, if any.

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,19 @@ expect class Node {
188188
fun fieldNameForNamedChild(index: UInt): String?
189189

190190
/** Get the child of the node that contains the given descendant, if any. */
191+
@Deprecated(
192+
"This method will not return a direct descendant",
193+
ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
194+
)
191195
fun childContainingDescendant(descendant: Node): Node?
192196

197+
/**
198+
* Get the node that contains the given descendant, if any.
199+
*
200+
* @since 0.24.0
201+
*/
202+
fun childWithDescendant(descendant: Node): Node?
203+
193204
/**
194205
* Get the smallest node within this node
195206
* that spans the given byte range, if any.

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,19 @@ class NodeTest : FunSpec({
174174
rootNode.child(0U)!!.fieldNameForNamedChild(2U).shouldBeNull()
175175
}
176176

177+
@Suppress("DEPRECATION")
177178
test("childContainingDescendant()") {
178179
val descendant = rootNode.child(0U)!!.child(0U)!!
179180
val child = rootNode.childContainingDescendant(descendant)
180181
child?.type shouldBe "class_declaration"
181182
}
182183

184+
test("childWithDescendant()") {
185+
val descendant = rootNode.child(0U)!!
186+
val child = rootNode.childWithDescendant(descendant)
187+
child?.type shouldBe "class_declaration"
188+
}
189+
183190
test("descendant()") {
184191
rootNode.descendant(0U, 5U)?.type shouldBe "class"
185192
rootNode.descendant(Point(0U, 10U), Point(0U, 12U))?.type shouldBe "class_body"

ktreesitter/src/jni/node.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,16 @@ jobject JNICALL node_child_containing_descendant(JNIEnv *env, jobject this, jobj
285285
return marshal_node(env, result, tree);
286286
}
287287

288+
jobject JNICALL node_child_with_descendant(JNIEnv *env, jobject this, jobject descendant) {
289+
TSNode self = unmarshal_node(env, this);
290+
TSNode other = unmarshal_node(env, descendant);
291+
TSNode result = ts_node_child_with_descendant(self, other);
292+
if (ts_node_is_null(result))
293+
return NULL;
294+
jobject tree = GET_FIELD(Object, this, Node_tree);
295+
return marshal_node(env, result, tree);
296+
}
297+
288298
jobject JNICALL node_descendant__bytes(JNIEnv *env, jobject this, jint start, jint end) {
289299
TSNode self = unmarshal_node(env, this);
290300
TSNode result = ts_node_descendant_for_byte_range(self, (uint32_t)start, (uint32_t)end);
@@ -391,6 +401,8 @@ const JNINativeMethod Node_methods[] = {
391401
{"fieldNameForNamedChild", "(I)Ljava/lang/String;", (void *)&node_field_name_for_named_child},
392402
{"childContainingDescendant", "(L" PACKAGE "Node;)L" PACKAGE "Node;",
393403
(void *)&node_child_containing_descendant},
404+
{"childWithDescendant", "(L" PACKAGE "Node;)L" PACKAGE "Node;",
405+
(void *)&node_child_with_descendant},
394406
{"descendant", "(II)L" PACKAGE "Node;", (void *)&node_descendant__bytes},
395407
{"descendant", "(L" PACKAGE "Point;L" PACKAGE "Point;)L" PACKAGE "Node;",
396408
(void *)&node_descendant__points},

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,19 @@ actual class Node internal constructor(
245245
actual external fun fieldNameForNamedChild(index: UInt): String?
246246

247247
/** Get the child of the node that contains the given descendant, if any. */
248+
@Deprecated(
249+
"This method will not return a direct descendant",
250+
ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
251+
)
248252
actual external fun childContainingDescendant(descendant: Node): Node?
249253

254+
/**
255+
* Get the node that contains the given descendant, if any.
256+
*
257+
* @since 0.24.0
258+
*/
259+
actual external fun childWithDescendant(descendant: Node): Node?
260+
250261
/**
251262
* Get the smallest node within this node
252263
* that spans the given byte range, if any.

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,21 @@ actual class Node internal constructor(
269269
}
270270

271271
/** Get the child of the node that contains the given descendant, if any. */
272+
@Deprecated(
273+
"This method will not return a direct descendant",
274+
ReplaceWith("childWithDescendant(descendant)", "io.github.treesitter.ktreesitter.Node")
275+
)
272276
actual fun childContainingDescendant(descendant: Node) =
273277
ts_node_child_containing_descendant(self, descendant.self).convert(tree)
274278

279+
/**
280+
* Get the node that contains the given descendant, if any.
281+
*
282+
* @since 0.24.0
283+
*/
284+
actual fun childWithDescendant(descendant: Node) =
285+
ts_node_child_with_descendant(self, descendant.self).convert(tree)
286+
275287
/**
276288
* Get the smallest node within this node
277289
* that spans the given byte range, if any.

0 commit comments

Comments
 (0)