Documentation
¶
Overview ¶
Package domain provides core domain types and logic for art-dupl.
This package defines value objects for code duplication detection: - ProcessedClone / ProcessedCloneGroup: canonical clone data with validation - CloneClassification: category, priority, and actionability metadata - ClonePriority, CloneCategory, CloneActionability: typed enums with JSON marshaling - Error sentinels for clone validation failures
Index ¶
- Variables
- type ClassificationInput
- type CloneActionability
- type CloneCategory
- type CloneClassification
- type CloneNode
- type ClonePriority
- func (p ClonePriority) GetPriorityColor() string
- func (p ClonePriority) GetPriorityEmoji() string
- func (p ClonePriority) IsValid() bool
- func (p ClonePriority) MarshalJSON() ([]byte, error)
- func (p ClonePriority) Rank() int
- func (p ClonePriority) String() string
- func (p *ClonePriority) UnmarshalJSON(data []byte) error
- type CloneRef
- type CloneType
- type DetectionMethod
- type DetectionMode
- func (dm DetectionMode) HashesIdentifiers() bool
- func (dm DetectionMode) IsSemantic() bool
- func (dm DetectionMode) IsValid() bool
- func (dm DetectionMode) MarshalJSON() ([]byte, error)
- func (dm DetectionMode) NormalizesLiterals() bool
- func (dm DetectionMode) NormalizesLocals() bool
- func (dm DetectionMode) String() string
- func (dm *DetectionMode) UnmarshalJSON(data []byte) error
- type DiffMode
- type Extractability
- type FileReaderFunc
- type HealthScore
- type OutputFormat
- type ProcessedClone
- type ProcessedCloneGroup
- type SortCriteria
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidCloneCategory = errors.New("invalid clone category") ErrInvalidClonePriority = errors.New("invalid clone priority") ErrInvalidCloneActionability = errors.New("invalid clone actionability") ErrInvalidCloneType = errors.New("invalid clone type") ErrInvalidHealthScore = errors.New("invalid health score") ErrInvalidThreshold = errors.New("threshold must be >= 1") ErrThresholdTooLarge = errors.New("threshold too large (max 1000)") ErrEmptyFilename = errors.New("filename cannot be empty") ErrLineEndBeforeStart = errors.New("line end is before line start") ErrNegativeTokenCount = errors.New("token count cannot be negative") ErrEmptyCloneGroup = errors.New("clone group must have at least one clone") ErrTokenCountMismatch = errors.New("group token count does not match sum of clones") )
Static errors for domain type validation.
var ErrInvalidDetectionMethod = errors.New("invalid detection method")
ErrInvalidDetectionMethod is returned when a detection method is not recognized.
var ErrInvalidDetectionMode = errors.New("invalid detection mode")
ErrInvalidDetectionMode is returned when a detection mode is not recognized.
var ErrInvalidDiffMode = errors.New("invalid diff mode")
ErrInvalidDiffMode is returned when a diff mode value is not recognized.
var ErrInvalidOutputFormat = errors.New("invalid output format")
ErrInvalidOutputFormat is returned when an output format value is not recognized.
var ErrInvalidSortCriteria = errors.New("invalid sort criteria")
ErrInvalidSortCriteria is returned when a sort criteria value is not recognized.
Functions ¶
This section is empty.
Types ¶
type ClassificationInput ¶ added in v0.2.0
ClassificationInput holds the data needed to classify a clone. Using a struct instead of primitives ensures the compiler catches missing fields when new classification inputs are added.
type CloneActionability ¶ added in v0.2.0
type CloneActionability string
CloneActionability indicates whether a clone can realistically be deduplicated.
const ( // Actionable clones represent real logic duplication that can be extracted, // composed, or otherwise refactored to reduce duplication. Actionable CloneActionability = "actionable" // NonActionable clones are idiomatic patterns that cannot be deduplicated // without breaking Go semantics, interfaces, or standard conventions. NonActionable CloneActionability = "non-actionable" )
func (CloneActionability) IsValid ¶ added in v0.3.0
func (a CloneActionability) IsValid() bool
IsValid returns true if the actionability is one of the defined constants.
func (CloneActionability) MarshalJSON ¶ added in v0.4.0
func (a CloneActionability) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler for CloneActionability.
func (CloneActionability) String ¶ added in v0.3.0
func (a CloneActionability) String() string
String returns the string representation of the actionability.
func (*CloneActionability) UnmarshalJSON ¶ added in v0.4.0
func (a *CloneActionability) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler for CloneActionability.
type CloneCategory ¶ added in v0.2.0
type CloneCategory string
CloneCategory represents the category of code that was duplicated.
const ( CategoryFunction CloneCategory = "function" CategoryMethod CloneCategory = "method" CategoryTest CloneCategory = "test" CategoryStruct CloneCategory = "struct" CategoryInterface CloneCategory = "interface" CategoryHandler CloneCategory = "handler" CategoryLoop CloneCategory = "loop" CategoryConditional CloneCategory = "conditional" CategoryTestBoilerplate CloneCategory = "test-boilerplate" CategoryTestFixture CloneCategory = "test-fixture" CategoryAssignment CloneCategory = "assignment" CategoryExpression CloneCategory = "expression" CategoryUnknown CloneCategory = "unknown" )
func (CloneCategory) GetCategoryEmoji ¶ added in v0.2.0
func (c CloneCategory) GetCategoryEmoji() string
func (CloneCategory) IsCompleteUnit ¶ added in v0.4.0
func (c CloneCategory) IsCompleteUnit() bool
IsCompleteUnit reports whether a clone classification category represents a complete, extractable syntactic unit (function/method/block) rather than a fragment or partial match.
func (CloneCategory) IsValid ¶ added in v0.3.0
func (c CloneCategory) IsValid() bool
IsValid returns true if the category is one of the defined constants.
func (CloneCategory) MarshalJSON ¶ added in v0.4.0
func (c CloneCategory) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler for CloneCategory.
func (CloneCategory) String ¶ added in v0.3.0
func (c CloneCategory) String() string
String returns the string representation of the category.
func (*CloneCategory) UnmarshalJSON ¶ added in v0.4.0
func (c *CloneCategory) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler for CloneCategory.
type CloneClassification ¶ added in v0.2.0
type CloneClassification struct {
Category CloneCategory
IsTest bool
Priority ClonePriority
Actionability CloneActionability
CloneType CloneType
Extractability Extractability
Tokens int
Lines int
Suggestion string
}
CloneClassification provides metadata about a code clone for actionable reports.
type CloneNode ¶ added in v0.4.0
type CloneNode struct {
// BaseType is the 8-bit base AST node type, already decoded from the raw
// syntax.Node.Type (which packs identifier/operator hashes into the upper
// 24 bits). Compare against syntax/golang constants (golang.FuncDecl, etc.).
BaseType int32
// Name is the identifier or method name associated with this node.
Name string
// Filename is the source file this node originated from.
Filename string
// Children are the direct sub-nodes in tree order.
Children []*CloneNode
}
CloneNode is a minimal, immutable recursive tree representation used by the printer's actionability evaluation layer. It decouples pattern detection from syntax.Node internals (which carry mutable serialization state, positions, and ownership tracking that the actionability layer does not need).
The bridge in printer/clone_processor.go converts []*syntax.Node into []*CloneNode before passing them to EvaluateActionability.
func (*CloneNode) HasChildren ¶ added in v0.4.0
HasChildren returns true if the node has at least one child.
type ClonePriority ¶ added in v0.2.0
type ClonePriority string
ClonePriority represents how important it is to address this clone.
const ( PriorityCritical ClonePriority = "critical" PriorityHigh ClonePriority = "high" PriorityMedium ClonePriority = "medium" PriorityLow ClonePriority = "low" )
func (ClonePriority) GetPriorityColor ¶ added in v0.2.0
func (p ClonePriority) GetPriorityColor() string
func (ClonePriority) GetPriorityEmoji ¶ added in v0.2.0
func (p ClonePriority) GetPriorityEmoji() string
func (ClonePriority) IsValid ¶ added in v0.3.0
func (p ClonePriority) IsValid() bool
IsValid returns true if the priority is one of the defined constants.
func (ClonePriority) MarshalJSON ¶ added in v0.4.0
func (p ClonePriority) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler for ClonePriority.
func (ClonePriority) Rank ¶ added in v0.4.0
func (p ClonePriority) Rank() int
Rank returns the ordinal rank of the priority (higher = more important). Used for sorting and comparison. Returns 0 for invalid values.
func (ClonePriority) String ¶ added in v0.3.0
func (p ClonePriority) String() string
String returns the string representation of the priority.
func (*ClonePriority) UnmarshalJSON ¶ added in v0.4.0
func (p *ClonePriority) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler for ClonePriority.
type CloneRef ¶ added in v0.4.0
type CloneRef struct {
Filename string `json:"filename"`
LineStart int `json:"line_start"`
LineEnd int `json:"line_end"`
Fragment string `json:"fragment,omitempty"`
}
CloneRef carries the location and source text of a single clone occurrence. It is designed for embedding into type-specific Clone structs (ProcessedClone, artdupl.Clone, etc.) to eliminate field-name drift without collapsing the DTO boundary between packages.
type CloneType ¶ added in v0.4.0
type CloneType string
CloneType represents the standard code clone taxonomy (Bellon et al.).
const ( // CloneType1 is an exact copy-paste: identical text (except whitespace/comments). // In semantic mode, all clones are Type 1 because identifiers and literals // are encoded into the token hash. CloneType1 CloneType = "type-1" // CloneType2 is a parameterized copy: same structure, different identifier // names or literal values. Detected when Name fields differ across fragments // but the AST structure is identical. CloneType2 CloneType = "type-2" // CloneType3 is a near-miss clone: small structural differences (added, // deleted, or modified statements). Future capability — not currently // detected by the suffix tree algorithm. CloneType3 CloneType = "type-3" )
func (CloneType) IsValid ¶ added in v0.4.0
IsValid returns true if the clone type is one of the defined constants.
func (CloneType) MarshalJSON ¶ added in v0.4.0
MarshalJSON implements json.Marshaler for CloneType.
func (CloneType) String ¶ added in v0.4.0
String returns the string representation of the clone type.
func (*CloneType) UnmarshalJSON ¶ added in v0.4.0
UnmarshalJSON implements json.Unmarshaler for CloneType.
type DetectionMethod ¶ added in v0.4.0
type DetectionMethod string
DetectionMethod represents the algorithm used for duplicate detection. This is the canonical definition — config, sdk, and detection packages reference this type via aliases to prevent drift.
const ( // MethodArtDupl uses suffix tree algorithm on AST tokens. MethodArtDupl DetectionMethod = "art-dupl" // MethodHash uses rolling hash on file content. MethodHash DetectionMethod = "hash" )
func AllDetectionMethods ¶ added in v0.4.0
func AllDetectionMethods() []DetectionMethod
AllDetectionMethods returns all supported detection methods.
func DefaultDetectionMethod ¶ added in v0.4.0
func DefaultDetectionMethod() DetectionMethod
DefaultDetectionMethod returns the default detection method.
func (DetectionMethod) IsValid ¶ added in v0.4.0
func (m DetectionMethod) IsValid() bool
IsValid returns true if the detection method is one of the defined constants.
func (DetectionMethod) MarshalJSON ¶ added in v0.4.0
func (m DetectionMethod) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler.
func (DetectionMethod) String ¶ added in v0.4.0
func (m DetectionMethod) String() string
String returns the string representation of the detection method.
func (*DetectionMethod) UnmarshalJSON ¶ added in v0.4.0
func (m *DetectionMethod) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler.
type DetectionMode ¶ added in v0.4.0
type DetectionMode string
DetectionMode controls how identifier names participate in clone matching. This is the canonical definition: config and syntax/golang reference this type via aliases to prevent drift.
Three modes form a spectrum from strictest (fewest matches) to loosest (most matches):
- Exact: identifier names are hashed verbatim. Two clones match only if they use the same variable/function/method names. This is copy-paste detection (Type 1 clones).
- Semantic: local identifiers are alpha-normalized (canonicalized to v0, v1, …) before hashing. Two clones match when they have the same structure even if every variable was renamed. This detects Type 2 (parameterized) clones, the most common real-world duplication.
- Structural: identifier names are ignored entirely. Two clones match on AST shape alone. Loosest matching; produces the most candidates.
const ( // DetectionModeExact hashes identifier names verbatim, so only // copy-paste-identical code (same names) matches. DetectionModeExact DetectionMode = "exact" // DetectionModeSemantic alpha-normalizes local identifiers before hashing, // so structurally identical code with renamed variables matches. This is // the default and the mode that detects Type 2 clones. DetectionModeSemantic DetectionMode = "semantic" // DetectionModeStructural ignores identifier names, matching on AST shape // alone. DetectionModeStructural DetectionMode = "structural" )
func AllDetectionModes ¶ added in v0.4.0
func AllDetectionModes() []DetectionMode
AllDetectionModes returns all supported detection modes.
func DefaultDetectionMode ¶ added in v0.4.0
func DefaultDetectionMode() DetectionMode
DefaultDetectionMode returns the default detection mode.
func (DetectionMode) HashesIdentifiers ¶ added in v0.4.0
func (dm DetectionMode) HashesIdentifiers() bool
HashesIdentifiers reports whether identifier names are folded into the token hash. Exact and Semantic include them; Structural does not.
func (DetectionMode) IsSemantic ¶ added in v0.4.0
func (dm DetectionMode) IsSemantic() bool
IsSemantic returns true when identifier names participate in matching. In Semantic and Exact modes names are hashed, so they participate; only Structural mode ignores them entirely.
Deprecated for internal gating: prefer HashesIdentifiers / NormalizesLocals, which express the actual question being asked.
func (DetectionMode) IsValid ¶ added in v0.4.0
func (dm DetectionMode) IsValid() bool
IsValid returns true if the DetectionMode is one of the defined constants.
func (DetectionMode) MarshalJSON ¶ added in v0.4.0
func (dm DetectionMode) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler.
func (DetectionMode) NormalizesLiterals ¶ added in v0.4.0
func (dm DetectionMode) NormalizesLiterals() bool
NormalizesLiterals reports whether literal VALUES (strings, numbers) are normalized to their KIND (STRING, INT, FLOAT) before hashing. Semantic mode normalizes literals so that Type-2 clones with different literal values are detected. Exact mode hashes literal values verbatim (Type-1 only).
func (DetectionMode) NormalizesLocals ¶ added in v0.4.0
func (dm DetectionMode) NormalizesLocals() bool
NormalizesLocals reports whether local identifiers are alpha-normalized before hashing. Only Semantic mode does this; Exact hashes original names and Structural ignores names entirely.
func (DetectionMode) String ¶ added in v0.4.0
func (dm DetectionMode) String() string
String returns the string representation of the detection mode.
func (*DetectionMode) UnmarshalJSON ¶ added in v0.4.0
func (dm *DetectionMode) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler.
type DiffMode ¶ added in v0.4.0
type DiffMode string
DiffMode controls diff visualization in HTML output.
func AllDiffModes ¶ added in v0.4.0
func AllDiffModes() []DiffMode
func DefaultDiffMode ¶ added in v0.4.0
func DefaultDiffMode() DiffMode
func (DiffMode) MarshalJSON ¶ added in v0.4.0
func (*DiffMode) UnmarshalJSON ¶ added in v0.4.0
type Extractability ¶ added in v0.4.0
type Extractability struct {
// CanExtract is true when the clone spans a complete syntactic unit (a
// function body or a statement block) and duplicating it to a shared helper
// would reduce total lines.
CanExtract bool
// EstimatedLinesSaved is the net line reduction from extracting: the lines
// currently duplicated across all instances minus the one shared copy plus
// its function signature overhead. Negative or zero means extraction would
// not reduce line count.
EstimatedLinesSaved int
// Reason explains the verdict in one sentence for display in reports.
Reason string
}
Extractability assesses whether a clone group can be cleanly extracted into a shared function, turning clone reports into actionable refactoring advice.
func AssessExtractability ¶ added in v0.4.0
func AssessExtractability(lines, instances int, isComplete bool) Extractability
AssessExtractability computes an Extractability verdict from clone metadata.
lines — lines spanned by one clone instance instances — number of duplicate sites isComplete — true if the clone root is a complete function or block
type FileReaderFunc ¶ added in v0.4.0
FileReaderFunc represents a function that reads file contents by filename. This is the canonical definition — printer and SDK packages reference this type via aliases to prevent drift between identical function-type definitions.
type HealthScore ¶ added in v0.3.0
type HealthScore string
HealthScore represents an A-F grade for code health based on duplication metrics.
const ( HealthScoreA HealthScore = "A" HealthScoreB HealthScore = "B" HealthScoreC HealthScore = "C" HealthScoreD HealthScore = "D" HealthScoreF HealthScore = "F" )
func (HealthScore) IsValid ¶ added in v0.3.0
func (h HealthScore) IsValid() bool
IsValid reports whether the health score is one of the defined constants.
func (HealthScore) MarshalJSON ¶ added in v0.3.0
func (h HealthScore) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler for HealthScore.
func (HealthScore) String ¶ added in v0.3.0
func (h HealthScore) String() string
String returns the string representation of the health score.
func (*HealthScore) UnmarshalJSON ¶ added in v0.3.0
func (h *HealthScore) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler for HealthScore.
type OutputFormat ¶ added in v0.4.0
type OutputFormat string
OutputFormat controls the presentation format of clone detection results.
const ( OutputFormatText OutputFormat = "text" OutputFormatHTML OutputFormat = "html" OutputFormatJSON OutputFormat = "json" OutputFormatCSV OutputFormat = "csv" OutputFormatPlumbing OutputFormat = "plumbing" OutputFormatSimpleJSON OutputFormat = "simple-json" OutputFormatSARIF OutputFormat = "sarif" )
func AllOutputFormats ¶ added in v0.4.0
func AllOutputFormats() []OutputFormat
func DefaultOutputFormat ¶ added in v0.4.0
func DefaultOutputFormat() OutputFormat
func ParseOutputFormat ¶ added in v0.4.0
func ParseOutputFormat(value string) (OutputFormat, error)
func (OutputFormat) IsValid ¶ added in v0.4.0
func (of OutputFormat) IsValid() bool
func (OutputFormat) MarshalJSON ¶ added in v0.4.0
func (of OutputFormat) MarshalJSON() ([]byte, error)
func (OutputFormat) String ¶ added in v0.4.0
func (of OutputFormat) String() string
func (*OutputFormat) UnmarshalJSON ¶ added in v0.4.0
func (of *OutputFormat) UnmarshalJSON(data []byte) error
type ProcessedClone ¶ added in v0.2.0
type ProcessedClone struct {
CloneRef
StartPos int32
EndPos int32
TokenCount int
FileSize int
Classification CloneClassification
}
ProcessedClone represents a single clone instance with extracted fragment data. Decouples printer output from syntax.Node internals.
func (ProcessedClone) Validate ¶ added in v0.4.0
func (c ProcessedClone) Validate() error
Validate checks that the clone's invariants hold. A valid clone must have a non-empty filename, LineEnd >= LineStart, and a non-negative TokenCount.
type ProcessedCloneGroup ¶ added in v0.2.0
type ProcessedCloneGroup struct {
Hash string
TokenCount int
Clones []ProcessedClone
}
ProcessedCloneGroup represents a group of duplicate code fragments.
func NewProcessedCloneGroup ¶ added in v0.4.0
func NewProcessedCloneGroup(hash string, clones []ProcessedClone) ProcessedCloneGroup
NewProcessedCloneGroup creates a group with TokenCount computed from clones. This is the canonical constructor — avoids inconsistent TokenCount states.
func (ProcessedCloneGroup) TotalTokenCount ¶ added in v0.4.0
func (g ProcessedCloneGroup) TotalTokenCount() int
TotalTokenCount returns the sum of TokenCount across all clones in the group. This is the canonical way to compute total tokens — avoids manual iteration.
func (ProcessedCloneGroup) Validate ¶ added in v0.4.0
func (g ProcessedCloneGroup) Validate() error
Validate checks that the group's invariants hold:
- Must have at least one clone.
- Every clone must pass its own Validate().
- Group TokenCount must equal the sum of clone TokenCounts.
type SortCriteria ¶ added in v0.4.0
type SortCriteria string
SortCriteria controls how clone groups are ordered in output.
const ( SortBySize SortCriteria = "size" SortByOccurrence SortCriteria = "occurrence" SortByHash SortCriteria = "hash" SortByTotalTokens SortCriteria = "total-tokens" )
func AllSortCriteria ¶ added in v0.4.0
func AllSortCriteria() []SortCriteria
func DefaultSortCriteria ¶ added in v0.4.0
func DefaultSortCriteria() SortCriteria
func ParseSortCriteria ¶ added in v0.4.0
func ParseSortCriteria(value string) (SortCriteria, error)
func (SortCriteria) IsValid ¶ added in v0.4.0
func (sc SortCriteria) IsValid() bool
func (SortCriteria) MarshalJSON ¶ added in v0.4.0
func (sc SortCriteria) MarshalJSON() ([]byte, error)
func (SortCriteria) String ¶ added in v0.4.0
func (sc SortCriteria) String() string
func (*SortCriteria) UnmarshalJSON ¶ added in v0.4.0
func (sc *SortCriteria) UnmarshalJSON(data []byte) error