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.

Install
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.

File A
// 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
}
File B
// 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.

Features

AST-based detection Looks at structure, not text. Two functions with renamed variables but the same shape are still flagged as a clone.
Swift, Objective-C, and C One tool across the whole Apple-platform codebase, including legacy modules and bridging layers.
CI-ready enforcement Run in pipelines to fail builds when new duplication appears. Treat duplication as a policy, not a habit.
Configurable thresholds Tune minimum token count, line count, clone types, and exclusion patterns through a small YAML file.