ryo-source 0.1.0

High-speed Rust AST manipulation engine
Documentation
#![warn(missing_docs)]
//! # ryo-source
//!
//! High-speed Rust AST manipulation engine for the RYO (流) project's "Fluid Code" paradigm.
//!
//! This crate provides two complementary AST representations optimized for different use cases:
//! [`RustAST`] for full-fidelity manipulation and [`PureFile`] for thread-safe parallel processing.
//!
//! # Core Philosophy: Fluid Code
//!
//! Code is not static text—it's a living, flowing structure that can be manipulated,
//! analyzed, and transformed at high speed. The AST is the "shadow" of source code,
//! a pure representation that enables:
//!
//! - **Instant Analysis**: Query definitions, references, and dependencies in nanoseconds
//! - **Safe Mutation**: Transform code with type-safe operations
//! - **Parallel Processing**: Share and analyze code across threads via [`PureFile`]
//!
//! # Dual AST Architecture
//!
//! ```text
//!                          Source Code
//!                      "fn main() { ... }"
//!//!//!                          syn::parse
//!//!              ┌───────────────┴───────────────┐
//!              ▼                               ▼
//!     ┌─────────────────┐           ┌─────────────────┐
//!     │     RustAST     │           │    PureFile     │
//!     │  (Full-fidelity)│           │  (Thread-safe)  │
//!     ├─────────────────┤           ├─────────────────┤
//!     │ • syn::File     │           │ • Span-free     │
//!     │ • Complete info │  ToPure   │ • Send + Sync   │
//!     │ • Span preserve │ ───────▶  │ • Arc-shareable │
//!     │ • Code gen      │  (~10%)   │ • Serializable  │
//!     │ • NOT Send/Sync │           │ • Lightweight   │
//!     └─────────────────┘           └─────────────────┘
//! ```
//!
//! # RustAST: Full-Fidelity AST
//!
//! [`RustAST`] wraps `syn::File` to provide high-level operations while preserving
//! complete syntactic information including spans (source locations).
//!
//! ```
//! use ryo_source::RustAST;
//!
//! // Parse source code
//! let mut ast = RustAST::parse("use std::io;\nfn main() {}").unwrap();
//!
//! // Remove unused imports
//! let removed = ast.remove_unused_imports();
//! assert_eq!(removed.len(), 1);
//!
//! // Generate cleaned code
//! let code = ast.to_string_pretty();
//! assert!(!code.contains("use std::io"));
//! ```
//!
//! # PureFile: Thread-Safe AST
//!
//! [`PureFile`] strips all `Span` information, creating a pure data structure
//! that can be safely shared across threads with `Arc`.
//!
//! ```
//! use std::sync::Arc;
//! use std::thread;
//! use ryo_source::PureFile;
//!
//! // Parse directly to PureFile
//! let pure = PureFile::from_source("fn foo() {} fn bar() {}").unwrap();
//!
//! // Share across threads
//! let shared = Arc::new(pure);
//!
//! let s1 = Arc::clone(&shared);
//! let h1 = thread::spawn(move || s1.functions().len());
//!
//! let s2 = Arc::clone(&shared);
//! let h2 = thread::spawn(move || s2.find_fn("foo").is_some());
//!
//! assert_eq!(h1.join().unwrap(), 2);
//! assert!(h2.join().unwrap());
//! ```
//!
//! # Operations
//!
//! ## Query Operations (Read-only)
//!
//! | Operation | Description |
//! |-----------|-------------|
//! | [`DefRefs::analyze`] | Find all symbol definitions and references |
//! | [`DefRefs::find_definition`] | Locate where a symbol is defined |
//! | [`DefRefs::find_references`] | Find all uses of a symbol |
//! | [`PureFile::functions`] | Get all functions (thread-safe) |
//! | [`PureFile::find_fn`] | Find function by name (thread-safe) |
//!
//! ## Mutation Operations
//!
//! | Operation | Description | Pattern |
//! |-----------|-------------|---------|
//! | [`Rename::apply`] | Rename symbols globally | In-place |
//! | [`Rename::rename_local_in_fn`] | Rename within specific function | In-place |
//! | [`RemoveUnusedImports::apply`] | Remove unused imports | In-place |
//! | [`CowMut::rename`] | Copy-on-write rename | Returns new AST |
//! | [`CowMut::chain_renames`] | Sequential renames | Returns new AST |
//!
//! # Copy-on-Write Mutation
//!
//! For scenarios requiring multiple independent mutations:
//!
//! ```
//! use ryo_source::{RustAST, CowMut};
//!
//! let ast = RustAST::parse("fn foo() { fn bar() {} }").unwrap();
//!
//! // Each rename produces an independent copy
//! let results = CowMut::multi_rename(&ast, &[
//!     ("foo", "alpha"),
//!     ("bar", "beta"),
//! ]);
//!
//! // results[0].ast has foo→alpha, bar unchanged
//! // results[1].ast has bar→beta, foo unchanged
//! // Original ast is unchanged
//! assert!(ast.to_string().contains("foo"));
//! ```
//!
//! # Why syn over tree-sitter?
//!
//! We chose `syn` for Rust because:
//!
//! 1. **Semantic Awareness**: syn understands Rust's semantics, not just syntax
//! 2. **Type Safety**: Operations are checked at compile time
//! 3. **Ecosystem Integration**: Works with `quote`, `proc-macro2`, and Rust tooling
//! 4. **Rust-First Philosophy**: Optimized for Rust's unique features
//!
//! [`RustAST`]: crate::RustAST
//! [`PureFile`]: crate::PureFile
//! [`DefRefs::analyze`]: crate::DefRefs::analyze
//! [`DefRefs::find_definition`]: crate::DefRefs::find_definition
//! [`DefRefs::find_references`]: crate::DefRefs::find_references
//! [`PureFile::functions`]: crate::pure::PureFile::functions
//! [`PureFile::find_fn`]: crate::pure::PureFile::find_fn
//! [`Rename::apply`]: crate::Rename::apply
//! [`Rename::rename_local_in_fn`]: crate::Rename::rename_local_in_fn
//! [`RemoveUnusedImports::apply`]: crate::RemoveUnusedImports::apply
//! [`CowMut::rename`]: crate::CowMut::rename
//! [`CowMut::chain_renames`]: crate::CowMut::chain_renames

mod ast;
mod error;
pub mod generator;
pub mod ops;
pub mod parallel;
pub mod pure;
mod visitor;

// Test utilities (available with `test-utils` feature or in test builds)
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils;

pub use ast::RustAST;
pub use error::{SourceError, SourceResult};
pub use generator::{
    GeneratedFiles, GeneratedSource, ModuleTree, MultiFileGenerator, SingleFileGenerator,
    SourceGenerator,
};
pub use ops::{
    DefRefs, Location, RemoveUnusedImports, Rename, RenameResult, Symbol, SymbolKind, SymbolTable,
};
pub use parallel::{CowMut, MutResult, SourceParallel};
pub use pure::{ItemKind, PureFile, ToPure, ToSyn};