Help us shape the future of Go! Take the 2026 Go Developer Survey

goextract

package
v0.16.1 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package goextract implements Pass 1's Go-specific tree-walk (LANG-01): mapping a parsed Go file's tree-sitter concrete syntax tree onto the codegraph node/edge vocabulary (D-06) — function/method/struct/ interface/type_alias/constant/variable nodes, intra-file contains edges, and unresolved cross-file references (calls, imports, struct/ interface embedding) for Pass 2 (resolve, a later plan) to settle.

This package takes only primitives (a parser.Parser, plain strings and bytes) and returns plain data — it does not import internal/indexer, so internal/indexer can depend on it without an import cycle.

Index

Constants

View Source
const (
	KindFile      = "file"
	KindFunction  = "function"
	KindMethod    = "method"
	KindStruct    = "struct"
	KindInterface = "interface"
	KindTypeAlias = "type_alias"
	KindConstant  = "constant"
	KindVariable  = "variable"

	// KindRoute is a Phase 5 addition (LANG-07, D-08): a framework-detected
	// HTTP route (path + method), linked to its handler symbol via a
	// heuristic-provenance edge. Additive within SchemaVersion 1 — no
	// pre-existing Kind* constant above is renamed or removed.
	KindRoute = "route"
)

Node kinds this extractor emits (D-06). No other kind is ever produced — in particular, no "field" node is emitted (ratified skip, 02-RESEARCH.md Open Question 3).

View Source
const (
	RefKindCalls    = "calls"
	RefKindImports  = "imports"
	RefKindEmbeds   = "embeds"
	RefKindContains = "contains"
)

UnresolvedRef.Kind values. "calls" and "imports" and "embeds" are the three cross-file reference kinds named in RES-01/D-04. "contains" is a fourth, narrower kind this extractor also emits: a method whose receiver type is declared in a DIFFERENT file than the method itself cannot yield an IntraEdge (both ids must be known within a single file's walk), so the containment is instead recorded here for Pass 2 to resolve once it has seen every file's type declarations.

View Source
const (
	RefKindReferences   = "references"   // new Pass-1 capture
	RefKindInstantiates = "instantiates" // new Pass-1 capture
	RefKindReturns      = "returns"      // new Pass-1 capture (reuses parsed ReturnType)
	RefKindTypeOf       = "type_of"      // new Pass-1 capture
)

New RefKind* constants for D-09's 6 missing RANK_EDGES kinds (01-RESEARCH.md §B/§C.1). These four are Pass-1-captured: each language extractor emits an UnresolvedRef with one of these Kind values, and Pass 2 (resolve.go) resolves the referenced name to a target node id, exactly like the existing RefKindCalls/RefKindEmbeds shape. extends/overrides (below) are Pass-2 synthesis only and do NOT get a RefKind*/UnresolvedRef.Kind case.

View Source
const EdgeKindExtends = "extends"

EdgeKindExtends is a D-09 addition (01-RESEARCH.md §B): resolve.go's existing RefKindEmbeds promotion branch (today an unconditional "embeds" fallback when the target is not an interface) splits further — class/struct-extends-class/struct becomes this kind instead. Pass-2 SYNTHESIS ONLY; no new UnresolvedRef.Kind case is added for it. Named here (mirroring EdgeKindImplements's doc-comment discipline above) so resolve.go's promotion check and query/rwr.go's RankEdges share ONE definition rather than separate copies of "extends".

View Source
const EdgeKindImplements = "implements"

EdgeKindImplements is a Phase 5 addition (RES-02, D-06): resolve.go sets this literal on schema.Edge.Kind for two distinct synthesis paths — the declared-implements promotion (Pattern 2: a RefKindEmbeds-shaped unresolved ref whose resolved target is an interface node) and Go's structural method-set match (dispatch.SynthesizeImplements, Pattern 3). Named here (not left as a bare string literal, unlike "calls"/"embeds"/ "contains"/"imports" today) so dispatch.go, resolve.go's promotion check, and query/traverse.go's dispatch-index filter share ONE definition rather than three copies of "implements". Distinct from RefKindEmbeds — do not repurpose that constant (D-06/RES-03: additive only, no existing edge kind is renamed).

View Source
const EdgeKindOverrides = "overrides"

EdgeKindOverrides is a D-09 addition (01-RESEARCH.md §B): derived at Pass-2 by walking already-resolved "contains" (type->method) and extends/implements/embeds (type->supertype) edges to find a same-named method on a supertype — mirrors synthesizeGoImplements's composition-from-already-resolved-edges pattern (resolve.go). Pass-2 SYNTHESIS ONLY; no new UnresolvedRef.Kind case. Named here so resolve.go's synthesis and query/rwr.go's RankEdges share ONE definition rather than separate copies of "overrides".

Variables

This section is empty.

Functions

This section is empty.

Types

type ExtractedNode

type ExtractedNode struct {
	Node *schema.Node
}

ExtractedNode wraps a fully-formed schema.Node produced during the tree-walk. Its id is already computed via nodeid.NodeID, so Pass 2 never needs to recompute or rename it.

type FileResult

type FileResult struct {
	ImportPath string
	RelPath    string
	Language   string

	// ModuleKeyDeclared reports that ImportPath is the module the file's
	// source declares (a Java or Kotlin package, a C# or PHP namespace),
	// not the key discovery computed from its path.
	ModuleKeyDeclared bool

	Nodes      []ExtractedNode
	IntraEdges []IntraEdge
	Unresolved []UnresolvedRef

	// Imports maps each import_spec's effective local alias (explicit
	// alias, "." for dot imports, "_" for blank imports, or the default
	// last-path-segment name) to its import path.
	Imports map[string]string

	// InterfaceMethods records, per interface node this file declares, the
	// method specs declared directly in that interface's own body (Phase 5
	// RES-02/Pattern 3). Embedded interfaces (`type A interface { B }`)
	// are NOT flattened here — dispatch.SynthesizeImplements composes an
	// interface's transitive method set itself, via the "embeds" edges
	// Pass 2 already resolves between two interface nodes.
	InterfaceMethods map[string][]MethodSpec

	// MethodArity maps a method node's id to its declared parameter count
	// (Phase 5 RES-02/Pattern 3). Keyed by the method's OWN node id (not
	// scoped by struct or file) because Pass 2 resolves a struct's full,
	// possibly cross-file, method set via "contains" edges — exactly like
	// TestResolve_CrossFileMethodContainment — so dispatch synthesis looks
	// arity up post-resolution, by method id, not at extraction time.
	MethodArity map[string]int32

	// ContentHash is hex(sha256(source bytes)) — SHA-256 per D-02a, never
	// MD5 — computed regardless of whether extraction below it succeeds.
	ContentHash string

	// MtimeUnixNs and SizeBytes carry the on-disk file's stat info at
	// extraction time (Phase 4 D-01a), copied verbatim from the
	// DiscoveredFile that produced this result. Pass 2 stamps these onto
	// the committed schema.File record so Sync's stat pre-filter has
	// something cheap to compare against on a later invocation.
	MtimeUnixNs int64
	SizeBytes   int64

	// Err is set instead of returning a non-nil error from Extract when
	// this specific file could not be parsed/extracted.
	Err error
}

FileResult is the complete Pass-1 intermediate for one Go source file: every node it declares, every intra-file edge those nodes participate in, and every cross-file reference Pass 2 must resolve.

Err is non-nil when this file was SKIPPED (e.g. parser.ErrSourceTooLarge or any other single-file extraction failure) — a skip is recorded here, never surfaced as Extract's own return error, so one bad file never aborts the run (RESEARCH Pitfall 4 / threat T-02-03).

func Extract

func Extract(p parser.Parser, importPath, relPath string, src []byte) (FileResult, error)

Extract walks a single Go file's parsed syntax tree and produces its Pass-1 intermediate: every node it declares (LANG-01 vocabulary, D-06), every intra-file edge those nodes participate in, and every unresolved cross-file reference (calls/imports/embeds/contains) Pass 2 must later settle against a global symbol index.

Size/skip contract (RESEARCH Pitfall 4, threat T-02-03): p.Parse owns the parser.MaxSourceBytes ceiling. If Parse fails for ANY reason — parser.ErrSourceTooLarge or otherwise — that failure is recorded on the returned FileResult.Err and Extract itself returns a nil error, so one bad file never aborts a caller's batch.

type IntraEdge

type IntraEdge struct {
	Edge *schema.Edge
}

IntraEdge wraps a schema.Edge whose source and target ids are BOTH known at extraction time — a same-file relationship (file->symbol contains, or a method's type->method contains edge when the receiver type is declared in the same file). Cross-file relationships are never recorded here; they become UnresolvedRefs instead.

type MethodSpec

type MethodSpec struct {
	Name  string
	Arity int32
}

MethodSpec is a bare (name, parameter-count) signature captured during extraction. Go's implicit interface-satisfaction synthesis (RES-02, Phase 5 Pattern 3) compares a struct's method set against an interface's method-spec set by (Name, Arity), not full type identity — D-06's bounded-matching discipline (name+arity), never a full Go type checker.

type UnresolvedRef

type UnresolvedRef struct {
	// FromID is the node id of the enclosing symbol (the calling
	// function/method, the embedding struct/interface, the containing
	// file for an import, or the method itself for a cross-file
	// "contains" ref) that this reference originates from.
	FromID string
	// Name is the referenced identifier (a callee name, an embedded
	// type's name, an import path for "imports" refs, or a receiver
	// type's name for "contains" refs).
	Name string
	// PkgAlias is the local package alias for a qualified reference
	// (pkg.Fn(), pkg.Type embedding) — empty for an unqualified
	// reference.
	PkgAlias string
	// Kind is one of RefKindCalls, RefKindImports, RefKindEmbeds,
	// RefKindContains, RefKindReferences, RefKindInstantiates,
	// RefKindReturns, or RefKindTypeOf. (EdgeKindExtends/EdgeKindOverrides
	// are Pass-2 synthesis only and are never a Kind here.)
	Kind string
	// Line and Col are the 1-based line / 0-based column of the
	// reference's call/use site (D-04).
	Line, Col int32
}

UnresolvedRef is a reference this file's extraction could not resolve to a target node id on its own, because doing so requires information from other files (a global symbol index) that Pass 1 — being embarrassingly parallel over single files — does not have. Pass 2 (resolve, a later plan) builds that global index and turns these into calls/imports/embeds (or type->method contains) edges.

Jump to

Keyboard shortcuts

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