SkillAgentSearch skills...

SwiftStaticAnalysis

High-performance Swift static analysis framework for code duplication detection and unused code elimination

Install / Use

/learn @g-cqd/SwiftStaticAnalysis
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

SwiftStaticAnalysis

Swift 6.2 Platform License CI Documentation

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:ignore comments
  • High-Performance Parsing: Memory-mapped I/O, SoA token storage, and arena allocation
  • Zero-Boilerplate CLI: Full-featured swa command with JSON/text/Xcode output formats
  • Swift 6 Concurrency: Thread-safe design with Sendable conformance 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

View on GitHub
GitHub Stars10
CategoryDevelopment
Updated2mo ago
Forks0

Languages

Swift

Security Score

90/100

Audited on Feb 2, 2026

No findings