File tree Expand file tree Collapse file tree 2 files changed +33
-0
lines changed
Expand file tree Collapse file tree 2 files changed +33
-0
lines changed Original file line number Diff line number Diff line change @@ -818,6 +818,8 @@ func (q *Query) StringValueForId(id uint32) string {
818818type QueryCursor struct {
819819 c * C.TSQueryCursor
820820 t * Tree
821+ // keep a pointer to the query to avoid garbage collection
822+ q * Query
821823
822824 isClosed bool
823825}
@@ -832,6 +834,7 @@ func NewQueryCursor() *QueryCursor {
832834
833835// Exec executes the query on a given syntax node.
834836func (qc * QueryCursor ) Exec (q * Query , n * Node ) {
837+ qc .q = q
835838 qc .t = n .t
836839 C .ts_query_cursor_exec (qc .c , q .c , n .c )
837840}
Original file line number Diff line number Diff line change @@ -596,6 +596,36 @@ func TestLeakParseInput(t *testing.T) {
596596 assert .Less (t , m .Alloc , uint64 (1024 * 1024 ))
597597}
598598
599+ // see https://github.com/smacker/go-tree-sitter/issues/75
600+ func TestCursorKeepsQuery (t * testing.T ) {
601+ source := bytes .Repeat ([]byte ("1 + 1" ), 10000 )
602+
603+ parser := NewParser ()
604+ parser .SetLanguage (getTestGrammar ())
605+
606+ tree := parser .Parse (nil , source )
607+ root := tree .RootNode ()
608+
609+ for i := 0 ; i < 100 ; i ++ {
610+ query , _ := NewQuery (
611+ []byte ("(number) @match" ),
612+ getTestGrammar (),
613+ )
614+
615+ qc := NewQueryCursor ()
616+
617+ qc .Exec (query , root )
618+
619+ for {
620+ // ensure qc.NextMatch() doesn't cause a segfault
621+ match , exists := qc .NextMatch ()
622+ if ! exists || match == nil {
623+ break
624+ }
625+ }
626+ }
627+ }
628+
599629func BenchmarkParse (b * testing.B ) {
600630 ctx := context .Background ()
601631 parser := NewParser ()
You can’t perform that action at this time.
0 commit comments