analyzer

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 1, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
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

func CalculateNestingDepth(node *parser.Node) int

CalculateNestingDepth calculates the maximum nesting depth of a function

func ComputeKeyRoots

func ComputeKeyRoots(root *TreeNode) []int

ComputeKeyRoots identifies key roots for path decomposition

func ComputeLeftMostLeaves

func ComputeLeftMostLeaves(root *TreeNode)

ComputeLeftMostLeaves computes left-most leaf descendants for all nodes

func DetectAll

func DetectAll(cfgs map[string]*CFG, filePath string) map[string]*DeadCodeResult

DetectAll analyzes dead code for all functions in a file

func PostOrderTraversal

func PostOrderTraversal(root *TreeNode)

PostOrderTraversal performs post-order traversal and assigns post-order IDs

func PrepareTreeForAPTED

func PrepareTreeForAPTED(root *TreeNode) []int

PrepareTreeForAPTED prepares a tree for APTED algorithm by computing all necessary indices

Types

type APTEDAnalyzer

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

APTEDAnalyzer implements the APTED (All Path Tree Edit Distance) algorithm Based on Pawlik & Augsten's optimal O(n² log n) algorithm

func NewAPTEDAnalyzer

func NewAPTEDAnalyzer(costModel CostModel) *APTEDAnalyzer

NewAPTEDAnalyzer creates a new APTED analyzer with the given cost model

func (*APTEDAnalyzer) BatchComputeDistances

func (a *APTEDAnalyzer) BatchComputeDistances(pairs [][2]*TreeNode) []float64

BatchComputeDistances computes distances between multiple tree pairs efficiently

func (*APTEDAnalyzer) ClusterSimilarTrees

func (a *APTEDAnalyzer) ClusterSimilarTrees(trees []*TreeNode, similarityThreshold float64) *ClusterResult

ClusterSimilarTrees clusters trees based on similarity threshold

func (*APTEDAnalyzer) ComputeDetailedDistance

func (a *APTEDAnalyzer) ComputeDetailedDistance(tree1, tree2 *TreeNode) *TreeEditResult

ComputeDetailedDistance computes detailed tree edit distance information

func (*APTEDAnalyzer) ComputeDistance

func (a *APTEDAnalyzer) ComputeDistance(tree1, tree2 *TreeNode) float64

ComputeDistance computes the tree edit distance between two trees

func (*APTEDAnalyzer) ComputeSimilarity

func (a *APTEDAnalyzer) ComputeSimilarity(tree1, tree2 *TreeNode) float64

ComputeSimilarity computes similarity score between two trees (0.0 to 1.0)

type ASTFeatureExtractor

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

ASTFeatureExtractor implements FeatureExtractor for TreeNode

func NewASTFeatureExtractor

func NewASTFeatureExtractor() *ASTFeatureExtractor

NewASTFeatureExtractor creates a feature extractor with sensible defaults

func (*ASTFeatureExtractor) ExtractFeatures

func (a *ASTFeatureExtractor) ExtractFeatures(ast *TreeNode) ([]string, error)

ExtractFeatures builds a mixed set of features from the tree - Subtree hashes (bottom-up) up to maxSubtreeHeight - k-grams from pre-order traversal labels - Node type presence and lightweight distribution markers - Structural pattern tokens

func (*ASTFeatureExtractor) ExtractNodeSequences

func (a *ASTFeatureExtractor) ExtractNodeSequences(ast *TreeNode, k int) []string

ExtractNodeSequences returns k-grams from pre-order traversal labels

func (*ASTFeatureExtractor) ExtractSubtreeHashes

func (a *ASTFeatureExtractor) ExtractSubtreeHashes(ast *TreeNode, maxHeight int) []string

ExtractSubtreeHashes computes bottom-up hashes of subtrees up to maxHeight

func (*ASTFeatureExtractor) WithOptions

func (a *ASTFeatureExtractor) WithOptions(maxHeight, k int, includeTypes, includeLiterals bool) *ASTFeatureExtractor

WithOptions allows overriding defaults

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 CBOAnalyzer

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

CBOAnalyzer analyzes Coupling Between Objects for JavaScript/TypeScript modules

func NewCBOAnalyzer

func NewCBOAnalyzer(config *CBOAnalyzerConfig) *CBOAnalyzer

NewCBOAnalyzer creates a new CBO analyzer with the given configuration

func (*CBOAnalyzer) AnalyzeFile

func (ca *CBOAnalyzer) AnalyzeFile(ast *parser.Node, filePath string) (*domain.ClassCoupling, error)

AnalyzeFile analyzes a single file and returns its CBO metrics

type CBOAnalyzerConfig

type CBOAnalyzerConfig struct {
	// IncludeBuiltins includes Node.js builtin modules in coupling count
	IncludeBuiltins bool

	// IncludeTypeImports includes TypeScript type imports in coupling count
	IncludeTypeImports bool

	// LowThreshold is the CBO threshold for low risk (CBO <= LowThreshold)
	LowThreshold int

	// MediumThreshold is the CBO threshold for medium risk (LowThreshold < CBO <= MediumThreshold)
	MediumThreshold int
}

CBOAnalyzerConfig holds configuration for the CBO analyzer

func DefaultCBOAnalyzerConfig

func DefaultCBOAnalyzerConfig() *CBOAnalyzerConfig

DefaultCBOAnalyzerConfig returns the default configuration

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 NewCFG

func NewCFG(name string) *CFG

NewCFG creates a new 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) Size

func (cfg *CFG) Size() int

Size returns the number of blocks in the graph

func (*CFG) String

func (cfg *CFG) String() string

String returns a string representation of the CFG

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 NewCFGBuilder

func NewCFGBuilder() *CFGBuilder

NewCFGBuilder creates a new CFG builder

func (*CFGBuilder) Build

func (b *CFGBuilder) Build(node *parser.Node) (*CFG, error)

Build constructs a CFG from an AST node

func (*CFGBuilder) BuildAll

func (b *CFGBuilder) BuildAll(node *parser.Node) (map[string]*CFG, error)

BuildAll builds CFGs for all functions in the AST

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 CentroidGrouping

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

CentroidGrouping uses BFS expansion with strict similarity to all existing members

func NewCentroidGrouping

func NewCentroidGrouping(threshold float64) *CentroidGrouping

func (*CentroidGrouping) GetName

func (cg *CentroidGrouping) GetName() string

func (*CentroidGrouping) GroupClones

func (cg *CentroidGrouping) GroupClones(pairs []*domain.ClonePair) []*domain.CloneGroup

type CircularDependencyDetector

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

CircularDependencyDetector detects circular dependencies using Tarjan's algorithm

func NewCircularDependencyDetector

func NewCircularDependencyDetector() *CircularDependencyDetector

NewCircularDependencyDetector creates a new CircularDependencyDetector

func (*CircularDependencyDetector) DetectCycles

DetectCycles finds all cycles in the dependency graph using Tarjan's SCC algorithm

func (*CircularDependencyDetector) FindCyclePath

func (d *CircularDependencyDetector) FindCyclePath(from, to string, graph *domain.DependencyGraph) []string

FindCyclePath finds a path from one module to another within a cycle

type ClassDependencies

type ClassDependencies struct {
	// Unique modules/classes this class depends on
	DependentClasses map[string]bool

	// Breakdown by type
	ImportDependencies          map[string]bool
	InstantiationDependencies   map[string]bool
	TypeHintDependencies        map[string]bool
	AttributeAccessDependencies map[string]bool
}

ClassDependencies holds all dependencies for a class/module

func NewClassDependencies

func NewClassDependencies() *ClassDependencies

NewClassDependencies creates a new ClassDependencies instance

type CloneDetector

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

CloneDetector detects code clones using APTED algorithm

func NewCloneDetector

func NewCloneDetector(config *CloneDetectorConfig) *CloneDetector

NewCloneDetector creates a new clone detector with the given configuration

func (*CloneDetector) DetectClones

func (cd *CloneDetector) DetectClones(fragments []*CodeFragment) ([]*domain.ClonePair, []*domain.CloneGroup)

DetectClones detects clones in the given code fragments

func (*CloneDetector) DetectClonesWithContext

func (cd *CloneDetector) DetectClonesWithContext(ctx context.Context, fragments []*CodeFragment) ([]*domain.ClonePair, []*domain.CloneGroup)

DetectClonesWithContext detects clones with context support for cancellation

func (*CloneDetector) DetectClonesWithLSH

func (cd *CloneDetector) DetectClonesWithLSH(ctx context.Context, fragments []*CodeFragment) ([]*domain.ClonePair, []*domain.CloneGroup)

DetectClonesWithLSH runs a two-stage pipeline using LSH for candidate generation, followed by APTED verification on candidates only. Falls back to exhaustive if misconfigured.

func (*CloneDetector) ExtractFragments

func (cd *CloneDetector) ExtractFragments(astNodes []*parser.Node, filePath string) []*CodeFragment

ExtractFragments extracts code fragments from AST nodes

func (*CloneDetector) GetStatistics

func (cd *CloneDetector) GetStatistics() map[string]interface{}

GetStatistics returns clone detection statistics

func (*CloneDetector) SetBatchSizeLarge

func (cd *CloneDetector) SetBatchSizeLarge(size int)

SetBatchSizeLarge sets the batch size for normal projects (used in testing)

func (*CloneDetector) SetUseLSH

func (cd *CloneDetector) SetUseLSH(enabled bool)

SetUseLSH enables or disables LSH acceleration for clone detection

type CloneDetectorConfig

type CloneDetectorConfig struct {
	// Minimum number of lines for a code fragment to be considered
	MinLines int

	// Minimum number of AST nodes for a code fragment
	MinNodes int

	// Similarity thresholds for different clone types
	Type1Threshold float64
	Type2Threshold float64
	Type3Threshold float64
	Type4Threshold float64

	// Maximum edit distance allowed
	MaxEditDistance float64

	// Whether to ignore differences in literals
	IgnoreLiterals bool

	// Whether to ignore differences in identifiers
	IgnoreIdentifiers bool

	// Cost model to use for APTED
	CostModelType string // "default", "javascript", "weighted"

	// Performance tuning parameters
	MaxClonePairs      int // Maximum pairs to keep in memory
	BatchSizeThreshold int // Minimum fragments to trigger batching
	BatchSizeLarge     int // Batch size for normal projects
	BatchSizeSmall     int // Batch size for large projects
	LargeProjectSize   int // Fragment count threshold for large projects

	// Grouping configuration
	GroupingMode      GroupingMode // Default: GroupingModeConnected
	GroupingThreshold float64      // Default: Type3Threshold
	KCoreK            int          // Default: 2

	// LSH Configuration (optional, opt-in)
	UseLSH                 bool    // Enable LSH acceleration
	LSHSimilarityThreshold float64 // Candidate threshold using MinHash similarity
	LSHBands               int     // Number of LSH bands (default: 32)
	LSHRows                int     // Rows per band (default: 4)
	LSHMinHashCount        int     // Number of MinHash functions (default: 128)
}

CloneDetectorConfig holds configuration for clone detection

func DefaultCloneDetectorConfig

func DefaultCloneDetectorConfig() *CloneDetectorConfig

DefaultCloneDetectorConfig returns default configuration

type ClusterResult

type ClusterResult struct {
	Groups    [][]int     // Groups of tree indices that are similar
	Distances [][]float64 // Distance matrix between all trees
	Threshold float64     // Similarity threshold used
}

ClusterResult represents the result of tree clustering

type CodeFragment

type CodeFragment struct {
	Location   *CodeLocation
	ASTNode    *parser.Node
	TreeNode   *TreeNode
	Content    string // Original source code content
	Hash       string // Hash for quick comparison
	Size       int    // Number of AST nodes
	LineCount  int    // Number of source lines
	Complexity int    // Cyclomatic complexity (if applicable)
}

CodeFragment represents a fragment of code

func NewCodeFragment

func NewCodeFragment(location *CodeLocation, astNode *parser.Node, content string) *CodeFragment

NewCodeFragment creates a new code fragment

type CodeLocation

type CodeLocation struct {
	FilePath  string
	StartLine int
	EndLine   int
	StartCol  int
	EndCol    int
}

CodeLocation represents a location in source code

func (*CodeLocation) String

func (cl *CodeLocation) String() string

String returns string representation of CodeLocation

type CompleteLinkageGrouping

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

CompleteLinkageGrouping ensures all pairs within a group have similarity above threshold

func NewCompleteLinkageGrouping

func NewCompleteLinkageGrouping(threshold float64) *CompleteLinkageGrouping

func (*CompleteLinkageGrouping) GetName

func (c *CompleteLinkageGrouping) GetName() string

func (*CompleteLinkageGrouping) GroupClones

func (c *CompleteLinkageGrouping) GroupClones(pairs []*domain.ClonePair) []*domain.CloneGroup

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 ConnectedGrouping

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

ConnectedGrouping wraps transitive grouping logic using Union-Find

func NewConnectedGrouping

func NewConnectedGrouping(threshold float64) *ConnectedGrouping

func (*ConnectedGrouping) GetName

func (c *ConnectedGrouping) GetName() string

func (*ConnectedGrouping) GroupClones

func (c *ConnectedGrouping) GroupClones(pairs []*domain.ClonePair) []*domain.CloneGroup

type CostModel

type CostModel interface {
	// Insert returns the cost of inserting a node
	Insert(node *TreeNode) float64

	// Delete returns the cost of deleting a node
	Delete(node *TreeNode) float64

	// Rename returns the cost of renaming node1 to node2
	Rename(node1, node2 *TreeNode) float64
}

CostModel defines the interface for calculating edit operation costs

type CouplingMetricsCalculator

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

CouplingMetricsCalculator calculates coupling metrics for modules

func NewCouplingMetricsCalculator

func NewCouplingMetricsCalculator(config *CouplingMetricsConfig) *CouplingMetricsCalculator

NewCouplingMetricsCalculator creates a new CouplingMetricsCalculator

func (*CouplingMetricsCalculator) CalculateCouplingAnalysis

CalculateCouplingAnalysis generates a comprehensive coupling analysis

func (*CouplingMetricsCalculator) CalculateMaxDepth

func (c *CouplingMetricsCalculator) CalculateMaxDepth(graph *domain.DependencyGraph) int

CalculateMaxDepth calculates the maximum dependency depth in the graph

func (*CouplingMetricsCalculator) CalculateMetrics

CalculateMetrics computes coupling metrics for all modules in the graph

func (*CouplingMetricsCalculator) CalculateTransitiveDependencies

func (c *CouplingMetricsCalculator) CalculateTransitiveDependencies(nodeID string, graph *domain.DependencyGraph) []string

CalculateTransitiveDependencies calculates all transitive dependencies for a module

type CouplingMetricsConfig

type CouplingMetricsConfig struct {
	// InstabilityHighThreshold defines the threshold for high instability (default: 0.8)
	InstabilityHighThreshold float64

	// InstabilityLowThreshold defines the threshold for low instability (default: 0.2)
	InstabilityLowThreshold float64

	// DistanceThreshold defines the threshold for main sequence deviation (default: 0.3)
	DistanceThreshold float64

	// CouplingHighThreshold defines the threshold for high coupling risk (default: 10)
	CouplingHighThreshold int

	// CouplingMediumThreshold defines the threshold for medium coupling risk (default: 5)
	CouplingMediumThreshold int
}

CouplingMetricsConfig configures the CouplingMetricsCalculator

func DefaultCouplingMetricsConfig

func DefaultCouplingMetricsConfig() *CouplingMetricsConfig

DefaultCouplingMetricsConfig returns a config with sensible defaults

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 DefaultCostModel

type DefaultCostModel struct{}

DefaultCostModel implements a uniform cost model where all operations cost 1.0

func NewDefaultCostModel

func NewDefaultCostModel() *DefaultCostModel

NewDefaultCostModel creates a new default cost model

func (*DefaultCostModel) Delete

func (c *DefaultCostModel) Delete(node *TreeNode) float64

Delete returns the cost of deleting a node (always 1.0)

func (*DefaultCostModel) Insert

func (c *DefaultCostModel) Insert(node *TreeNode) float64

Insert returns the cost of inserting a node (always 1.0)

func (*DefaultCostModel) Rename

func (c *DefaultCostModel) Rename(node1, node2 *TreeNode) float64

Rename returns the cost of renaming node1 to node2

type DependencyGraphBuilder

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

DependencyGraphBuilder builds a dependency graph from module analysis results

func NewDependencyGraphBuilder

func NewDependencyGraphBuilder(config *DependencyGraphBuilderConfig) *DependencyGraphBuilder

NewDependencyGraphBuilder creates a new DependencyGraphBuilder

func (*DependencyGraphBuilder) BuildGraph

BuildGraph constructs a DependencyGraph from ModuleAnalysisResult

func (*DependencyGraphBuilder) BuildGraphFromASTs

func (b *DependencyGraphBuilder) BuildGraphFromASTs(asts map[string]*parser.Node) (*domain.DependencyGraph, error)

BuildGraphFromASTs constructs a DependencyGraph directly from parsed ASTs

type DependencyGraphBuilderConfig

type DependencyGraphBuilderConfig struct {
	// IncludeExternal includes external modules (node_modules) in the graph
	IncludeExternal bool

	// IncludeTypeImports includes TypeScript type-only imports
	IncludeTypeImports bool

	// ProjectRoot is the root directory for path normalization
	ProjectRoot string
}

DependencyGraphBuilderConfig configures the DependencyGraphBuilder

func DefaultDependencyGraphBuilderConfig

func DefaultDependencyGraphBuilderConfig() *DependencyGraphBuilderConfig

DefaultDependencyGraphBuilderConfig returns a config with sensible defaults

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
)

func (EdgeType) String

func (e EdgeType) String() string

String returns string representation of EdgeType

type FeatureExtractor

type FeatureExtractor interface {
	ExtractFeatures(ast *TreeNode) ([]string, error)
	ExtractSubtreeHashes(ast *TreeNode, maxHeight int) []string
	ExtractNodeSequences(ast *TreeNode, k int) []string
}

FeatureExtractor converts AST trees into feature sets for Jaccard similarity

type GroupingConfig

type GroupingConfig struct {
	Mode           GroupingMode
	Threshold      float64
	KCoreK         int
	Type1Threshold float64
	Type2Threshold float64
	Type3Threshold float64
	Type4Threshold float64
}

GroupingConfig holds configuration for clone grouping

type GroupingMode

type GroupingMode string

GroupingMode represents the mode of grouping strategy

const (
	GroupingModeConnected       GroupingMode = "connected"
	GroupingModeKCore           GroupingMode = "k_core"
	GroupingModeStarMedoid      GroupingMode = "star_medoid"
	GroupingModeCompleteLinkage GroupingMode = "complete_linkage"
	GroupingModeCentroid        GroupingMode = "centroid"
)

type GroupingStrategy

type GroupingStrategy interface {
	// GroupClones groups the given clone pairs into clone groups.
	GroupClones(pairs []*domain.ClonePair) []*domain.CloneGroup
	// GetName returns the strategy name.
	GetName() string
}

GroupingStrategy defines a strategy for grouping clone pairs into clone groups.

func CreateGroupingStrategy

func CreateGroupingStrategy(config GroupingConfig) GroupingStrategy

CreateGroupingStrategy creates a grouping strategy based on config

type HashFunc

type HashFunc func(uint64) uint64

HashFunc maps a 64-bit base hash to another 64-bit value

type JavaScriptCostModel

type JavaScriptCostModel struct {
	// Base costs for different operations
	BaseInsertCost float64
	BaseDeleteCost float64
	BaseRenameCost float64

	// Whether to ignore differences in literal values
	IgnoreLiterals bool

	// Whether to ignore differences in identifier names
	IgnoreIdentifiers bool
}

JavaScriptCostModel implements a JavaScript-aware cost model with different costs for different node types

func NewJavaScriptCostModel

func NewJavaScriptCostModel() *JavaScriptCostModel

NewJavaScriptCostModel creates a new JavaScript-aware cost model with default settings

func NewJavaScriptCostModelWithConfig

func NewJavaScriptCostModelWithConfig(ignoreLiterals, ignoreIdentifiers bool) *JavaScriptCostModel

NewJavaScriptCostModelWithConfig creates a JavaScript cost model with custom configuration

func (*JavaScriptCostModel) Delete

func (c *JavaScriptCostModel) Delete(node *TreeNode) float64

Delete returns the cost of deleting a node

func (*JavaScriptCostModel) Insert

func (c *JavaScriptCostModel) Insert(node *TreeNode) float64

Insert returns the cost of inserting a node

func (*JavaScriptCostModel) Rename

func (c *JavaScriptCostModel) Rename(node1, node2 *TreeNode) float64

Rename returns the cost of renaming node1 to node2

type KCoreGrouping

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

KCoreGrouping ensures each clone has at least k similar neighbors

func NewKCoreGrouping

func NewKCoreGrouping(threshold float64, k int) *KCoreGrouping

func (*KCoreGrouping) GetName

func (kg *KCoreGrouping) GetName() string

func (*KCoreGrouping) GroupClones

func (kg *KCoreGrouping) GroupClones(pairs []*domain.ClonePair) []*domain.CloneGroup

type LSHIndex

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

LSHIndex implements MinHash LSH with banding

func NewLSHIndex

func NewLSHIndex(bands, rows int) *LSHIndex

NewLSHIndex creates an index with banding parameters

func (*LSHIndex) AddFragment

func (idx *LSHIndex) AddFragment(id string, signature *MinHashSignature) error

AddFragment inserts a fragment signature into the index

func (*LSHIndex) Bands

func (idx *LSHIndex) Bands() int

Bands returns the number of bands

func (*LSHIndex) BuildIndex

func (idx *LSHIndex) BuildIndex() error

BuildIndex is a no-op for incremental building (kept for API symmetry)

func (*LSHIndex) FindCandidates

func (idx *LSHIndex) FindCandidates(signature *MinHashSignature) []string

FindCandidates retrieves candidate fragment IDs that share at least one band bucket

func (*LSHIndex) GetSignature

func (idx *LSHIndex) GetSignature(id string) *MinHashSignature

GetSignature returns the stored signature for a fragment ID

func (*LSHIndex) Rows

func (idx *LSHIndex) Rows() int

Rows returns the number of rows per band

func (*LSHIndex) Size

func (idx *LSHIndex) Size() int

Size returns the number of fragments in the index

type MinHashSignature

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

MinHashSignature holds the signature vector

func (*MinHashSignature) NumHashes

func (s *MinHashSignature) NumHashes() int

NumHashes returns the number of hash functions used

func (*MinHashSignature) Signatures

func (s *MinHashSignature) Signatures() []uint64

Signatures returns the signature slice

type MinHasher

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

MinHasher computes MinHash signatures for feature sets

func NewMinHasher

func NewMinHasher(numHashes int) *MinHasher

NewMinHasher creates a MinHasher with numHashes functions (default 128 if invalid)

func (*MinHasher) ComputeSignature

func (m *MinHasher) ComputeSignature(features []string) *MinHashSignature

ComputeSignature computes the MinHash signature for a set of features

func (*MinHasher) EstimateJaccardSimilarity

func (m *MinHasher) EstimateJaccardSimilarity(sig1, sig2 *MinHashSignature) float64

EstimateJaccardSimilarity estimates Jaccard similarity via signature agreement ratio

func (*MinHasher) NumHashes

func (m *MinHasher) NumHashes() int

NumHashes returns the number of hash functions

type ModuleAnalyzer

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

ModuleAnalyzer analyzes JavaScript/TypeScript module imports and exports

func NewModuleAnalyzer

func NewModuleAnalyzer(config *ModuleAnalyzerConfig) *ModuleAnalyzer

NewModuleAnalyzer creates a new module analyzer with the given configuration

func (*ModuleAnalyzer) AnalyzeAll

func (ma *ModuleAnalyzer) AnalyzeAll(asts map[string]*parser.Node) (*domain.ModuleAnalysisResult, error)

AnalyzeAll analyzes multiple files and returns aggregated results

func (*ModuleAnalyzer) AnalyzeFile

func (ma *ModuleAnalyzer) AnalyzeFile(ast *parser.Node, filePath string) (*domain.ModuleInfo, error)

AnalyzeFile analyzes a single file and returns its module info

type ModuleAnalyzerConfig

type ModuleAnalyzerConfig struct {
	// IncludeBuiltins includes Node.js builtin modules in analysis
	IncludeBuiltins bool

	// ResolveRelative enables resolution of relative import paths
	ResolveRelative bool

	// IncludeTypeImports includes TypeScript type imports
	IncludeTypeImports bool

	// AliasPatterns are path alias patterns to recognize (@/, ~/, etc.)
	AliasPatterns []string
}

ModuleAnalyzerConfig holds configuration for the module analyzer

func DefaultModuleAnalyzerConfig

func DefaultModuleAnalyzerConfig() *ModuleAnalyzerConfig

DefaultModuleAnalyzerConfig returns the default configuration

type OptimizedAPTEDAnalyzer

type OptimizedAPTEDAnalyzer struct {
	*APTEDAnalyzer
	// contains filtered or unexported fields
}

OptimizedAPTEDAnalyzer extends APTEDAnalyzer with performance optimizations

func NewOptimizedAPTEDAnalyzer

func NewOptimizedAPTEDAnalyzer(costModel CostModel, maxDistance float64) *OptimizedAPTEDAnalyzer

NewOptimizedAPTEDAnalyzer creates an optimized APTED analyzer

func (*OptimizedAPTEDAnalyzer) ComputeDistance

func (a *OptimizedAPTEDAnalyzer) ComputeDistance(tree1, tree2 *TreeNode) float64

ComputeDistance computes tree edit distance with early stopping optimization

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"
)

type StarMedoidGrouping

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

StarMedoidGrouping uses iterative medoid optimization for balanced precision/recall

func NewStarMedoidGrouping

func NewStarMedoidGrouping(threshold float64) *StarMedoidGrouping

func (*StarMedoidGrouping) GetName

func (s *StarMedoidGrouping) GetName() string

func (*StarMedoidGrouping) GroupClones

func (s *StarMedoidGrouping) GroupClones(pairs []*domain.ClonePair) []*domain.CloneGroup

type TreeConverter

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

TreeConverter converts parser AST nodes to APTED tree nodes

func NewTreeConverter

func NewTreeConverter() *TreeConverter

NewTreeConverter creates a new tree converter

func (*TreeConverter) ConvertAST

func (tc *TreeConverter) ConvertAST(astNode *parser.Node) *TreeNode

ConvertAST converts a parser AST node to an APTED tree

type TreeEditResult

type TreeEditResult struct {
	Distance   float64
	Similarity float64
	Tree1Size  int
	Tree2Size  int
	Operations int // Estimated number of edit operations
}

TreeEditResult holds the result of tree edit distance computation

type TreeNode

type TreeNode struct {
	// Unique identifier for this node
	ID int

	// Label for the node (typically the node type or value)
	Label string

	// Tree structure
	Children []*TreeNode
	Parent   *TreeNode

	// APTED-specific fields for optimization
	PostOrderID  int  // Post-order traversal position
	LeftMostLeaf int  // Left-most leaf descendant
	KeyRoot      bool // Whether this node is a key root

	// Optional metadata from original AST
	OriginalNode *parser.Node
}

TreeNode represents a node in the ordered tree for APTED algorithm

func GetNodeByPostOrderID

func GetNodeByPostOrderID(root *TreeNode, postOrderID int) *TreeNode

GetNodeByPostOrderID finds a node by its post-order ID

func GetSubtreeNodes

func GetSubtreeNodes(root *TreeNode) []*TreeNode

GetSubtreeNodes returns all nodes in the subtree rooted at the given node

func GetSubtreeNodesWithDepthLimit

func GetSubtreeNodesWithDepthLimit(root *TreeNode, maxDepth int) []*TreeNode

GetSubtreeNodesWithDepthLimit returns all nodes with maximum recursion depth limit

func NewTreeNode

func NewTreeNode(id int, label string) *TreeNode

NewTreeNode creates a new tree node with the given ID and label

func (*TreeNode) AddChild

func (t *TreeNode) AddChild(child *TreeNode)

AddChild adds a child node to this node

func (*TreeNode) Height

func (t *TreeNode) Height() int

Height returns the height of the subtree rooted at this node

func (*TreeNode) HeightWithDepthLimit

func (t *TreeNode) HeightWithDepthLimit(maxDepth int) int

HeightWithDepthLimit returns the height with maximum recursion depth limit

func (*TreeNode) IsLeaf

func (t *TreeNode) IsLeaf() bool

IsLeaf returns true if this node has no children

func (*TreeNode) Size

func (t *TreeNode) Size() int

Size returns the size of the subtree rooted at this node

func (*TreeNode) SizeWithDepthLimit

func (t *TreeNode) SizeWithDepthLimit(maxDepth int) int

SizeWithDepthLimit returns the size with maximum recursion depth limit

func (*TreeNode) String

func (t *TreeNode) String() string

String returns a string representation of the node

type WeightedCostModel

type WeightedCostModel struct {
	InsertWeight  float64
	DeleteWeight  float64
	RenameWeight  float64
	BaseCostModel CostModel
}

WeightedCostModel allows custom weights for different operation types

func NewWeightedCostModel

func NewWeightedCostModel(insertWeight, deleteWeight, renameWeight float64, baseCostModel CostModel) *WeightedCostModel

NewWeightedCostModel creates a new weighted cost model

func (*WeightedCostModel) Delete

func (c *WeightedCostModel) Delete(node *TreeNode) float64

Delete returns the weighted cost of deleting a node

func (*WeightedCostModel) Insert

func (c *WeightedCostModel) Insert(node *TreeNode) float64

Insert returns the weighted cost of inserting a node

func (*WeightedCostModel) Rename

func (c *WeightedCostModel) Rename(node1, node2 *TreeNode) float64

Rename returns the weighted cost of renaming node1 to node2

Jump to

Keyboard shortcuts

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