25
25
#include " utils/ts_preconditions.h"
26
26
#include " utils/ts_log.h"
27
27
28
- static std::mutex cancellation_flag_mutex;
29
- static std::atomic<size_t *> cancellation_flag (nullptr );
28
+ /* *
29
+ * `TSParserInternal` stores the actual tree sitter parser instance along
30
+ * with the cancellation flag and the cancellation flag mutex.
31
+ */
32
+ class TSParserInternal {
33
+ public:
30
34
31
- static size_t *get_cancellation_flag () {
32
- std::lock_guard<std::mutex> get_lock (cancellation_flag_mutex);
33
- return cancellation_flag.load ();
34
- }
35
+ TSParserInternal () {
36
+ cancellation_flag_mutex = new std::mutex ();
37
+ cancellation_flag = new std::atomic<size_t *>(nullptr );
38
+ parser = ts_parser_new ();
39
+ }
35
40
36
- static void set_cancellation_flag (size_t *flag) {
37
- std::lock_guard<std::mutex> set_lock (cancellation_flag_mutex);
38
- cancellation_flag.store (flag);
39
- }
41
+ ~TSParserInternal () {
42
+ delete cancellation_flag_mutex;
43
+ delete cancellation_flag;
44
+
45
+ ts_parser_delete (parser);
46
+
47
+ cancellation_flag_mutex = nullptr ;
48
+ cancellation_flag = nullptr ;
49
+ parser = nullptr ;
50
+ }
51
+
52
+ TSParser *getParser (JNIEnv *env) {
53
+ if (check_destroyed (env)) {
54
+ return nullptr ;
55
+ }
56
+
57
+ return this ->parser ;
58
+ }
59
+
60
+ bool begin_round (JNIEnv *env) {
61
+ auto flag = get_cancellation_flag (env);
62
+
63
+ if (flag) {
64
+ throw_illegal_state (env,
65
+ " Parser is already parsing another syntax tree! You must cancel the current parse first!" );
66
+ return false ;
67
+ }
68
+
69
+ // allocate a new cancellation flag
70
+ flag = (size_t *) malloc (sizeof (int ));
71
+ set_cancellation_flag (env, flag);
72
+
73
+ // set the cancellation flag to '0' to indicate that the parser should continue parsing
74
+ *flag = 0 ;
75
+ ts_parser_set_cancellation_flag (getParser (env), flag);
76
+
77
+ return true ;
78
+ }
79
+
80
+ void end_round (JNIEnv *env) {
81
+
82
+ size_t *flag = get_cancellation_flag (env);
83
+
84
+ // release the cancellation flag
85
+ free ((size_t *) flag);
86
+ set_cancellation_flag (env, nullptr );
87
+ ts_parser_set_cancellation_flag (getParser (env), nullptr );
88
+ }
89
+
90
+ size_t *get_cancellation_flag (JNIEnv *env) {
91
+ if (check_destroyed (env)) {
92
+ return nullptr ;
93
+ }
94
+
95
+ std::lock_guard<std::mutex> get_lock (*cancellation_flag_mutex);
96
+ return cancellation_flag->load ();
97
+ }
98
+
99
+ void set_cancellation_flag (JNIEnv *env, size_t *flag) {
100
+ if (check_destroyed (env)) {
101
+ return ;
102
+ }
103
+
104
+ std::lock_guard<std::mutex> set_lock (*cancellation_flag_mutex);
105
+ cancellation_flag->store (flag);
106
+ }
107
+
108
+ private:
109
+ std::mutex *cancellation_flag_mutex;
110
+ std::atomic<size_t *> *cancellation_flag;
111
+
112
+ TSParser *parser;
113
+
114
+ bool check_destroyed (JNIEnv *env) {
115
+ if (cancellation_flag_mutex == nullptr || cancellation_flag == nullptr || parser == nullptr ) {
116
+ throw_illegal_state (env, " TSParserInternal has already been destroyed" );
117
+ return true ;
118
+ }
119
+
120
+ return false ;
121
+ }
122
+ };
40
123
41
124
extern " C" JNIEXPORT jlong JNICALL
42
125
Java_com_itsaky_androidide_treesitter_TSParser_00024Native_newParser (
43
126
JNIEnv *env, jclass self) {
44
- return (jlong) ts_parser_new ();
127
+ auto parser = new TSParserInternal;
128
+ return (jlong) parser;
45
129
}
46
130
47
131
extern " C" JNIEXPORT void JNICALL
48
132
Java_com_itsaky_androidide_treesitter_TSParser_00024Native_delete (
49
- JNIEnv *env, jclass self, jlong parser) {
50
- req_nnp (env, parser);
51
- ts_parser_delete ((TSParser *) parser);
133
+ JNIEnv *env, jclass self, jlong parser_ptr) {
134
+ req_nnp (env, parser_ptr);
135
+
136
+ auto parser = (TSParserInternal *) parser_ptr;
137
+ delete parser;
52
138
}
53
139
54
140
extern " C" JNIEXPORT void JNICALL
55
141
Java_com_itsaky_androidide_treesitter_TSParser_00024Native_setLanguage (
56
142
JNIEnv *env, jclass self, jlong parser, jlong language) {
57
143
req_nnp (env, parser, " parser" );
58
144
req_nnp (env, language, " language" );
59
- ts_parser_set_language ((TSParser *) parser, (TSLanguage *) language);
145
+ ts_parser_set_language (((TSParserInternal *) parser)-> getParser (env) , (TSLanguage *) language);
60
146
}
61
147
62
148
extern " C" JNIEXPORT jlong JNICALL
63
149
Java_com_itsaky_androidide_treesitter_TSParser_00024Native_getLanguage (
64
150
JNIEnv *env, jclass self, jlong parser) {
65
151
req_nnp (env, parser);
66
- return (jlong) ts_parser_language ((TSParser *) parser);
152
+ return (jlong) ts_parser_language (((TSParserInternal *) parser)-> getParser (env) );
67
153
}
68
154
69
155
extern " C" JNIEXPORT void JNICALL
70
156
Java_com_itsaky_androidide_treesitter_TSParser_00024Native_reset (JNIEnv *env,
71
157
jclass self,
72
158
jlong parser) {
73
159
req_nnp (env, parser);
74
- ts_parser_reset ((TSParser *) parser);
160
+ ts_parser_reset (((TSParserInternal *) parser)-> getParser (env) );
75
161
}
76
162
77
163
extern " C" JNIEXPORT void JNICALL
78
164
Java_com_itsaky_androidide_treesitter_TSParser_00024Native_setTimeout (
79
165
JNIEnv *env, jclass self, jlong parser, jlong macros) {
80
166
req_nnp (env, parser);
81
- ts_parser_set_timeout_micros ((TSParser *) parser, macros);
167
+ ts_parser_set_timeout_micros (((TSParserInternal *) parser)-> getParser (env) , macros);
82
168
}
83
169
84
170
extern " C" JNIEXPORT jlong JNICALL
85
171
Java_com_itsaky_androidide_treesitter_TSParser_00024Native_getTimeout (
86
172
JNIEnv *env, jclass self, jlong parser) {
87
173
req_nnp (env, parser);
88
- return (jlong) ts_parser_timeout_micros ((TSParser *) parser);
174
+ return (jlong) ts_parser_timeout_micros (((TSParserInternal *) parser)-> getParser (env) );
89
175
}
90
176
91
177
extern " C" JNIEXPORT jboolean JNICALL
@@ -102,7 +188,7 @@ Java_com_itsaky_androidide_treesitter_TSParser_00024Native_setIncludedRanges(
102
188
}
103
189
104
190
const TSRange *r = tsRanges;
105
- return (jboolean) ts_parser_set_included_ranges ((TSParser *) parser,
191
+ return (jboolean) ts_parser_set_included_ranges (((TSParserInternal *) parser)-> getParser (env) ,
106
192
r,
107
193
count);
108
194
}
@@ -112,7 +198,7 @@ Java_com_itsaky_androidide_treesitter_TSParser_00024Native_getIncludedRanges(
112
198
JNIEnv *env, jclass self, jlong parser) {
113
199
req_nnp (env, parser);
114
200
jint count;
115
- const TSRange *ranges = ts_parser_included_ranges ((TSParser *) parser,
201
+ const TSRange *ranges = ts_parser_included_ranges (((TSParserInternal *) parser)-> getParser (env) ,
116
202
reinterpret_cast <uint32_t *>(&count));
117
203
jobjectArray result = createRangeArr (env, count);
118
204
req_nnp (env, result, " TSRange[] from factory" );
@@ -133,25 +219,12 @@ Java_com_itsaky_androidide_treesitter_TSParser_00024Native_parse(JNIEnv *env,
133
219
jlong str_pointer) {
134
220
req_nnp (env, parser);
135
221
req_nnp (env, str_pointer, " string" );
136
- auto *ts_parser = (TSParser *) parser;
222
+ auto *ts_parser_internal = (TSParserInternal *) parser;
223
+ TSParser *ts_parser = ts_parser_internal->getParser (env);
137
224
TSTree *old_tree = tree_pointer == 0 ? nullptr : (TSTree *) tree_pointer;
138
225
auto *source = as_str (str_pointer);
139
226
140
- auto flag = get_cancellation_flag ();
141
-
142
- if (flag) {
143
- throw_illegal_state (env,
144
- " Parser is already parsing another syntax tree! You must cancel the current parse first!" );
145
- return 0 ;
146
- }
147
-
148
- // allocate a new cancellation flag
149
- flag = (size_t *) malloc (sizeof (int ));
150
- set_cancellation_flag (flag);
151
-
152
- // set the cancellation flag to '0' to indicate that the parser should continue parsing
153
- *flag = 0 ;
154
- ts_parser_set_cancellation_flag (ts_parser, flag);
227
+ ts_parser_internal->begin_round (env);
155
228
156
229
// start parsing
157
230
// if the user cancels the parse while this method is being executed
@@ -163,10 +236,7 @@ Java_com_itsaky_androidide_treesitter_TSParser_00024Native_parse(JNIEnv *env,
163
236
source->byte_length (),
164
237
TSInputEncodingUTF16);
165
238
166
- // release the cancellation flag
167
- free ((size_t *) flag);
168
- set_cancellation_flag (nullptr );
169
- ts_parser_set_cancellation_flag (ts_parser, nullptr );
239
+ ts_parser_internal->end_round (env);
170
240
171
241
return (jlong) tree;
172
242
}
@@ -175,9 +245,11 @@ extern "C"
175
245
JNIEXPORT jboolean JNICALL
176
246
Java_com_itsaky_androidide_treesitter_TSParser_00024Native_requestCancellation (
177
247
JNIEnv *env,
178
- jclass clazz) {
248
+ jclass clazz,
249
+ jlong parser) {
179
250
180
- auto flag = get_cancellation_flag ();
251
+ auto *parserInternal = (TSParserInternal *) parser;
252
+ auto flag = parserInternal->get_cancellation_flag (env);
181
253
182
254
// no parse is in progress
183
255
if (flag == nullptr ) {
0 commit comments