callgraph

package
v1.22.0 Latest Latest
Warning

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

Go to latest
Published: Jul 1, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package callgraph builds and queries call relationships between functions.

Index

Constants

View Source
const (

	// CrossLanguageFetchKind is the node Kind set on synthetic nodes injected
	// by the cross-language enrichment pass (HANDLES → FETCHES traversal).
	CrossLanguageFetchKind = "cross_language_fetch"
)

Variables

This section is empty.

Functions

func EagerWarmRepos

func EagerWarmRepos(ctx context.Context, dirs []string)

EagerWarmRepos enumerates immediate subdirectories of each path in dirs that contain a go.mod, then runs the GOCACHE prewarm for each in parallel (bounded by eagerWarmParallelism). Returns when all warmups have settled.

Intended to be invoked once at process startup from a goroutine so it does not block the MCP server bring-up. The caller is responsible for goroutine dispatch — this function blocks until completion to make tests deterministic.

func InjectHookEdges

func InjectHookEdges(cg *CallGraph, hookRoutes []HookRoute)

InjectHookEdges adds synthetic call edges for WordPress hook connections.

For each hook name that has both a registration (add_action/add_filter, Side="server") and an invocation (do_action/apply_filters, Side="client"), it creates a CallEdge from the invoking function to the callback function.

hookRoutes must come from routes.ExtractAll("php", ...) and symbols from the same repository's parsed symbol table.

func InvalidateBuildCache

func InvalidateBuildCache()

InvalidateBuildCache clears the entire BuildFromRepo cache. Used in tests and when a rebuild is explicitly requested.

func ResolveSpeculative

func ResolveSpeculative(ctx context.Context, client *oxcodes.Client, root, language string, nodes []CallChainNode)

ResolveSpeculative walks the call tree and fills Speculative candidates for unresolved nodes (Symbol.Kind == "external") using ox-codes text search. At most maxSpeculativePerTrace resolutions are attempted for performance.

Types

type BuildOpts

type BuildOpts struct {
	// IncludeFieldAccess keeps heuristic argref/field-access call sites even
	// when they don't resolve to a known function symbol. Default false —
	// unresolved CallSite.IsArgRef entries are dropped to avoid reporting
	// vars (`ctx`, `localPath`) and member access (`opts.Slug`) as callees.
	IncludeFieldAccess bool
}

BuildOpts controls how parser.CallSite entries are converted into call graph edges.

type CallChainNode

type CallChainNode struct {
	Symbol      *parser.Symbol    `json:"symbol"`
	Children    []CallChainNode   `json:"children,omitempty"`
	CallLine    uint32            `json:"callLine,omitempty"`
	Cycle       bool              `json:"cycle,omitempty"`
	Speculative []SpeculativeCall `json:"speculative,omitempty"` // candidates for unresolved calls
	Kind        string            `json:"kind,omitempty"`        // empty = normal; CrossLanguageFetchKind for synthetic nodes
	Depth       int               `json:"depth,omitempty"`       // only set on synthetic cross-language nodes
}

CallChainNode is a single node in the call chain tree.

type CallEdge

type CallEdge struct {
	Caller      *parser.Symbol // function containing the call
	Callee      *parser.Symbol // target function (nil if unresolved)
	CalleeName  string         // original name from source
	Receiver    string         // qualifier if method call
	Line        uint32         // 1-based call site line
	IsInterface bool           // true when resolved via interface dispatch (go/types or SCIP)
}

CallEdge is a resolved (or unresolved) call from one function to another.

type CallGraph

type CallGraph struct {
	Edges         []CallEdge
	Symbols       []*parser.Symbol
	TypeRels      []parser.TypeRelationship // interface/extends/embeds relationships
	HookCallbacks []string                  // function names registered as hook callbacks
	Tier          string                    // "basic" (tree-sitter), "enhanced" (go/types merged), "full" (future)
	Backend       string                    // resolution backend: "tree-sitter", "tree-sitter+go/types", "tree-sitter+scip"
	// UsesIndex maps a target file's relative path to a list of relative paths
	// of Astro files that render it as a component (<Foo />). Populated by
	// ResolveTemplateRefs during BuildFromRepo. Enables impact_analysis to
	// report file-level USES callers for Astro components.
	UsesIndex map[string][]string
}

CallGraph holds all call relationships for a repository.

func BuildCallGraph

func BuildCallGraph(symbols []*parser.Symbol, calls []parser.CallSite) *CallGraph

BuildCallGraph resolves call sites against the symbol table. Resolution: same-file -> same-package (directory) -> global name match.

Heuristic argref sites (parser.CallSite.IsArgRef==true) are dropped when they don't resolve to a function/method symbol — this filters noise like member access (`opts.Slug`) and local variable references (`ctx`, `localPath`) that the parser captures inside argument lists.

func BuildCallGraphWithOpts

func BuildCallGraphWithOpts(symbols []*parser.Symbol, calls []parser.CallSite, opts BuildOpts) *CallGraph

BuildCallGraphWithOpts is BuildCallGraph with explicit options.

func BuildFromRepo

func BuildFromRepo(ctx context.Context, input TraceRepoInput) (*CallGraph, error)

BuildFromRepo ingests a repo, parses files, and returns the call graph without tracing a specific symbol.

func ConvertToCallGraph

func ConvertToCallGraph(typedEdges []goanalysis.TypedEdge, tsSymbols []*parser.Symbol) *CallGraph

ConvertToCallGraph converts typed edges to the existing CallGraph format by matching callers/callees against tree-sitter symbols by name and file.

func MergeCallGraphs

func MergeCallGraphs(tsGraph, typedGraph *CallGraph) *CallGraph

MergeCallGraphs merges a tree-sitter call graph with a typed call graph. Typed edges take priority; unmatched tree-sitter edges are appended. HookCallbacks are preserved from the tree-sitter graph. Returns nil only if both inputs are nil.

type HookRoute

type HookRoute struct {
	Method  string // "ACTION" or "FILTER"
	Path    string // hook name
	Handler string // callback function name (empty for client-side)
	Side    string // "server" or "client"
	Line    uint32
}

HookRoute is a minimal representation of a WordPress hook route used by InjectHookEdges. It mirrors the fields needed from routes.Route without importing the routes package (to avoid circular dependencies).

type SpeculativeCall

type SpeculativeCall struct {
	Name       string  `json:"name"`
	File       string  `json:"file"`
	Line       int     `json:"line"`
	Confidence float64 `json:"confidence"` // 0.0-1.0
}

SpeculativeCall represents a candidate callee found via text search.

type TemplateUsage added in v1.22.0

type TemplateUsage struct {
	// From is the relative path of the file that contains the template ref.
	From string
	// To is the relative path of the imported component file.
	To string
	// Line is the 1-based line number of the tag usage in the source file.
	Line uint32
}

TemplateUsage represents a resolved USES relationship from a component file (Astro or Svelte) to the file it renders as a child component.

func ResolveTemplateRefs

func ResolveTemplateRefs(src []byte, refs []preproc.TemplateRef, fileRel, root string) []TemplateUsage

ResolveTemplateRefs joins TemplateRefs against a file's import bindings to produce file-level USES relationships.

The import-binding source depends on the file kind:

  • Astro (.astro and any non-.svelte): imports declared in the leading --- frontmatter block (scanFrontmatterBindings).
  • Svelte (.svelte): imports declared in the component's <script> blocks (scanSvelteScriptBindings).

The binding→ref join and path resolution below are generic over both kinds.

Resolution order:

  1. Relative imports (./…, ../…) — resolved directly against the file's directory.
  2. Alias imports (~/…, @/…, any non-relative path) — looked up in the repo's tsconfig.json compilerOptions.paths (and astro.config vite.resolve.alias as fallback). The alias map is loaded once per root and cached process-wide.
  3. Unresolved — either (a) no alias key matched (bare/scoped npm package such as 'svelte', '@guide/core', 'astro:transitions') — silently dropped without incrementing the counter; or (b) an alias prefix matched but the resolved path does not exist on disk — the gocode_parser_unresolved_alias_total counter is incremented and the ref is dropped (broken declared alias).

type TraceOpts

type TraceOpts struct {
	Direction string // "callees" (default) or "callers"
	MaxDepth  int    // default 5, max 10

	// CrossRefs, when non-nil, extends the trace through HANDLES/FETCHES
	// edges at +1 depth beyond the existing call graph. Noop when nil.
	CrossRefs graphx.CrossRefs
	// Repo is the repo key used for CrossRefs lookups. Required when CrossRefs is set.
	Repo string
}

TraceOpts controls the call chain traversal.

type TraceRepoInput

type TraceRepoInput struct {
	Root     string
	Symbol   string
	Focus    string
	Language string
	Opts     TraceOpts

	// IncludeFieldAccess keeps heuristic argref/field-access call sites even
	// when they don't resolve to a known function symbol. Default false —
	// unresolved argref captures (`opts.Slug`, `ctx`, `localPath`) are
	// dropped. Set via the `field_access=true` MCP tool flag for legacy
	// permissive behaviour.
	IncludeFieldAccess bool
}

TraceRepoInput configures a full repo call chain trace.

type TraceResult

type TraceResult struct {
	Root       *parser.Symbol  `json:"root,omitempty"`
	Tree       []CallChainNode `json:"tree"`
	MaxDepth   int             `json:"maxDepth"`
	TotalNodes int             `json:"totalNodes"`
	Resolved   int             `json:"resolved"`
	Unresolved int             `json:"unresolved"`
	Tier       string          `json:"tier,omitempty"`
}

TraceResult holds the complete call chain traversal output.

func Trace

func Trace(ctx context.Context, g *CallGraph, symbolName string, opts TraceOpts) TraceResult

Trace walks the call graph from the named symbol, building a tree of call chains. Direction "callees" follows outgoing calls; "callers" follows incoming calls.

When opts.CrossRefs is non-nil and opts.Repo is non-empty, a single extra pass runs after the main BFS/DFS: for each discovered node at depth <= MaxDepth-1 it checks whether the symbol HANDLES an HTTP route, then queries FetchedBy for upstream callers. Results are appended as synthetic CallChainNode values with Kind == CrossLanguageFetchKind. The pass never recurses. CrossRefs errors are swallowed (slog.Debug) — the feature is purely opportunistic.

func TraceRepo

func TraceRepo(ctx context.Context, input TraceRepoInput) (*TraceResult, error)

TraceRepo ingests a repo, extracts symbols and calls, builds call graph, traces from symbol.

Jump to

Keyboard shortcuts

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