55import io .github .treesitter .jtreesitter .internal .*;
66import java .lang .foreign .Arena ;
77import java .lang .foreign .MemorySegment ;
8+ import java .lang .foreign .SegmentAllocator ;
89import java .util .*;
910import java .util .function .BiPredicate ;
1011import java .util .function .Consumer ;
@@ -480,10 +481,12 @@ public Map<String, Optional<String>> getPatternAssertions(@Unsigned int index, b
480481 /**
481482 * Iterate over all the matches in the order that they were found.
482483 *
484+ * @implNote The lifetime of the matches is bound to that of the query.
485+ *
483486 * @param node The node that the query will run on.
484487 */
485488 public Stream <QueryMatch > findMatches (Node node ) {
486- return findMatches (node , null );
489+ return findMatches (node , arena , null );
487490 }
488491
489492 /**
@@ -500,14 +503,26 @@ public Stream<QueryMatch> findMatches(Node node) {
500503 * });
501504 * }
502505 *
506+ * @implNote The lifetime of the matches is bound to that of the query.
507+ *
503508 * @param node The node that the query will run on.
504509 * @param predicate A function that handles custom predicates.
505510 */
506511 public Stream <QueryMatch > findMatches (Node node , @ Nullable BiPredicate <QueryPredicate , QueryMatch > predicate ) {
512+ return findMatches (node , arena , predicate );
513+ }
514+
515+ /**
516+ * Iterate over all the matches in the order that they were found, using the given allocator.
517+ *
518+ * @see #findMatches(Node, BiPredicate)
519+ */
520+ public Stream <QueryMatch > findMatches (
521+ Node node , SegmentAllocator allocator , @ Nullable BiPredicate <QueryPredicate , QueryMatch > predicate ) {
507522 try (var alloc = Arena .ofConfined ()) {
508523 ts_query_cursor_exec (cursor , query , node .copy (alloc ));
509524 }
510- return StreamSupport .stream (new MatchesIterator (node .getTree (), predicate ), false );
525+ return StreamSupport .stream (new MatchesIterator (node .getTree (), allocator , predicate ), false );
511526 }
512527
513528 @ Override
@@ -537,11 +552,14 @@ private void checkIndex(@Unsigned int index) throws IndexOutOfBoundsException {
537552 private final class MatchesIterator extends Spliterators .AbstractSpliterator <QueryMatch > {
538553 private final @ Nullable BiPredicate <QueryPredicate , QueryMatch > predicate ;
539554 private final Tree tree ;
555+ private final SegmentAllocator allocator ;
540556
541- public MatchesIterator (Tree tree , @ Nullable BiPredicate <QueryPredicate , QueryMatch > predicate ) {
557+ public MatchesIterator (
558+ Tree tree , SegmentAllocator allocator , @ Nullable BiPredicate <QueryPredicate , QueryMatch > predicate ) {
542559 super (Long .MAX_VALUE , Spliterator .IMMUTABLE | Spliterator .NONNULL );
543560 this .predicate = predicate ;
544561 this .tree = tree ;
562+ this .allocator = allocator ;
545563 }
546564
547565 @ Override
@@ -555,7 +573,7 @@ public boolean tryAdvance(Consumer<? super QueryMatch> action) {
555573 for (int i = 0 ; i < count ; ++i ) {
556574 var capture = TSQueryCapture .asSlice (matchCaptures , i );
557575 var name = captureNames .get (TSQueryCapture .index (capture ));
558- var node = TSNode .allocate (arena ).copyFrom (TSQueryCapture .node (capture ));
576+ var node = TSNode .allocate (allocator ).copyFrom (TSQueryCapture .node (capture ));
559577 captureList .add (new QueryCapture (name , new Node (node , tree )));
560578 }
561579 var patternIndex = TSQueryMatch .pattern_index (match );
0 commit comments