resolution

package
v0.0.0-...-460d0d3 Latest Latest
Warning

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

Go to latest
Published: May 23, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package resolution provides bidirectional type inference.

Package resolution provides enhanced chain resolution.

Package resolution provides type information structures for type resolution and inference.

This package defines the type system used by the type inference engine and registry packages. It contains data structures that track variable bindings and function scopes during type analysis.

Type Information

The core type information is defined in the core package (core.TypeInfo), while this package focuses on scope and binding management:

typeInfo := &core.TypeInfo{
    TypeFQN:    "builtins.str",
    Source:     "literal",
    Confidence: 1.0,
}

binding := &resolution.VariableBinding{
    VarName: "username",
    Type:    typeInfo,
}

Function Scopes

FunctionScope tracks variable bindings within a function:

scope := resolution.NewFunctionScope("myapp.views.login")
scope.AddVariable(&resolution.VariableBinding{
    VarName: "user",
    Type:    &core.TypeInfo{TypeFQN: "myapp.models.User"},
})

Breaking Circular Dependencies

This package was created to resolve the circular dependency between builtin_registry.go and type_inference.go by providing shared type definitions that both packages can depend on without depending on each other.

Package resolution provides type caching for inference performance.

Package resolution provides scope-based type storage for inference.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildGoModuleRegistry

func BuildGoModuleRegistry(projectRoot string) (*core.GoModuleRegistry, error)

BuildGoModuleRegistry builds a registry mapping directories to Go import paths. It parses go.mod to extract the module path, then walks the directory tree to build bidirectional mappings between directories and import paths.

Parameters:

  • projectRoot: absolute path to the project root (contains go.mod)

Returns:

  • populated GoModuleRegistry or error if go.mod is missing/invalid

func ExtractCallSites

func ExtractCallSites(filePath string, sourceCode []byte, importMap *core.ImportMap) ([]*core.CallSite, error)

ExtractCallSites extracts all function/method call sites from a Python file. It traverses the AST to find call expressions and builds CallSite objects with caller context, callee information, and arguments.

Algorithm:

  1. Parse source code with tree-sitter Python parser
  2. Traverse AST to find call expressions
  3. For each call, extract: - Caller function/method (containing context) - Callee name (function/method being called) - Arguments (positional and keyword) - Source location (file, line, column)
  4. Build CallSite objects for each call

Parameters:

  • filePath: absolute path to the Python file being analyzed
  • sourceCode: contents of the Python file as byte array
  • importMap: import mappings for resolving qualified names

Returns:

  • []CallSite: list of all call sites found in the file
  • error: if parsing fails or source is invalid

Example:

Source code:
  def process_data():
      result = sanitize(data)
      db.query(result)

Extracts CallSites:
  [
    {Caller: "process_data", Callee: "sanitize", Args: ["data"]},
    {Caller: "process_data", Callee: "db.query", Args: ["result"]}
  ]

func ExtractGoImports

func ExtractGoImports(filePath string, sourceCode []byte, registry *core.GoModuleRegistry) (*core.GoImportMap, error)

ExtractGoImports extracts import statements from a Go source file. It parses the file's AST to find all import declarations and builds a mapping from local names (or aliases) to full import paths.

Parameters:

  • filePath: absolute path to the Go source file
  • sourceCode: the file's source code as bytes
  • registry: the Go module registry (currently unused but kept for consistency)

Returns:

  • GoImportMap containing all imports, or error if parsing fails

func ExtractImports

func ExtractImports(filePath string, sourceCode []byte, registry *core.ModuleRegistry) (*core.ImportMap, error)

ExtractImports extracts all import statements from a Python file and builds an ImportMap. It handles four main import styles:

  1. Simple imports: import module
  2. From imports: from module import name
  3. Aliased imports: from module import name as alias
  4. Relative imports: from . import module, from .. import module

The resulting ImportMap maps local names (aliases or imported names) to their fully qualified module paths, enabling later resolution of function calls.

Algorithm:

  1. Parse source code with tree-sitter Python parser
  2. Traverse AST to find all import statements
  3. Process each import to extract module paths and aliases
  4. Resolve relative imports using module registry
  5. Build ImportMap with resolved fully qualified names

Parameters:

  • filePath: absolute path to the Python file being analyzed
  • sourceCode: contents of the Python file as byte array
  • registry: module registry for resolving module paths and relative imports

Returns:

  • ImportMap: map of local names to fully qualified module paths
  • error: if parsing fails or source is invalid

Example:

Source code:
  import os
  from myapp.utils import sanitize
  from myapp.db import query as db_query
  from . import helper
  from ..config import settings

Result ImportMap:
  {
    "os": "os",
    "sanitize": "myapp.utils.sanitize",
    "db_query": "myapp.db.query",
    "helper": "myapp.submodule.helper",
    "settings": "myapp.config.settings"
  }

func IsDjangoORMPattern

func IsDjangoORMPattern(target string) (bool, string)

IsDjangoORMPattern checks if a call target matches Django ORM pattern. Django ORM pattern: ModelName.objects.<method>

Examples:

  • "Task.objects.filter" → true
  • "User.objects.get" → true
  • "Annotation.objects.all" → true
  • "task.save" → false (instance method, not manager)

Parameters:

  • target: call target string (e.g., "Task.objects.filter")

Returns:

  • true if it matches Django ORM pattern
  • the method name if matched (e.g., "filter")

func IsORMPattern

func IsORMPattern(target string) (bool, string, string)

IsORMPattern checks if a call target matches any known ORM pattern.

Parameters:

  • target: call target string

Returns:

  • true if it matches any ORM pattern
  • the ORM pattern name (e.g., "Django ORM")
  • the method name (e.g., "filter")

func IsSQLAlchemyORMPattern

func IsSQLAlchemyORMPattern(target string) (bool, string)

IsSQLAlchemyORMPattern checks if a call target matches SQLAlchemy ORM pattern. SQLAlchemy patterns are more varied, but common ones include:

  • session.query(Model).filter(...)
  • db.session.query(Model).all()
  • Model.query.filter_by(...)

Parameters:

  • target: call target string

Returns:

  • true if it matches SQLAlchemy ORM pattern
  • the method name if matched

func MakeCacheKey

func MakeCacheKey(file string, line, col int, varName string) string

MakeCacheKey creates a cache key for a variable at a location.

func MergeReturnTypes

func MergeReturnTypes(statements []*ReturnStatement) map[string]*core.TypeInfo

MergeReturnTypes combines multiple return statements for same function. Takes the highest confidence return type.

func PrintAttributeFailureStats

func PrintAttributeFailureStats(logger interface{ IsDebug() bool })

PrintAttributeFailureStats prints detailed statistics about attribute chain failures. Only prints if debug mode is enabled via the provided logger.

func PropagateParentParamTypes

func PropagateParentParamTypes(
	childMethodFQN string,
	parentClassFQN string,
	methodName string,
	typeEngine *TypeInferenceEngine,
	thirdPartyRemote any,
	logger *output.Logger,
)

PropagateParentParamTypes copies parameter types from a parent class method to a child class method override. For example, if django.views.View.get has parameter "request: django.http.HttpRequest", and a child TestView.get overrides it, this function adds "request" with type "django.http.HttpRequest" to TestView.get's scope.

func ResolveAttributePlaceholders

func ResolveAttributePlaceholders(
	registry *registry.AttributeRegistry,
	typeEngine *TypeInferenceEngine,
	moduleRegistry *core.ModuleRegistry,
	codeGraph *graph.CodeGraph,
)

ResolveAttributePlaceholders resolves placeholder types in the attribute registry Placeholders are created during extraction when we can't determine the exact type:

  • class:User → resolve to fully qualified class name
  • call:calculate → resolve to function return type
  • param:User → resolve to fully qualified class name

This is Pass 3 of the attribute extraction algorithm.

Parameters:

  • registry: attribute registry with placeholder types
  • typeEngine: type inference engine with return types
  • moduleRegistry: module registry for resolving class names
  • codeGraph: code graph for finding class definitions

func ResolveChainedCall

func ResolveChainedCall(
	target string,
	typeEngine *TypeInferenceEngine,
	builtins *registry.BuiltinRegistry,
	moduleRegistry *core.ModuleRegistry,
	codeGraph *graph.CodeGraph,
	callerFQN string,
	currentModule string,
	callGraph *core.CallGraph,
) (string, bool, *core.TypeInfo)

ResolveChainedCall resolves a method chain by walking each step and tracking types.

Algorithm:

  1. Parse chain into individual steps
  2. Resolve first step: - If it's a call: resolve as function call, get return type - If it's a variable: look up type in scopes
  3. For each subsequent step: - Use previous step's type to resolve method - Get method's return type from builtins or return type registry - Track confidence through the chain (multiply confidences)
  4. Return final type and resolution status

Parameters:

  • target: the full target string (e.g., "create_builder().append().upper()")
  • typeEngine: type inference engine with scopes and return types
  • builtins: builtin registry for builtin method lookups
  • registry: module registry for validation
  • codeGraph: code graph for function lookups
  • callerFQN: FQN of the calling function (for scope lookups)
  • currentModule: current module path
  • callGraph: call graph for function lookups

Returns:

  • targetFQN: the fully qualified name of the final call
  • resolved: true if chain was successfully resolved
  • typeInfo: type information for the final result

func ResolveClassInstantiation

func ResolveClassInstantiation(
	callNode *sitter.Node,
	sourceCode []byte,
	modulePath string,
	importMap *core.ImportMap,
	registry *core.ModuleRegistry,
) *core.TypeInfo

ResolveClassInstantiation attempts to resolve class instantiation patterns.

func ResolveDeepAttributeChain

func ResolveDeepAttributeChain(
	attributeNames []string,
	startingType core.Type,
	attrRegistry strategies.AttributeRegistryInterface,
) (core.Type, float64)

ResolveDeepAttributeChain resolves self.a.b.c.method() patterns. Takes the chain as a slice of attribute names.

func ResolveDjangoORMCall

func ResolveDjangoORMCall(target string, modulePath string, registry *core.ModuleRegistry, codeGraph *graph.CodeGraph) (string, bool)

ResolveDjangoORMCall attempts to resolve a Django ORM call pattern. It constructs a synthetic FQN for the ORM method even though it doesn't exist in source code, because Django generates these methods at runtime.

Parameters:

  • target: the call target (e.g., "Task.objects.filter")
  • modulePath: the current module path
  • registry: module registry
  • codeGraph: the parsed code graph (for model validation)

Returns:

  • fully qualified name for the ORM call
  • true if successfully resolved as Django ORM

func ResolveInheritedSelfAttribute

func ResolveInheritedSelfAttribute(
	parentClassFQN string,
	attrName string,
	thirdPartyRemote any,
	logger *output.Logger,
) *core.TypeInfo

ResolveInheritedSelfAttribute resolves self.attr access when the attribute isn't defined in the child class but exists in a parent class from typeshed. For example, self.request in a Django View subclass resolves to django.http.HttpRequest.

func ResolveInlineInstantiation

func ResolveInlineInstantiation(
	callNode *sitter.Node,
	sourceCode []byte,
	attrRegistry strategies.AttributeRegistryInterface,
	moduleRegistry strategies.ModuleRegistryInterface,
	filePath string,
) (core.Type, float64)

ResolveInlineInstantiation resolves ClassName().method() patterns. Returns the resolved class type.

func ResolveORMCall

func ResolveORMCall(target string, modulePath string, registry *core.ModuleRegistry, codeGraph *graph.CodeGraph) (string, bool)

ResolveORMCall attempts to resolve any ORM pattern.

Parameters:

  • target: the call target
  • modulePath: the current module path
  • registry: module registry
  • codeGraph: the parsed code graph

Returns:

  • fully qualified name for the ORM call
  • true if successfully resolved as any ORM pattern

func ResolveParentClassFQN

func ResolveParentClassFQN(
	classFQN string,
	superClassName string,
	filePath string,
	typeEngine *TypeInferenceEngine,
	registry *core.ModuleRegistry,
) string

ResolveParentClassFQN resolves a superclass name (e.g., "View") to its fully qualified name (e.g., "django.views.View") using the file's import map.

Strategy:

  1. Check imports for direct match (e.g., "View" → "django.views.View")
  2. Handle dotted superclass (e.g., "views.View" → resolve "views" + ".View")
  3. Check same module for local classes

func ResolveSQLAlchemyORMCall

func ResolveSQLAlchemyORMCall(target string, modulePath string) (string, bool)

ResolveSQLAlchemyORMCall attempts to resolve a SQLAlchemy ORM call pattern.

Parameters:

  • target: the call target
  • modulePath: the current module path

Returns:

  • fully qualified name for the ORM call
  • true if successfully resolved as SQLAlchemy ORM

func ResolveSelfAttributeCall

func ResolveSelfAttributeCall(
	target string,
	callerFQN string,
	typeEngine *TypeInferenceEngine,
	builtins *registry.BuiltinRegistry,
	callGraph *core.CallGraph,
) (string, bool, *core.TypeInfo)

ResolveSelfAttributeCall resolves self.attribute.method() patterns with support for arbitrary chain depth (e.g., self.obj.attr.method()).

Algorithm:

  1. Detect pattern: target starts with "self." and has 2+ dots
  2. Parse: self.attr₁.attr₂...attrN.method → chain=[attr₁..attrN], method
  3. Find containing class from callerFQN
  4. Walk the chain: for each attribute, look up its type and advance
  5. Resolve the final method on the terminal type

Examples:

2-level: self.value.upper → chain=["value"], method="upper"
3-level: self.core.config.get → chain=["core","config"], method="get"
4-level: self.app.db.session.execute → chain=["app","db","session"], method="execute"

Parameters:

  • target: call target string (e.g., "self.value.upper")
  • callerFQN: fully qualified name of calling function
  • typeEngine: type inference engine with attribute registry
  • builtins: builtin registry for method lookup
  • callGraph: call graph for class lookup

Returns:

  • resolvedFQN: fully qualified method name
  • resolved: true if resolution succeeded
  • typeInfo: inferred type information

func ValidateDjangoModel

func ValidateDjangoModel(modelName string, codeGraph *graph.CodeGraph) bool

ValidateDjangoModel checks if a name is likely a Django model by examining the code graph for the class definition and checking if it inherits from django.db.models.Model or has "Model" in its name.

This is a heuristic check since we can't always definitively determine if something is a Django model without runtime information.

Parameters:

  • modelName: the name to check (e.g., "Task", "User")
  • codeGraph: the parsed code graph

Returns:

  • true if the name is likely a Django model

Types

type BidirectionalInferencer

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

BidirectionalInferencer orchestrates type inference using strategies.

func NewBidirectionalInferencer

func NewBidirectionalInferencer(
	attrReg strategies.AttributeRegistryInterface,
	modReg strategies.ModuleRegistryInterface,
	builtinReg strategies.BuiltinRegistryInterface,
	cacheCapacity int,
) *BidirectionalInferencer

NewBidirectionalInferencer creates a new BidirectionalInferencer.

func (*BidirectionalInferencer) CacheStats

func (bi *BidirectionalInferencer) CacheStats() (hits, misses int64, size int)

CacheStats returns cache hit/miss statistics.

func (*BidirectionalInferencer) CheckType

func (bi *BidirectionalInferencer) CheckType(
	node *sitter.Node,
	expectedType core.Type,
	store *TypeStore,
	sourceCode []byte,
	filePath string,
	selfType core.Type,
	classFQN string,
) bool

CheckType verifies if a node can produce an expected type.

func (*BidirectionalInferencer) InferType

func (bi *BidirectionalInferencer) InferType(
	node *sitter.Node,
	store *TypeStore,
	sourceCode []byte,
	filePath string,
	selfType core.Type,
	classFQN string,
	functionFQN string,
) (core.Type, float64)

InferType infers the type of an AST node using registered strategies. This is the main entry point for type inference.

func (*BidirectionalInferencer) InvalidateFile

func (bi *BidirectionalInferencer) InvalidateFile(filePath string) int

InvalidateFile clears cached types for a modified file.

func (*BidirectionalInferencer) RegisterStrategy

func (bi *BidirectionalInferencer) RegisterStrategy(strategy strategies.InferenceStrategy)

RegisterStrategy adds a strategy to the inferencer.

type CFunctionScope

type CFunctionScope struct {
	// FunctionFQN is the fully-qualified name of the owning function
	// (e.g. "src/net/socket.c::handle_request").
	FunctionFQN string

	// Variables maps a bare variable name to every binding observed
	// for it within this function. The latest binding is the last
	// element of each slice.
	Variables map[string][]*CVariableBinding
}

CFunctionScope tracks every variable declared inside one C function. Bindings are stored as a slice per name so later phases can audit reassignment history; GetVariable always returns the most recent one.

func NewCFunctionScope

func NewCFunctionScope(functionFQN string) *CFunctionScope

NewCFunctionScope returns an empty scope keyed to the given function FQN with its Variables map pre-allocated.

func (*CFunctionScope) AddVariable

func (s *CFunctionScope) AddVariable(binding *CVariableBinding)

AddVariable appends binding to the per-name binding history. nil bindings are silently dropped so callers can write `scope.AddVariable(makeBinding(...))` without nil checks.

func (*CFunctionScope) GetAllBindings

func (s *CFunctionScope) GetAllBindings(varName string) []*CVariableBinding

GetAllBindings returns every binding recorded for varName, in insertion order. Callers must not mutate the slice — return value is the live storage for performance.

func (*CFunctionScope) GetVariable

func (s *CFunctionScope) GetVariable(varName string) *CVariableBinding

GetVariable returns the latest binding for varName, or nil when the variable is unknown to this scope.

func (*CFunctionScope) HasVariable

func (s *CFunctionScope) HasVariable(varName string) bool

HasVariable reports whether at least one binding exists for varName.

type CTypeInferenceEngine

type CTypeInferenceEngine struct {
	// Scopes maps function FQN to the variables declared inside it.
	Scopes map[string]*CFunctionScope

	// ReturnTypes maps function FQN to its declared return type. void
	// returns are intentionally absent — see ExtractReturnType.
	ReturnTypes map[string]*core.TypeInfo

	// Registry exposes the C module registry for FQN resolution. The
	// engine itself never mutates the registry.
	Registry *core.CModuleRegistry
	// contains filtered or unexported fields
}

CTypeInferenceEngine indexes explicit type information for a parsed C codebase: function return types and per-function variable scopes.

The engine performs no inference, no propagation, and no flow analysis — every entry mirrors a type that appears verbatim in the source. Higher-confidence handlers (PR-07's call-graph builder) layer further analysis on top.

Lifecycle:

  • Construct once with NewCTypeInferenceEngine(registry).
  • Populate from multiple goroutines during parallel Pass 2 extraction (`go test -race` clean).
  • Read-only consumption during call-graph construction.

Embedding: CppTypeInferenceEngine embeds this type by value to inherit every method, so consumers can call ExtractReturnType, GetScope, etc. uniformly across both languages.

func NewCTypeInferenceEngine

func NewCTypeInferenceEngine(registry *core.CModuleRegistry) *CTypeInferenceEngine

NewCTypeInferenceEngine returns an engine with allocated maps wired to the supplied registry. Passing a nil registry is permitted — the engine will simply produce no FQN-aware lookups, but type extraction still works (useful for unit tests).

func (*CTypeInferenceEngine) AddReturnType

func (e *CTypeInferenceEngine) AddReturnType(fqn string, typeInfo *core.TypeInfo)

AddReturnType stores a precomputed TypeInfo for fqn. Useful when the caller has already classified a return type (e.g. through a future stdlib registry). Nil typeInfo is ignored.

func (*CTypeInferenceEngine) AddScope

func (e *CTypeInferenceEngine) AddScope(scope *CFunctionScope)

AddScope replaces (or installs) a complete scope for a function. Used by tests or by callers that want to batch-build a scope before publishing it to the engine. Nil scopes are ignored.

func (*CTypeInferenceEngine) ExtractReturnType

func (e *CTypeInferenceEngine) ExtractReturnType(fqn, returnType string)

ExtractReturnType records the explicit return type for the function identified by fqn. Empty types and the literal "void" are dropped: a void return carries no information for type-driven resolution and would only pollute downstream lookups.

Safe for concurrent use.

func (*CTypeInferenceEngine) ExtractVariableType

func (e *CTypeInferenceEngine) ExtractVariableType(functionFQN, varName, typeStr string, loc Location)

ExtractVariableType registers an explicit variable declaration inside functionFQN. Empty arguments are silently dropped so callers do not need to pre-validate parser output.

Safe for concurrent use. The function lazily creates the scope on first sight of functionFQN, so callers do not have to call AddScope before the first variable.

func (*CTypeInferenceEngine) GetAllReturnTypes

func (e *CTypeInferenceEngine) GetAllReturnTypes() map[string]*core.TypeInfo

GetAllReturnTypes returns a snapshot copy of every registered return type. The copy keeps the caller insulated from concurrent writes.

func (*CTypeInferenceEngine) GetAllScopes

func (e *CTypeInferenceEngine) GetAllScopes() map[string]*CFunctionScope

GetAllScopes returns a snapshot copy of every registered scope.

func (*CTypeInferenceEngine) GetReturnType

func (e *CTypeInferenceEngine) GetReturnType(fqn string) *core.TypeInfo

GetReturnType returns the recorded return type for fqn, or nil when none was registered (which includes void functions).

func (*CTypeInferenceEngine) GetScope

func (e *CTypeInferenceEngine) GetScope(functionFQN string) *CFunctionScope

GetScope returns the scope for functionFQN, or nil if none exists.

func (*CTypeInferenceEngine) HasReturnType

func (e *CTypeInferenceEngine) HasReturnType(fqn string) bool

HasReturnType reports whether a return type has been recorded for fqn.

func (*CTypeInferenceEngine) HasScope

func (e *CTypeInferenceEngine) HasScope(functionFQN string) bool

HasScope reports whether a scope exists for functionFQN.

type CVariableBinding

type CVariableBinding struct {
	// VarName is the bare identifier of the declared variable.
	VarName string

	// Type is the explicit type drawn from the source declaration.
	// For C/C++, the engine sets Confidence=1.0 and Source="declaration"
	// on every entry produced from an explicit type; the only exception
	// is C++ `auto` (see CppTypeInferenceEngine.ExtractVariableType).
	Type *core.TypeInfo

	// Location is the source location of the declaration.
	Location Location
}

CVariableBinding captures the explicit type of a single variable declaration inside a C function. Multiple bindings may exist for the same name when the variable is reassigned; the latest binding wins during lookup.

Example:

int n = 0;            // CVariableBinding{VarName:"n", Type: int}
const char *msg = ""; // CVariableBinding{VarName:"msg", Type: const char*}

Location reuses the package-level resolution.Location so call-site reporting and type tracking share one source-location vocabulary.

type ChainResolver

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

ChainResolver provides a fluent interface for chain resolution.

func NewChainResolver

NewChainResolver creates a new ChainResolver.

func (*ChainResolver) Resolve

func (r *ChainResolver) Resolve(node *sitter.Node) (core.Type, float64)

Resolve resolves a chain call node.

func (*ChainResolver) WithContext

func (r *ChainResolver) WithContext(filePath string, sourceCode []byte) *ChainResolver

WithContext sets the resolution context.

func (*ChainResolver) WithSelf

func (r *ChainResolver) WithSelf(selfType core.Type, classFQN string) *ChainResolver

WithSelf sets the self type for method resolution.

func (*ChainResolver) WithVariable

func (r *ChainResolver) WithVariable(name string, typ core.Type) *ChainResolver

WithVariable registers a known variable.

type ChainStep

type ChainStep struct {
	Expression string         // The full expression for this step (e.g., "create_builder()")
	MethodName string         // Just the method/function name (e.g., "create_builder")
	IsCall     bool           // True if this step is a function call (has parentheses)
	Type       *core.TypeInfo // Resolved type after this step
}

ChainStep represents a single step in a method chain. For example, in "obj.method1().method2()", there are 2 steps:

  • Step 1: obj.method1() → returns some type
  • Step 2: result.method2() → returns some type

func ParseChain

func ParseChain(target string) []ChainStep

ParseChain parses a method chain into individual steps.

Examples:

  • "create_builder().append()" → ["create_builder()", "append()"]
  • "text.strip().upper().split()" → ["text.strip()", "upper()", "split()"]
  • "obj.attr.method()" → ["obj.attr.method()"] (not a chain, just nested attribute)

A chain is identified by the pattern "().": a call followed by more method access.

Parameters:

  • target: the full target string from call site

Returns:

  • []ChainStep: parsed chain steps, or nil if not a chain

type CppTypeInferenceEngine

type CppTypeInferenceEngine struct {
	// CTypeInferenceEngine provides function- and variable-level
	// indexing. Embedded by value so methods like ExtractReturnType,
	// GetScope, and GetVariable resolve uniformly through the C++ engine.
	CTypeInferenceEngine

	// CppRegistry is the C++-aware module registry. The embedded C
	// engine holds a pointer to its CModuleRegistry for the C-only
	// lookups; CppRegistry preserves access to NamespaceIndex and
	// ClassIndex without forcing callers to type-assert.
	CppRegistry *core.CppModuleRegistry

	// ClassMethods maps className -> methodName -> return type. nil
	// outer entries are created lazily on first registration.
	ClassMethods map[string]map[string]*core.TypeInfo

	// ClassFields maps className -> fieldName -> field type. Same
	// lazy-allocation contract as ClassMethods.
	ClassFields map[string]map[string]*core.TypeInfo
	// contains filtered or unexported fields
}

CppTypeInferenceEngine extends CTypeInferenceEngine with C++ class member tracking. By embedding the C engine it inherits every scope- and return-type method, so callers can use a single engine to resolve both C-style functions and C++ classes.

In addition to the C-level data, it indexes:

  • Method return types per class — used by call-graph resolution to compute the type of `obj.method()` once the receiver type is known.
  • Field types per class — used by call-graph resolution when a method is invoked via a member like `this->buffer.write(...)`.

The maps are keyed by bare class name (e.g. "Socket") rather than fully-qualified class FQN; that mirrors how the parser emits class declarations and keeps lookups fast on hot paths. Callers requiring disambiguation across namespaces should pass FQNs explicitly to RegisterClassMethod.

func NewCppTypeInferenceEngine

func NewCppTypeInferenceEngine(registry *core.CppModuleRegistry) *CppTypeInferenceEngine

NewCppTypeInferenceEngine constructs an engine wired to a C++ module registry. The embedded C engine is bound to the same root by reference (it borrows registry's CModuleRegistry), so any field added to the registry post-construction is visible to both.

A nil registry is permitted; the engine still functions for tests and isolated extraction.

func (*CppTypeInferenceEngine) ExtractVariableType

func (e *CppTypeInferenceEngine) ExtractVariableType(functionFQN, varName, typeStr string, loc Location)

ExtractVariableType overrides the embedded C engine's behaviour to recognise the C++ `auto` placeholder. Auto declarations are recorded with Confidence=0 and Source="unresolved_auto" so later inference phases can find and refine them; resolvers gate on Confidence>=1.0 for explicit-only resolution and skip these.

All non-auto types delegate to the C engine for identical handling.

func (*CppTypeInferenceEngine) GetFieldType

func (e *CppTypeInferenceEngine) GetFieldType(className, fieldName string) *core.TypeInfo

GetFieldType looks up the recorded type of fieldName on className. Returns nil when the class is unknown or the field is unregistered.

func (*CppTypeInferenceEngine) GetMethodReturnType

func (e *CppTypeInferenceEngine) GetMethodReturnType(className, methodName string) *core.TypeInfo

GetMethodReturnType looks up the recorded return type of methodName on className. Returns nil when the class is unknown or the method is unregistered (including void methods, which are intentionally not stored).

func (*CppTypeInferenceEngine) HasClassField

func (e *CppTypeInferenceEngine) HasClassField(className, fieldName string) bool

HasClassField reports whether a field type has been registered for className/fieldName.

func (*CppTypeInferenceEngine) HasClassMethod

func (e *CppTypeInferenceEngine) HasClassMethod(className, methodName string) bool

HasClassMethod reports whether a method type has been registered for className/methodName.

func (*CppTypeInferenceEngine) RegisterClassField

func (e *CppTypeInferenceEngine) RegisterClassField(className, fieldName, typeStr string)

RegisterClassField records the explicit type of fieldName on className. Empty arguments are silently dropped. Like RegisterClassMethod, repeated calls overwrite — duplicate field declarations should never happen in well-formed C++.

Safe for concurrent use.

func (*CppTypeInferenceEngine) RegisterClassMethod

func (e *CppTypeInferenceEngine) RegisterClassMethod(className, methodName, returnType string)

RegisterClassMethod records the explicit return type of methodName on className. Empty arguments are silently dropped. Calling the function twice for the same key replaces the previous entry — the most recent declaration wins, mirroring C++ overload behaviour where redeclarations must agree.

Safe for concurrent use.

type FailureStats

type FailureStats struct {
	TotalAttempts          int
	NotSelfPrefix          int
	DeepChains             int // 3+ levels
	ClassNotFound          int
	AttributeNotFound      int
	MethodNotInBuiltins    int
	CustomClassUnsupported int

	// Pattern samples for analysis
	DeepChainSamples         []string
	AttributeNotFoundSamples []string
	CustomClassSamples       []string
}

FailureStats tracks why attribute chain resolution fails.

type FunctionScope

type FunctionScope struct {
	FunctionFQN string                        // Fully qualified name of the function
	Variables   map[string][]*VariableBinding // Variable name -> bindings (per-assignment)
	ReturnType  *core.TypeInfo                // Inferred return type of the function
}

FunctionScope represents the type environment within a function. It tracks variable types and return type for a specific function. Variables stores multiple bindings per variable name to support reassignment tracking.

func NewFunctionScope

func NewFunctionScope(functionFQN string) *FunctionScope

NewFunctionScope creates a new function scope with initialized maps.

Parameters:

  • functionFQN: fully qualified name of the function

Returns:

  • Initialized FunctionScope

func (*FunctionScope) AddVariable

func (fs *FunctionScope) AddVariable(binding *VariableBinding)

AddVariable appends a variable binding in the scope. Multiple bindings per variable name are preserved for reassignment tracking.

Parameters:

  • binding: the variable binding to add

func (*FunctionScope) GetVariable

func (fs *FunctionScope) GetVariable(varName string) *VariableBinding

GetVariable retrieves the last variable binding by name. Returns the most recent binding, which preserves backward compatibility for callers that expect a single binding per variable.

Parameters:

  • varName: the variable name to look up

Returns:

  • Last VariableBinding if found, nil otherwise

func (*FunctionScope) GetVariableAtLine

func (fs *FunctionScope) GetVariableAtLine(varName string, line uint32) *VariableBinding

GetVariableAtLine retrieves a variable binding at a specific line. Used for line-aware type lookup (e.g., when a variable is reassigned with different types).

Parameters:

  • varName: the variable name to look up
  • line: the line number to match

Returns:

  • VariableBinding at the specified line, nil if not found

func (*FunctionScope) HasVariable

func (fs *FunctionScope) HasVariable(varName string) bool

HasVariable checks if a variable exists in the scope.

Parameters:

  • varName: the variable name to check

Returns:

  • true if the variable exists, false otherwise

type GoFunctionScope

type GoFunctionScope struct {
	// Function FQN (e.g., "github.com/myapp/handlers.HandleRequest")
	FunctionFQN string

	// Variable name → bindings (multiple bindings for reassignment)
	// Latest binding is always last in the slice
	Variables map[string][]*GoVariableBinding
}

GoFunctionScope tracks variable type bindings within a single function. Variables can have multiple bindings due to reassignment - latest binding is always at the end of the slice.

Example:

scope := NewGoFunctionScope("github.com/myapp/handlers.HandleRequest")
scope.AddVariable(&GoVariableBinding{VarName: "user", ...})
binding := scope.GetVariable("user")  // Returns latest binding

func NewGoFunctionScope

func NewGoFunctionScope(functionFQN string) *GoFunctionScope

NewGoFunctionScope creates a new function scope.

func (*GoFunctionScope) AddVariable

func (s *GoFunctionScope) AddVariable(binding *GoVariableBinding)

AddVariable adds a variable binding to the scope. Supports multiple bindings for reassignment (latest is last in slice).

func (*GoFunctionScope) GetAllBindings

func (s *GoFunctionScope) GetAllBindings(varName string) []*GoVariableBinding

GetAllBindings returns all bindings for a variable (for reassignment analysis). Useful for debugging and understanding variable evolution.

func (*GoFunctionScope) GetVariable

func (s *GoFunctionScope) GetVariable(varName string) *GoVariableBinding

GetVariable retrieves the latest binding for a variable. Returns nil if variable not found.

func (*GoFunctionScope) HasVariable

func (s *GoFunctionScope) HasVariable(varName string) bool

HasVariable checks if a variable exists in the scope.

type GoImportResolver

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

GoImportResolver classifies Go import paths as stdlib, third-party, or local. It uses the registry's StdlibLoader for dynamic, version-aware stdlib detection, falling back to a heuristic (no domain in path) when the loader is unavailable.

Example:

resolver := NewGoImportResolver(registry)
if resolver.isStdlibImport("net/http") { ... }
kind := resolver.ClassifyImport("github.com/gorilla/mux")

func NewGoImportResolver

func NewGoImportResolver(registry *core.GoModuleRegistry) *GoImportResolver

NewGoImportResolver creates a GoImportResolver backed by the given module registry. registry may be nil; in that case all classification falls back to the heuristic.

func (*GoImportResolver) ClassifyImport

func (r *GoImportResolver) ClassifyImport(importPath string) ImportType

ClassifyImport categorises a single import path.

func (*GoImportResolver) ResolveImports

func (r *GoImportResolver) ResolveImports(imports []string) map[string]ImportType

ResolveImports classifies each import path in the given slice.

type GoTypeInferenceEngine

type GoTypeInferenceEngine struct {
	// Function FQN → variable scopes
	Scopes map[string]*GoFunctionScope

	// Function FQN → return type
	ReturnTypes map[string]*core.TypeInfo

	// Go module registry (from Phase 1)
	Registry *core.GoModuleRegistry
	// contains filtered or unexported fields
}

GoTypeInferenceEngine manages type information for Go code. Thread-safe implementation for parallel extraction.

Architecture:

  • Scopes: Map function FQN → GoFunctionScope (per-function variable tracking)
  • ReturnTypes: Map function FQN → TypeInfo (return type for each function)
  • Registry: Go module registry for resolving import paths

Thread Safety:

All public methods use RWMutex for safe concurrent access during parallel
file processing in Pass 2a and Pass 2b.

Example:

engine := NewGoTypeInferenceEngine(registry)
engine.AddReturnType("myapp.GetUser", &core.TypeInfo{...})
scope := NewGoFunctionScope("myapp.HandleRequest")
engine.AddScope(scope)

func NewGoTypeInferenceEngine

func NewGoTypeInferenceEngine(registry *core.GoModuleRegistry) *GoTypeInferenceEngine

NewGoTypeInferenceEngine creates an initialized type inference engine.

func (*GoTypeInferenceEngine) AddReturnType

func (e *GoTypeInferenceEngine) AddReturnType(functionFQN string, typeInfo *core.TypeInfo)

AddReturnType stores return type for a function (thread-safe write). Ignores nil type info.

func (*GoTypeInferenceEngine) AddScope

func (e *GoTypeInferenceEngine) AddScope(scope *GoFunctionScope)

AddScope stores a function scope (thread-safe write). Ignores nil scopes.

func (*GoTypeInferenceEngine) GetAllReturnTypes

func (e *GoTypeInferenceEngine) GetAllReturnTypes() map[string]*core.TypeInfo

GetAllReturnTypes returns all return types (for testing/debugging). Returns a copy to prevent external modification.

func (*GoTypeInferenceEngine) GetAllScopes

func (e *GoTypeInferenceEngine) GetAllScopes() map[string]*GoFunctionScope

GetAllScopes returns all function scopes (for testing/debugging). Returns a copy to prevent external modification.

func (*GoTypeInferenceEngine) GetReturnType

func (e *GoTypeInferenceEngine) GetReturnType(functionFQN string) (*core.TypeInfo, bool)

GetReturnType retrieves the return type for a function (thread-safe read).

Lookup order:

  1. Locally-registered return types (user-code declarations populated during parsing).
  2. Go stdlib registry — when the engine's Registry has a StdlibLoader, the FQN is split into an import path and function name and queried against the manifest. The first non-error, non-empty return type is returned with Confidence 1.0 and Source "stdlib".

Returns (typeInfo, true) if a type was found, (nil, false) otherwise.

func (*GoTypeInferenceEngine) GetScope

func (e *GoTypeInferenceEngine) GetScope(functionFQN string) *GoFunctionScope

GetScope retrieves a function scope (thread-safe read). Returns nil if scope not found.

func (*GoTypeInferenceEngine) HasReturnType

func (e *GoTypeInferenceEngine) HasReturnType(functionFQN string) bool

HasReturnType checks if a return type exists for a function.

func (*GoTypeInferenceEngine) HasScope

func (e *GoTypeInferenceEngine) HasScope(functionFQN string) bool

HasScope checks if a scope exists for a function.

type GoVariableBinding

type GoVariableBinding struct {
	// Variable name (e.g., "user", "config", "result")
	VarName string

	// Inferred type information
	Type *core.TypeInfo

	// FQN of function that assigned this value, or "literal" for constants
	AssignedFrom string

	// Source location of assignment
	Location Location
}

GoVariableBinding represents a variable's type information at a specific assignment. Multiple bindings can exist for the same variable (reassignment tracking).

Example:

user := GetUser(123)  // Creates binding with type from GetUser's return type

Supports reassignment:

user := GetUser(1)    // Binding 1
user = NewUser()      // Binding 2 (latest)

type ImportType

type ImportType int

ImportType classifies a Go import path.

const (
	ImportUnknown    ImportType = iota
	ImportStdlib                // Go standard library (e.g., "fmt", "net/http")
	ImportThirdParty            // External module (e.g., "github.com/gorilla/mux")
	ImportLocal                 // Same module (e.g., "github.com/myapp/handlers" or "./utils")
)

type Location

type Location struct {
	File      string // File path
	Line      uint32 // Line number
	Column    uint32 // Column number
	StartByte uint32 // Starting byte offset
	EndByte   uint32 // Ending byte offset
}

Location represents a source code location.

type ORMPattern

type ORMPattern struct {
	Name        string   // Pattern name (e.g., "Django ORM")
	MethodNames []string // Common ORM method names
	Description string   // Human-readable description
}

ORMPattern represents a recognized ORM pattern (e.g., Django ORM, SQLAlchemy). These patterns are dynamically generated at runtime and won't be found in source code, but we can still resolve them by recognizing the pattern.

type ReturnStatement

type ReturnStatement struct {
	FunctionFQN string
	ReturnType  *core.TypeInfo
	Location    Location
}

ReturnStatement represents a return statement in a function.

func ExtractReturnTypes

func ExtractReturnTypes(
	filePath string,
	sourceCode []byte,
	modulePath string,
	builtinRegistry *registry.BuiltinRegistry,
	importMap *core.ImportMap,
) ([]*ReturnStatement, map[string]bool, error)

ExtractReturnTypes analyzes return statements in all functions in a file. Returns:

  • []*ReturnStatement: return statements with inferred types
  • map[string]bool: set of function FQNs that have at least one `return <expr>` statement (used to distinguish void functions from functions with uninferrable returns)

type StdlibRegistryRemote

type StdlibRegistryRemote any

StdlibRegistryRemote will be defined in registry package. For now, use an interface or accept nil.

type TypeBinding

type TypeBinding struct {
	VarName    string
	Type       core.Type
	Source     core.ConfidenceSource
	File       string
	Line       int
	Column     int
	ScopeDepth int
}

TypeBinding represents a variable-to-type binding with metadata.

type TypeCache

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

TypeCache provides LRU-based caching for inferred types. Thread-safe for concurrent access during parallel file processing.

func NewTypeCache

func NewTypeCache(capacity int) *TypeCache

NewTypeCache creates a new TypeCache with the given capacity.

func (*TypeCache) Clear

func (tc *TypeCache) Clear()

Clear removes all entries from the cache.

func (*TypeCache) Get

func (tc *TypeCache) Get(key string) (core.Type, bool)

Get retrieves a type from the cache. Returns the type and true if found, nil and false otherwise.

func (*TypeCache) HitRate

func (tc *TypeCache) HitRate() float64

HitRate returns the cache hit rate as a percentage.

func (*TypeCache) InvalidateFile

func (tc *TypeCache) InvalidateFile(file string) int

InvalidateFile removes all entries associated with a file. Used when a file is modified.

func (*TypeCache) Put

func (tc *TypeCache) Put(key string, typ core.Type, file string)

Put adds a type to the cache. If the cache is at capacity, evicts the least recently used entry.

func (*TypeCache) Stats

func (tc *TypeCache) Stats() (hits, misses int64, size int)

Stats returns cache statistics.

type TypeInferenceEngine

type TypeInferenceEngine struct {
	Scopes           map[string]*FunctionScope   // Function FQN -> scope
	ReturnTypes      map[string]*core.TypeInfo   // Function FQN -> return type
	Builtins         *registry.BuiltinRegistry   // Builtin types registry
	Registry         *core.ModuleRegistry        // Module registry reference
	Attributes       *registry.AttributeRegistry // Class attributes registry (Phase 3 Task 12)
	StdlibRegistry   *core.StdlibRegistry        // Python stdlib registry (PR #2)
	StdlibRemote     any                         // Remote loader for lazy module loading (PR #3)
	ThirdPartyRemote any                         // Remote loader for third-party type registries (PR #4)
	ImportMaps       map[string]*core.ImportMap  // File path -> ImportMap (P0 fix: for attribute placeholder resolution)
	// contains filtered or unexported fields
}

TypeInferenceEngine manages type inference across the codebase. It maintains function scopes, return types, and references to other registries. Thread-safe for concurrent access via mutex protection.

func NewTypeInferenceEngine

func NewTypeInferenceEngine(registry *core.ModuleRegistry) *TypeInferenceEngine

NewTypeInferenceEngine creates a new type inference engine. The engine is initialized with empty scopes and return types.

Parameters:

  • registry: module registry for resolving module paths

Returns:

  • Initialized TypeInferenceEngine

func (*TypeInferenceEngine) AddImportMap

func (te *TypeInferenceEngine) AddImportMap(filePath string, importMap *core.ImportMap)

AddImportMap stores an ImportMap for a file. Thread-safe for concurrent writes.

Parameters:

  • filePath: absolute path to the file
  • importMap: the ImportMap for that file

func (*TypeInferenceEngine) AddReturnTypesToEngine

func (te *TypeInferenceEngine) AddReturnTypesToEngine(returnTypes map[string]*core.TypeInfo)

AddReturnTypesToEngine populates TypeInferenceEngine with return types. Thread-safe for concurrent writes.

func (*TypeInferenceEngine) AddScope

func (te *TypeInferenceEngine) AddScope(scope *FunctionScope)

AddScope adds or updates a function scope in the engine. Thread-safe for concurrent writes.

Parameters:

  • scope: the function scope to add

func (*TypeInferenceEngine) ForEachImportMap

func (te *TypeInferenceEngine) ForEachImportMap(fn func(filePath string, importMap *core.ImportMap))

ForEachImportMap iterates over all stored ImportMaps, calling fn for each. Thread-safe for concurrent reads.

func (*TypeInferenceEngine) GetImportMap

func (te *TypeInferenceEngine) GetImportMap(filePath string) *core.ImportMap

GetImportMap retrieves an ImportMap for a file. Thread-safe for concurrent reads.

Parameters:

  • filePath: absolute path to the file

Returns:

  • ImportMap if found, nil otherwise

func (*TypeInferenceEngine) GetModuleVariableType

func (te *TypeInferenceEngine) GetModuleVariableType(modulePath string, varName string, line uint32) *core.ModuleVariableInfo

GetModuleVariableType returns type information for a module-level variable. It looks up the module's scope and retrieves the variable binding's type info. When line > 0, it returns the binding at that specific line (for reassignment tracking). When line == 0, it returns the last binding (backward compatibility). Thread-safe for concurrent reads.

Parameters:

  • modulePath: fully qualified module path (e.g., "main", "helpers")
  • varName: variable name (e.g., "x", "calc")
  • line: line number to match (0 for last binding)

Returns:

  • ModuleVariableInfo if the variable has type info, nil otherwise

func (*TypeInferenceEngine) GetReturnType

func (te *TypeInferenceEngine) GetReturnType(functionFQN string) (*core.TypeInfo, bool)

GetReturnType retrieves a function's return type. Thread-safe for concurrent reads.

Parameters:

  • functionFQN: fully qualified name of the function

Returns:

  • TypeInfo if found, nil otherwise
  • bool indicating whether the type was found

func (*TypeInferenceEngine) GetScope

func (te *TypeInferenceEngine) GetScope(functionFQN string) *FunctionScope

GetScope retrieves a function scope by its fully qualified name. Thread-safe for concurrent reads.

Parameters:

  • functionFQN: fully qualified name of the function

Returns:

  • FunctionScope if found, nil otherwise

func (*TypeInferenceEngine) ResolveReturnVariableReferences

func (te *TypeInferenceEngine) ResolveReturnVariableReferences()

ResolveReturnVariableReferences resolves "var:varName" placeholders in return types by looking up the variable's type in the function's scope. This handles the common pattern:

def foo():
    result = some_expression
    return result  # return type was "var:result", resolved to type of result

Must be called AFTER ExtractVariableAssignments and BEFORE UpdateVariableBindingsWithFunctionReturns.

func (*TypeInferenceEngine) ResolveVariableType

func (te *TypeInferenceEngine) ResolveVariableType(
	assignedFrom string,
	confidence float32,
) *core.TypeInfo

ResolveVariableType resolves the type of a variable assignment from a function call. It looks up the return type of the called function and propagates it with confidence decay. Thread-safe for concurrent reads.

Parameters:

  • assignedFrom: Function FQN that was called
  • confidence: Base confidence from assignment

Returns:

  • TypeInfo with propagated type, or nil if function has no return type

func (*TypeInferenceEngine) UpdateVariableBindingsWithFunctionReturns

func (te *TypeInferenceEngine) UpdateVariableBindingsWithFunctionReturns()

UpdateVariableBindingsWithFunctionReturns resolves "call:funcName" placeholders. It iterates through all scopes and replaces placeholder types with actual return types.

This enables inter-procedural type propagation:

user = create_user()  # Initially typed as "call:create_user"
# After update, typed as "test.User" based on create_user's return type

type TypeStore

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

TypeStore provides hierarchical scope-based type storage. Supports push/pop semantics for nested scopes (functions, loops, etc.).

func NewTypeStore

func NewTypeStore() *TypeStore

NewTypeStore creates a new TypeStore with a global scope.

func (*TypeStore) AllBindings

func (ts *TypeStore) AllBindings() []*TypeBinding

AllBindings returns all bindings across all scopes.

func (*TypeStore) AsInterface

func (ts *TypeStore) AsInterface() *TypeStore

Ensure TypeStore is compatible with strategies package.

func (*TypeStore) Clear

func (ts *TypeStore) Clear()

Clear removes all bindings except the global scope.

func (*TypeStore) Clone

func (ts *TypeStore) Clone() *TypeStore

Clone creates a deep copy of the TypeStore. Useful for speculative inference branches.

func (*TypeStore) CurrentScopeDepth

func (ts *TypeStore) CurrentScopeDepth() int

CurrentScopeDepth returns the current scope nesting level.

func (*TypeStore) Get

func (ts *TypeStore) Get(varName string) *TypeBinding

Get retrieves the type for a variable, searching from innermost to outermost scope.

func (*TypeStore) GetInCurrentScope

func (ts *TypeStore) GetInCurrentScope(varName string) *TypeBinding

GetInCurrentScope retrieves a binding only from the current scope.

func (*TypeStore) Lookup

func (ts *TypeStore) Lookup(varName string) core.Type

Lookup is an alias for Get that returns just the type.

func (*TypeStore) PopScope

func (ts *TypeStore) PopScope() map[string]*TypeBinding

PopScope removes the current scope level. Returns the removed bindings for debugging.

func (*TypeStore) PushScope

func (ts *TypeStore) PushScope(name string)

PushScope creates a new scope level.

func (*TypeStore) ScopeNames

func (ts *TypeStore) ScopeNames() []string

ScopeNames returns the names of all active scopes (for debugging).

func (*TypeStore) Set

func (ts *TypeStore) Set(varName string, typ core.Type, source core.ConfidenceSource, file string, line, col int)

Set binds a variable to a type in the current scope.

func (*TypeStore) Update

func (ts *TypeStore) Update(varName string, typ core.Type) bool

Update updates an existing binding in its original scope. Returns false if the variable doesn't exist.

type TypeStoreAdapter

type TypeStoreAdapter struct {
	*TypeStore
}

TypeStoreAdapter adapts TypeStore to strategies.InferenceContext. This ensures the interface contract is maintained.

type VariableBinding

type VariableBinding struct {
	VarName      string         // Variable name
	Type         *core.TypeInfo // Inferred type information
	AssignedFrom string         // FQN of function that assigned this value (if from function call)
	Location     Location       // Source location of the assignment
}

VariableBinding tracks a variable's type within a scope. It captures the variable name, its inferred type, and source location.

Directories

Path Synopsis
Package strategies provides AttributeAccessStrategy for general attribute access.
Package strategies provides AttributeAccessStrategy for general attribute access.

Jump to

Keyboard shortcuts

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