package ryo:transform@0.1.0;
interface mutation {
use types.{api-version, node-kind, match-result, capture, type-hint, text-edit};
/// Mutation manifest - returned once at plugin load
record mutation-manifest {
/// API version (must match host)
api-version: api-version,
/// Unique identifier (e.g., "bool-simplify", "unwrap-to-question")
name: string,
/// Human-readable description
description: string,
/// Category for organization
category: mutation-category,
/// Priority tier (1: high-frequency clippy, 2: pattern transform, 3: custom)
tier: u8,
/// Primary pattern (syn-based DSL or custom format)
pattern: string,
/// Transform strategy
transform: transform-def,
}
/// Mutation category
variant mutation-category {
/// Clippy-style idiom improvements (BoolSimplify, AssignOp, etc.)
idiom,
/// Structural refactoring (ExtractFunction, MoveItem)
refactor,
/// Code generation (Builder, Getters)
generate,
/// User-defined custom transforms
custom,
}
/// Transform definition
variant transform-def {
/// Simple template replacement (Host executes)
/// Supports {{capture_name}} interpolation
template(string),
/// Complex logic requiring WASM execution
wasm-execute,
}
/// Transform execution context (passed to execute-transform)
record transform-context {
/// Path to the file being transformed
file-path: string,
/// Full source text of the file
source-text: string,
/// Type hints from analysis (optional)
type-hints: list<type-hint>,
/// Function return type if inside a function (for ? operator)
fn-return-type: option<string>,
}
/// Transform error variants
variant transform-error {
/// A required capture was not found in the match
missing-capture(string),
/// The context is invalid for this transform
invalid-context(string),
/// Type mismatch prevents transformation
type-mismatch(string),
/// Pattern is not applicable to this context
pattern-not-applicable(string),
/// Internal error
internal(string),
}
// === Exported Functions ===
/// Get mutation manifest (called once at plugin load)
get-manifest: func() -> mutation-manifest;
/// Get additional pattern sources (called once at plugin load)
/// Return empty string if primary pattern is sufficient
get-pattern-source: func() -> string;
/// Execute transform (called only when transform = wasm-execute)
execute-transform: func(
matches: list<match-result>,
context: transform-context,
) -> result<list<text-edit>, transform-error>;
}