SwiftStaticAnalysis
High-performance Swift static analysis framework for code duplication detection and unused code elimination
Install / Use
/learn @g-cqd/SwiftStaticAnalysisREADME
SwiftStaticAnalysis
A high-performance Swift static analysis framework for code duplication detection, unused code elimination, and symbol lookup.
Features
- Multi-Algorithm Clone Detection: Exact (Type-1), near (Type-2), and semantic (Type-3/4) clone detection with parallel MinHash/LSH (enabled by default)
- IndexStoreDB Integration: Accurate cross-module unused code detection using compiler index data with improved auto-discovery
- Reachability Analysis: Graph-based dead code detection with entry point tracking, parallel edge building, and direction-optimizing BFS
- Symbol Lookup: Find symbols by name, qualified name, selector, USR, or regex pattern with rich context extraction
- Symbol Context: Extract surrounding code, documentation, signatures, and scope information for matched symbols
- MCP Server Integration: Model Context Protocol server (
swa-mcp) for AI assistant integration - Ignore Directives: Suppress false positives with
// swa:ignorecomments - High-Performance Parsing: Memory-mapped I/O, SoA token storage, and arena allocation
- Zero-Boilerplate CLI: Full-featured
swacommand with JSON/text/Xcode output formats - Swift 6 Concurrency: Thread-safe design with
Sendableconformance throughout - Scope-Aware Dataflow Analysis: Tuple pattern extraction, closure capture handling, and
_-skip rules - Configurable Filtering: Exclude imports, test suites, deinit methods, and custom patterns
Requirements
- macOS 15.0+
- Swift 6.2+
- Xcode 26.0+
Installation
Swift Package Manager
Add to your Package.swift:
dependencies: [
.package(url: "https://github.com/g-cqd/SwiftStaticAnalysis.git", from: "0.1.4")
]
Then add the dependency to your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "SwiftStaticAnalysis", package: "SwiftStaticAnalysis"),
]
)
This gives you access to all components including the MCP server. Alternatively, import individual modules:
.target(
name: "YourTarget",
dependencies: [
.product(name: "SwiftStaticAnalysisCore", package: "SwiftStaticAnalysis"), // Core only
.product(name: "DuplicationDetector", package: "SwiftStaticAnalysis"), // Clone detection
.product(name: "UnusedCodeDetector", package: "SwiftStaticAnalysis"), // Unused code
.product(name: "SymbolLookup", package: "SwiftStaticAnalysis"), // Symbol lookup
.product(name: "SwiftStaticAnalysisMCP", package: "SwiftStaticAnalysis"), // MCP server
]
)
Pre-built Binary (Recommended)
Download the latest release from GitHub:
# Universal binary (works on both Apple Silicon and Intel)
curl -L https://github.com/g-cqd/SwiftStaticAnalysis/releases/latest/download/swa-macos-universal.tar.gz | tar xz
sudo mv swa /usr/local/bin/
# Or for Apple Silicon only
curl -L https://github.com/g-cqd/SwiftStaticAnalysis/releases/latest/download/swa-macos-arm64.tar.gz | tar xz
# Or for Intel only
curl -L https://github.com/g-cqd/SwiftStaticAnalysis/releases/latest/download/swa-macos-x86_64.tar.gz | tar xz
Build from Source
# Build release binary
swift build -c release
# Install to PATH
cp .build/release/swa /usr/local/bin/
Quick Start
CLI Usage
# Full analysis (duplicates + unused code)
swa analyze /path/to/project
# Detect code duplicates
swa duplicates /path/to/project --types exact --types near --types semantic
# Detect unused code with reachability analysis
swa unused /path/to/project --mode reachability
# Enable parallel reachability (large graphs)
swa unused /path/to/project --mode reachability --parallel-mode safe
# Apply sensible filters to reduce false positives
swa unused . --sensible-defaults --exclude-paths "**/Tests/**"
# Look up symbols by name
swa symbol NetworkManager /path/to/project
# Look up with filters
swa symbol "fetch" --kind method --access public /path/to/project
# Find symbol usages
swa symbol "SharedCache.instance" --usages /path/to/project
# Symbol lookup with context (surrounding code)
swa symbol "NetworkManager" --context-lines 3 /path/to/project
# Include documentation and signature
swa symbol "fetchData" --context-documentation --context-signature /path/to/project
# Include all context information
swa symbol "CacheManager" --context-all /path/to/project
# Parallel MinHash/LSH clone detection (large codebases)
swa duplicates /path/to/project --types near --algorithm minHashLSH --parallel-mode safe
# Output as JSON for CI integration
swa analyze . --format json > report.json
# Xcode-compatible warnings
swa unused . --format xcode
Configuration File
Create a .swa.json file in your project root for persistent configuration:
{
"unused": {
"mode": "reachability",
"parallelMode": "safe",
"minConfidence": "medium",
"excludePaths": ["**/Tests/**", "**/Fixtures/**"],
"excludeImports": true,
"excludeTestSuites": true,
"treatPublicAsRoot": true,
"treatSwiftUIViewsAsRoot": true
},
"duplicates": {
"types": ["exact", "near"],
"minTokens": 50,
"minSimilarity": 0.8,
"algorithm": "minHashLSH",
"parallelMode": "safe"
}
}
parallelMode controls parallel execution: none, safe, maximum. safe matches legacy --parallel, while maximum enables streaming/backpressure in programmatic pipelines. Legacy parallel is still supported but deprecated.
Then run with:
swa analyze --config .swa.json
Programmatic API
import SwiftStaticAnalysis
Duplication Detection
let config = DuplicationConfiguration(
minimumTokens: 50,
cloneTypes: [.exact, .near, .semantic],
minimumSimilarity: 0.8
)
let detector = DuplicationDetector(configuration: config)
let clones = try await detector.detectClones(in: swiftFiles)
for group in clones {
print("[\(group.type.rawValue)] \(group.occurrences) occurrences")
for clone in group.clones {
print(" \(clone.file):\(clone.startLine)-\(clone.endLine)")
}
}
Unused Code Detection
// Use reachability analysis for accurate detection
let config = UnusedCodeConfiguration.reachability
let detector = UnusedCodeDetector(configuration: config)
let unused = try await detector.detectUnused(in: swiftFiles)
// Filter results with sensible defaults
let filtered = unused.filteredWithSensibleDefaults()
for item in filtered {
print("[\(item.confidence.rawValue)] \(item.declaration.location): \(item.suggestion)")
}
IndexStore-Enhanced Detection
// Use compiler's index data for cross-module accuracy
var config = UnusedCodeConfiguration.indexStore
config.indexStorePath = ".build/debug/index/store"
config.autoBuild = true // Build if index is stale
let detector = UnusedCodeDetector(configuration: config)
let unused = try await detector.detectUnused(in: swiftFiles)
If you omit indexStorePath, the detector attempts to auto-discover it in .build/.../index/store or Xcode DerivedData.
Symbol Lookup
import SwiftStaticAnalysis
// Create a symbol finder
let finder = SymbolFinder(projectPath: "/path/to/project")
// Find symbols by name
let query = SymbolQuery.name("NetworkManager")
let matches = try await finder.find(query)
for match in matches {
print("\(match.kind) \(match.name) at \(match.file):\(match.line)")
}
// Find by qualified name
let qualified = SymbolQuery.qualifiedName("APIClient", "shared")
let results = try await finder.find(qualified)
// Find method by selector (with parameter labels)
let selector = SymbolQuery.selector("fetch", labels: ["id", "completion"])
let methods = try await finder.find(selector)
// Find usages of a symbol
if let match = matches.first {
let usages = try await finder.findUsages(of: match)
for usage in usages {
print(" Referenced at \(usage.file):\(usage.line)")
}
}
Ignore Directives
Suppress false positives directly in your source code using // swa:ignore comments.
Supported Formats
// swa:ignore - Ignore all warnings for this declaration
// swa:ignore-unused - Ignore unused code warnings
// swa:ignore-unused-cases - Ignore unused enum case warnings (for exhaustive enums)
// swa:ignore-unused - Reason - Add description after hyphen separator
/// Doc comment. // swa:ignore - Also works in doc comments
/* swa:ignore */ - Block comments work too
Example Usage
/// Known error types for API responses.
/// Exhaustive for serialization. // swa:ignore-unused-cases
public enum APIError: String, Codable {
case networkError
case authenticationFailed
case serverError // May not be used yet, but needed for API compatibility
case rateLimited
}
// swa:ignore
func debugHelper() {
// Intentionally unused in production, used only during development
}
Directive Inheritance
Ignore directives are inherited by nested declarations:
/// Protocol message types. // swa:ignore-unused-cases
enum MessageType {
case request // ← Automatically ignored
case response // ← Automatically ignored
}
// swa:ignore-unused - SIMD utility operations
public extension SIMDStorage {
func optimizedSum() -> Float { ... } // ← Inherits ig
Related Skills
node-connect
349.7kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.7kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.7kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
