Skip to content
treesitter-symbols

go · 17 languages · one parse

Code symbols across seventeen languages.

Extract definitions, imports, references, call edges, and method→owner relations from source in 17 languages — Go via go/ast, the rest via a pure-Go tree-sitter runtime — with cyclomatic + cognitive complexity from the same parse.

MIT licensed · pure Go, no cgo · one small API

symbols.go
s, _ := symbols.Extract("rust", src)  // any of 17 languages
s.Functions     // ["build", "greet", …]
s.Imports       // ["std::collections::HashMap", …]
s.CallEdges     // [{Caller:"Write" Callee:"helper"}, …]
s.MethodOwners  // [{Method:"Write" Owner:"Buffer"}, …]

what you get

One parse, everything about the code.

A single pass over each file yields the structural facts you need to build call graphs, coupling metrics, and dead-code analysis — across a whole polyglot repo.

17 languages, one API

Go, Python, JS, TS, Java, Rust, C, C++, C#, Kotlin, PHP, Ruby, Scala, R, MATLAB, Perl, and Swift — all through the same Extract call.

Everything from one parse

Defs, imports, references, call edges, method→owner, the declared package, and the exported set — all recovered in a single pass.

Complexity included

Cyclomatic + cognitive complexity per function span, computed in the same pass — no second walk over the tree.

Pure-Go runtime

Native go/ast for Go, a pure-Go tree-sitter runtime for the rest — no cgo, so it cross-compiles cleanly everywhere.

Resilient parsing

Best-effort and name-based; partial parses still yield recovered symbols, and it never errors on timeout.

Trim the binary

Grammar-subset build tags embed only the languages you use — the full build is roughly 22 MB.

usage

Extract, then walk the graph.

Point Extract at any supported language, or take the native go/ast path for Go. Then range over the call edges to stitch a cross-language call graph together.

// Any of 17 languages, one call
s, err := symbols.Extract("rust", src)

// Go takes the native go/ast path
g, err := symbols.ExtractGo(src)
// Build a cross-language call graph
for _, e := range s.CallEdges {
    fmt.Printf("%s -> %s\n",
        e.Caller, e.Callee)
}
  • Functions
  • Imports
  • References
  • CallEdges
  • MethodOwners
  • Package
  • Exported
  • Complexity

install

Add it to your module.

One import, pure Go, no cgo. Then call Extract and walk the results.

go get go get github.com/richardwooding/treesitter-symbols
import import symbols "github.com/richardwooding/treesitter-symbols"

Pairs naturally with go-coupling for coupling analysis. Full API on the Go Reference.