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

Commit ff070e8

Browse files
committed
feat: add TSLookaheadIterator
1 parent 2d9ccf1 commit ff070e8

File tree

3 files changed

+253
-0
lines changed

3 files changed

+253
-0
lines changed

android-tree-sitter/src/main/cpp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ add_library(android-tree-sitter SHARED
3535
ts.cc
3636
ts_cursor.cc
3737
ts_language.cc
38+
ts_lookahead_iterator.cc
3839
ts_node.cc
3940
ts_parser.cc
4041
ts_query.cc
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* This file is part of android-tree-sitter.
3+
*
4+
* android-tree-sitter library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* android-tree-sitter library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with android-tree-sitter. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <cstring>
19+
#include <jni.h>
20+
21+
#include "tree_sitter/api.h"
22+
#include "utils/jni_string.h"
23+
24+
extern "C"
25+
JNIEXPORT jlong JNICALL
26+
Java_com_itsaky_androidide_treesitter_TSLookaheadIterator_00024Native_newIterator(
27+
JNIEnv *env,
28+
jclass clazz,
29+
jlong pointer,
30+
jshort state_id) {
31+
32+
auto *iterator = ts_lookahead_iterator_new((TSLanguage *) pointer, state_id);
33+
return (jlong) iterator;
34+
}
35+
36+
extern "C"
37+
JNIEXPORT void JNICALL
38+
Java_com_itsaky_androidide_treesitter_TSLookaheadIterator_00024Native_delete(
39+
JNIEnv *env,
40+
jclass clazz,
41+
jlong pointer) {
42+
43+
ts_lookahead_iterator_delete((TSLookaheadIterator *) pointer);
44+
}
45+
46+
extern "C"
47+
JNIEXPORT jboolean JNICALL
48+
Java_com_itsaky_androidide_treesitter_TSLookaheadIterator_00024Native_next(
49+
JNIEnv *env,
50+
jclass clazz,
51+
jlong pointer) {
52+
53+
return (jboolean) ts_lookahead_iterator_next((TSLookaheadIterator *) pointer);
54+
}
55+
56+
extern "C"
57+
JNIEXPORT jshort JNICALL
58+
Java_com_itsaky_androidide_treesitter_TSLookaheadIterator_00024Native_currentSymbol(
59+
JNIEnv *env,
60+
jclass clazz,
61+
jlong pointer) {
62+
63+
return (jshort) ts_lookahead_iterator_current_symbol((TSLookaheadIterator *) pointer);
64+
}
65+
66+
extern "C"
67+
JNIEXPORT jstring JNICALL
68+
Java_com_itsaky_androidide_treesitter_TSLookaheadIterator_00024Native_currentSymbolName(
69+
JNIEnv *env,
70+
jclass clazz,
71+
jlong pointer) {
72+
73+
const char *name =
74+
ts_lookahead_iterator_current_symbol_name((TSLookaheadIterator *) pointer);
75+
return env->NewStringUTF(name);
76+
}
77+
78+
extern "C"
79+
JNIEXPORT jboolean JNICALL
80+
Java_com_itsaky_androidide_treesitter_TSLookaheadIterator_00024Native_resetState(
81+
JNIEnv *env,
82+
jclass clazz,
83+
jlong pointer,
84+
jshort state_id) {
85+
return (jboolean) ts_lookahead_iterator_reset_state((TSLookaheadIterator *) pointer,
86+
state_id);
87+
}
88+
89+
extern "C"
90+
JNIEXPORT jboolean JNICALL
91+
Java_com_itsaky_androidide_treesitter_TSLookaheadIterator_00024Native_reset(
92+
JNIEnv *env,
93+
jclass clazz,
94+
jlong pointer,
95+
jlong language,
96+
jshort state_id) {
97+
98+
return (jboolean) ts_lookahead_iterator_reset((TSLookaheadIterator *) pointer,
99+
(TSLanguage *) language,
100+
state_id);
101+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* This file is part of android-tree-sitter.
3+
*
4+
* android-tree-sitter library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* android-tree-sitter library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with android-tree-sitter. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.itsaky.androidide.treesitter;
19+
20+
import java.util.Objects;
21+
22+
/**
23+
* Lookahead iterators can be useful to generate suggestions and improve syntax error diagnostics.
24+
* To get symbols valid in an ERROR node, use the lookahead iterator on its first leaf node state.
25+
* For `MISSING` nodes, a lookahead iterator created on the previous non-extra leaf node may be
26+
* appropriate.
27+
* <p>
28+
* Repeatedly using {@link #next()} and {@link #getCurrentSymbol()} will generate valid symbols in
29+
* the given parse state. Newly created lookahead iterators will contain the `ERROR` symbol.
30+
*
31+
* @author Akash Yadav
32+
*/
33+
public class TSLookaheadIterator extends TSNativeObject {
34+
35+
private TSLanguage language;
36+
37+
/**
38+
* Create a new lookahead iterator for the given language and parse state.
39+
* <p>
40+
* This returns <code>null</code> if state is invalid for the language.
41+
*
42+
* @param language The {@link TSLanguage} for this lookahead iterator.
43+
* @param stateId The parse state.
44+
* @return The {@link TSLookaheadIterator} or <code>null</code> if there was an error creating the
45+
* iterator.
46+
*/
47+
public static TSLookaheadIterator newInstance(TSLanguage language, short stateId) {
48+
language.checkAccess();
49+
final var pointer = Native.newIterator(language.pointer, stateId);
50+
if (pointer == 0) {
51+
return null;
52+
}
53+
54+
return new TSLookaheadIterator(language, pointer);
55+
}
56+
57+
/**
58+
* Creates a new {@link TSLookaheadIterator} instance with the given pointer.
59+
*
60+
* @param pointer The pointer to the native object. Subclasses can initialize this
61+
* {@link TSLookaheadIterator} with pointer set to 0 and then set the pointer
62+
* lazily.
63+
*/
64+
private TSLookaheadIterator(TSLanguage language, long pointer) {
65+
super(pointer);
66+
Objects.requireNonNull(language);
67+
this.language = language;
68+
}
69+
70+
/**
71+
* Advance the lookahead iterator to the next symbol.
72+
* <p>
73+
* This returns `true` if there is a new symbol and `false` otherwise.
74+
*/
75+
public boolean next() {
76+
checkAccess();
77+
return Native.next(pointer);
78+
}
79+
80+
/**
81+
* Get the current symbol of the lookahead iterator;
82+
*/
83+
public short getCurrentSymbol() {
84+
checkAccess();
85+
return Native.currentSymbol(pointer);
86+
}
87+
88+
/**
89+
* Get the current symbol's name of the lookahead iterator;
90+
*/
91+
public String getCurrentSymbolName() {
92+
checkAccess();
93+
return Native.currentSymbolName(pointer);
94+
}
95+
96+
/**
97+
* Reset the lookahead iterator to another state.
98+
* <p>
99+
* This returns `true` if the iterator was reset to the given state and `false` otherwise.
100+
*/
101+
public boolean resetState(short stateId) {
102+
checkAccess();
103+
return Native.resetState(pointer, stateId);
104+
}
105+
106+
/**
107+
* Reset the lookahead iterator.
108+
* <p>
109+
* This returns `true` if the language was set successfully and `false` otherwise.
110+
*/
111+
public boolean reset(TSLanguage language, short stateId) {
112+
checkAccess();
113+
language.checkAccess();
114+
final var result = Native.reset(pointer, language.pointer, stateId);
115+
if (result) {
116+
this.language = language;
117+
}
118+
119+
return result;
120+
}
121+
122+
/**
123+
* Get the current language of the lookahead iterator.
124+
*/
125+
public TSLanguage getLanguage() {
126+
checkAccess();
127+
return language;
128+
}
129+
130+
@Override
131+
protected void closeNativeObj() {
132+
Native.delete(pointer);
133+
}
134+
135+
private static final class Native {
136+
137+
public static native long newIterator(long language, short stateId);
138+
139+
public static native void delete(long pointer);
140+
141+
public static native boolean next(long pointer);
142+
143+
public static native short currentSymbol(long pointer);
144+
145+
public static native String currentSymbolName(long pointer);
146+
147+
public static native boolean resetState(long pointer, short stateId);
148+
149+
public static native boolean reset(long pointer, long pointer1, short stateId);
150+
}
151+
}

0 commit comments

Comments
 (0)