Swift Code Paste Detector
Duplicated logic looks small until it isn’t. Two copies drift apart, bugs get fixed in one place and not the other, behavior diverges between features that should be consistent — and every refactor multiplies in cost. swift-cpd finds the duplicates before they compound, through structural analysis across Swift, Objective-C, and C.
brew tap ericodx/homebrew-tools brew install swift-cpd
What it detects
Same shape, different types. Renamed variables, different value checks — but the control flow is identical. swift-cpd surfaces this as a structural clone, so you can decide whether to extract a shared validator or accept the duplication consciously.
// Sources/App/Services/UserService.swift
func validate(_ user: User) -> Bool {
guard !user.name.isEmpty else { return false }
guard user.age >= 18 else { return false }
guard user.email.contains("@") else { return false }
return true
} // Sources/App/Services/ProductService.swift
func validate(_ product: Product) -> Bool {
guard !product.name.isEmpty else { return false }
guard product.price >= 0 else { return false }
guard product.sku.contains("-") else { return false }
return true
} The simplest case is the exact clone (Type 1), where the same block of code appears in more than one place and only whitespace or comments differ between the copies. This is what classic copy-paste creates: someone needed the same logic somewhere else, duplicated it, and moved on. It is also the easiest kind to spot once you know to look.
A parameterized clone (Type 2) has the same shape as another block, but the names and values inside have been changed. The example above is one of these: two validators with identical control flow, only operating on different types. This is what happens when copy-paste meets a small edit — the code was duplicated and then tweaked to fit a new context. swift-cpd sees past the renaming and reports both fragments as the same logic.
A near-miss clone (Type 3) is one where two blocks share most of their structure, but somewhere along the way a few statements were added, removed, or modified. Maybe an extra condition was inserted in one place, or a log line dropped in the other. The intent is still clearly the same on both sides, and swift-cpd still recognizes them as related — you can decide how forgiving the match should be by adjusting the similarity threshold.
The hardest class is the semantic clone (Type 4). Here, two pieces of code look completely different on the surface — different variable names, different control flow, even a different order of operations — but they do the same thing. This is where swift-cpd reaches beyond text and structure to compare actual behavior, catching rewrites and reorganizations that line-based or token-based detectors miss entirely.