Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit 41c3f90

Browse files
committed
Updated native TSQueryCursor implementation
1 parent 87f7142 commit 41c3f90

File tree

10 files changed

+106
-92
lines changed

10 files changed

+106
-92
lines changed

android-tree-sitter/src/main/java/com/itsaky/androidide/treesitter/TSQueryCursor.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,7 @@ public void setPointRange(TSPoint start, TSPoint end) {
5959
}
6060

6161
public TSQueryMatch nextMatch() {
62-
TSQueryMatch match = new TSQueryMatch();
63-
if (Native.nextMatch(this.pointer, match)) {
64-
return match;
65-
}
66-
67-
return null;
62+
return Native.nextMatch(this.pointer);
6863
}
6964

7065
public void removeMatch(int id) {
@@ -93,7 +88,7 @@ private static class Native {
9388

9489
public static native void setPointRange(long cursor, TSPoint start, TSPoint end);
9590

96-
public static native boolean nextMatch(long cursor, TSQueryMatch match);
91+
public static native TSQueryMatch nextMatch(long cursor);
9792

9893
public static native void removeMatch(long cursor, int id);
9994
}
-841 KB
Binary file not shown.
-617 KB
Binary file not shown.
-750 KB
Binary file not shown.
-793 KB
Binary file not shown.

android-tree-sitter/src/test/java/com/itsaky/androidide/treesitter/QueryTest.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ public class QueryTest extends TestBase {
1313
public void implementationTest() throws Exception {
1414
try (final var parser = new TSParser()) {
1515
parser.setLanguage(TSLanguages.java());
16-
try (final var tree = parser.parseString("public class MyClass { int x = 0; }");
17-
final var query = new TSQuery(tree.getLanguage(), "(class_body)");
18-
final var cursor = new TSQueryCursor()) {
16+
try (final var tree =
17+
parser.parseString("public class MyClass { int x = 0; public void myFunc(){} }")) {
18+
var query =
19+
new TSQuery(
20+
TSLanguages.java(), "(class_declaration name: (identifier) @MyClass)");
21+
var cursor = new TSQueryCursor();
1922
cursor.exec(query, tree.getRootNode());
20-
TSQueryMatch match;
21-
while((match = cursor.nextMatch()) != null) {
22-
assertThat(match.getCaptures()).isNotEmpty();
23-
}
23+
final var match = cursor.nextMatch();
24+
assertThat(match).isNotNull();
25+
assertThat(match.getCaptures()).hasLength(1);
26+
query.close();
27+
cursor.close();
28+
} catch (Throwable err) {
29+
throw new RuntimeException(err);
2430
}
2531
}
2632
}

lib/com_itsaky_androidide_treesitter_TSQueryCursor_Native.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/ts_query_cursor.cc

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
#include <iostream>
55

6-
void fillMatch(JNIEnv *, TSQueryMatch *, jobject);
7-
jobject createCaptureObj(JNIEnv *, const TSQueryCapture *, int, jclass);
8-
96
JNIEXPORT jlong JNICALL
107
Java_com_itsaky_androidide_treesitter_TSQueryCursor_00024Native_newCursor(
118
JNIEnv *env, jclass self) {
@@ -58,59 +55,19 @@ Java_com_itsaky_androidide_treesitter_TSQueryCursor_00024Native_setPointRange(
5855
_unmarshalPoint(env, end));
5956
}
6057

61-
JNIEXPORT jboolean JNICALL
58+
JNIEXPORT jobject JNICALL
6259
Java_com_itsaky_androidide_treesitter_TSQueryCursor_00024Native_nextMatch(
63-
JNIEnv *env, jclass self, jlong cursor, jobject match) {
64-
TSQueryMatch *m = new TSQueryMatch;
65-
bool b = ts_query_cursor_next_match((TSQueryCursor *)cursor, m);
60+
JNIEnv *env, jclass self, jlong cursor) {
61+
TSQueryMatch m;
62+
bool b = ts_query_cursor_next_match((TSQueryCursor *)cursor, &m);
6663
if (!b) {
67-
return false;
64+
return NULL;
6865
}
69-
fillMatch(env, m, match);
70-
return b;
66+
return _marshalMatch(env, m);
7167
}
7268

7369
JNIEXPORT void JNICALL
7470
Java_com_itsaky_androidide_treesitter_TSQueryCursor_00024Native_removeMatch(
7571
JNIEnv *env, jclass self, jlong cursor, jint id) {
7672
ts_query_cursor_remove_match((TSQueryCursor *)cursor, id);
77-
}
78-
79-
void fillMatch(JNIEnv *env, TSQueryMatch *m, jobject match) {
80-
jclass klass = env->GetObjectClass(match);
81-
jfieldID id = env->GetFieldID(klass, "id", "I");
82-
jfieldID pI = env->GetFieldID(klass, "patternIndex", "I");
83-
jfieldID cs = env->GetFieldID(
84-
klass, "captures", "[Lcom/itsaky/androidide/treesitter/TSQueryCapture;");
85-
env->SetIntField(match, id, m->id);
86-
env->SetIntField(match, pI, m->pattern_index);
87-
88-
uint16_t count = m->capture_count;
89-
jclass qClass;
90-
_loadClass(qClass, "com/itsaky/androidide/treesitter/TSQueryCapture");
91-
jobjectArray arr = env->NewObjectArray(count, qClass, NULL);
92-
93-
std::cout << "Match ID:" << m->id << std::endl;
94-
std::cout << "Match pattern index:" << m->pattern_index << std::endl;
95-
std::cout << "Match capture count:" << m->capture_count << std::endl;
96-
std::cout << "Number of captures in match:" << count << std::endl;
97-
for (uint16_t i = 0; i < count; i++) {
98-
env->SetObjectArrayElement(arr, i,
99-
createCaptureObj(env, m->captures, i, qClass));
100-
}
101-
102-
env->SetObjectField(match, cs, arr);
103-
}
104-
105-
jobject createCaptureObj(JNIEnv *env, TSQueryCapture *captures, int index,
106-
jclass klass) {
107-
jobject obj = env->AllocObject(klass);
108-
jfieldID nF = env->GetFieldID(klass, "node",
109-
"Lcom/itsaky/androidide/treesitter/TSNode;");
110-
jfieldID iF = env->GetFieldID(klass, "index", "I");
111-
112-
TSQueryCapture *capture = (captures + index);
113-
env->SetIntField(obj, iF, capture->index);
114-
env->SetObjectField(obj, nF, _marshalNode(env, capture->node));
115-
return obj;
11673
}

lib/ts_utils.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ jobject _marshalPoint(JNIEnv* env, TSPoint point);
3434

3535
TSPoint _unmarshalPoint(JNIEnv* env, jobject javaObject);
3636

37-
TSInputEdit _unmarshalInputEdit(JNIEnv* env, jobject inputEdit);
37+
TSInputEdit _unmarshalInputEdit(JNIEnv* env, jobject inputEdit);
38+
39+
jobject _marshalMatch(JNIEnv *env, TSQueryMatch match);
40+
jobject _marshalCapture(JNIEnv *env, TSQueryCapture capture);

lib/utils.cc

Lines changed: 78 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,19 @@ static jfieldID _inputEditStartPointField;
3333
static jfieldID _inputEditOldEndPointField;
3434
static jfieldID _inputEditNewEndPointField;
3535

36+
// TSQueryMatch
37+
static jclass _matchClass;
38+
static jfieldID _matchClassIdField;
39+
static jfieldID _matchClassPatternIndexField;
40+
static jfieldID _matchClassCapturesField;
41+
42+
// TSQueryCapture
43+
static jclass _captureClass;
44+
static jfieldID _captureClassIndexField;
45+
static jfieldID _captureClassNodeField;
3646

3747
void onLoad(JNIEnv* env) {
38-
// Node
48+
// Node
3949
_loadClass(_nodeClass, "com/itsaky/androidide/treesitter/TSNode");
4050
_loadField(_nodeContext0Field, _nodeClass, "context0", "I");
4151
_loadField(_nodeContext1Field, _nodeClass, "context1", "I");
@@ -45,7 +55,8 @@ void onLoad(JNIEnv* env) {
4555
_loadField(_nodeTreeField, _nodeClass, "tree", "J");
4656

4757
// TreeCursorNode
48-
_loadClass(_treeCursorNodeClass, "com/itsaky/androidide/treesitter/TSTreeCursorNode");
58+
_loadClass(_treeCursorNodeClass,
59+
"com/itsaky/androidide/treesitter/TSTreeCursorNode");
4960
_loadField(_treeCursorNodeTypeField, _treeCursorNodeClass, "type",
5061
"Ljava/lang/String;");
5162
_loadField(_treeCursorNodeNameField, _treeCursorNodeClass, "name",
@@ -64,14 +75,34 @@ void onLoad(JNIEnv* env) {
6475
_loadField(_inputEditStartByteField, _inputEditClass, "startByte", "I");
6576
_loadField(_inputEditOldEndByteField, _inputEditClass, "oldEndByte", "I");
6677
_loadField(_inputEditNewEndByteField, _inputEditClass, "newEndByte", "I");
67-
_loadField(_inputEditStartPointField, _inputEditClass, "start_point", "Lcom/itsaky/androidide/treesitter/TSPoint;");
68-
_loadField(_inputEditOldEndPointField, _inputEditClass, "old_end_point", "Lcom/itsaky/androidide/treesitter/TSPoint;");
69-
_loadField(_inputEditNewEndPointField, _inputEditClass, "new_end_point", "Lcom/itsaky/androidide/treesitter/TSPoint;");
78+
_loadField(_inputEditStartPointField, _inputEditClass, "start_point",
79+
"Lcom/itsaky/androidide/treesitter/TSPoint;");
80+
_loadField(_inputEditOldEndPointField, _inputEditClass, "old_end_point",
81+
"Lcom/itsaky/androidide/treesitter/TSPoint;");
82+
_loadField(_inputEditNewEndPointField, _inputEditClass, "new_end_point",
83+
"Lcom/itsaky/androidide/treesitter/TSPoint;");
84+
85+
// TSQueryMatch
86+
_loadClass(_matchClass, "com/itsaky/androidide/treesitter/TSQueryMatch");
87+
_loadField(_matchClassIdField, _matchClass, "id", "I");
88+
_loadField(_matchClassPatternIndexField, _matchClass, "patternIndex", "I");
89+
_loadField(_matchClassCapturesField, _matchClass, "captures",
90+
"[Lcom/itsaky/androidide/treesitter/TSQueryCapture;");
91+
92+
// TSQueryCapture
93+
_loadClass(_captureClass, "com/itsaky/androidide/treesitter/TSQueryCapture");
94+
_loadField(_captureClassIndexField, _captureClass, "index", "I");
95+
_loadField(_captureClassNodeField, _captureClass, "node",
96+
"Lcom/itsaky/androidide/treesitter/TSNode;");
7097
}
7198

7299
void onUnload(JNIEnv* env) {
73100
env->DeleteGlobalRef(_nodeClass);
74101
env->DeleteGlobalRef(_treeCursorNodeClass);
102+
env->DeleteGlobalRef(_pointClass);
103+
env->DeleteGlobalRef(_inputEditClass);
104+
env->DeleteGlobalRef(_matchClass);
105+
env->DeleteGlobalRef(_captureClass);
75106
}
76107

77108
// Node
@@ -87,16 +118,15 @@ jobject _marshalNode(JNIEnv* env, TSNode node) {
87118
}
88119

89120
TSNode _unmarshalNode(JNIEnv* env, jobject javaObject) {
90-
return (TSNode) {
91-
{
92-
(uint32_t)env->GetIntField(javaObject, _nodeContext0Field),
93-
(uint32_t)env->GetIntField(javaObject, _nodeContext1Field),
94-
(uint32_t)env->GetIntField(javaObject, _nodeContext2Field),
95-
(uint32_t)env->GetIntField(javaObject, _nodeContext3Field),
96-
},
97-
(const void*)env->GetLongField(javaObject, _nodeIdField),
98-
(const TSTree*)env->GetLongField(javaObject, _nodeTreeField)
99-
};
121+
return (TSNode){
122+
{
123+
(uint32_t)env->GetIntField(javaObject, _nodeContext0Field),
124+
(uint32_t)env->GetIntField(javaObject, _nodeContext1Field),
125+
(uint32_t)env->GetIntField(javaObject, _nodeContext2Field),
126+
(uint32_t)env->GetIntField(javaObject, _nodeContext3Field),
127+
},
128+
(const void*)env->GetLongField(javaObject, _nodeIdField),
129+
(const TSTree*)env->GetLongField(javaObject, _nodeTreeField)};
100130
}
101131

102132
// TreeCursorNode
@@ -122,22 +152,45 @@ jobject _marshalPoint(JNIEnv* env, TSPoint point) {
122152
}
123153

124154
TSPoint _unmarshalPoint(JNIEnv* env, jobject javaObject) {
125-
return (TSPoint) {
126-
(uint32_t)env->GetIntField(javaObject, _pointRowField),
127-
(uint32_t)env->GetIntField(javaObject, _pointColumnField),
155+
return (TSPoint){
156+
(uint32_t)env->GetIntField(javaObject, _pointRowField),
157+
(uint32_t)env->GetIntField(javaObject, _pointColumnField),
128158
};
129159
}
130160

131161
// TSInputEdit
132162
TSInputEdit _unmarshalInputEdit(JNIEnv* env, jobject inputEdit) {
133-
return (TSInputEdit) {
134-
(uint32_t)env->GetIntField(inputEdit, _inputEditStartByteField),
135-
(uint32_t)env->GetIntField(inputEdit, _inputEditOldEndByteField),
136-
(uint32_t)env->GetIntField(inputEdit, _inputEditNewEndByteField),
137-
_unmarshalPoint(env, env->GetObjectField(inputEdit, _inputEditStartPointField)),
138-
_unmarshalPoint(env, env->GetObjectField(inputEdit, _inputEditOldEndPointField)),
139-
_unmarshalPoint(env, env->GetObjectField(inputEdit, _inputEditNewEndPointField)),
163+
return (TSInputEdit){
164+
(uint32_t)env->GetIntField(inputEdit, _inputEditStartByteField),
165+
(uint32_t)env->GetIntField(inputEdit, _inputEditOldEndByteField),
166+
(uint32_t)env->GetIntField(inputEdit, _inputEditNewEndByteField),
167+
_unmarshalPoint(
168+
env, env->GetObjectField(inputEdit, _inputEditStartPointField)),
169+
_unmarshalPoint(
170+
env, env->GetObjectField(inputEdit, _inputEditOldEndPointField)),
171+
_unmarshalPoint(
172+
env, env->GetObjectField(inputEdit, _inputEditNewEndPointField)),
140173
};
141174
}
142175

176+
jobject _marshalMatch(JNIEnv* env, TSQueryMatch match) {
177+
jobject obj = env->AllocObject(_matchClass);
178+
env->SetIntField(obj, _matchClassIdField, match.id);
179+
env->SetIntField(obj, _matchClassPatternIndexField, match.pattern_index);
180+
jobjectArray captures = env->NewObjectArray(match.capture_count, _captureClass, NULL);
181+
for (int i = 0; i < match.capture_count; i++) {
182+
const TSQueryCapture* c = match.captures + i;
183+
env->SetObjectArrayElement(captures, i, _marshalCapture(env, *c));
184+
}
185+
env->SetObjectField(obj, _matchClassCapturesField, captures);
186+
return obj;
187+
}
188+
189+
jobject _marshalCapture(JNIEnv* env, TSQueryCapture capture) {
190+
jobject obj = env->AllocObject(_captureClass);
191+
env->SetIntField(obj, _captureClassIndexField, capture.index);
192+
env->SetObjectField(obj, _captureClassNodeField, _marshalNode(env, capture.node));
193+
return obj;
194+
}
195+
143196
#endif

0 commit comments

Comments
 (0)