Documentation
¶
Index ¶
- Constants
- func CalculateNestingDepth(node *parser.Node) int
- func DetectAll(cfgs map[string]*CFG, filePath string) map[string]*DeadCodeResult
- type BasicBlock
- type CFG
- func (cfg *CFG) AddBlock(block *BasicBlock)
- func (cfg *CFG) BreadthFirstWalk(visitor CFGVisitor)
- func (cfg *CFG) ConnectBlocks(from, to *BasicBlock, edgeType EdgeType) *Edge
- func (cfg *CFG) CreateBlock(label string) *BasicBlock
- func (cfg *CFG) GetBlock(id string) *BasicBlock
- func (cfg *CFG) RemoveBlock(block *BasicBlock)
- func (cfg *CFG) Size() int
- func (cfg *CFG) String() string
- func (cfg *CFG) Walk(visitor CFGVisitor)
- type CFGBuilder
- type CFGVisitor
- type ComplexityAnalyzer
- type ComplexityResult
- type DeadCodeDetector
- type DeadCodeFinding
- type DeadCodeReason
- type DeadCodeResult
- type Edge
- type EdgeType
- type ReachabilityAnalyzer
- type ReachabilityResult
- type SeverityLevel
Constants ¶
const ( LabelFunctionBody = "func_body" LabelClassBody = "class_body" LabelUnreachable = "unreachable" LabelMainModule = "main" LabelEntry = "ENTRY" LabelExit = "EXIT" // Loop-related labels LabelLoopHeader = "loop_header" LabelLoopBody = "loop_body" LabelLoopExit = "loop_exit" // Exception-related labels LabelTryBlock = "try_block" LabelCatchBlock = "catch_block" LabelFinallyBlock = "finally_block" // Switch-related labels LabelSwitchCase = "switch_case" LabelSwitchMerge = "switch_merge" )
Block label constants
Variables ¶
This section is empty.
Functions ¶
func CalculateNestingDepth ¶
CalculateNestingDepth calculates the maximum nesting depth of a function
Types ¶
type BasicBlock ¶
type BasicBlock struct {
// ID is the unique identifier for this block
ID string
// Statements contains the AST nodes in this block
Statements []*parser.Node
// Predecessors are blocks that can flow into this block
Predecessors []*Edge
// Successors are blocks that this block can flow to
Successors []*Edge
// Label is an optional human-readable label
Label string
// IsEntry indicates if this is an entry block
IsEntry bool
// IsExit indicates if this is an exit block
IsExit bool
}
BasicBlock represents a basic block in the control flow graph
func NewBasicBlock ¶
func NewBasicBlock(id string) *BasicBlock
NewBasicBlock creates a new basic block with the given ID
func (*BasicBlock) AddStatement ¶
func (bb *BasicBlock) AddStatement(stmt *parser.Node)
AddStatement adds an AST node to this block
func (*BasicBlock) AddSuccessor ¶
func (bb *BasicBlock) AddSuccessor(to *BasicBlock, edgeType EdgeType) *Edge
AddSuccessor adds an outgoing edge to another block
func (*BasicBlock) IsEmpty ¶
func (bb *BasicBlock) IsEmpty() bool
IsEmpty returns true if the block has no statements
func (*BasicBlock) RemoveSuccessor ¶
func (bb *BasicBlock) RemoveSuccessor(to *BasicBlock)
RemoveSuccessor removes an edge to the specified block
func (*BasicBlock) String ¶
func (bb *BasicBlock) String() string
String returns a string representation of the basic block
type CFG ¶
type CFG struct {
// Entry is the entry point of the graph
Entry *BasicBlock
// Exit is the exit point of the graph
Exit *BasicBlock
// Blocks contains all blocks in the graph, indexed by ID
Blocks map[string]*BasicBlock
// Name is the name of the CFG (e.g., function name)
Name string
// FunctionNode is the original AST node for the function
FunctionNode *parser.Node
// contains filtered or unexported fields
}
CFG represents a control flow graph
func (*CFG) AddBlock ¶
func (cfg *CFG) AddBlock(block *BasicBlock)
AddBlock adds an existing block to the graph
func (*CFG) BreadthFirstWalk ¶
func (cfg *CFG) BreadthFirstWalk(visitor CFGVisitor)
BreadthFirstWalk performs a breadth-first traversal of the CFG
func (*CFG) ConnectBlocks ¶
func (cfg *CFG) ConnectBlocks(from, to *BasicBlock, edgeType EdgeType) *Edge
ConnectBlocks creates an edge between two blocks
func (*CFG) CreateBlock ¶
func (cfg *CFG) CreateBlock(label string) *BasicBlock
CreateBlock creates a new basic block and adds it to the graph
func (*CFG) GetBlock ¶
func (cfg *CFG) GetBlock(id string) *BasicBlock
GetBlock retrieves a block by its ID
func (*CFG) RemoveBlock ¶
func (cfg *CFG) RemoveBlock(block *BasicBlock)
RemoveBlock removes a block from the graph
func (*CFG) Walk ¶
func (cfg *CFG) Walk(visitor CFGVisitor)
Walk performs a depth-first traversal of the CFG
type CFGBuilder ¶
type CFGBuilder struct {
// contains filtered or unexported fields
}
CFGBuilder builds control flow graphs from AST nodes
func (*CFGBuilder) Build ¶
func (b *CFGBuilder) Build(node *parser.Node) (*CFG, error)
Build constructs a CFG from an AST node
func (*CFGBuilder) SetLogger ¶
func (b *CFGBuilder) SetLogger(logger *log.Logger)
SetLogger sets an optional logger for error reporting
type CFGVisitor ¶
type CFGVisitor interface {
// VisitBlock is called for each basic block
// Returns false to stop traversal
VisitBlock(block *BasicBlock) bool
// VisitEdge is called for each edge
// Returns false to stop traversal
VisitEdge(edge *Edge) bool
}
CFGVisitor defines the interface for visiting CFG nodes
type ComplexityAnalyzer ¶
type ComplexityAnalyzer struct {
// contains filtered or unexported fields
}
ComplexityAnalyzer analyzes complexity for multiple functions
func NewComplexityAnalyzer ¶
func NewComplexityAnalyzer(cfg *config.ComplexityConfig) *ComplexityAnalyzer
NewComplexityAnalyzer creates a new complexity analyzer
func (*ComplexityAnalyzer) AnalyzeFile ¶
func (ca *ComplexityAnalyzer) AnalyzeFile(ast *parser.Node) ([]*ComplexityResult, error)
AnalyzeFile analyzes complexity for all functions in a file
type ComplexityResult ¶
type ComplexityResult struct {
// McCabe cyclomatic complexity
Complexity int
// Raw CFG metrics
Edges int
Nodes int
ConnectedComponents int
// Function/method information
FunctionName string
StartLine int
StartCol int
EndLine int
// Nesting depth
NestingDepth int
// Decision points breakdown
IfStatements int
LoopStatements int
ExceptionHandlers int
SwitchCases int
LogicalOperators int // JavaScript-specific: &&, ||, ??
TernaryOperators int // JavaScript-specific: ? :
// Risk assessment based on complexity thresholds
RiskLevel string // "low", "medium", "high"
}
ComplexityResult holds cyclomatic complexity metrics for a function or method
func CalculateComplexity ¶
func CalculateComplexity(cfg *CFG) *ComplexityResult
CalculateComplexity computes McCabe cyclomatic complexity for a CFG using default thresholds
func CalculateComplexityWithConfig ¶
func CalculateComplexityWithConfig(cfg *CFG, complexityConfig *config.ComplexityConfig) *ComplexityResult
CalculateComplexityWithConfig computes McCabe cyclomatic complexity using provided configuration
func (*ComplexityResult) GetComplexity ¶
func (cr *ComplexityResult) GetComplexity() int
func (*ComplexityResult) GetDetailedMetrics ¶
func (cr *ComplexityResult) GetDetailedMetrics() map[string]int
func (*ComplexityResult) GetFunctionName ¶
func (cr *ComplexityResult) GetFunctionName() string
func (*ComplexityResult) GetRiskLevel ¶
func (cr *ComplexityResult) GetRiskLevel() string
func (*ComplexityResult) String ¶
func (cr *ComplexityResult) String() string
String returns a human-readable representation of the complexity result
type DeadCodeDetector ¶
type DeadCodeDetector struct {
// contains filtered or unexported fields
}
DeadCodeDetector provides high-level dead code detection functionality
func NewDeadCodeDetector ¶
func NewDeadCodeDetector(cfg *CFG) *DeadCodeDetector
NewDeadCodeDetector creates a new dead code detector for the given CFG
func NewDeadCodeDetectorWithFilePath ¶
func NewDeadCodeDetectorWithFilePath(cfg *CFG, filePath string) *DeadCodeDetector
NewDeadCodeDetectorWithFilePath creates a new dead code detector with file path context
func (*DeadCodeDetector) Detect ¶
func (dcd *DeadCodeDetector) Detect() *DeadCodeResult
Detect performs dead code detection and returns structured findings
type DeadCodeFinding ¶
type DeadCodeFinding struct {
// Function information
FunctionName string `json:"function_name"`
FilePath string `json:"file_path"`
// Location information
StartLine int `json:"start_line"`
EndLine int `json:"end_line"`
// Dead code details
BlockID string `json:"block_id"`
Code string `json:"code"`
Reason DeadCodeReason `json:"reason"`
Severity SeverityLevel `json:"severity"`
Description string `json:"description"`
// Context information
Context []string `json:"context,omitempty"`
}
DeadCodeFinding represents a single dead code detection result
type DeadCodeReason ¶
type DeadCodeReason string
DeadCodeReason represents the reason why code is considered dead
const ( // ReasonUnreachableAfterReturn indicates code after a return statement ReasonUnreachableAfterReturn DeadCodeReason = "unreachable_after_return" // ReasonUnreachableAfterBreak indicates code after a break statement ReasonUnreachableAfterBreak DeadCodeReason = "unreachable_after_break" // ReasonUnreachableAfterContinue indicates code after a continue statement ReasonUnreachableAfterContinue DeadCodeReason = "unreachable_after_continue" // ReasonUnreachableAfterThrow indicates code after a throw statement ReasonUnreachableAfterThrow DeadCodeReason = "unreachable_after_throw" // ReasonUnreachableBranch indicates an unreachable branch condition ReasonUnreachableBranch DeadCodeReason = "unreachable_branch" // ReasonUnreachableAfterInfiniteLoop indicates code after an infinite loop ReasonUnreachableAfterInfiniteLoop DeadCodeReason = "unreachable_after_infinite_loop" )
type DeadCodeResult ¶
type DeadCodeResult struct {
// Function information
FunctionName string `json:"function_name"`
FilePath string `json:"file_path"`
// Analysis results
Findings []*DeadCodeFinding `json:"findings"`
TotalBlocks int `json:"total_blocks"`
DeadBlocks int `json:"dead_blocks"`
ReachableRatio float64 `json:"reachable_ratio"`
// Performance metrics
AnalysisTime time.Duration `json:"analysis_time"`
}
DeadCodeResult contains the results of dead code analysis for a single CFG
func (*DeadCodeResult) GetCriticalFindings ¶
func (dcr *DeadCodeResult) GetCriticalFindings() []*DeadCodeFinding
GetCriticalFindings returns only critical severity findings
func (*DeadCodeResult) GetWarningFindings ¶
func (dcr *DeadCodeResult) GetWarningFindings() []*DeadCodeFinding
GetWarningFindings returns only warning severity findings
func (*DeadCodeResult) HasFindings ¶
func (dcr *DeadCodeResult) HasFindings() bool
HasFindings returns true if there are any dead code findings
type Edge ¶
type Edge struct {
From *BasicBlock
To *BasicBlock
Type EdgeType
}
Edge represents a directed edge between two basic blocks
type EdgeType ¶
type EdgeType int
EdgeType represents the type of edge between basic blocks
const ( // EdgeNormal represents normal sequential flow EdgeNormal EdgeType = iota // EdgeCondTrue represents conditional true branch EdgeCondTrue // EdgeCondFalse represents conditional false branch EdgeCondFalse // EdgeException represents exception flow EdgeException // EdgeLoop represents loop back edge EdgeLoop // EdgeBreak represents break statement flow EdgeBreak // EdgeContinue represents continue statement flow EdgeContinue // EdgeReturn represents return statement flow EdgeReturn )
type ReachabilityAnalyzer ¶
type ReachabilityAnalyzer struct {
// contains filtered or unexported fields
}
ReachabilityAnalyzer performs reachability analysis on CFGs
func NewReachabilityAnalyzer ¶
func NewReachabilityAnalyzer(cfg *CFG) *ReachabilityAnalyzer
NewReachabilityAnalyzer creates a new reachability analyzer for the given CFG
func (*ReachabilityAnalyzer) AnalyzeReachability ¶
func (ra *ReachabilityAnalyzer) AnalyzeReachability() *ReachabilityResult
AnalyzeReachability performs reachability analysis starting from the entry block
func (*ReachabilityAnalyzer) AnalyzeReachabilityFrom ¶
func (ra *ReachabilityAnalyzer) AnalyzeReachabilityFrom(startBlock *BasicBlock) *ReachabilityResult
AnalyzeReachabilityFrom performs reachability analysis from a specific starting block
type ReachabilityResult ¶
type ReachabilityResult struct {
// ReachableBlocks contains blocks that can be reached from entry
ReachableBlocks map[string]*BasicBlock
// UnreachableBlocks contains blocks that cannot be reached from entry
UnreachableBlocks map[string]*BasicBlock
// TotalBlocks is the total number of blocks analyzed
TotalBlocks int
// ReachableCount is the number of reachable blocks
ReachableCount int
// UnreachableCount is the number of unreachable blocks
UnreachableCount int
// AnalysisTime is the time taken to perform the analysis
AnalysisTime time.Duration
}
ReachabilityResult contains the results of reachability analysis
func (*ReachabilityResult) GetReachabilityRatio ¶
func (result *ReachabilityResult) GetReachabilityRatio() float64
GetReachabilityRatio returns the ratio of reachable blocks to total blocks
func (*ReachabilityResult) GetUnreachableBlocksWithStatements ¶
func (result *ReachabilityResult) GetUnreachableBlocksWithStatements() map[string]*BasicBlock
GetUnreachableBlocksWithStatements returns unreachable blocks that contain statements
func (*ReachabilityResult) HasUnreachableCode ¶
func (result *ReachabilityResult) HasUnreachableCode() bool
HasUnreachableCode returns true if there are unreachable blocks with statements
type SeverityLevel ¶
type SeverityLevel string
SeverityLevel represents the severity of a dead code finding
const ( // SeverityLevelCritical indicates code that is definitely unreachable SeverityLevelCritical SeverityLevel = "critical" // SeverityLevelWarning indicates code that is likely unreachable SeverityLevelWarning SeverityLevel = "warning" // SeverityLevelInfo indicates potential optimization opportunities SeverityLevelInfo SeverityLevel = "info" )