Documentation
¶
Overview ¶
Package treesitter is a syntactic code-navigation fallback used when no language server can answer (the server binary is missing, crashed, or does not support the query). It parses source directly with per-language tree-sitter grammars and tags-style definition/reference queries — the same mechanism behind GitHub's basic ("search-based") code navigation.
The honest limit is that this tier is syntactic, not semantic: it has no cross-file type resolution, so it cannot disambiguate two same-named symbols the way an LSP server can. find_definition therefore returns *ranked candidates* for an ambiguous name (exact-name match among definitions, ranked same-file-first then by path proximity), and the caller surfaces a one-line caveat saying the match is syntactic. find_references is more reliable than grep because it matches AST nodes: a name appearing only in a comment or string literal is never reported as a reference.
The runtime is github.com/odvcencio/gotreesitter, a pure-Go tree-sitter implementation with no cgo and no C toolchain, so it builds under CGO_ENABLED=0 (the project's static-binary constraint that rules out the mainstream cgo bindings).
Grammar binary cost and subsetting ¶
The gotreesitter `grammars` package go:embeds ~206 compressed grammar blobs (~20MB) by default; importing it links them all even though this tier only uses go/python/typescript/tsx. The upstream supports build-tag subsetting: building with `-tags 'grammar_subset grammar_subset_go grammar_subset_python grammar_subset_typescript grammar_subset_tsx'` compiles out the all-grammars registry and embeds ONLY the selected blobs, cutting the project's static binary by ~21MB (86MB -> 65MB). `make build` sets these tags (see Makefile's GRAMMAR_TAGS). A plain `go build`/`go install` (no tags) still works — it just embeds every grammar. That is exactly what `go install github.com/dpoage/bugbot@latest` produces: the full all-grammars binary is the supported install path. The subset is only a build-time size optimization and CANNOT be selected through `go install`, which passes no build tags — so do not "fix" go-install by trying to force it on. If a new language is added to grammarTable, add its matching grammar_subset_<lang> tag to GRAMMAR_TAGS.
Index ¶
- type Backend
- func (b *Backend) Close() error
- func (b *Backend) Definition(absPath, symbol string) (Result, error)
- func (b *Backend) DefinitionBodies(absPath, symbol string) (Result, error)
- func (b *Backend) EnclosingDefinition(absPath string, lineNum int) (name string, ok bool)
- func (b *Backend) Outline(absPath string) ([]OutlineEntry, error)
- func (b *Backend) References(absPath, symbol string) (Result, error)
- func (b *Backend) Supports(path string) bool
- type Kind
- type OutlineEntry
- type Result
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Backend ¶
type Backend struct {
// contains filtered or unexported fields
}
Backend answers code-navigation queries for one repository root by parsing source files with tree-sitter. It is safe for concurrent use across agent runners; parsed taggers are cached per language for the backend's lifetime, and a per-file tag cache avoids re-parsing unchanged files on repeat queries.
func New ¶
New creates a tree-sitter backend rooted at the absolute path root. No grammars are loaded until the first query for a language.
func (*Backend) Close ¶
Close releases any resources. The pure-Go runtime holds no OS handles, so this is a no-op kept for symmetry with the LSP manager's lifecycle.
func (*Backend) Definition ¶
Definition returns ranked definition candidates for the symbol named symbol, whose query occurrence is in absPath. Because the tier is syntactic, it matches every definition of that exact name across the language's files and ranks them: same file first, then by path proximity to absPath.
func (*Backend) DefinitionBodies ¶
DefinitionBodies is like Definition but returns locations whose Range spans the WHOLE declaration node (the full function/method/type/def body), not just the symbol's name identifier. It exists so the read_symbol tool can render the complete declaration text — a 40-line function instead of a capped whole-file read — while Definition keeps returning name ranges, which find_definition's "path:line: source" rendering depends on. Ranking and the ambiguous/candidate accounting are identical to Definition; only the per-location Range differs.
func (*Backend) EnclosingDefinition ¶
EnclosingDefinition returns the name of the innermost definition node that contains lineNum (0-based) in absPath, by scanning all definition tags for absPath whose body Range spans the target line. If multiple definitions span the line, the narrowest one (smallest body, i.e. deepest nesting) wins. Returns ("", false) when no grammar covers the file, the file has no definitions, or none spans the given line.
func (*Backend) Outline ¶
func (b *Backend) Outline(absPath string) ([]OutlineEntry, error)
Outline returns all top-level definitions in the single file at absPath, ordered by line number. It uses the per-file tag cache and respects the same mtime+size invalidation as Definition/References. An unsupported extension returns (nil, nil); a real parse error returns (nil, err).
func (*Backend) References ¶
References returns every call site / member-access reference to symbol across the language's files. Unlike grep, comment and string-literal mentions are never reported, because the query matches AST call nodes.
type Kind ¶
type Kind string
Kind is the tree-sitter symbol kind for a declaration; it follows the "definition.X" convention (e.g. "definition.function", "definition.type").
const ( KindFunction Kind = "definition.function" KindMethod Kind = "definition.method" KindType Kind = "definition.type" KindClass Kind = "definition.class" KindInterface Kind = "definition.interface" KindVar Kind = "definition.var" KindConst Kind = "definition.const" KindModule Kind = "definition.module" )
type OutlineEntry ¶
type OutlineEntry struct {
Name string
Kind Kind
StartLine int // 1-based, inclusive
EndLine int // 1-based, inclusive
}
OutlineEntry is one top-level declaration in a file: its name, kind (e.g. KindFunction), and the 1-based start/end line of the full node body.