treesitter

package
v0.0.0-...-763b74c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

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

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

func New(root string) *Backend

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

func (b *Backend) Close() error

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

func (b *Backend) Definition(absPath, symbol string) (Result, error)

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

func (b *Backend) DefinitionBodies(absPath, symbol string) (Result, error)

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

func (b *Backend) EnclosingDefinition(absPath string, lineNum int) (name string, ok bool)

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

func (b *Backend) References(absPath, symbol string) (Result, error)

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.

func (*Backend) Supports

func (b *Backend) Supports(path string) bool

Supports reports whether this tier has a grammar for the file's extension. Callers use it to give a precise "no grammar for .X files" degradation message instead of a generic miss.

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.

type Result

type Result struct {
	Locations  []lsp.Location
	Candidates int
	Ambiguous  bool
}

Result is one tier query's answer: the located positions plus the count of distinct candidates considered (so the caller can render a "N candidates" caveat). Ambiguous reports whether more than one definition matched the name.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL