1212import java .util .regex .Pattern ;
1313import java .util .regex .PatternSyntaxException ;
1414import java .util .stream .Stream ;
15-
1615import org .jspecify .annotations .NullMarked ;
1716import org .jspecify .annotations .Nullable ;
1817
2524@ NullMarked
2625public final class Query implements AutoCloseable {
2726 private final MemorySegment query ;
28- private final QueryCursorOptions cursorOptions = new QueryCursorOptions ();
27+ private final QueryCursorConfig cursorConfig = new QueryCursorConfig ();
2928 private final Arena arena ;
3029 private final Language language ;
3130 private final String source ;
@@ -261,7 +260,7 @@ private static boolean invalidPredicateChar(char c) {
261260 return !(Character .isLetterOrDigit (c ) || c == '_' || c == '-' || c == '.' || c == '?' || c == '!' );
262261 }
263262
264- MemorySegment self (){
263+ MemorySegment self () {
265264 return query ;
266265 }
267266
@@ -275,30 +274,30 @@ MemorySegment self(){
275274 return ts_query_capture_count (query );
276275 }
277276
278- public List <List <QueryPredicate >> getPredicates (){
277+ public List <List <QueryPredicate >> getPredicates () {
279278 return predicates .stream ().map (Collections ::unmodifiableList ).toList ();
280279 }
281280
282- public List <String > getCaptureNames (){
281+ public List <String > getCaptureNames () {
283282 return Collections .unmodifiableList (captureNames );
284283 }
285284
286285 /**
287- * Get the maximum number of in-progress matches.
286+ * Get the maximum number of in-progress matches of the default {@link QueryCursorConfig}
288287 *
289288 * @apiNote Defaults to {@code -1} (unlimited).
290289 */
291290 public @ Unsigned int getMatchLimit () {
292- return cursorOptions .getMatchLimit ();
291+ return cursorConfig .getMatchLimit ();
293292 }
294293
295294 /**
296- * Get the maximum number of in-progress matches.
295+ * Set the maximum number of in-progress matches of the default {@link QueryCursorConfig}
297296 *
298297 * @throws IllegalArgumentException If {@code matchLimit == 0}.
299298 */
300299 public Query setMatchLimit (@ Unsigned int matchLimit ) throws IllegalArgumentException {
301- cursorOptions .setMatchLimit (matchLimit );
300+ cursorConfig .setMatchLimit (matchLimit );
302301 return this ;
303302 }
304303
@@ -308,19 +307,23 @@ public Query setMatchLimit(@Unsigned int matchLimit) throws IllegalArgumentExcep
308307 *
309308 * @apiNote Defaults to {@code 0} (unlimited).
310309 * @since 0.23.1
310+ * @deprecated
311311 */
312+ @ Deprecated (forRemoval = true )
312313 public @ Unsigned long getTimeoutMicros () {
313- return cursorOptions .getTimeoutMicros ();
314+ return cursorConfig .getTimeoutMicros ();
314315 }
315316
316317 /**
317318 * Set the maximum duration in microseconds that query
318319 * execution should be allowed to take before halting.
319320 *
320321 * @since 0.23.1
322+ * @deprecated
321323 */
324+ @ Deprecated (forRemoval = true )
322325 public Query setTimeoutMicros (@ Unsigned long timeoutMicros ) {
323- cursorOptions .setTimeoutMicros (timeoutMicros );
326+ cursorConfig .setTimeoutMicros (timeoutMicros );
324327 return this ;
325328 }
326329
@@ -331,25 +334,22 @@ public Query setTimeoutMicros(@Unsigned long timeoutMicros) {
331334 * <br>Note that if a pattern includes many children, then they will still be checked.
332335 */
333336 public Query setMaxStartDepth (@ Unsigned int maxStartDepth ) {
334- cursorOptions .setMaxStartDepth (maxStartDepth );
337+ cursorConfig .setMaxStartDepth (maxStartDepth );
335338 return this ;
336339 }
337340
338341 /** Set the range of bytes in which the query will be executed. */
339342 public Query setByteRange (@ Unsigned int startByte , @ Unsigned int endByte ) {
340- cursorOptions .setStartByte (startByte );
341- cursorOptions .setEndByte (endByte );
343+ cursorConfig .setByteRange (startByte , endByte );
342344 return this ;
343345 }
344346
345347 /** Set the range of points in which the query will be executed. */
346348 public Query setPointRange (Point startPoint , Point endPoint ) {
347- cursorOptions .setStartPoint (startPoint );
348- cursorOptions .setEndPoint (endPoint );
349+ cursorConfig .setPointRange (startPoint , endPoint );
349350 return this ;
350351 }
351352
352-
353353 /**
354354 * Disable a certain pattern within a query.
355355 *
@@ -477,14 +477,13 @@ public Map<String, Optional<String>> getPatternAssertions(@Unsigned int index, b
477477 return Collections .unmodifiableMap (assertions .get (index ));
478478 }
479479
480-
481480 /**
482- * Execute the query on a given node.
481+ * Execute the query on a given node with the default {@link QueryCursorConfig} .
483482 * @param node The node that the query will run on.
484483 * @return A cursor that can be used to iterate over the matches.
485484 */
486- public QueryCursor execute (Node node ){
487- return new QueryCursor (this , node , cursorOptions );
485+ public QueryCursor execute (Node node ) {
486+ return new QueryCursor (this , node , cursorConfig );
488487 }
489488
490489 /**
@@ -493,22 +492,22 @@ public QueryCursor execute(Node node){
493492 * @param options The options that will be used for this query.
494493 * @return A cursor that can be used to iterate over the matches.
495494 */
496- public QueryCursor execute (Node node , QueryCursorOptions options ){
495+ public QueryCursor execute (Node node , QueryCursorConfig options ) {
497496 return new QueryCursor (this , node , options );
498497 }
499498
500-
501499 /**
502500 * Iterate over all the matches in the order that they were found. The lifetime of the native memory of the returned
503501 * matches is bound to the lifetime of this query object.
504502 *
505503 * @param node The node that the query will run on.
504+ * @implNote The stream is not created lazily such that there is no open {@link QueryCursor} instance left behind.
505+ * For creating a lazy stream use {@link #execute(Node)} and {@link QueryCursor#matchStream()}.
506506 */
507507 public Stream <QueryMatch > findMatches (Node node ) {
508- return findMatches (node , null , arena );
508+ return findMatches (node , arena , null );
509509 }
510510
511-
512511 /**
513512 * Iterate over all the matches in the order that they were found. The lifetime of the native memory of the returned
514513 * matches is bound to the lifetime of this query object.
@@ -526,26 +525,29 @@ public Stream<QueryMatch> findMatches(Node node) {
526525 *
527526 * @param node The node that the query will run on.
528527 * @param predicate A function that handles custom predicates.
529- * @implNote The stream is not created lazily such that there is no open {@link QueryCursor} instance left behind. For creating a lazy stream use {@link #execute(Node)} and {@link QueryCursor#stream(BiPredicate)}.
528+ * @implNote The stream is not created lazily such that there is no open {@link QueryCursor} instance left behind.
529+ * For creating a lazy stream use {@link #execute(Node)} and {@link QueryCursor#matchStream(BiPredicate)}.
530530 */
531531 public Stream <QueryMatch > findMatches (Node node , @ Nullable BiPredicate <QueryPredicate , QueryMatch > predicate ) {
532- return findMatches (node , predicate , arena );
532+ return findMatches (node , arena , predicate );
533533 }
534534
535-
536535 /**
537536 * Like {@link #findMatches(Node, BiPredicate)} but the native memory of the returned matches is created using the
538537 * given allocator.
539538 *
540539 * @param node The node that the query will run on.
541540 * @param predicate A function that handles custom predicates.
542541 * @param allocator The allocator that is used to allocate the native memory of the returned matches.
542+ * @implNote The stream is not created lazily such that there is no open {@link QueryCursor} instance left behind.
543+ * For creating a lazy stream use {@link #execute(Node)} and {@link QueryCursor#matchStream(SegmentAllocator, BiPredicate)}.
543544 */
544- public Stream <QueryMatch > findMatches (Node node , @ Nullable BiPredicate <QueryPredicate , QueryMatch > predicate , SegmentAllocator allocator ) {
545- try (QueryCursor cursor = this .execute (node )){
545+ public Stream <QueryMatch > findMatches (
546+ Node node , SegmentAllocator allocator , @ Nullable BiPredicate <QueryPredicate , QueryMatch > predicate ) {
547+ try (QueryCursor cursor = this .execute (node )) {
546548 // make sure to load the entire stream into memory before closing the cursor.
547- // Otherwise, we call for nextMatch after closing the cursor which leads to undefined behavior .
548- return cursor .stream (allocator , predicate ).toList ().stream ();
549+ // Otherwise, we call for nextMatch after closing the cursor which leads to an exception .
550+ return cursor .matchStream (allocator , predicate ).toList ().stream ();
549551 }
550552 }
551553
@@ -559,13 +561,10 @@ public String toString() {
559561 return "Query{language=%s, source=%s}" .formatted (language , source );
560562 }
561563
562-
563564 private void checkIndex (@ Unsigned int index ) throws IndexOutOfBoundsException {
564565 if (Integer .compareUnsigned (index , getPatternCount ()) >= 0 ) {
565566 throw new IndexOutOfBoundsException (
566567 "Pattern index %s is out of bounds" .formatted (Integer .toUnsignedString (index )));
567568 }
568569 }
569-
570-
571570}
0 commit comments