analysis

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Mar 11, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package analysis provides language-agnostic code analysis through a unified interface. Each language implements the Analyzer interface, producing consistent structural metrics that feed into the certification scoring pipeline.

Index

Constants

This section is empty.

Variables

View Source
var DefaultLSPServers = map[string]LSPServerConfig{
	"ts": {Command: "typescript-language-server", Args: []string{"--stdio"}},
	"py": {Command: "pyright-langserver", Args: []string{"--stdio"}},
	"rs": {Command: "rust-analyzer", Args: nil},
}

DefaultLSPServers maps language identifiers to their default server configs.

Functions

func FormatLSPStatus added in v0.12.0

func FormatLSPStatus(avail []LSPAvailability) []string

FormatLSPStatus returns a human-readable status for doctor output.

func LangDisplayName added in v0.12.0

func LangDisplayName(lang string) string

LangDisplayName returns a display name for a language code.

func Languages

func Languages() []string

Languages returns all registered language identifiers.

func Register

func Register(lang string, factory func() Analyzer)

Register adds an analyzer for a language.

Types

type AbstractionResult added in v0.12.0

type AbstractionResult struct {
	TotalParams     int // total number of params
	ConcreteDeps    int // params accepting concrete struct types from other packages
	InterfaceParams int // params accepting interface types
}

AbstractionResult holds the param abstraction analysis for a function.

type Analyzer

type Analyzer interface {
	// Language returns the language identifier (e.g., "go", "ts", "py").
	Language() string

	// Discover finds all symbols in a source file.
	Discover(path string, src []byte) ([]Symbol, error)

	// Analyze returns structural metrics for a specific symbol.
	Analyze(path string, src []byte, symbol string) (Metrics, error)

	// AnalyzeFile returns file-level metrics.
	AnalyzeFile(path string, src []byte) (FileMetrics, error)
}

Analyzer provides language-agnostic structural analysis.

func ForLanguage

func ForLanguage(lang string) Analyzer

ForLanguage returns an Analyzer for the given language, or nil if unsupported.

type DeepGoAnalyzer added in v0.12.0

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

DeepGoAnalyzer provides type-aware cross-file analysis for Go using go/packages + SSA + VTA call graph analysis.

func LoadGoProject added in v0.12.0

func LoadGoProject(root string, patterns ...string) (*DeepGoAnalyzer, error)

LoadGoProject loads all Go packages under root and builds the call graph. patterns is typically []string{"./..."} to load all packages.

func (*DeepGoAnalyzer) AllResults added in v0.12.0

func (a *DeepGoAnalyzer) AllResults() map[FuncKey]DeepResult

AllResults returns all computed deep analysis results.

func (*DeepGoAnalyzer) CouplingScore added in v0.12.0

func (a *DeepGoAnalyzer) CouplingScore(pkg, funcName string) float64

CouplingScore computes a normalized coupling score for a function. coupling = fan_in * fan_out, normalized to [0, 1] range.

func (*DeepGoAnalyzer) DepDepth added in v0.12.0

func (a *DeepGoAnalyzer) DepDepth(pkgPath string) int

DepDepth returns the maximum transitive local import depth for a package. Only counts imports within the project (same module prefix), not stdlib.

func (*DeepGoAnalyzer) FanIn added in v0.12.0

func (a *DeepGoAnalyzer) FanIn(pkg, funcName string) int

FanIn returns the number of call sites that invoke the named function.

func (*DeepGoAnalyzer) FanOut added in v0.12.0

func (a *DeepGoAnalyzer) FanOut(pkg, funcName string) int

FanOut returns the number of distinct functions called by the named function.

func (*DeepGoAnalyzer) Instability added in v0.12.0

func (a *DeepGoAnalyzer) Instability(pkgPath string) float64

Instability computes Robert C. Martin's instability metric: Ce / (Ca + Ce) Ce = efferent coupling (local imports this package makes) Ca = afferent coupling (local packages that import this one) Returns 0.0 (fully stable) to 1.0 (fully unstable).

func (*DeepGoAnalyzer) InterfaceSize added in v0.12.0

func (a *DeepGoAnalyzer) InterfaceSize(pkg, funcName string) int

InterfaceSize returns the number of methods in the interface that the named type's method belongs to (0 if not a method or not implementing an interface).

func (*DeepGoAnalyzer) Lookup added in v0.12.0

func (a *DeepGoAnalyzer) Lookup(pkg, funcName string) (DeepResult, bool)

Lookup returns the deep analysis result for a specific function.

func (*DeepGoAnalyzer) ParamAbstraction added in v0.12.0

func (a *DeepGoAnalyzer) ParamAbstraction(pkg, funcName string) AbstractionResult

ParamAbstraction checks whether function params use interfaces or concrete types from other packages.

func (*DeepGoAnalyzer) TypeAwareErrorWrapping added in v0.12.0

func (a *DeepGoAnalyzer) TypeAwareErrorWrapping(pkg, funcName string) int

TypeAwareErrorWrapping returns the count of error return statements that don't wrap the error with context. Uses type information to verify the value is actually of type error, reducing false positives.

func (*DeepGoAnalyzer) UnusedExports added in v0.12.0

func (a *DeepGoAnalyzer) UnusedExports() []UnusedSymbol

UnusedExports returns exported symbols with zero external references.

func (*DeepGoAnalyzer) UnusedParams added in v0.12.0

func (a *DeepGoAnalyzer) UnusedParams(pkg, funcName string) int

UnusedParams returns the count of parameters that are never referenced in the function body. Does not count receiver or blank identifier (_).

type DeepResult added in v0.12.0

type DeepResult struct {
	FanIn      int  // number of call sites that invoke this function
	FanOut     int  // number of distinct functions called by this function
	IsDeadCode bool // exported with zero external references
}

DeepResult holds the type-aware analysis results for a single function.

type FileMetrics

type FileMetrics struct {
	HasInitFunc        bool
	GlobalMutableCount int
}

FileMetrics holds file-level analysis results.

type FuncKey added in v0.12.0

type FuncKey struct {
	Pkg  string // full package path
	Name string // function or method name (e.g., "Hello" or "(*T).Method")
}

FuncKey uniquely identifies a function by package path and name.

type GoAnalyzer

type GoAnalyzer struct{}

GoAnalyzer implements Analyzer for Go source code using go/ast.

func NewGoAnalyzer

func NewGoAnalyzer() *GoAnalyzer

NewGoAnalyzer creates a new Go analyzer.

func (*GoAnalyzer) Analyze

func (a *GoAnalyzer) Analyze(path string, src []byte, symbol string) (Metrics, error)

Analyze returns structural metrics for a specific symbol.

func (*GoAnalyzer) AnalyzeFile

func (a *GoAnalyzer) AnalyzeFile(path string, src []byte) (FileMetrics, error)

AnalyzeFile returns file-level metrics.

func (*GoAnalyzer) Discover

func (a *GoAnalyzer) Discover(path string, src []byte) ([]Symbol, error)

Discover finds all functions, methods, and types in Go source.

func (*GoAnalyzer) Language

func (a *GoAnalyzer) Language() string

type LSPAnalyzer added in v0.12.0

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

LSPAnalyzer wraps an LSP client to provide Tier 2 analysis for non-Go languages.

func NewLSPAnalyzer added in v0.12.0

func NewLSPAnalyzer(lang, rootDir string) (*LSPAnalyzer, error)

NewLSPAnalyzer starts the appropriate language server and returns an analyzer. Returns nil, nil if no LSP server is available for the language.

func (*LSPAnalyzer) FanIn added in v0.12.0

func (a *LSPAnalyzer) FanIn(file string, line, col int) (int, error)

FanIn returns incoming call count for a symbol at the given position.

func (*LSPAnalyzer) FanOut added in v0.12.0

func (a *LSPAnalyzer) FanOut(file string, line, col int) (int, error)

FanOut returns outgoing call count from a symbol at the given position.

func (*LSPAnalyzer) IsDeadCode added in v0.12.0

func (a *LSPAnalyzer) IsDeadCode(file string, line, col int) (bool, error)

IsDeadCode returns true if symbol has zero references outside its file.

func (*LSPAnalyzer) OpenFile added in v0.12.0

func (a *LSPAnalyzer) OpenFile(file string) error

OpenFile sends a textDocument/didOpen notification for a file.

func (*LSPAnalyzer) Shutdown added in v0.12.0

func (a *LSPAnalyzer) Shutdown() error

Shutdown gracefully stops the language server.

type LSPAvailability added in v0.12.0

type LSPAvailability struct {
	Language    string
	Available   bool
	Command     string
	InstallHint string
}

LSPAvailability describes what LSP servers are available per language.

func DetectLSPServers added in v0.12.0

func DetectLSPServers() []LSPAvailability

DetectLSPServers checks which language servers are installed.

type LSPServerConfig added in v0.12.0

type LSPServerConfig struct {
	Command string
	Args    []string
}

LSPServerConfig describes how to start a language server.

type Metrics

type Metrics struct {
	// Shape
	ParamCount      int // Number of function parameters
	ReturnCount     int // Number of return values
	FuncLines       int // Lines in function body
	MaxNestingDepth int // Deepest nesting level (if/for/switch/etc.)

	// Documentation
	HasDocComment bool   // Has a doc comment
	IsExported    bool   // Exported / public symbol
	ReceiverName  string // Receiver type name (empty for standalone)
	IsConstructor bool   // Matches constructor pattern (New*, __init__, constructor)

	// Complexity
	CyclomaticComplexity int    // McCabe cyclomatic complexity
	CognitiveComplexity  int    // Sonar-style cognitive complexity
	LoopNestingDepth     int    // Max nested loop depth (for/while only)
	RecursiveCalls       int    // Direct recursive calls
	AlgoComplexity       string // Estimated Big-O: O(1), O(n), O(n²), etc.

	// Error handling
	ErrorsIgnored    int // Discarded error returns
	ErrorsNotWrapped int // Errors returned without wrapping/context
	NakedReturns     int // Bare return in named-return function
	PanicCalls       int // panic(), throw, unwrap() — unrecoverable exits
	EmptyCatchBlocks int // catch/except/recover with empty body

	// Security
	UnsafeImports    []string // Dangerous imports (os/exec, unsafe, eval, etc.)
	HardcodedSecrets int      // String literals matching secret patterns

	// Design
	MethodCount     int  // Methods on a type (type-level only)
	DeferInLoop     int  // Defer/finally inside loops
	ContextNotFirst bool // context.Context not first param (Go-specific)

	// Performance
	NestedLoopPairs   int // Inner loops nested in outer loops
	QuadraticPatterns int // Known O(n²) anti-patterns

	// File-level
	HasInitFunc        bool // File contains init() or equivalent
	GlobalMutableCount int  // Package-level mutable variables
	OsExitCalls        int  // os.Exit() or sys.exit() calls

	// Language-specific extras
	Extra map[string]float64
}

Metrics holds language-agnostic structural analysis results for a code unit.

func (Metrics) ToEvidence

func (m Metrics) ToEvidence() domain.Evidence

ToEvidence converts Metrics to a domain.Evidence for the scoring pipeline.

type PythonAnalyzer

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

PythonAnalyzer implements Analyzer for Python using tree-sitter.

func NewPythonAnalyzer

func NewPythonAnalyzer() *PythonAnalyzer

NewPythonAnalyzer creates a new Python analyzer.

func (*PythonAnalyzer) Analyze

func (a *PythonAnalyzer) Analyze(path string, src []byte, symbol string) (Metrics, error)

Analyze returns structural metrics for a symbol.

func (*PythonAnalyzer) AnalyzeFile

func (a *PythonAnalyzer) AnalyzeFile(path string, src []byte) (FileMetrics, error)

AnalyzeFile returns file-level metrics.

func (*PythonAnalyzer) Discover

func (a *PythonAnalyzer) Discover(path string, src []byte) ([]Symbol, error)

Discover finds all symbols in Python source.

func (*PythonAnalyzer) Language

func (a *PythonAnalyzer) Language() string

type RustAnalyzer

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

RustAnalyzer implements Analyzer for Rust using tree-sitter.

func NewRustAnalyzer

func NewRustAnalyzer() *RustAnalyzer

NewRustAnalyzer creates a new Rust analyzer.

func (*RustAnalyzer) Analyze

func (a *RustAnalyzer) Analyze(path string, src []byte, symbol string) (Metrics, error)

Analyze returns structural metrics for a symbol.

func (*RustAnalyzer) AnalyzeFile

func (a *RustAnalyzer) AnalyzeFile(path string, src []byte) (FileMetrics, error)

AnalyzeFile returns file-level metrics.

func (*RustAnalyzer) Discover

func (a *RustAnalyzer) Discover(path string, src []byte) ([]Symbol, error)

Discover finds all symbols in Rust source.

func (*RustAnalyzer) Language

func (a *RustAnalyzer) Language() string

type Symbol

type Symbol struct {
	Name      string     // Symbol name
	Kind      SymbolKind // Function, method, class, etc.
	StartLine int        // 1-indexed start line
	EndLine   int        // 1-indexed end line (inclusive)
	Parent    string     // Enclosing type/class name (empty for top-level)
	Exported  bool       // Whether the symbol is exported/public
}

Symbol represents a discovered code unit within a source file.

type SymbolKind

type SymbolKind int

SymbolKind identifies the type of a discovered code symbol.

const (
	SymbolFunction  SymbolKind = iota // Standalone function
	SymbolMethod                      // Method on a type/class
	SymbolClass                       // Type, class, struct, interface
	SymbolConstant                    // Exported constant or variable
	SymbolInterface                   // Interface (separate from class for languages that distinguish)
)

func (SymbolKind) String

func (k SymbolKind) String() string

type TSAnalyzer

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

TSAnalyzer implements Analyzer for TypeScript using tree-sitter.

func NewTSAnalyzer

func NewTSAnalyzer() *TSAnalyzer

NewTSAnalyzer creates a new TypeScript analyzer.

func (*TSAnalyzer) Analyze

func (a *TSAnalyzer) Analyze(path string, src []byte, symbol string) (Metrics, error)

Analyze returns structural metrics for a specific symbol.

func (*TSAnalyzer) AnalyzeFile

func (a *TSAnalyzer) AnalyzeFile(path string, src []byte) (FileMetrics, error)

AnalyzeFile returns file-level metrics.

func (*TSAnalyzer) Discover

func (a *TSAnalyzer) Discover(path string, src []byte) ([]Symbol, error)

Discover finds all symbols in a TypeScript source file.

func (*TSAnalyzer) Language

func (a *TSAnalyzer) Language() string

type UnusedSymbol added in v0.12.0

type UnusedSymbol struct {
	Pkg      string // package path
	Name     string // symbol name
	FilePath string // file where it's defined
	Line     int    // line number
}

UnusedSymbol represents an exported symbol with no external references.

Directories

Path Synopsis
Package lsp provides a generic JSON-RPC 2.0 client for communicating with Language Server Protocol servers via stdin/stdout.
Package lsp provides a generic JSON-RPC 2.0 client for communicating with Language Server Protocol servers via stdin/stdout.

Jump to

Keyboard shortcuts

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