Skip to content

Commit b01c35e

Browse files
feat!: separate QueryCursor class
1 parent c48b4e1 commit b01c35e

File tree

10 files changed

+738
-365
lines changed

10 files changed

+738
-365
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package io.github.treesitter.jtreesitter;
2+
3+
import static io.github.treesitter.jtreesitter.internal.TreeSitter.C_INT;
4+
import static io.github.treesitter.jtreesitter.internal.TreeSitter.ts_query_cursor_next_capture;
5+
6+
import io.github.treesitter.jtreesitter.internal.TSQueryMatch;
7+
import java.lang.foreign.MemorySegment;
8+
import java.lang.foreign.SegmentAllocator;
9+
import java.util.AbstractMap.SimpleImmutableEntry;
10+
import java.util.Spliterator;
11+
import java.util.Spliterators;
12+
import java.util.function.BiPredicate;
13+
import java.util.function.Consumer;
14+
import org.jspecify.annotations.NullMarked;
15+
import org.jspecify.annotations.Nullable;
16+
17+
@NullMarked
18+
class CapturesIterator extends Spliterators.AbstractSpliterator<SimpleImmutableEntry<Integer, QueryMatch>> {
19+
private final @Nullable BiPredicate<QueryPredicate, QueryMatch> predicate;
20+
private final Tree tree;
21+
private final SegmentAllocator allocator;
22+
private final Query query;
23+
private final MemorySegment cursor;
24+
25+
public CapturesIterator(
26+
Query query,
27+
MemorySegment cursor,
28+
Tree tree,
29+
SegmentAllocator allocator,
30+
@Nullable BiPredicate<QueryPredicate, QueryMatch> predicate) {
31+
super(Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.NONNULL);
32+
this.predicate = predicate;
33+
this.tree = tree;
34+
this.allocator = allocator;
35+
this.query = query;
36+
this.cursor = cursor;
37+
}
38+
39+
@Override
40+
public boolean tryAdvance(Consumer<? super SimpleImmutableEntry<Integer, QueryMatch>> action) {
41+
var hasNoText = tree.getText() == null;
42+
MemorySegment match = allocator.allocate(TSQueryMatch.layout());
43+
MemorySegment index = allocator.allocate(C_INT);
44+
var captureNames = query.getCaptureNames();
45+
while (ts_query_cursor_next_capture(cursor, match, index)) {
46+
var result = QueryMatch.from(match, captureNames, tree, allocator);
47+
if (hasNoText || query.matches(predicate, result)) {
48+
var entry = new SimpleImmutableEntry<>(index.get(C_INT, 0), result);
49+
action.accept(entry);
50+
return true;
51+
}
52+
}
53+
return false;
54+
}
55+
}

src/main/java/io/github/treesitter/jtreesitter/Language.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,9 @@ public LookaheadIterator lookaheadIterator(@Unsigned short state) throws Illegal
255255
* Create a new query from a string containing one or more S-expression patterns.
256256
*
257257
* @throws QueryError If an error occurred while creating the query.
258+
* @deprecated Use the {@link Query#Query(Language, String) Query} constructor instead.
258259
*/
260+
@Deprecated(since = "0.25.0")
259261
public Query query(String source) throws QueryError {
260262
return new Query(this, source);
261263
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package io.github.treesitter.jtreesitter;
2+
3+
import static io.github.treesitter.jtreesitter.internal.TreeSitter.ts_query_cursor_next_match;
4+
5+
import io.github.treesitter.jtreesitter.internal.TSQueryMatch;
6+
import java.lang.foreign.MemorySegment;
7+
import java.lang.foreign.SegmentAllocator;
8+
import java.util.Spliterator;
9+
import java.util.Spliterators;
10+
import java.util.function.BiPredicate;
11+
import java.util.function.Consumer;
12+
import org.jspecify.annotations.NullMarked;
13+
import org.jspecify.annotations.Nullable;
14+
15+
@NullMarked
16+
class MatchesIterator extends Spliterators.AbstractSpliterator<QueryMatch> {
17+
private final @Nullable BiPredicate<QueryPredicate, QueryMatch> predicate;
18+
private final Tree tree;
19+
private final SegmentAllocator allocator;
20+
private final Query query;
21+
private final MemorySegment cursor;
22+
23+
public MatchesIterator(
24+
Query query,
25+
MemorySegment cursor,
26+
Tree tree,
27+
SegmentAllocator allocator,
28+
@Nullable BiPredicate<QueryPredicate, QueryMatch> predicate) {
29+
super(Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.NONNULL);
30+
this.predicate = predicate;
31+
this.tree = tree;
32+
this.allocator = allocator;
33+
this.query = query;
34+
this.cursor = cursor;
35+
}
36+
37+
@Override
38+
public boolean tryAdvance(Consumer<? super QueryMatch> action) {
39+
var hasNoText = tree.getText() == null;
40+
MemorySegment match = allocator.allocate(TSQueryMatch.layout());
41+
var captureNames = query.getCaptureNames();
42+
while (ts_query_cursor_next_match(cursor, match)) {
43+
var result = QueryMatch.from(match, captureNames, tree, allocator);
44+
if (hasNoText || query.matches(predicate, result)) {
45+
action.accept(result);
46+
return true;
47+
}
48+
}
49+
return false;
50+
}
51+
}

0 commit comments

Comments
 (0)