Documentation
¶
Overview ¶
Package analysis provides scope-aware semantic analysis for ELPS lisp source.
The analyzer builds a scope tree from parsed expressions, resolves symbol references, and identifies unresolved symbols. It is designed to be used by lint analyzers for semantic checks like undefined-symbol and unused-variable.
Index ¶
- func ExtractPackageExports(reg *lisp.PackageRegistry) map[string][]ExternalSymbol
- func ScanWorkspaceAll(root string) (globals []ExternalSymbol, pkgs map[string][]ExternalSymbol, ...)
- func ScanWorkspacePackages(root string) (map[string][]ExternalSymbol, error)
- func ScanWorkspaceRefs(root string, cfg *Config) map[string][]FileReference
- func ShouldSkipDir(name string) bool
- type Config
- type DefFormSpec
- type ExternalSymbol
- type FileReference
- type Reference
- type Result
- type Scope
- func (s *Scope) Define(sym *Symbol)
- func (s *Scope) DefineImported(sym *Symbol, pkg string)
- func (s *Scope) DefineQualifiedOnly(sym *Symbol)
- func (s *Scope) Lookup(name string) *Symbol
- func (s *Scope) LookupAllLocal(name string) []*Symbol
- func (s *Scope) LookupInPackage(name, pkg string) *Symbol
- func (s *Scope) LookupLocal(name string) *Symbol
- func (s *Scope) LookupLocalInPackage(name, pkg string) *Symbol
- func (s *Scope) LookupLocalVisible(name, pkg string) *Symbol
- type ScopeKind
- type Signature
- type Symbol
- type SymbolKey
- type SymbolKind
- type UnresolvedRef
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExtractPackageExports ¶
func ExtractPackageExports(reg *lisp.PackageRegistry) map[string][]ExternalSymbol
ExtractPackageExports creates a map of package name to exported symbols from a loaded runtime's package registry. This is used to resolve use-package imports for packages defined in Go (stdlib) that cannot be found by workspace scanning.
func ScanWorkspaceAll ¶ added in v1.39.0
func ScanWorkspaceAll(root string) (globals []ExternalSymbol, pkgs map[string][]ExternalSymbol, allDefs []ExternalSymbol, err error)
ScanWorkspaceAll combines ScanWorkspaceFull and ScanWorkspaceDefinitions into a single pass: each file is parsed once and all three results are extracted from the same AST.
func ScanWorkspacePackages ¶
func ScanWorkspacePackages(root string) (map[string][]ExternalSymbol, error)
ScanWorkspacePackages is like ScanWorkspace but returns a map of package name to exported symbols, suitable for use as Config.PackageExports.
func ScanWorkspaceRefs ¶ added in v1.31.0
func ScanWorkspaceRefs(root string, cfg *Config) map[string][]FileReference
ScanWorkspaceRefs walks the workspace directory tree, performs full analysis on each .lisp file, and extracts cross-file references. The cfg should have ExtraGlobals and PackageExports populated from a prior ScanWorkspaceFull call. Parsing is done concurrently.
Returns a map from SymbolKey.String() to FileReference slices.
func ShouldSkipDir ¶ added in v1.32.0
ShouldSkipDir returns true for directories that should not be walked. It skips hidden directories (e.g. .git, .vscode) and node_modules, but not "." or ".." which represent the current/parent directory.
Types ¶
type Config ¶
type Config struct {
// ExtraGlobals are symbols from other files (e.g. workspace scanning).
ExtraGlobals []ExternalSymbol
// PackageExports maps package names to their exported symbols.
// Used to resolve use-package imports from stdlib and workspace packages.
PackageExports map[string][]ExternalSymbol
// DefForms declares additional definition-form heads for embedding programs.
// Head is matched exactly against the form head symbol. FormalsIndex must
// point at the parameter list cell. If BindsName is true, NameIndex points
// at the defined symbol cell and the analyzer registers it using NameKind.
DefForms []DefFormSpec
// Filename is the source file being analyzed.
Filename string
}
Config controls the behavior of the analyzer.
type DefFormSpec ¶ added in v1.38.0
type DefFormSpec struct {
Head string
FormalsIndex int
BindsName bool
NameIndex int
NameKind SymbolKind
}
DefFormSpec describes a custom definition-like form.
type ExternalSymbol ¶
type ExternalSymbol struct {
Name string
Kind SymbolKind
Package string
Signature *Signature
Source *token.Location
DocString string
}
ExternalSymbol represents a symbol defined in another file.
func ScanWorkspace ¶
func ScanWorkspace(root string) ([]ExternalSymbol, error)
ScanWorkspace walks a directory tree, parsing all .lisp files and extracting exported top-level definitions. The result can be used as Config.ExtraGlobals for cross-file symbol resolution.
Files that fail to parse are silently skipped (fault tolerant).
func ScanWorkspaceDefinitions ¶ added in v1.39.0
func ScanWorkspaceDefinitions(root string) ([]ExternalSymbol, error)
ScanWorkspaceDefinitions walks a directory tree and returns all top-level definitions, including non-exported symbols. The result is intended for workspace symbol search, not cross-file resolution.
func ScanWorkspaceFull ¶ added in v1.27.0
func ScanWorkspaceFull(root string) ([]ExternalSymbol, map[string][]ExternalSymbol, error)
ScanWorkspaceFull walks a directory tree in a single pass, parsing all .lisp files and extracting both global symbols and package exports. It skips hidden directories (names starting with '.'), node_modules, and vendor directories. Stops collecting after maxWorkspaceFiles. Parsing is done concurrently using a bounded worker pool.
Files that fail to parse are silently skipped (fault tolerant).
type FileReference ¶ added in v1.31.0
type FileReference struct {
SymbolKey SymbolKey
Source *token.Location
File string // absolute path
Enclosing string // name of enclosing function ("" if top-level)
EnclosingSource *token.Location // definition site of enclosing function
EnclosingKind SymbolKind // kind of enclosing function
}
FileReference represents a cross-file reference to a symbol.
func ExtractFileRefs ¶ added in v1.31.0
func ExtractFileRefs(result *Result, filePath string) []FileReference
ExtractFileRefs extracts cross-file-trackable references from an analysis result. Only references to global-scope, non-builtin symbols are included (builtins, special ops, parameters, and locals are skipped).
type Result ¶
type Result struct {
RootScope *Scope
Symbols []*Symbol
References []*Reference
Unresolved []*UnresolvedRef
}
Result holds the output of semantic analysis.
type Scope ¶
type Scope struct {
Kind ScopeKind
Parent *Scope
Children []*Scope
Symbols map[string]*Symbol
PackageSymbols map[string]*Symbol
PackageImports map[string]map[string]*Symbol
Node *lisp.LVal // the AST node that introduced this scope
// contains filtered or unexported fields
}
Scope represents a lexical scope in the source.
func ScopeAtPosition ¶ added in v1.31.0
ScopeAtPosition returns the innermost scope that contains the given 1-based ELPS line and column. It walks the scope tree depth-first.
func (*Scope) DefineImported ¶ added in v1.39.0
DefineImported adds a symbol that should be visible both by package-qualified name and as an unqualified import in the current scope.
func (*Scope) DefineQualifiedOnly ¶ added in v1.39.0
DefineQualifiedOnly adds a package-qualified symbol without adding it to the bare-name Symbols map. The symbol is still reachable through Lookup/LookupLocal via the bareNameIndex for package-agnostic callers (e.g., minifier, lint arity checker).
func (*Scope) Lookup ¶
Lookup resolves a symbol by walking the parent chain. Returns nil if the symbol is not found.
func (*Scope) LookupAllLocal ¶ added in v1.39.0
LookupAllLocal returns all symbols matching a bare name in this scope, across Symbols and all PackageSymbols entries. Used by call hierarchy to find all package variants of a function name.
func (*Scope) LookupInPackage ¶ added in v1.39.0
LookupInPackage resolves a symbol by preferring a package-qualified match in the current scope chain before falling back to a bare-name lookup. The bare-name fallback into Symbols is intentional: builtins and user-package symbols are registered with Package == "" and must be reachable when no qualified entry matches.
Unlike Lookup, LookupInPackage does not consult bareNameIndex — a symbol registered only via DefineQualifiedOnly is invisible to LookupInPackage unless the correct package is specified.
func (*Scope) LookupLocal ¶
LookupLocal resolves a symbol only in this scope (not parents).
func (*Scope) LookupLocalInPackage ¶ added in v1.39.0
LookupLocalInPackage resolves a symbol in the current scope, preferring the package-qualified key when a package is provided.
The bare-name fallback into Symbols is restricted to the default user package. This prevents builtins (Package == "") from blocking package-local definitions like (in-package 'foo) (defun set ...). Unlike LookupInPackage, this method does not consult bareNameIndex.
func (*Scope) LookupLocalVisible ¶ added in v1.39.0
LookupLocalVisible resolves a symbol as it would be seen unqualified in the current scope: first the active package, then imported/bare symbols.
type Signature ¶
Signature describes the parameter signature of a callable symbol.
type Symbol ¶
type Symbol struct {
Name string
Package string
Kind SymbolKind
Source *token.Location // nil for builtins
Node *lisp.LVal
Scope *Scope
Signature *Signature // non-nil for callables
DocString string
References int
Exported bool
External bool // true for workspace-scanned or package-imported symbols
}
Symbol represents a defined name in a scope.
func FindEnclosingFunction ¶ added in v1.31.0
FindEnclosingFunction finds the function symbol that contains the given 1-based position by walking the scope tree.
type SymbolKey ¶ added in v1.31.0
type SymbolKey struct {
Package string
Name string
Kind SymbolKind
}
SymbolKey identifies a symbol across files by name and kind.
func SymbolKeyFromNameKind ¶ added in v1.31.0
SymbolKeyFromNameKind creates a SymbolKey from raw name and kind strings. The kind string should match SymbolKind.String() output.
func SymbolToKey ¶ added in v1.31.0
SymbolToKey derives a SymbolKey from an analysis Symbol.
type SymbolKind ¶
type SymbolKind int
SymbolKind classifies a symbol definition.
const ( SymVariable SymbolKind = iota // set, let binding SymFunction // defun, flet/labels binding SymMacro // defmacro SymParameter // function/lambda parameter SymSpecialOp // special operator (if, cond, etc.) SymBuiltin // builtin function SymType // deftype )
func (SymbolKind) String ¶
func (k SymbolKind) String() string