diff --git a/bindings.go b/bindings.go index 5c3cca3a..1ebf86bc 100644 --- a/bindings.go +++ b/bindings.go @@ -227,6 +227,7 @@ func (p *Parser) Debug() { func (p *Parser) Close() { if !p.isClosed { C.ts_parser_delete(p.c) + runtime.SetFinalizer(p, nil) } p.isClosed = true @@ -309,6 +310,7 @@ func (t *Tree) cachedNode(ptr C.TSNode) *Node { func (t *BaseTree) Close() { if !t.isClosed { C.ts_tree_delete(t.c) + runtime.SetFinalizer(t, nil) } t.isClosed = true @@ -626,6 +628,7 @@ func NewTreeCursor(n *Node) *TreeCursor { func (c *TreeCursor) Close() { if !c.isClosed { C.ts_tree_cursor_delete(c.c) + runtime.SetFinalizer(c, nil) } c.isClosed = true @@ -872,6 +875,7 @@ func NewQuery(pattern []byte, lang *Language) (*Query, error) { func (q *Query) Close() { if !q.isClosed { C.ts_query_delete(q.c) + runtime.SetFinalizer(q, nil) } q.isClosed = true @@ -995,6 +999,7 @@ func (qc *QueryCursor) SetPointRange(startPoint Point, endPoint Point) { func (qc *QueryCursor) Close() { if !qc.isClosed { C.ts_query_cursor_delete(qc.c) + runtime.SetFinalizer(qc, nil) } qc.isClosed = true diff --git a/bindings_test.go b/bindings_test.go index c9f96079..1bfc6d3f 100644 --- a/bindings_test.go +++ b/bindings_test.go @@ -679,3 +679,27 @@ func BenchmarkParseInput(b *testing.B) { _, _ = parser.ParseInputCtx(ctx, nil, input) } } + +func TestManualClose(t *testing.T) { + js := "1 + 2" + + parser := NewParser() + parser.SetLanguage(getTestGrammar()) + tree, err := parser.ParseCtx(context.Background(), nil, []byte(js)) + assert.NoError(t, err) + root := tree.RootNode() + + q, err := NewQuery([]byte("(sum) (number)"), getTestGrammar()) + assert.Nil(t, err) + + qc := NewQueryCursor() + qc.Exec(q, root) + + parser.Close() + tree.Close() + qc.Close() + q.Close() + + // run GC to check nothing panics when finalizers (should) have run + runtime.GC() +}