ast

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 11, 2026 License: AGPL-3.0 Imports: 31 Imported by: 0

Documentation

Overview

Package ast provides types and interfaces for language-agnostic AST parsing.

This package defines the core data structures used throughout the Trace service for representing parsed code symbols, their locations, and relationships. All parser implementations (Go, Python, TypeScript, etc.) produce output conforming to these types.

Design principles:

  • Language-agnostic: Types work for any supported language
  • Timestamps as int64 UnixMilli per project conventions
  • No map[string]interface{} - concrete types only
  • Comprehensive documentation on all exported types

Index

Constants

View Source
const (
	// DefaultMaxFileSize is the maximum file size the parser will accept (10MB).
	DefaultMaxFileSize = 10 * 1024 * 1024

	// WarnFileSize is the threshold at which a warning is logged (1MB).
	WarnFileSize = 1 * 1024 * 1024
)

File size constants for security validation.

View Source
const (
	// QueryFunctions is a tree-sitter query pattern for function declarations.
	QueryFunctions = `
(function_declaration
  name: (identifier) @name
  parameters: (parameter_list) @params
  result: (_)? @result) @func
`

	// QueryMethods is a tree-sitter query pattern for method declarations.
	QueryMethods = `` /* 164-byte string literal not displayed */

	// QueryTypes is a tree-sitter query pattern for type declarations.
	QueryTypes = `
(type_declaration
  (type_spec
    name: (type_identifier) @name
    type: (_) @type)) @typedef
`

	// QueryImports is a tree-sitter query pattern for import declarations.
	QueryImports = `` /* 149-byte string literal not displayed */

)

Example tree-sitter query patterns for reference.

These patterns could be used with tree-sitter's query language if we decide to switch from direct traversal. They're included here for documentation.

Note: The current implementation uses direct node traversal because: 1. It provides more precise control over what we extract 2. It's easier to debug and modify 3. It handles edge cases more gracefully

Function query:

(function_declaration
  name: (identifier) @name
  parameters: (parameter_list) @params
  result: (_)? @result) @func

Method query:

(method_declaration
  receiver: (parameter_list) @receiver
  name: (field_identifier) @name
  parameters: (parameter_list) @params
  result: (_)? @result) @method

Type query:

(type_declaration
  (type_spec
    name: (type_identifier) @name
    type: (_) @type)) @typedef

Import query:

(import_declaration
  (import_spec_list
    (import_spec
      name: (package_identifier)? @alias
      path: (interpreted_string_literal) @path)))
View Source
const (
	// QueryPythonFunctions is a tree-sitter query pattern for function declarations.
	QueryPythonFunctions = `` /* 127-byte string literal not displayed */

	// QueryPythonAsyncFunctions is a tree-sitter query pattern for async functions.
	QueryPythonAsyncFunctions = `` /* 169-byte string literal not displayed */

	// QueryPythonClasses is a tree-sitter query pattern for class definitions.
	QueryPythonClasses = `
(class_definition
  name: (identifier) @name
  superclasses: (argument_list)? @bases
  body: (block) @body) @class
`

	// QueryPythonImports is a tree-sitter query pattern for import statements.
	QueryPythonImports = `` /* 175-byte string literal not displayed */

	// QueryPythonDecorators is a tree-sitter query pattern for decorators.
	QueryPythonDecorators = `` /* 254-byte string literal not displayed */

	// QueryPythonVariables is a tree-sitter query pattern for variable assignments.
	QueryPythonVariables = `
(expression_statement
  (assignment
    left: (identifier) @name
    type: (type)? @type
    right: (_) @value)) @var
`
)

Example tree-sitter query patterns for reference.

These patterns could be used with tree-sitter's query language if we decide to switch from direct traversal. They're included here for documentation.

Note: The current implementation uses direct node traversal because: 1. It provides more precise control over what we extract 2. It's easier to debug and modify 3. It handles edge cases more gracefully

View Source
const (
	// QueryTSFunctions is a tree-sitter query pattern for function declarations.
	QueryTSFunctions = `` /* 197-byte string literal not displayed */

	// QueryTSClasses is a tree-sitter query pattern for class declarations.
	QueryTSClasses = `` /* 168-byte string literal not displayed */

	// QueryTSInterfaces is a tree-sitter query pattern for interface declarations.
	QueryTSInterfaces = `` /* 184-byte string literal not displayed */

	// QueryTSTypes is a tree-sitter query pattern for type alias declarations.
	QueryTSTypes = `` /* 141-byte string literal not displayed */

	// QueryTSEnums is a tree-sitter query pattern for enum declarations.
	QueryTSEnums = `
(enum_declaration
  name: (identifier) @name
  body: (enum_body) @body) @enum
`

	// QueryTSImports is a tree-sitter query pattern for import statements.
	QueryTSImports = `` /* 224-byte string literal not displayed */

	// QueryTSExports is a tree-sitter query pattern for export statements.
	QueryTSExports = `
(export_statement
  (decorator)* @decorators
  declaration: (_) @declaration) @export
`
)

Example tree-sitter query patterns for reference.

These patterns could be used with tree-sitter's query language if we decide to switch from direct traversal.

View Source
const MaxCallExpressionDepth = 50

MaxCallExpressionDepth is the maximum nesting depth for call expression traversal. This prevents stack overflow from deeply nested expressions like f(g(h(i(...)))).

View Source
const MaxCallSitesPerSymbol = 1000

MaxCallSitesPerSymbol is the maximum number of call sites extracted per symbol. This prevents memory exhaustion from pathologically large functions.

View Source
const MaxSymbolDepth = 100

MaxSymbolDepth is the maximum nesting depth for symbol traversal. This prevents stack overflow from maliciously crafted input.

View Source
const MaxTypeReferencesPerSymbol = 200

MaxTypeReferencesPerSymbol is the maximum number of type references extracted per symbol. This prevents memory exhaustion from functions with extremely long parameter lists.

Variables

View Source
var (
	// ErrUnsupportedLanguage indicates that no parser is available for the
	// requested language or file extension.
	//
	// Example:
	//   parser, ok := registry.GetByExtension(".xyz")
	//   if !ok {
	//       return fmt.Errorf("file type .xyz: %w", ErrUnsupportedLanguage)
	//   }
	ErrUnsupportedLanguage = errors.New("unsupported language")

	// ErrParseFailed indicates that parsing failed completely and no
	// useful result could be produced.
	//
	// This is different from partial parse failures, which are reported
	// in ParseResult.Errors while still returning extracted symbols.
	//
	// Common causes:
	//   - Invalid UTF-8 encoding
	//   - Corrupted file content
	//   - Parser internal error
	ErrParseFailed = errors.New("parse failed")

	// ErrInvalidContent indicates that the provided content is invalid
	// and cannot be processed.
	//
	// Common causes:
	//   - Nil content slice
	//   - Non-UTF-8 encoding
	//   - Binary file content
	ErrInvalidContent = errors.New("invalid content")

	// ErrContextCanceled indicates that parsing was canceled via context.
	//
	// This wraps context.Canceled but provides a parse-specific error
	// that can be distinguished from other context cancellations.
	ErrContextCanceled = errors.New("parse canceled")

	// ErrTimeout indicates that parsing exceeded the allowed time limit.
	//
	// Large files or complex syntax may trigger this error.
	// Consider increasing the context timeout or splitting the file.
	ErrTimeout = errors.New("parse timeout")
)

Sentinel errors for common parse failure conditions.

These errors can be checked using errors.Is() to determine the category of failure without inspecting error messages.

View Source
var BashNodeTypes = map[SymbolKind][]string{
	SymbolKindFunction: {bashNodeFunctionDefinition},
	SymbolKindVariable: {bashNodeVariableAssignment},
	SymbolKindConstant: {bashNodeDeclarationCommand},
	SymbolKindAlias:    {bashNodeCommand},
}

BashNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

View Source
var CSSNodeTypes = map[SymbolKind][]string{
	SymbolKindCSSClass:    {cssNodeClassSelector},
	SymbolKindCSSID:       {cssNodeIDSelector},
	SymbolKindCSSVariable: {cssNodeDeclaration},
	SymbolKindAnimation:   {cssNodeKeyframesStatement},
	SymbolKindMediaQuery:  {cssNodeMediaStatement},
	SymbolKindImport:      {cssNodeImportStatement},
}

CSSNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

View Source
var DockerfileNodeTypes = map[SymbolKind][]string{
	SymbolKindStage:       {dockerfileNodeFromInstruction},
	SymbolKindArg:         {dockerfileNodeArgInstruction},
	SymbolKindEnvVar:      {dockerfileNodeEnvInstruction},
	SymbolKindLabel:       {dockerfileNodeLabelInstruction},
	SymbolKindPort:        {dockerfileNodeExposeInstruction},
	SymbolKindVolume:      {dockerfileNodeVolumeInstruction},
	SymbolKindInstruction: {dockerfileNodeRunInstruction, dockerfileNodeCopyInstruction, dockerfileNodeAddInstruction},
}

DockerfileNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

View Source
var ErrFileTooLarge = errors.New("file exceeds maximum size limit")

ErrFileTooLarge is returned when input content exceeds the maximum file size.

View Source
var GoNodeTypes = map[SymbolKind][]string{
	SymbolKindPackage:   {nodePackageClause},
	SymbolKindImport:    {nodeImportDeclaration, nodeImportSpec},
	SymbolKindFunction:  {nodeFunctionDeclaration},
	SymbolKindMethod:    {nodeMethodDeclaration, nodeMethodSpec},
	SymbolKindStruct:    {nodeTypeDeclaration, nodeStructType},
	SymbolKindInterface: {nodeTypeDeclaration, nodeInterfaceType},
	SymbolKindType:      {nodeTypeDeclaration, nodeTypeSpec},
	SymbolKindField:     {nodeFieldDeclaration},
	SymbolKindVariable:  {nodeVarDeclaration, nodeVarSpec},
	SymbolKindConstant:  {nodeConstDeclaration, nodeConstSpec},
}

GoNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

This provides a reference for understanding how Go constructs map to symbols:

KindPackage   <- package_clause/package_identifier
KindImport    <- import_declaration/import_spec
KindFunction  <- function_declaration
KindMethod    <- method_declaration, method_spec (in interfaces)
KindStruct    <- type_declaration/type_spec/struct_type
KindInterface <- type_declaration/type_spec/interface_type
KindType      <- type_declaration/type_spec (aliases)
KindField     <- field_declaration (in structs)
KindVariable  <- var_declaration/var_spec
KindConstant  <- const_declaration/const_spec
View Source
var HTMLNodeTypes = map[SymbolKind][]string{
	SymbolKindElement:   {htmlNodeElement},
	SymbolKindForm:      {htmlNodeElement},
	SymbolKindComponent: {htmlNodeElement},
	SymbolKindImport:    {htmlNodeScriptElement, htmlNodeElement},
}

HTMLNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

View Source
var JavaScriptNodeTypes = map[SymbolKind][]string{
	SymbolKindImport:   {jsNodeImportStatement},
	SymbolKindFunction: {jsNodeFunctionDeclaration, jsNodeArrowFunction, jsNodeGeneratorFunctionDecl},
	SymbolKindClass:    {jsNodeClassDeclaration},
	SymbolKindMethod:   {jsNodeMethodDefinition},
	SymbolKindField:    {jsNodeFieldDefinition},
	SymbolKindVariable: {jsNodeLexicalDeclaration, jsNodeVariableDeclaration},
	SymbolKindConstant: {jsNodeLexicalDeclaration},
}

JavaScriptNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

View Source
var MarkdownNodeTypes = map[SymbolKind][]string{
	SymbolKindHeading:   {markdownNodeAtxHeading},
	SymbolKindCodeBlock: {markdownNodeFencedCodeBlock, markdownNodeIndentedCodeBlock},
	SymbolKindList:      {markdownNodeList},
	SymbolKindLink:      {markdownNodeLinkRefDef},
}

MarkdownNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

View Source
var PythonNodeTypes = map[SymbolKind][]string{
	SymbolKindPackage:   {pyNodeModule},
	SymbolKindImport:    {pyNodeImportStatement, pyNodeImportFromStatement},
	SymbolKindFunction:  {pyNodeFunctionDefinition, pyNodeAsyncFunctionDefinition},
	SymbolKindMethod:    {pyNodeFunctionDefinition},
	SymbolKindClass:     {pyNodeClassDefinition},
	SymbolKindProperty:  {pyNodeFunctionDefinition},
	SymbolKindField:     {pyNodeAssignment},
	SymbolKindVariable:  {pyNodeAssignment},
	SymbolKindConstant:  {pyNodeAssignment},
	SymbolKindDecorator: {pyNodeDecorator},
}

PythonNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

This provides a reference for understanding how Python constructs map to symbols:

KindPackage   <- module (first docstring)
KindImport    <- import_statement, import_from_statement
KindFunction  <- function_definition, async_function_definition
KindMethod    <- function_definition (inside class body)
KindClass     <- class_definition
KindProperty  <- function_definition with @property decorator
KindField     <- assignment in class body
KindVariable  <- assignment at module level
KindConstant  <- assignment at module level with ALL_CAPS name
KindDecorator <- decorator
View Source
var SQLNodeTypes = map[SymbolKind][]string{
	SymbolKindTable:  {sqlNodeCreateTable},
	SymbolKindColumn: {sqlNodeColumnDefinition},
	SymbolKindView:   {sqlNodeCreateView},
	SymbolKindIndex:  {sqlNodeCreateIndex},
}

SQLNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

View Source
var TypeScriptNodeTypes = map[SymbolKind][]string{
	SymbolKindImport:     {tsNodeImportStatement},
	SymbolKindFunction:   {tsNodeFunctionDeclaration, tsNodeArrowFunction},
	SymbolKindClass:      {tsNodeClassDeclaration, tsNodeAbstractClassDeclaration},
	SymbolKindInterface:  {tsNodeInterfaceDeclaration},
	SymbolKindType:       {tsNodeTypeAliasDeclaration},
	SymbolKindEnum:       {tsNodeEnumDeclaration},
	SymbolKindEnumMember: {tsNodeEnumAssignment},
	SymbolKindMethod:     {tsNodeMethodDefinition, tsNodeMethodSignature},
	SymbolKindField:      {tsNodePublicFieldDefinition, tsNodePropertySignature},
	SymbolKindVariable:   {tsNodeLexicalDeclaration, tsNodeVariableDeclaration},
	SymbolKindConstant:   {tsNodeLexicalDeclaration},
}

TypeScriptNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

This provides a reference for understanding how TypeScript constructs map to symbols:

KindImport    <- import_statement
KindFunction  <- function_declaration, arrow_function (named)
KindClass     <- class_declaration, abstract_class_declaration
KindInterface <- interface_declaration
KindType      <- type_alias_declaration
KindEnum      <- enum_declaration
KindEnumMember<- enum_assignment, property_identifier (in enum)
KindMethod    <- method_definition, method_signature
KindField     <- public_field_definition, property_signature
KindVariable  <- lexical_declaration (let), variable_declaration
KindConstant  <- lexical_declaration (const)
View Source
var YAMLNodeTypes = map[SymbolKind][]string{
	SymbolKindKey:      {yamlNodeBlockMappingPair, yamlNodeFlowPair},
	SymbolKindAnchor:   {yamlNodeAnchor},
	SymbolKindDocument: {yamlNodeDocument},
}

YAMLNodeTypes maps symbol kinds to the tree-sitter node types that produce them.

Functions

func GenerateID

func GenerateID(filePath string, startLine int, name string) string

GenerateID creates a unique identifier for a symbol based on its location and name.

Format: "file_path:start_line:name"

This format ensures uniqueness within a project while remaining human-readable and useful for debugging. Two symbols at the same location with the same name are considered identical.

SECURITY: Callers MUST validate that filePath is within the project boundary before calling this function. This function does NOT perform path validation to avoid redundant checks when called in bulk. Use Symbol.Validate() or ParseResult.Validate() to verify paths don't contain traversal sequences.

Parameters:

  • filePath: Path relative to project root. Must not contain ".." sequences.
  • startLine: 1-indexed line number where the symbol starts.
  • name: The symbol's identifier name.

func IsParseError

func IsParseError(err error) bool

IsParseError checks if an error is or wraps a ParseError.

Parameters:

  • err: The error to check.

Returns:

True if the error is or contains a ParseError.

func IsParseFailed

func IsParseFailed(err error) bool

IsParseFailed checks if an error indicates a complete parse failure.

Parameters:

  • err: The error to check.

Returns:

True if the error is or wraps ErrParseFailed.

func IsUnsupportedLanguage

func IsUnsupportedLanguage(err error) bool

IsUnsupportedLanguage checks if an error indicates an unsupported language.

Parameters:

  • err: The error to check.

Returns:

True if the error is or wraps ErrUnsupportedLanguage.

func WrapParseError

func WrapParseError(err error, filePath string) error

WrapParseError wraps an error with file context.

If the error is already a ParseError, it returns it unchanged. Otherwise, it creates a new ParseError wrapping the original error.

Parameters:

  • err: The error to wrap.
  • filePath: Path to the file where the error occurred.

Returns:

A ParseError wrapping the original error, or nil if err is nil.

Types

type BashParser

type BashParser struct {
	// contains filtered or unexported fields
}

BashParser extracts symbols from Bash script source code.

Description:

BashParser uses tree-sitter to parse Bash scripts and extract
structured symbol information including functions, variables,
exported variables, constants (readonly), and aliases.

Thread Safety:

BashParser is safe for concurrent use. Multiple goroutines can call Parse
simultaneously. Each Parse call creates its own tree-sitter parser instance.

Example:

parser := NewBashParser()
result, err := parser.Parse(ctx, content, "script.sh")
if err != nil {
    return fmt.Errorf("parse: %w", err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewBashParser

func NewBashParser(opts ...BashParserOption) *BashParser

NewBashParser creates a new BashParser with the given options.

Description:

Creates a parser configured for Bash script files. The parser can be
reused for multiple files and is safe for concurrent use.

Example:

// Default options
parser := NewBashParser()

// With custom options
parser := NewBashParser(
    WithBashMaxFileSize(5 * 1024 * 1024),
    WithBashExtractAliases(false),
)

func (*BashParser) Extensions

func (p *BashParser) Extensions() []string

Extensions returns the file extensions this parser handles.

func (*BashParser) Language

func (p *BashParser) Language() string

Language returns the language name for this parser.

func (*BashParser) Parse

func (p *BashParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from Bash script source code.

Description:

Parses the provided Bash content using tree-sitter and extracts all
symbols including functions, variables, constants, and aliases.

Inputs:

ctx      - Context for cancellation. Checked before/after parsing.
content  - Raw Bash source bytes. Must be valid UTF-8.
filePath - Path to the file (relative to project root, for ID generation).

Outputs:

*ParseResult - Extracted symbols and metadata. Never nil on success.
error        - Non-nil only for complete failures (invalid UTF-8, too large).

Thread Safety:

This method is safe for concurrent use.

type BashParserOption

type BashParserOption func(*BashParserOptions)

BashParserOption is a functional option for configuring BashParser.

func WithBashExtractAliases

func WithBashExtractAliases(extract bool) BashParserOption

WithBashExtractAliases sets whether to extract alias definitions.

func WithBashMaxFileSize

func WithBashMaxFileSize(size int) BashParserOption

WithBashMaxFileSize sets the maximum file size for parsing.

type BashParserOptions

type BashParserOptions struct {
	// MaxFileSize is the maximum file size in bytes to parse.
	// Files larger than this return ErrFileTooLarge.
	// Default: 10MB
	MaxFileSize int

	// ExtractAliases determines whether to extract alias definitions.
	// Default: true
	ExtractAliases bool
}

BashParserOptions configures BashParser behavior.

func DefaultBashParserOptions

func DefaultBashParserOptions() BashParserOptions

DefaultBashParserOptions returns the default options.

type CSSParser

type CSSParser struct {
	// contains filtered or unexported fields
}

CSSParser extracts symbols from CSS source code.

Description:

CSSParser uses tree-sitter to parse CSS source files and extract
structured symbol information including class selectors, ID selectors,
CSS custom properties (variables), animations, and media queries.

Thread Safety:

CSSParser is safe for concurrent use. Multiple goroutines can call Parse
simultaneously. Each Parse call creates its own tree-sitter parser instance.

Example:

parser := NewCSSParser()
result, err := parser.Parse(ctx, content, "styles.css")
if err != nil {
    return fmt.Errorf("parse: %w", err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewCSSParser

func NewCSSParser(opts ...CSSParserOption) *CSSParser

NewCSSParser creates a new CSSParser with the given options.

Description:

Creates a parser configured for CSS source files. The parser can be
reused for multiple files and is safe for concurrent use.

Example:

// Default options
parser := NewCSSParser()

// With custom options
parser := NewCSSParser(
    WithCSSMaxFileSize(5 * 1024 * 1024),
)

func (*CSSParser) Extensions

func (p *CSSParser) Extensions() []string

Extensions returns the file extensions this parser handles.

func (*CSSParser) Language

func (p *CSSParser) Language() string

Language returns the language name for this parser.

func (*CSSParser) Parse

func (p *CSSParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from CSS source code.

Description:

Parses the provided CSS content using tree-sitter and extracts all
symbols including class selectors, ID selectors, CSS variables,
animations, and media queries.

Inputs:

ctx      - Context for cancellation. Checked before and after parsing.
content  - Raw CSS source bytes. Must be valid UTF-8.
filePath - Path to the file (relative to project root, for ID generation).

Outputs:

*ParseResult - Extracted symbols and metadata. Never nil on success.
error        - Non-nil only for complete failures (invalid UTF-8, too large).

Thread Safety:

This method is safe for concurrent use.

type CSSParserOption

type CSSParserOption func(*CSSParserOptions)

CSSParserOption is a functional option for configuring CSSParser.

func WithCSSExtractNestedClasses

func WithCSSExtractNestedClasses(extract bool) CSSParserOption

WithCSSExtractNestedClasses sets whether to extract classes inside media queries.

func WithCSSMaxFileSize

func WithCSSMaxFileSize(size int) CSSParserOption

WithCSSMaxFileSize sets the maximum file size for parsing.

type CSSParserOptions

type CSSParserOptions struct {
	// MaxFileSize is the maximum file size in bytes to parse.
	// Files larger than this return ErrFileTooLarge.
	// Default: 10MB
	MaxFileSize int

	// ExtractNestedClasses determines whether to extract classes inside media queries.
	// Default: true
	ExtractNestedClasses bool
}

CSSParserOptions configures CSSParser behavior.

func DefaultCSSParserOptions

func DefaultCSSParserOptions() CSSParserOptions

DefaultCSSParserOptions returns the default options.

type CallSite

type CallSite struct {
	// Target is the name of the called function or method.
	//
	// For simple function calls: "FunctionName"
	// For qualified calls: "package.Function" or "receiver.Method"
	// For method calls: "Method" (receiver tracked separately)
	//
	// Example values:
	//   - "Setup" (local function)
	//   - "config.Load" (imported package function)
	//   - "Connect" (method call, Receiver="db")
	Target string `json:"target"`

	// Location is where the call expression occurs in the source file.
	// Points to the start of the call expression.
	Location Location `json:"location"`

	// IsMethod indicates if this is a method call (has a receiver).
	// True for: obj.Method(), s.Initialize()
	// False for: Function(), pkg.Function()
	IsMethod bool `json:"is_method,omitempty"`

	// Receiver is the receiver expression text for method calls.
	// Empty for plain function calls.
	//
	// Examples:
	//   - "db" for db.Connect()
	//   - "s" for s.Initialize()
	//   - "ctx" for ctx.Done()
	Receiver string `json:"receiver,omitempty"`

	// FunctionArgs lists identifiers passed as callback/HOF arguments.
	// Only populated when a call passes identifiers that may reference other functions.
	// IT-03a C-1: Enables EdgeTypeReferences from caller to callback arguments.
	//
	// Examples:
	//   - ["middleware"] for app.use(middleware)
	//   - ["LoggingInterceptor"] for UseInterceptors(LoggingInterceptor)
	FunctionArgs []string `json:"function_args,omitempty"`
}

CallSite represents a function or method call within a symbol's body.

Description:

CallSite captures the essential information about a function or method
call expression found during AST parsing. This enables the graph builder
to create EdgeTypeCalls edges for the find_callers and find_callees tools.

Used by:

  • GoParser.extractCallSites() to collect calls from function bodies
  • Builder.extractCallEdges() to create EdgeTypeCalls edges
  • find_callers/find_callees CRS tools for call graph queries

Thread Safety: CallSite is immutable after creation and safe for concurrent read.

func (*CallSite) Validate

func (c *CallSite) Validate() error

Validate checks if the CallSite has valid field values.

Returns nil if valid, or a ValidationError describing the issue.

Validates:

  • Target is non-empty
  • Location.StartLine is positive

type DockerfileParser

type DockerfileParser struct {
	// contains filtered or unexported fields
}

DockerfileParser extracts symbols from Dockerfile source files.

Description:

DockerfileParser uses tree-sitter to parse Dockerfiles and extract
structured symbol information including stages, ARG/ENV variables,
labels, exposed ports, and volumes.

Thread Safety:

DockerfileParser is safe for concurrent use. Multiple goroutines can call Parse
simultaneously. Each Parse call creates its own tree-sitter parser instance.

Example:

parser := NewDockerfileParser()
result, err := parser.Parse(ctx, content, "Dockerfile")
if err != nil {
    return fmt.Errorf("parse: %w", err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewDockerfileParser

func NewDockerfileParser(opts ...DockerfileParserOption) *DockerfileParser

NewDockerfileParser creates a new DockerfileParser with the given options.

Description:

Creates a parser configured for Dockerfile files. The parser can be
reused for multiple files and is safe for concurrent use.

Example:

// Default options
parser := NewDockerfileParser()

// With custom options
parser := NewDockerfileParser(
    WithDockerfileMaxFileSize(5 * 1024 * 1024),
)

func (*DockerfileParser) Extensions

func (p *DockerfileParser) Extensions() []string

Extensions returns the file extensions this parser handles.

func (*DockerfileParser) Language

func (p *DockerfileParser) Language() string

Language returns the language name for this parser.

func (*DockerfileParser) Parse

func (p *DockerfileParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from Dockerfile source code.

Description:

Parses the provided Dockerfile content using tree-sitter and extracts all
symbols including stages, variables, labels, ports, and volumes.

Inputs:

ctx      - Context for cancellation. Checked before/after parsing.
content  - Raw Dockerfile source bytes. Must be valid UTF-8.
filePath - Path to the file (relative to project root, for ID generation).

Outputs:

*ParseResult - Extracted symbols and metadata. Never nil on success.
error        - Non-nil only for complete failures (invalid UTF-8, too large).

Thread Safety:

This method is safe for concurrent use.

type DockerfileParserOption

type DockerfileParserOption func(*DockerfileParserOptions)

DockerfileParserOption is a functional option for configuring DockerfileParser.

func WithDockerfileMaxFileSize

func WithDockerfileMaxFileSize(size int) DockerfileParserOption

WithDockerfileMaxFileSize sets the maximum file size for parsing.

type DockerfileParserOptions

type DockerfileParserOptions struct {
	// MaxFileSize is the maximum file size in bytes to parse.
	// Files larger than this return ErrFileTooLarge.
	// Default: 10MB
	MaxFileSize int
}

DockerfileParserOptions configures DockerfileParser behavior.

func DefaultDockerfileParserOptions

func DefaultDockerfileParserOptions() DockerfileParserOptions

DefaultDockerfileParserOptions returns the default options.

type GoParser

type GoParser struct {
	// contains filtered or unexported fields
}

GoParser implements the Parser interface for Go source code.

Description:

GoParser uses tree-sitter to parse Go source files and extract symbols.
It supports concurrent use from multiple goroutines - each Parse call
creates its own tree-sitter parser instance internally.

Thread Safety:

GoParser instances are safe for concurrent use. Multiple goroutines
may call Parse simultaneously on the same GoParser instance.

Example:

parser := NewGoParser()
result, err := parser.Parse(ctx, []byte("package main\n\nfunc main() {}"), "main.go")
if err != nil {
    log.Fatal(err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewGoParser

func NewGoParser(opts ...GoParserOption) *GoParser

NewGoParser creates a new GoParser with the given options.

Description:

Creates a GoParser configured with sensible defaults. Options can be
provided to customize behavior such as maximum file size.

Inputs:

  • opts: Optional configuration functions (WithMaxFileSize, WithParseOptions)

Outputs:

  • *GoParser: Configured parser instance, never nil

Example:

// Default configuration
parser := NewGoParser()

// Custom max file size
parser := NewGoParser(WithMaxFileSize(5 * 1024 * 1024))

Thread Safety:

The returned GoParser is safe for concurrent use.

func (*GoParser) Extensions

func (p *GoParser) Extensions() []string

Extensions returns the file extensions this parser handles.

Returns:

  • []string{".go"} for Go source files

func (*GoParser) Language

func (p *GoParser) Language() string

Language returns the canonical language name for this parser.

Returns:

  • "go" for Go source files

func (*GoParser) Parse

func (p *GoParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from Go source code.

Description:

Parse uses tree-sitter to parse the provided Go source code and extract
all symbols (functions, methods, types, interfaces, etc.) into a ParseResult.
The parser is error-tolerant and will return partial results for syntactically
invalid code.

Inputs:

  • ctx: Context for cancellation. Checked before and after parsing. Note: Tree-sitter parsing itself cannot be interrupted mid-parse.
  • content: Raw Go source code bytes. Must be valid UTF-8.
  • filePath: Path to the file (for ID generation and error reporting). Should be relative to project root using forward slashes.

Outputs:

  • *ParseResult: Extracted symbols and metadata. Never nil on success. May contain partial results with errors for syntactically invalid code.
  • error: Non-nil for complete failures:
  • ErrFileTooLarge: Content exceeds maxFileSize
  • ErrInvalidContent: Content is not valid UTF-8
  • Context errors: Context was canceled or timed out

Example:

result, err := parser.Parse(ctx, []byte("package main\n\nfunc Hello() {}"), "main.go")
if err != nil {
    return err
}
fmt.Printf("Found %d symbols\n", len(result.Symbols))

Limitations:

  • Tree-sitter parsing is synchronous and cannot be interrupted mid-parse
  • Very large files may take significant time to parse
  • Some edge cases in Go syntax may not be fully handled

Assumptions:

  • Content is valid UTF-8 (validated internally)
  • FilePath uses forward slashes as path separator
  • FilePath does not contain path traversal sequences

Thread Safety:

This method is safe for concurrent use.

type GoParserOption

type GoParserOption func(*GoParser)

GoParserOption configures a GoParser instance.

func WithMaxFileSize

func WithMaxFileSize(bytes int64) GoParserOption

WithMaxFileSize sets the maximum file size the parser will accept.

Parameters:

  • bytes: Maximum file size in bytes. Must be positive.

Example:

parser := NewGoParser(WithMaxFileSize(5 * 1024 * 1024)) // 5MB limit

func WithParseOptions

func WithParseOptions(opts ParseOptions) GoParserOption

WithParseOptions applies the given ParseOptions to the parser.

Parameters:

  • opts: ParseOptions to apply.

Example:

parser := NewGoParser(WithParseOptions(ParseOptions{IncludePrivate: false}))

type HTMLParser

type HTMLParser struct {
	// contains filtered or unexported fields
}

HTMLParser extracts symbols from HTML source code.

Description:

HTMLParser uses tree-sitter to parse HTML source files and extract
structured symbol information including elements with IDs, forms,
custom elements (web components), and script/stylesheet references.
It delegates inline <script> and <style> content to JavaScriptParser
and CSSParser respectively.

Thread Safety:

HTMLParser is safe for concurrent use. Multiple goroutines can call Parse
simultaneously. Each Parse call creates its own tree-sitter parser instance.

Example:

parser := NewHTMLParser()
result, err := parser.Parse(ctx, content, "index.html")
if err != nil {
    return fmt.Errorf("parse: %w", err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewHTMLParser

func NewHTMLParser(opts ...HTMLParserOption) *HTMLParser

NewHTMLParser creates a new HTMLParser with the given options.

Description:

Creates a parser configured for HTML source files. The parser can be
reused for multiple files and is safe for concurrent use.

Example:

// Default options
parser := NewHTMLParser()

// With custom options
parser := NewHTMLParser(
    WithHTMLMaxFileSize(5 * 1024 * 1024),
    WithHTMLParseInlineScripts(false),
)

func (*HTMLParser) Extensions

func (p *HTMLParser) Extensions() []string

Extensions returns the file extensions this parser handles.

func (*HTMLParser) Language

func (p *HTMLParser) Language() string

Language returns the language name for this parser.

func (*HTMLParser) Parse

func (p *HTMLParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from HTML source code.

Description:

Parses the provided HTML content using tree-sitter and extracts all
symbols including elements with IDs, forms, custom elements, and imports.
Inline <script> and <style> content is delegated to the respective parsers.

Inputs:

ctx      - Context for cancellation. Checked before/after parsing and delegation.
content  - Raw HTML source bytes. Must be valid UTF-8.
filePath - Path to the file (relative to project root, for ID generation).

Outputs:

*ParseResult - Extracted symbols and metadata. Never nil on success.
error        - Non-nil only for complete failures (invalid UTF-8, too large).

Thread Safety:

This method is safe for concurrent use.

type HTMLParserOption

type HTMLParserOption func(*HTMLParserOptions)

HTMLParserOption is a functional option for configuring HTMLParser.

func WithHTMLMaxFileSize

func WithHTMLMaxFileSize(size int) HTMLParserOption

WithHTMLMaxFileSize sets the maximum file size for parsing.

func WithHTMLParseInlineScripts

func WithHTMLParseInlineScripts(parse bool) HTMLParserOption

WithHTMLParseInlineScripts sets whether to parse inline scripts.

func WithHTMLParseInlineStyles

func WithHTMLParseInlineStyles(parse bool) HTMLParserOption

WithHTMLParseInlineStyles sets whether to parse inline styles.

type HTMLParserOptions

type HTMLParserOptions struct {
	// MaxFileSize is the maximum file size in bytes to parse.
	// Files larger than this return ErrFileTooLarge.
	// Default: 10MB
	MaxFileSize int

	// ParseInlineScripts determines whether to parse inline <script> content.
	// Default: true
	ParseInlineScripts bool

	// ParseInlineStyles determines whether to parse inline <style> content.
	// Default: true
	ParseInlineStyles bool
}

HTMLParserOptions configures HTMLParser behavior.

func DefaultHTMLParserOptions

func DefaultHTMLParserOptions() HTMLParserOptions

DefaultHTMLParserOptions returns the default options.

type Import

type Import struct {
	// Path is the import path or module name.
	// Example: "github.com/gin-gonic/gin" for Go, "os.path" for Python.
	Path string `json:"path"`

	// Alias is the local alias if the import is aliased.
	// Example: "gin" for 'import "github.com/gin-gonic/gin"' (Go default).
	// Example: "pd" for 'import pandas as pd' (Python).
	Alias string `json:"alias,omitempty"`

	// Names lists specific names imported (for selective imports).
	// Example: ["useState", "useEffect"] for 'import { useState, useEffect } from "react"'.
	Names []string `json:"names,omitempty"`

	// IsWildcard indicates if this is a wildcard import.
	// Example: 'from module import *' in Python.
	IsWildcard bool `json:"is_wildcard,omitempty"`

	// IsRelative indicates if this is a relative import.
	// Example: 'from . import foo' or 'from ..utils import bar' in Python.
	// For absolute imports, this is false.
	IsRelative bool `json:"is_relative,omitempty"`

	// IsDefault indicates if this is a default import.
	// Example: 'import foo from "bar"' in JavaScript/TypeScript.
	IsDefault bool `json:"is_default,omitempty"`

	// IsNamespace indicates if this is a namespace import.
	// Example: 'import * as foo from "bar"' in JavaScript/TypeScript.
	IsNamespace bool `json:"is_namespace,omitempty"`

	// IsTypeOnly indicates if this is a type-only import.
	// Example: 'import type { Foo } from "bar"' in TypeScript.
	IsTypeOnly bool `json:"is_type_only,omitempty"`

	// IsCommonJS indicates if this is a CommonJS require() import.
	// Example: 'const foo = require("bar")' in JavaScript.
	IsCommonJS bool `json:"is_commonjs,omitempty"`

	// IsDynamic indicates this is a dynamic import() call inside a function body.
	// Example: 'const X = React.lazy(() => import("./HeavyComponent"))' in JavaScript.
	// When true, the import was detected inside an expression rather than at top level.
	// Enables the builder's resolveDynamicImportEdges post-pass and analytics filtering.
	IsDynamic bool `json:"is_dynamic,omitempty"`

	// IsScript indicates this is a script import (HTML <script src>).
	IsScript bool `json:"is_script,omitempty"`

	// IsStylesheet indicates this is a stylesheet import (HTML <link href> or CSS @import).
	IsStylesheet bool `json:"is_stylesheet,omitempty"`

	// IsModule indicates this is an ES module import.
	// For HTML: <script type="module">
	// For JS: import statement (vs require)
	IsModule bool `json:"is_module,omitempty"`

	// MediaQuery contains the media query for conditional imports.
	// Example: @import 'print.css' print → MediaQuery: "print"
	MediaQuery string `json:"media_query,omitempty"`

	// Location is where the import statement appears in the file.
	Location Location `json:"location"`
}

Import represents an import statement in source code.

Import statements are tracked separately for building the dependency graph and for seeding library documentation.

type JavaScriptParser

type JavaScriptParser struct {
	// contains filtered or unexported fields
}

JavaScriptParser extracts symbols from JavaScript source code.

Description:

JavaScriptParser uses tree-sitter to parse JavaScript source files and extract
structured symbol information. It supports all modern JavaScript features including
ES6+ modules, classes, async/await, generators, and private fields.

Thread Safety:

JavaScriptParser is safe for concurrent use. Multiple goroutines can call Parse
simultaneously. Each Parse call creates its own tree-sitter parser instance.

Example:

parser := NewJavaScriptParser()
result, err := parser.Parse(ctx, content, "app.js")
if err != nil {
    return fmt.Errorf("parse: %w", err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewJavaScriptParser

func NewJavaScriptParser(opts ...JavaScriptParserOption) *JavaScriptParser

NewJavaScriptParser creates a new JavaScriptParser with the given options.

Description:

Creates a parser configured for JavaScript source files. The parser can be
reused for multiple files and is safe for concurrent use.

Example:

// Default options
parser := NewJavaScriptParser()

// With custom options
parser := NewJavaScriptParser(
    WithJSMaxFileSize(5 * 1024 * 1024),
    WithJSIncludePrivate(false),
)

func (*JavaScriptParser) Extensions

func (p *JavaScriptParser) Extensions() []string

Extensions returns the file extensions this parser handles.

func (*JavaScriptParser) Language

func (p *JavaScriptParser) Language() string

Language returns the language name for this parser.

func (*JavaScriptParser) Parse

func (p *JavaScriptParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from JavaScript source code.

Description:

Parses the provided JavaScript content using tree-sitter and extracts all
symbols including functions, classes, methods, fields, variables, and imports.

Inputs:

ctx      - Context for cancellation. Checked before and after parsing.
content  - Raw JavaScript source bytes. Must be valid UTF-8.
filePath - Path to the file (relative to project root, for ID generation).

Outputs:

*ParseResult - Extracted symbols and metadata. Never nil on success.
error        - Non-nil only for complete failures (invalid UTF-8, too large).

Thread Safety:

This method is safe for concurrent use.

type JavaScriptParserOption

type JavaScriptParserOption func(*JavaScriptParserOptions)

JavaScriptParserOption is a functional option for configuring JavaScriptParser.

func WithJSExtractBodies

func WithJSExtractBodies(extract bool) JavaScriptParserOption

WithJSExtractBodies sets whether to include function bodies.

func WithJSIncludePrivate

func WithJSIncludePrivate(include bool) JavaScriptParserOption

WithJSIncludePrivate sets whether to include non-exported symbols.

func WithJSMaxFileSize

func WithJSMaxFileSize(size int) JavaScriptParserOption

WithJSMaxFileSize sets the maximum file size for parsing.

type JavaScriptParserOptions

type JavaScriptParserOptions struct {
	// MaxFileSize is the maximum file size in bytes to parse.
	// Files larger than this return ErrFileTooLarge.
	// Default: 10MB
	MaxFileSize int

	// IncludePrivate determines whether to include non-exported symbols.
	// Default: true
	IncludePrivate bool

	// ExtractBodies determines whether to include function body text.
	// Default: false (bodies are expensive and often not needed)
	ExtractBodies bool
}

JavaScriptParserOptions configures JavaScriptParser behavior.

func DefaultJavaScriptParserOptions

func DefaultJavaScriptParserOptions() JavaScriptParserOptions

DefaultJavaScriptParserOptions returns the default options.

type Location

type Location struct {
	// FilePath is the path to the source file, relative to project root.
	FilePath string `json:"file_path"`

	// StartLine is the 1-indexed line number where the symbol starts.
	StartLine int `json:"start_line"`

	// EndLine is the 1-indexed line number where the symbol ends.
	EndLine int `json:"end_line"`

	// StartCol is the 0-indexed column where the symbol starts on StartLine.
	StartCol int `json:"start_col"`

	// EndCol is the 0-indexed column where the symbol ends on EndLine.
	EndCol int `json:"end_col"`
}

Location represents a position range within a source file.

Line numbers are 1-indexed (first line is 1). Column numbers are 0-indexed (first column is 0). This matches the convention used by most editors and LSP.

func (Location) String

func (l Location) String() string

String returns a human-readable representation of the location.

Format: "file_path:start_line:start_col"

type MarkdownParser

type MarkdownParser struct {
	// contains filtered or unexported fields
}

MarkdownParser extracts symbols from Markdown source files.

Description:

MarkdownParser uses tree-sitter to parse Markdown files and extract
structured symbol information including headings, code blocks, links,
and lists.

Thread Safety:

MarkdownParser is safe for concurrent use. Multiple goroutines can call Parse
simultaneously. Each Parse call creates its own tree-sitter parser instance.

Example:

parser := NewMarkdownParser()
result, err := parser.Parse(ctx, content, "README.md")
if err != nil {
    return fmt.Errorf("parse: %w", err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewMarkdownParser

func NewMarkdownParser(opts ...MarkdownParserOption) *MarkdownParser

NewMarkdownParser creates a new MarkdownParser with the given options.

Description:

Creates a parser configured for Markdown files. The parser can be
reused for multiple files and is safe for concurrent use.

Example:

// Default options
parser := NewMarkdownParser()

// With custom options
parser := NewMarkdownParser(
    WithMarkdownMaxFileSize(5 * 1024 * 1024),
    WithMarkdownMaxHeadingDepth(3),
)

func (*MarkdownParser) Extensions

func (p *MarkdownParser) Extensions() []string

Extensions returns the file extensions this parser handles.

func (*MarkdownParser) Language

func (p *MarkdownParser) Language() string

Language returns the language name for this parser.

func (*MarkdownParser) Parse

func (p *MarkdownParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from Markdown source code.

Description:

Parses the provided Markdown content using tree-sitter and extracts all
symbols including headings, code blocks, links, and lists.

Inputs:

ctx      - Context for cancellation. Checked before/after parsing.
content  - Raw Markdown source bytes. Must be valid UTF-8.
filePath - Path to the file (relative to project root, for ID generation).

Outputs:

*ParseResult - Extracted symbols and metadata. Never nil on success.
error        - Non-nil only for complete failures (invalid UTF-8, too large).

Thread Safety:

This method is safe for concurrent use.

type MarkdownParserOption

type MarkdownParserOption func(*MarkdownParserOptions)

MarkdownParserOption is a functional option for configuring MarkdownParser.

func WithMarkdownExtractCodeBlocks

func WithMarkdownExtractCodeBlocks(extract bool) MarkdownParserOption

WithMarkdownExtractCodeBlocks sets whether to extract code blocks.

func WithMarkdownExtractLinks(extract bool) MarkdownParserOption

WithMarkdownExtractLinks sets whether to extract link definitions.

func WithMarkdownExtractLists

func WithMarkdownExtractLists(extract bool) MarkdownParserOption

WithMarkdownExtractLists sets whether to extract lists.

func WithMarkdownMaxFileSize

func WithMarkdownMaxFileSize(size int) MarkdownParserOption

WithMarkdownMaxFileSize sets the maximum file size for parsing.

func WithMarkdownMaxHeadingDepth

func WithMarkdownMaxHeadingDepth(depth int) MarkdownParserOption

WithMarkdownMaxHeadingDepth sets the maximum heading depth to extract.

type MarkdownParserOptions

type MarkdownParserOptions struct {
	// MaxFileSize is the maximum file size in bytes to parse.
	// Files larger than this return ErrFileTooLarge.
	// Default: 10MB
	MaxFileSize int

	// MaxHeadingDepth is the maximum heading level to extract (1-6).
	// Default: 6 (extract all headings)
	MaxHeadingDepth int

	// ExtractCodeBlocks determines whether to extract fenced code blocks.
	// Default: true
	ExtractCodeBlocks bool

	// ExtractLinks determines whether to extract link reference definitions.
	// Default: true
	ExtractLinks bool

	// ExtractLists determines whether to extract lists.
	// Default: true
	ExtractLists bool
}

MarkdownParserOptions configures MarkdownParser behavior.

func DefaultMarkdownParserOptions

func DefaultMarkdownParserOptions() MarkdownParserOptions

DefaultMarkdownParserOptions returns the default options.

type MethodSignature

type MethodSignature struct {
	// Name is the method name.
	// Example: "Read", "Write", "Close"
	Name string `json:"name"`

	// Params is the normalized parameter list (types only, no names).
	// Example: "[]byte" for func Read(p []byte) (int, error)
	// Used for Phase 2 signature matching.
	Params string `json:"params,omitempty"`

	// Returns is the normalized return type list.
	// Example: "int, error" for func Read(p []byte) (int, error)
	// Used for Phase 2 signature matching.
	Returns string `json:"returns,omitempty"`

	// ParamCount is the number of parameters.
	// Used for quick filtering before detailed signature comparison.
	ParamCount int `json:"param_count"`

	// ReturnCount is the number of return values.
	// Used for quick filtering before detailed signature comparison.
	ReturnCount int `json:"return_count"`

	// ReceiverType is the receiver type for methods (e.g., "*Handler", "Handler").
	// Empty for interface method declarations.
	// Used to distinguish value vs pointer receivers.
	ReceiverType string `json:"receiver_type,omitempty"`
}

MethodSignature represents a method's signature for interface implementation detection.

This struct captures the essential signature information needed to determine if a type implements an interface via method-set matching. It focuses on structural compatibility rather than exact type matching.

For Go interface implementation detection, we compare method names and parameter/return counts. Full type checking would require go/types which needs the complete compilation context.

type ParseError

type ParseError struct {
	// FilePath is the path to the file where the error occurred.
	FilePath string

	// Line is the 1-indexed line number where the error occurred.
	// May be 0 if the error is not associated with a specific line.
	Line int

	// Column is the 0-indexed column where the error occurred.
	// May be 0 if the error is not associated with a specific column.
	Column int

	// Message describes the error in human-readable form.
	Message string

	// Cause is the underlying error that triggered this parse error.
	// May be nil if this is a primary error.
	Cause error
}

ParseError provides detailed information about a parse failure.

ParseError wraps an underlying error with additional context about where the error occurred in the source file. It implements the error interface and can be unwrapped to access the underlying cause.

Example:

result, err := parser.Parse(ctx, content, "main.go")
if err != nil {
    var parseErr *ParseError
    if errors.As(err, &parseErr) {
        fmt.Printf("Error at %s:%d:%d: %s\n",
            parseErr.FilePath, parseErr.Line, parseErr.Column, parseErr.Message)
    }
}

func NewParseError

func NewParseError(filePath string, line, column int, message string) *ParseError

NewParseError creates a new ParseError with the given details.

Parameters:

  • filePath: Path to the file where the error occurred.
  • line: 1-indexed line number (0 if unknown).
  • column: 0-indexed column number (0 if unknown).
  • message: Human-readable error description.

Returns:

A new ParseError instance.

func NewParseErrorWithCause

func NewParseErrorWithCause(filePath string, line, column int, message string, cause error) *ParseError

NewParseErrorWithCause creates a new ParseError wrapping an underlying error.

Parameters:

  • filePath: Path to the file where the error occurred.
  • line: 1-indexed line number (0 if unknown).
  • column: 0-indexed column number (0 if unknown).
  • message: Human-readable error description.
  • cause: The underlying error that triggered this failure.

Returns:

A new ParseError instance wrapping the cause.

func (*ParseError) Error

func (e *ParseError) Error() string

Error returns a formatted error message including file location.

Format depends on available location information:

  • With line and column: "file.go:10:5: unexpected token"
  • With line only: "file.go:10: unexpected token"
  • Without location: "file.go: unexpected token"

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

Unwrap returns the underlying cause error.

This enables use with errors.Is() and errors.As() to check or extract the underlying error.

type ParseOptions

type ParseOptions struct {
	// IncludeComments determines whether to extract comments as symbols.
	// Default: false (comments extracted as DocComment on associated symbols only)
	IncludeComments bool

	// IncludePrivate determines whether to include non-exported symbols.
	// Default: true (include all symbols)
	IncludePrivate bool

	// MaxDepth limits the nesting depth for child symbol extraction.
	// 0 means no limit. Default: 0
	MaxDepth int

	// ExtractBodies determines whether to include function/method body text.
	// Default: false (bodies are expensive and often not needed)
	ExtractBodies bool
}

ParseOptions configures parser behavior.

Parsers may accept ParseOptions to customize their behavior. Not all options are supported by all parsers.

func DefaultParseOptions

func DefaultParseOptions() ParseOptions

DefaultParseOptions returns the default parse options.

type ParseResult

type ParseResult struct {
	// FilePath is the path to the parsed file, relative to project root.
	FilePath string `json:"file_path"`

	// Language is the detected or specified language of the file.
	// Example: "go", "python", "typescript"
	Language string `json:"language"`

	// Symbols contains all symbols extracted from the file.
	// Symbols are in source order (top to bottom).
	// Note: Import statements appear here as SymbolKindImport entries.
	Symbols []*Symbol `json:"symbols"`

	// Imports lists all import statements with structured metadata.
	// Use this field for dependency resolution and library documentation seeding.
	// See Import type for details on the structured import data.
	Imports []Import `json:"imports"`

	// Package is the package/module name declared in the file.
	// May be empty for languages without package declarations.
	Package string `json:"package"`

	// ParsedAtMilli is the Unix timestamp in milliseconds when parsing completed.
	ParsedAtMilli int64 `json:"parsed_at_milli"`

	// ParseDurationMs is how long parsing took in milliseconds.
	ParseDurationMs int64 `json:"parse_duration_ms"`

	// Errors contains non-fatal parse errors encountered.
	// The parse may still produce partial results despite errors.
	Errors []string `json:"errors,omitempty"`

	// Hash is the SHA256 hash of the file content at parse time.
	// Used for cache invalidation and staleness detection.
	Hash string `json:"hash"`
}

ParseResult contains the output of parsing a single source file.

This struct is returned by Parser.Parse() and contains all symbols extracted from the file along with metadata about the parse operation.

Import Handling

Imports are stored in two places by design:

  • Imports field: Structured data optimized for dependency resolution and library seeding (path, alias, specific names imported)
  • Symbols field: Import symbols with Kind=SymbolKindImport for graph building and location tracking (consistent with other symbol types)

This duplication is intentional: the Imports field provides rich import metadata (aliases, selective imports, wildcards) while the Symbols field maintains a uniform representation for graph construction. Consumers should use Imports for dependency analysis and Symbols for code navigation.

func (*ParseResult) HasErrors

func (r *ParseResult) HasErrors() bool

HasErrors returns true if the parse result contains any errors.

func (*ParseResult) SetParsedAt

func (r *ParseResult) SetParsedAt()

SetParsedAt sets the ParsedAtMilli field to the current time.

func (*ParseResult) SymbolCount

func (r *ParseResult) SymbolCount() int

SymbolCount returns the total number of symbols in the parse result, including nested children up to MaxSymbolDepth levels.

Uses an iterative approach with explicit stack to prevent stack overflow from deeply nested symbol hierarchies.

func (*ParseResult) SymbolCountWithDepth

func (r *ParseResult) SymbolCountWithDepth(maxDepth int) int

SymbolCountWithDepth returns the total number of symbols up to the specified depth.

Parameters:

  • maxDepth: Maximum nesting depth to traverse. 0 means only top-level symbols. Use MaxSymbolDepth constant for default safe limit.

Uses an iterative approach with explicit stack to prevent stack overflow.

func (*ParseResult) Validate

func (r *ParseResult) Validate() error

Validate checks if the ParseResult has valid field values.

Returns nil if valid, or a ValidationError describing the first invalid field.

Validates:

  • FilePath is non-empty and doesn't contain path traversal
  • Language is non-empty
  • All Symbols are valid (via Symbol.Validate())
  • All Imports have valid locations

type Parser

type Parser interface {
	// Parse extracts symbols and metadata from source code.
	//
	// The method parses the provided content and returns a ParseResult containing
	// all extracted symbols, imports, and metadata. Parsing should be resilient
	// to syntax errors, returning partial results when possible.
	//
	// Parameters:
	//   - ctx: Context for cancellation. Long-running parses should check ctx.Done().
	//   - content: Raw source code bytes (must be valid UTF-8).
	//   - filePath: Path to the file (relative to project root, for ID generation).
	//
	// Returns:
	//   - *ParseResult: Extracted symbols and metadata. Never nil on success.
	//   - error: Non-nil only for complete parse failures (e.g., invalid UTF-8).
	//            Syntax errors are reported in ParseResult.Errors.
	//
	// Thread Safety:
	//   Implementations should be safe for concurrent use. Multiple goroutines
	//   may call Parse simultaneously with different content.
	Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

	// Language returns the canonical name of the language this parser handles.
	//
	// Returns a lowercase string identifying the language:
	//   - "go" for Go
	//   - "python" for Python
	//   - "typescript" for TypeScript
	//   - "javascript" for JavaScript
	//   - "html" for HTML
	//   - "css" for CSS
	//
	// This value is used for:
	//   - Setting ParseResult.Language and Symbol.Language
	//   - Parser selection based on file type
	//   - Logging and debugging
	Language() string

	// Extensions returns the file extensions this parser can handle.
	//
	// Returns a slice of extensions including the leading dot:
	//   - Go: [".go"]
	//   - Python: [".py", ".pyi"]
	//   - TypeScript: [".ts", ".tsx", ".mts", ".cts"]
	//   - JavaScript: [".js", ".jsx", ".mjs", ".cjs"]
	//   - HTML: [".html", ".htm"]
	//   - CSS: [".css"]
	//
	// Extensions are used by the parser registry to select the appropriate
	// parser for a given file. Extensions are case-sensitive and should
	// be lowercase.
	Extensions() []string
}

Parser defines the contract for language-specific AST parsing.

Description:

Parser implementations extract structured symbol information from source code.
Each implementation handles a specific programming language (Go, Python, TypeScript, etc.)
but produces output in the common ParseResult format defined in types.go.

The Parser interface is designed to be:
- Context-aware: Supports cancellation and timeouts via context.Context
- Language-agnostic: Common output format regardless of source language
- Error-tolerant: Partial results returned even when parse errors occur

Inputs:

ctx      - Context for cancellation and timeout control. Implementations should
           check ctx.Done() during long-running operations.
content  - Raw source code bytes to parse. Must be valid UTF-8.
filePath - Path to the file being parsed (for error reporting and ID generation).
           Should be relative to project root for consistency.

Outputs:

*ParseResult - Contains extracted symbols, imports, and metadata.
               May contain partial results even when errors occur.
error        - Non-nil if parsing failed completely. Partial failures
               are reported in ParseResult.Errors instead.

Example:

parser := NewGoParser()
content, _ := os.ReadFile("main.go")
result, err := parser.Parse(ctx, content, "main.go")
if err != nil {
    return fmt.Errorf("parse failed: %w", err)
}
for _, symbol := range result.Symbols {
    fmt.Printf("%s: %s at line %d\n", symbol.Kind, symbol.Name, symbol.StartLine)
}

Limitations:

  • Does not resolve type information across files (single-file analysis only)
  • May produce incomplete results for syntactically invalid code
  • Language-specific edge cases may not be fully handled
  • Does not perform semantic analysis (type checking, reference resolution)

Assumptions:

  • Content is valid UTF-8 encoded text
  • FilePath uses forward slashes as path separator
  • File extension matches the parser's supported extensions
  • Caller handles concurrent access if sharing parser instances

type ParserRegistry

type ParserRegistry struct {
	// contains filtered or unexported fields
}

ParserRegistry manages parser instances by language and file extension.

Description:

ParserRegistry provides a central lookup mechanism for finding the appropriate
parser for a given file or language. It supports registration of multiple
parsers and lookup by language name or file extension.

Thread Safety:

ParserRegistry is fully thread-safe. All methods can be called concurrently
from multiple goroutines. Registration uses write locks, lookups use read locks.

func NewParserRegistry

func NewParserRegistry() *ParserRegistry

NewParserRegistry creates a new empty ParserRegistry.

func (*ParserRegistry) Extensions

func (r *ParserRegistry) Extensions() []string

Extensions returns a list of all registered file extensions.

Thread Safety: This method is safe for concurrent use.

func (*ParserRegistry) GetByExtension

func (r *ParserRegistry) GetByExtension(ext string) (Parser, bool)

GetByExtension returns the parser for the given file extension.

Thread Safety: This method is safe for concurrent use.

Parameters:

  • ext: The file extension including the dot (e.g., ".go", ".py"). Case-sensitive.

Returns:

  • Parser: The registered parser, or nil if not found.
  • bool: True if a parser was found.

func (*ParserRegistry) GetByLanguage

func (r *ParserRegistry) GetByLanguage(language string) (Parser, bool)

GetByLanguage returns the parser for the given language name.

Thread Safety: This method is safe for concurrent use.

Parameters:

  • language: The language name (e.g., "go", "python"). Case-sensitive.

Returns:

  • Parser: The registered parser, or nil if not found.
  • bool: True if a parser was found.

func (*ParserRegistry) Languages

func (r *ParserRegistry) Languages() []string

Languages returns a list of all registered language names.

Thread Safety: This method is safe for concurrent use.

func (*ParserRegistry) Register

func (r *ParserRegistry) Register(parser Parser)

Register adds a parser to the registry.

The parser is registered under its Language() name and all its Extensions(). If a language or extension is already registered, it will be overwritten.

Thread Safety: This method is safe for concurrent use.

Parameters:

  • parser: The parser to register. Must not be nil.

Example:

registry := NewParserRegistry()
registry.Register(NewGoParser())
registry.Register(NewPythonParser())

type PythonParser

type PythonParser struct {
	// contains filtered or unexported fields
}

PythonParser implements the Parser interface for Python source code.

Description:

PythonParser uses tree-sitter to parse Python source files and extract symbols.
It supports concurrent use from multiple goroutines - each Parse call
creates its own tree-sitter parser instance internally.

Thread Safety:

PythonParser instances are safe for concurrent use. Multiple goroutines
may call Parse simultaneously on the same PythonParser instance.

Example:

parser := NewPythonParser()
result, err := parser.Parse(ctx, []byte("def hello(): pass"), "main.py")
if err != nil {
    log.Fatal(err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewPythonParser

func NewPythonParser(opts ...PythonParserOption) *PythonParser

NewPythonParser creates a new PythonParser with the given options.

Description:

Creates a PythonParser configured with sensible defaults. Options can be
provided to customize behavior such as maximum file size.

Inputs:

  • opts: Optional configuration functions (WithPythonMaxFileSize, WithPythonParseOptions)

Outputs:

  • *PythonParser: Configured parser instance, never nil

Example:

// Default configuration
parser := NewPythonParser()

// Custom max file size
parser := NewPythonParser(WithPythonMaxFileSize(5 * 1024 * 1024))

Thread Safety:

The returned PythonParser is safe for concurrent use.

func (*PythonParser) Extensions

func (p *PythonParser) Extensions() []string

Extensions returns the file extensions this parser handles.

Returns:

  • []string{".py", ".pyi"} for Python source and stub files

func (*PythonParser) Language

func (p *PythonParser) Language() string

Language returns the canonical language name for this parser.

Returns:

  • "python" for Python source files

func (*PythonParser) Parse

func (p *PythonParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from Python source code.

Description:

Parse uses tree-sitter to parse the provided Python source code and extract
all symbols (functions, classes, methods, etc.) into a ParseResult.
The parser is error-tolerant and will return partial results for syntactically
invalid code.

Inputs:

  • ctx: Context for cancellation. Checked before and after parsing. Note: Tree-sitter parsing itself cannot be interrupted mid-parse.
  • content: Raw Python source code bytes. Must be valid UTF-8.
  • filePath: Path to the file (for ID generation and error reporting). Should be relative to project root using forward slashes.

Outputs:

  • *ParseResult: Extracted symbols and metadata. Never nil on success. May contain partial results with errors for syntactically invalid code.
  • error: Non-nil for complete failures:
  • ErrFileTooLarge: Content exceeds maxFileSize
  • ErrInvalidContent: Content is not valid UTF-8
  • Context errors: Context was canceled or timed out

Example:

result, err := parser.Parse(ctx, []byte("def hello(): pass"), "main.py")
if err != nil {
    return err
}
fmt.Printf("Found %d symbols\n", len(result.Symbols))

Limitations:

  • Tree-sitter parsing is synchronous and cannot be interrupted mid-parse
  • Very large files may take significant time to parse
  • Some edge cases in Python syntax may not be fully handled

Assumptions:

  • Content is valid UTF-8 (validated internally)
  • FilePath uses forward slashes as path separator
  • FilePath does not contain path traversal sequences

Thread Safety:

This method is safe for concurrent use.

type PythonParserOption

type PythonParserOption func(*PythonParser)

PythonParserOption configures a PythonParser instance.

func WithPythonMaxFileSize

func WithPythonMaxFileSize(bytes int64) PythonParserOption

WithPythonMaxFileSize sets the maximum file size the parser will accept.

Parameters:

  • bytes: Maximum file size in bytes. Must be positive.

Example:

parser := NewPythonParser(WithPythonMaxFileSize(5 * 1024 * 1024)) // 5MB limit

func WithPythonParseOptions

func WithPythonParseOptions(opts ParseOptions) PythonParserOption

WithPythonParseOptions applies the given ParseOptions to the parser.

Parameters:

  • opts: ParseOptions to apply.

Example:

parser := NewPythonParser(WithPythonParseOptions(ParseOptions{IncludePrivate: false}))

type SQLParser

type SQLParser struct {
	// contains filtered or unexported fields
}

SQLParser extracts symbols from SQL source code.

Description:

SQLParser uses tree-sitter to parse SQL source files and extract
structured symbol information including tables, columns, views,
indexes, and constraints.

Thread Safety:

SQLParser is safe for concurrent use. Multiple goroutines can call Parse
simultaneously. Each Parse call creates its own tree-sitter parser instance.

Example:

parser := NewSQLParser()
result, err := parser.Parse(ctx, content, "schema.sql")
if err != nil {
    return fmt.Errorf("parse: %w", err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewSQLParser

func NewSQLParser(opts ...SQLParserOption) *SQLParser

NewSQLParser creates a new SQLParser with the given options.

Description:

Creates a parser configured for SQL source files. The parser can be
reused for multiple files and is safe for concurrent use.

Example:

// Default options
parser := NewSQLParser()

// With custom options
parser := NewSQLParser(
    WithSQLMaxFileSize(5 * 1024 * 1024),
    WithSQLExtractColumns(false),
)

func (*SQLParser) Extensions

func (p *SQLParser) Extensions() []string

Extensions returns the file extensions this parser handles.

func (*SQLParser) Language

func (p *SQLParser) Language() string

Language returns the language name for this parser.

func (*SQLParser) Parse

func (p *SQLParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from SQL source code.

Description:

Parses the provided SQL content using tree-sitter and extracts all
symbols including tables, columns, views, and indexes.

Inputs:

ctx      - Context for cancellation. Checked before/after parsing.
content  - Raw SQL source bytes. Must be valid UTF-8.
filePath - Path to the file (relative to project root, for ID generation).

Outputs:

*ParseResult - Extracted symbols and metadata. Never nil on success.
error        - Non-nil only for complete failures (invalid UTF-8, too large).

Thread Safety:

This method is safe for concurrent use.

type SQLParserOption

type SQLParserOption func(*SQLParserOptions)

SQLParserOption is a functional option for configuring SQLParser.

func WithSQLExtractColumns

func WithSQLExtractColumns(extract bool) SQLParserOption

WithSQLExtractColumns sets whether to extract individual columns.

func WithSQLMaxFileSize

func WithSQLMaxFileSize(size int) SQLParserOption

WithSQLMaxFileSize sets the maximum file size for parsing.

type SQLParserOptions

type SQLParserOptions struct {
	// MaxFileSize is the maximum file size in bytes to parse.
	// Files larger than this return ErrFileTooLarge.
	// Default: 10MB
	MaxFileSize int

	// ExtractColumns determines whether to extract individual columns.
	// Default: true
	ExtractColumns bool
}

SQLParserOptions configures SQLParser behavior.

func DefaultSQLParserOptions

func DefaultSQLParserOptions() SQLParserOptions

DefaultSQLParserOptions returns the default options.

type Symbol

type Symbol struct {
	// ID is a unique identifier for this symbol.
	// Format: "file_path:start_line:name"
	// Example: "handlers/agent.go:27:HandleAgent"
	ID string `json:"id"`

	// Name is the symbol's identifier as it appears in source code.
	// Example: "HandleAgent", "UserService", "MAX_RETRIES"
	Name string `json:"name"`

	// Kind indicates what type of symbol this is (function, struct, etc.).
	Kind SymbolKind `json:"kind"`

	// FilePath is the path to the containing file, relative to project root.
	FilePath string `json:"file_path"`

	// StartLine is the 1-indexed line number where the symbol definition starts.
	StartLine int `json:"start_line"`

	// EndLine is the 1-indexed line number where the symbol definition ends.
	EndLine int `json:"end_line"`

	// StartCol is the 0-indexed column where the symbol starts on StartLine.
	StartCol int `json:"start_col"`

	// EndCol is the 0-indexed column where the symbol ends on EndLine.
	EndCol int `json:"end_col"`

	// Signature is the type signature or declaration.
	// Example: "func(ctx context.Context) error" for a Go function.
	Signature string `json:"signature"`

	// DocComment is the documentation comment associated with the symbol.
	// Extracted from preceding comment blocks (GoDoc, docstrings, JSDoc, etc.).
	DocComment string `json:"doc_comment"`

	// Receiver is the receiver type name for methods.
	// Empty for non-method symbols.
	// Example: "UserService" for method "func (s *UserService) Create(...)"
	Receiver string `json:"receiver"`

	// Package is the package or module name containing this symbol.
	// Example: "handlers" for Go, "myapp.services" for Python.
	Package string `json:"package"`

	// Exported indicates whether the symbol is publicly visible.
	// In Go: starts with uppercase. In Python: not prefixed with underscore.
	// In TypeScript: has "export" keyword.
	Exported bool `json:"exported"`

	// Language is the programming language of the source file.
	// Example: "go", "python", "typescript"
	Language string `json:"language"`

	// ParsedAtMilli is the Unix timestamp in milliseconds when this symbol was parsed.
	// Used for cache invalidation and staleness detection.
	ParsedAtMilli int64 `json:"parsed_at_milli"`

	// Children contains nested symbols (e.g., methods within a class).
	// May be nil if the symbol has no children.
	Children []*Symbol `json:"children,omitempty"`

	// Metadata contains language-specific additional information.
	// Examples: decorators for Python, generics for TypeScript.
	// Keys are well-defined strings, not arbitrary data.
	Metadata *SymbolMetadata `json:"metadata,omitempty"`

	// Calls contains function/method calls made within this symbol's body.
	// Only populated for functions and methods during AST parsing.
	// Used by the graph builder to create EdgeTypeCalls edges.
	// See GR-41: Call Edge Extraction for find_callers/find_callees.
	Calls []CallSite `json:"calls,omitempty"`

	// TypeReferences contains type identifiers referenced in this symbol's type annotations.
	// Populated for functions/methods (parameter types, return types) and variables (type annotations).
	// Used by the graph builder to create EdgeTypeReferences edges.
	// IT-06 Bug 9: Enables graph-based discovery of type usage across the codebase.
	// Primitives and language-specific constructs (e.g., str, int, Optional, List) are excluded.
	TypeReferences []TypeReference `json:"type_references,omitempty"`
}

Symbol represents a code symbol extracted from AST parsing.

A symbol is any named code construct: function, type, variable, etc. Symbols form the nodes in the code graph, with edges representing relationships like "calls", "implements", or "imports".

Note: All timestamps are int64 UnixMilli per project conventions.

func (*Symbol) Location

func (s *Symbol) Location() Location

Location returns the symbol's location as a Location struct.

func (*Symbol) SetParsedAt

func (s *Symbol) SetParsedAt()

SetParsedAt sets the ParsedAtMilli field to the current time.

func (*Symbol) Validate

func (s *Symbol) Validate() error

Validate checks if the Symbol has valid field values.

Returns nil if valid, or a ValidationError describing the first invalid field.

Validates:

  • Name is non-empty
  • FilePath is non-empty and doesn't contain path traversal
  • StartLine is positive (1-indexed)
  • EndLine >= StartLine
  • StartCol is non-negative (0-indexed)
  • EndCol >= 0
  • Language is non-empty

type SymbolKind

type SymbolKind int

SymbolKind represents the type of code symbol extracted from source code.

Each kind maps to a common programming construct that exists across multiple languages. Language-specific constructs are mapped to the closest general kind (e.g., Python's class maps to Struct).

const (
	// SymbolKindUnknown indicates an unrecognized or unparseable symbol.
	SymbolKindUnknown SymbolKind = iota

	// SymbolKindPackage represents a package or module declaration.
	// Examples: Go package, Python module, TypeScript namespace.
	SymbolKindPackage

	// SymbolKindFile represents a source file as a symbol.
	// Used for file-level relationships like imports.
	SymbolKindFile

	// SymbolKindFunction represents a standalone function declaration.
	// Examples: Go func, Python def, TypeScript function.
	SymbolKindFunction

	// SymbolKindMethod represents a function attached to a type/class.
	// Examples: Go method with receiver, Python class method, TypeScript class method.
	SymbolKindMethod

	// SymbolKindInterface represents an interface or protocol definition.
	// Examples: Go interface, Python Protocol (typing), TypeScript interface.
	SymbolKindInterface

	// SymbolKindStruct represents a composite data type.
	// Examples: Go struct, Python class, TypeScript class.
	SymbolKindStruct

	// SymbolKindType represents a type alias or definition.
	// Examples: Go type alias, TypeScript type alias.
	SymbolKindType

	// SymbolKindVariable represents a variable declaration.
	// Examples: Go var, Python variable, TypeScript let/const.
	SymbolKindVariable

	// SymbolKindConstant represents a constant declaration.
	// Examples: Go const, Python CONSTANT (by convention), TypeScript const.
	SymbolKindConstant

	// SymbolKindField represents a field within a struct/class.
	// Examples: Go struct field, Python class attribute, TypeScript class property.
	SymbolKindField

	// SymbolKindImport represents an import statement.
	// Examples: Go import, Python import/from, TypeScript import.
	SymbolKindImport

	// SymbolKindClass represents a class definition (alias for Struct in OOP languages).
	// Used primarily for Python and TypeScript where "class" is the idiomatic term.
	SymbolKindClass

	// SymbolKindDecorator represents a decorator or annotation.
	// Examples: Python @decorator, TypeScript @decorator.
	SymbolKindDecorator

	// SymbolKindEnum represents an enumeration type.
	// Examples: Go const block with iota, TypeScript enum.
	SymbolKindEnum

	// SymbolKindEnumMember represents a member of an enumeration.
	SymbolKindEnumMember

	// SymbolKindParameter represents a function/method parameter.
	SymbolKindParameter

	// SymbolKindProperty represents a property (getter/setter).
	// Examples: Python @property, TypeScript get/set accessors.
	SymbolKindProperty

	// SymbolKindCSSClass represents a CSS class selector.
	SymbolKindCSSClass

	// SymbolKindCSSID represents a CSS ID selector.
	SymbolKindCSSID

	// SymbolKindCSSVariable represents a CSS custom property (variable).
	SymbolKindCSSVariable

	// SymbolKindAnimation represents a CSS animation or keyframes.
	SymbolKindAnimation

	// SymbolKindMediaQuery represents a CSS media query.
	SymbolKindMediaQuery

	// SymbolKindComponent represents a UI component (HTML custom element, React component).
	SymbolKindComponent

	// SymbolKindElement represents an HTML element with an ID.
	SymbolKindElement

	// SymbolKindForm represents an HTML form.
	SymbolKindForm

	// SymbolKindTable represents a SQL table definition.
	SymbolKindTable

	// SymbolKindColumn represents a SQL column definition.
	SymbolKindColumn

	// SymbolKindView represents a SQL view definition.
	SymbolKindView

	// SymbolKindIndex represents a SQL index definition.
	SymbolKindIndex

	// SymbolKindTrigger represents a SQL trigger definition.
	SymbolKindTrigger

	// SymbolKindProcedure represents a SQL stored procedure.
	SymbolKindProcedure

	// SymbolKindSchema represents a SQL schema/database.
	SymbolKindSchema

	// SymbolKindConstraint represents a SQL constraint (PRIMARY KEY, FOREIGN KEY, etc).
	SymbolKindConstraint

	// SymbolKindKey represents a YAML key in a mapping.
	SymbolKindKey

	// SymbolKindAnchor represents a YAML anchor (&name).
	SymbolKindAnchor

	// SymbolKindDocument represents a YAML document (separated by ---).
	SymbolKindDocument

	// SymbolKindAlias represents a shell alias definition.
	SymbolKindAlias

	// SymbolKindScript represents an executable script.
	SymbolKindScript

	// SymbolKindStage represents a Docker build stage (FROM ... AS name).
	SymbolKindStage

	// SymbolKindInstruction represents a Dockerfile instruction (FROM, RUN, COPY, etc).
	SymbolKindInstruction

	// SymbolKindPort represents an exposed port (EXPOSE).
	SymbolKindPort

	// SymbolKindVolume represents a Docker volume (VOLUME).
	SymbolKindVolume

	// SymbolKindLabel represents a Docker label (LABEL).
	SymbolKindLabel

	// SymbolKindEnvVar represents an environment variable (ENV).
	SymbolKindEnvVar

	// SymbolKindArg represents a build argument (ARG).
	SymbolKindArg

	// SymbolKindHeading represents a markdown heading (# H1, ## H2, etc).
	SymbolKindHeading

	// SymbolKindCodeBlock represents a fenced code block (“`language).
	SymbolKindCodeBlock

	// SymbolKindLink represents a markdown link [text](url).
	SymbolKindLink

	// SymbolKindList represents a markdown list (ordered or unordered).
	SymbolKindList

	// SymbolKindBlockquote represents a markdown blockquote (> text).
	SymbolKindBlockquote

	// SymbolKindImage represents a markdown image ![alt](url).
	SymbolKindImage

	// SymbolKindExternal represents an external/unresolved symbol.
	// Used for placeholder nodes representing symbols from external packages
	// or unresolved references during graph building.
	SymbolKindExternal
)

func ParseSymbolKind

func ParseSymbolKind(s string) SymbolKind

ParseSymbolKind converts a string to a SymbolKind.

Returns SymbolKindUnknown if the string is not recognized.

func (SymbolKind) MarshalJSON

func (k SymbolKind) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for SymbolKind.

Serializes the kind as a JSON string (e.g., "function") rather than a number for better readability and forward compatibility.

func (SymbolKind) String

func (k SymbolKind) String() string

String returns the string representation of the SymbolKind.

Returns "unknown" for unrecognized values.

func (*SymbolKind) UnmarshalJSON

func (k *SymbolKind) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler for SymbolKind.

Accepts both string values (e.g., "function") and numeric values for backward compatibility.

type SymbolMetadata

type SymbolMetadata struct {
	// Decorators lists decorator/annotation names applied to the symbol.
	// Example: ["staticmethod", "cache"] for Python.
	Decorators []string `json:"decorators,omitempty"`

	// DecoratorArgs maps decorator names to their argument identifiers.
	// Only populated when a decorator has arguments that reference symbols.
	// Example: {"UseInterceptors": ["LoggingInterceptor"], "Module": ["UserService"]}
	// IT-03a A-3: Enables EdgeTypeReferences from decorated symbol to decorator arguments.
	DecoratorArgs map[string][]string `json:"decorator_args,omitempty"`

	// TypeParameters lists generic type parameter names.
	// Example: ["T", "U"] for TypeScript generic function.
	TypeParameters []string `json:"type_parameters,omitempty"`

	// TypeArguments lists type identifiers used as generic arguments in the symbol's type annotations.
	// IT-03a C-2: Tracks type arguments like User in Promise<User>, Handler in Map<string, Handler>.
	// Only populated for non-primitive type names (skips string, number, boolean, etc.).
	TypeArguments []string `json:"type_arguments,omitempty"`

	// ReturnType is the declared return type (if available).
	// Example: "Promise<User>" for TypeScript async function.
	ReturnType string `json:"return_type,omitempty"`

	// IsAsync indicates if the function/method is asynchronous.
	IsAsync bool `json:"is_async,omitempty"`

	// IsGenerator indicates if the function is a generator.
	IsGenerator bool `json:"is_generator,omitempty"`

	// IsAbstract indicates if the class/method is abstract.
	IsAbstract bool `json:"is_abstract,omitempty"`

	// IsStatic indicates if the method is static.
	IsStatic bool `json:"is_static,omitempty"`

	// AccessModifier is the access level (public, private, protected).
	// Empty string means default/public access.
	AccessModifier string `json:"access_modifier,omitempty"`

	// Implements lists interface names that a class/struct implements.
	// For languages with explicit implements (TypeScript, Java), this is populated
	// by the parser. For Go, this is populated by the graph builder via
	// method-set matching (see GR-40).
	Implements []string `json:"implements,omitempty"`

	// Extends is the parent class name for inheritance.
	Extends string `json:"extends,omitempty"`

	// Methods contains method signatures for interfaces and types.
	// For interfaces: lists required method signatures.
	// For structs/types: lists methods with receivers matching this type.
	// Used for Go interface implementation detection via method-set matching (GR-40).
	Methods []MethodSignature `json:"methods,omitempty"`

	// IsConstructor indicates a JavaScript constructor function (uses this.x = ...).
	// IT-03a B-1: Constructor functions are reclassified as SymbolKindClass for graph visibility.
	IsConstructor bool `json:"is_constructor,omitempty"`

	// TypeNarrowings lists type identifiers used in type narrowing expressions.
	// IT-03a C-3: Tracks types referenced via instanceof, typeof, and type predicates.
	// Example: ["Router", "Response"] for code containing `x instanceof Router`.
	TypeNarrowings []string `json:"type_narrowings,omitempty"`

	// IsOverload indicates the symbol is a Python @overload stub (type-checking only).
	// IT-06c H-3: Overload stubs have no function body (just `...`) and zero callees.
	// The actual implementation is the same-name function WITHOUT @overload.
	// Symbol resolution should prefer non-overload symbols over overload stubs.
	IsOverload bool `json:"is_overload,omitempty"`

	// PrototypeOf indicates this symbol was assigned via Foo.prototype.method = ...
	// IT-03a B-2: Links prototype method assignments to their constructor function.
	PrototypeOf string `json:"prototype_of,omitempty"`

	// CSSSelector is the full CSS selector for CSS symbols.
	CSSSelector string `json:"css_selector,omitempty"`

	// ParentName is the parent symbol name (e.g., table name for columns).
	ParentName string `json:"parent_name,omitempty"`

	// SQLConstraints lists SQL constraints for columns (PRIMARY KEY, UNIQUE, etc.).
	SQLConstraints []string `json:"sql_constraints,omitempty"`

	// HeadingLevel is the heading level (1-6) for Markdown headings.
	HeadingLevel int `json:"heading_level,omitempty"`

	// CodeLanguage is the language identifier for fenced code blocks.
	// Example: "go", "python", "javascript"
	CodeLanguage string `json:"code_language,omitempty"`

	// ListType is the type of list: "ordered" or "unordered".
	ListType string `json:"list_type,omitempty"`

	// ListItems is the number of items in a list.
	ListItems int `json:"list_items,omitempty"`

	// LinkURL is the destination URL for link reference definitions.
	LinkURL string `json:"link_url,omitempty"`

	// LinkTitle is the optional title for link reference definitions.
	LinkTitle string `json:"link_title,omitempty"`
}

SymbolMetadata contains optional language-specific metadata for a symbol.

This struct provides type-safe storage for language-specific information that doesn't fit in the core Symbol fields. All fields are optional.

type TypeReference

type TypeReference struct {
	// Name is the type identifier as it appears in source code.
	// This is the unqualified name (e.g., "Series", not "pandas.Series").
	// Primitives and language constructs are excluded at extraction time.
	Name string `json:"name"`

	// Location is where the type reference appears in the source file.
	Location Location `json:"location"`
}

TypeReference represents a type identifier referenced in a symbol's type annotations.

Description:

TypeReference captures a type name used in a function parameter annotation,
return type annotation, or variable type annotation. These enable the graph
builder to create EdgeTypeReferences edges for type-usage relationships.

IT-06 Bug 9: Without these, the graph only has call edges — type annotations like "def foo(x: Series) -> DataFrame" produce no edges, so types referenced only via annotations are invisible to find_references.

Thread Safety: TypeReference is immutable after creation and safe for concurrent read.

type TypeScriptParser

type TypeScriptParser struct {
	// contains filtered or unexported fields
}

TypeScriptParser implements the Parser interface for TypeScript source code.

Description:

TypeScriptParser uses tree-sitter to parse TypeScript source files and extract symbols.
It supports concurrent use from multiple goroutines - each Parse call
creates its own tree-sitter parser instance internally.

Thread Safety:

TypeScriptParser instances are safe for concurrent use. Multiple goroutines
may call Parse simultaneously on the same TypeScriptParser instance.

Example:

parser := NewTypeScriptParser()
result, err := parser.Parse(ctx, []byte("export function hello(): string { return 'hi'; }"), "main.ts")
if err != nil {
    log.Fatal(err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewTypeScriptParser

func NewTypeScriptParser(opts ...TypeScriptParserOption) *TypeScriptParser

NewTypeScriptParser creates a new TypeScriptParser with the given options.

Description:

Creates a TypeScriptParser configured with sensible defaults. Options can be
provided to customize behavior such as maximum file size.

Inputs:

  • opts: Optional configuration functions (WithTypeScriptMaxFileSize, WithTypeScriptParseOptions)

Outputs:

  • *TypeScriptParser: Configured parser instance, never nil

Example:

// Default configuration
parser := NewTypeScriptParser()

// Custom max file size
parser := NewTypeScriptParser(WithTypeScriptMaxFileSize(5 * 1024 * 1024))

Thread Safety:

The returned TypeScriptParser is safe for concurrent use.

func (*TypeScriptParser) Extensions

func (p *TypeScriptParser) Extensions() []string

Extensions returns the file extensions this parser handles.

Returns:

  • []string{".ts", ".tsx", ".mts", ".cts"} for TypeScript source files

func (*TypeScriptParser) Language

func (p *TypeScriptParser) Language() string

Language returns the canonical language name for this parser.

Returns:

  • "typescript" for TypeScript source files

func (*TypeScriptParser) Parse

func (p *TypeScriptParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from TypeScript source code.

Description:

Parse uses tree-sitter to parse the provided TypeScript source code and extract
all symbols (functions, classes, interfaces, etc.) into a ParseResult.
The parser is error-tolerant and will return partial results for syntactically
invalid code.

Inputs:

  • ctx: Context for cancellation. Checked before and after parsing. Note: Tree-sitter parsing itself cannot be interrupted mid-parse.
  • content: Raw TypeScript source code bytes. Must be valid UTF-8.
  • filePath: Path to the file (for ID generation and error reporting). Should be relative to project root using forward slashes.

Outputs:

  • *ParseResult: Extracted symbols and metadata. Never nil on success. May contain partial results with errors for syntactically invalid code.
  • error: Non-nil for complete failures:
  • ErrFileTooLarge: Content exceeds maxFileSize
  • ErrInvalidContent: Content is not valid UTF-8
  • Context errors: Context was canceled or timed out

Example:

result, err := parser.Parse(ctx, []byte("export const x = 1;"), "main.ts")
if err != nil {
    return err
}
fmt.Printf("Found %d symbols\n", len(result.Symbols))

Limitations:

  • Tree-sitter parsing is synchronous and cannot be interrupted mid-parse
  • Very large files may take significant time to parse
  • Some edge cases in TypeScript syntax may not be fully handled

Assumptions:

  • Content is valid UTF-8 (validated internally)
  • FilePath uses forward slashes as path separator
  • FilePath does not contain path traversal sequences

Thread Safety:

This method is safe for concurrent use.

type TypeScriptParserOption

type TypeScriptParserOption func(*TypeScriptParser)

TypeScriptParserOption configures a TypeScriptParser instance.

func WithTypeScriptMaxFileSize

func WithTypeScriptMaxFileSize(bytes int64) TypeScriptParserOption

WithTypeScriptMaxFileSize sets the maximum file size the parser will accept.

Parameters:

  • bytes: Maximum file size in bytes. Must be positive.

Example:

parser := NewTypeScriptParser(WithTypeScriptMaxFileSize(5 * 1024 * 1024)) // 5MB limit

func WithTypeScriptParseOptions

func WithTypeScriptParseOptions(opts ParseOptions) TypeScriptParserOption

WithTypeScriptParseOptions applies the given ParseOptions to the parser.

Parameters:

  • opts: ParseOptions to apply.

Example:

parser := NewTypeScriptParser(WithTypeScriptParseOptions(ParseOptions{IncludePrivate: false}))

type ValidationError

type ValidationError struct {
	Field   string
	Message string
}

ValidationError represents a validation failure with field context.

func (ValidationError) Error

func (e ValidationError) Error() string

type YAMLParser

type YAMLParser struct {
	// contains filtered or unexported fields
}

YAMLParser extracts symbols from YAML source files.

Description:

YAMLParser uses tree-sitter to parse YAML files and extract
structured symbol information including top-level keys, nested keys,
anchors, and document boundaries.

Thread Safety:

YAMLParser is safe for concurrent use. Multiple goroutines can call Parse
simultaneously. Each Parse call creates its own tree-sitter parser instance.

Example:

parser := NewYAMLParser()
result, err := parser.Parse(ctx, content, "config.yaml")
if err != nil {
    return fmt.Errorf("parse: %w", err)
}
for _, sym := range result.Symbols {
    fmt.Printf("%s: %s\n", sym.Kind, sym.Name)
}

func NewYAMLParser

func NewYAMLParser(opts ...YAMLParserOption) *YAMLParser

NewYAMLParser creates a new YAMLParser with the given options.

Description:

Creates a parser configured for YAML files. The parser can be
reused for multiple files and is safe for concurrent use.

Example:

// Default options
parser := NewYAMLParser()

// With custom options
parser := NewYAMLParser(
    WithYAMLMaxFileSize(5 * 1024 * 1024),
    WithYAMLMaxKeyDepth(5),
)

func (*YAMLParser) Extensions

func (p *YAMLParser) Extensions() []string

Extensions returns the file extensions this parser handles.

func (*YAMLParser) Language

func (p *YAMLParser) Language() string

Language returns the language name for this parser.

func (*YAMLParser) Parse

func (p *YAMLParser) Parse(ctx context.Context, content []byte, filePath string) (*ParseResult, error)

Parse extracts symbols from YAML source code.

Description:

Parses the provided YAML content using tree-sitter and extracts all
symbols including keys, anchors, and document boundaries.

Inputs:

ctx      - Context for cancellation. Checked before/after parsing.
content  - Raw YAML source bytes. Must be valid UTF-8.
filePath - Path to the file (relative to project root, for ID generation).

Outputs:

*ParseResult - Extracted symbols and metadata. Never nil on success.
error        - Non-nil only for complete failures (invalid UTF-8, too large).

Thread Safety:

This method is safe for concurrent use.

type YAMLParserOption

type YAMLParserOption func(*YAMLParserOptions)

YAMLParserOption is a functional option for configuring YAMLParser.

func WithYAMLExtractAnchors

func WithYAMLExtractAnchors(extract bool) YAMLParserOption

WithYAMLExtractAnchors sets whether to extract anchor definitions.

func WithYAMLMaxFileSize

func WithYAMLMaxFileSize(size int) YAMLParserOption

WithYAMLMaxFileSize sets the maximum file size for parsing.

func WithYAMLMaxKeyDepth

func WithYAMLMaxKeyDepth(depth int) YAMLParserOption

WithYAMLMaxKeyDepth sets the maximum key depth for extraction.

type YAMLParserOptions

type YAMLParserOptions struct {
	// MaxFileSize is the maximum file size in bytes to parse.
	// Files larger than this return ErrFileTooLarge.
	// Default: 10MB
	MaxFileSize int

	// MaxKeyDepth is the maximum nesting depth for key extraction.
	// 0 = top-level only, 1 = one level deep, etc.
	// Default: 3
	MaxKeyDepth int

	// ExtractAnchors determines whether to extract anchor definitions.
	// Default: true
	ExtractAnchors bool
}

YAMLParserOptions configures YAMLParser behavior.

func DefaultYAMLParserOptions

func DefaultYAMLParserOptions() YAMLParserOptions

DefaultYAMLParserOptions returns the default options.

Jump to

Keyboard shortcuts

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