Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Refactor DSL

A domain-specific language for multi-language code refactoring with Git-aware matching.

What is Refactor DSL?

Refactor DSL is a Rust library and CLI tool that provides a fluent, type-safe API for performin code refactoring operations across multiple programming languages. It combines:

  • Git-aware matching - Filter repositories by branch, commit history, and working state
  • Flexible file matching - Glob patterns, extensions, and content-based filtering
  • AST-powered queries - Find and transform code using tree-sitter syntax patterns
  • LSP integration - Semantic refactoring through Language Server Protocol
  • Multi-language support - Rust, TypeScript, Python, Go, Java, C#, and Ruby
  • IDE-like refactoring - Extract, Inline, Move, Change Signature, Safe Delete, Find Dead Code
  • Scope analysis - Track bindings, resolve references, and analyze usage across files
  • Enhanced discovery - Filter repositories by dependencies, frameworks, and metrics

Key Features

Fluent Builder API

#![allow(unused)]
fn main() {
use refactor::prelude::*;

Refactor::in_repo("./my-project")
    .matching(|m| m
        .git(|g| g.branch("main"))
        .files(|f| f.extension("rs").exclude("**/target/**")))
    .transform(|t| t
        .replace_pattern(r"\.unwrap\(\)", ".expect(\"TODO\")"))
    .dry_run()
    .apply()?;
}

Powerful Matching

  • Match repositories by Git branch, commit age, remotes, and working tree state
  • Match files by extension, glob patterns, content patterns, and size
  • Match code structures using tree-sitter AST queries

Safe Transformations

  • Preview changes with dry_run() before applying
  • Generate unified diffs for review
  • Atomic file operations with rollback on failure

LSP-based Semantic Refactoring

  • Rename symbols with full project awareness
  • Auto-install LSP servers from the Mason registry
  • Support for rust-analyzer, typescript-language-server, pyright, gopls, jdtls, omnisharp, solargraph, and clangd

IDE-Like Refactoring Operations

#![allow(unused)]
fn main() {
use refactor::prelude::*;

// Extract a function from selected code
ExtractFunction::new("calculate_total")
    .from_file("src/checkout.rs")
    .range(Range::new(Position::new(10, 0), Position::new(20, 0)))
    .visibility(Visibility::Public)
    .execute()?;

// Find dead code in a workspace
let report = FindDeadCode::in_workspace("./project")
    .include(DeadCodeType::UnusedFunctions)
    .include(DeadCodeType::UnusedImports)
    .execute()?;

// Safely delete a symbol with usage checking
SafeDelete::symbol("unused_helper")
    .in_file("src/utils.rs")
    .check_usages(true)
    .execute()?;
}

Enhanced Repository Discovery

#![allow(unused)]
fn main() {
use refactor::prelude::*;

// Filter GitHub org repos by dependencies and frameworks
Codemod::from_github_org("acme-corp", token)
    .repositories(|r| r
        .has_dependency("react", ">=17.0")
        .uses_framework(Framework::NextJs)
        .lines_of_code(ComparisonOp::GreaterThan, 1000.0))
    .apply(upgrade)
    .execute()?;
}

When to Use This

Refactor DSL is ideal for:

  • Codebase migrations - Update API usage patterns across many files
  • Style enforcement - Apply consistent code patterns
  • Bulk refactoring - Rename symbols, update imports, transform patterns
  • Multi-repo operations - Apply the same changes across multiple repositories
  • Automated code cleanup - Remove deprecated patterns, add missing annotations
  • Code quality - Find and remove dead code, enforce naming conventions
  • Safe refactoring - Extract functions, change signatures with call-site updates

Architecture

┌───────────────────────────────────────────────────────────────────────┐
│                           Refactor DSL                                │
├───────────────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌───────────────┐  ┌────────────┐  │
│  │  Matchers   │  │ Transforms  │  │ LSP Client    │  │ Discovery  │  │
│  │             │  │             │  │               │  │            │  │
│  │ - Git       │  │ - Text      │  │ - Rename      │  │ - Deps     │  │
│  │ - File      │  │ - AST       │  │ - References  │  │ - Framework│  │
│  │ - AST       │  │ - File      │  │ - Definition  │  │ - Metrics  │  │
│  └─────────────┘  └─────────────┘  └───────────────┘  └────────────┘  │
├───────────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────────────────┐  │
│  │                    Refactoring Operations                       │  │
│  │                                                                 │  │
│  │  Extract │ Inline │ Move │ ChangeSignature │ SafeDelete │ Dead  │  │
│  └─────────────────────────────────────────────────────────────────┘  │
├───────────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────────────────┐  │
│  │                      Scope Analysis                             │  │
│  │                                                                 │  │
│  │  Bindings │ References │ Usage Analysis │ Cross-file Resolution │  │
│  └─────────────────────────────────────────────────────────────────┘  │
├───────────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────────────────┐  │
│  │                      Language Support                           │  │
│  │                                                                 │  │
│  │  Rust │ TypeScript │ Python │ Go │ Java │ C# │ Ruby │ C/C++     │  │
│  └─────────────────────────────────────────────────────────────────┘  │
├───────────────────────────────────────────────────────────────────────┤
│  tree-sitter │ git2 │ walkdir │ globset │ regex │ lsp-types           │
└───────────────────────────────────────────────────────────────────────┘