tape refactor

Usage

bash
tape refactor <file.tape> [options]

Purpose

Materializes refactor("path") { ... } blocks into separate .tape files. The compiler validates these blocks on every build — by the time this command runs, the extraction is already proven correct.

bash
tape refactor app.tape
#   wrote ./store.tape
#   rewrote app.tape (1 refactor block materialized)

What it does

  1. Run analysis pass (scan, parse, lower, typecheck) to validate refactor boundaries
  2. For each refactor("path") { ... } block in the source:
    • Generate the target file with only the imports the moved code uses
    • Wrap the declarations in pub {}, unless every one is already pub
    • Inherit @profile from the source file
  3. Rewrite the source file:
    • Remove the refactor block(s)
    • Add selective imports for symbols that the remaining code references
    • Drop an import that only the moved code used

Examples

bash
# Materialize all refactor blocks:
tape refactor app.tape

# Preview without writing:
tape refactor app.tape --dry-run

# Overwrite existing target files:
tape refactor app.tape --force

—dry-run output

plaintext
=== ./store.tape (from refactor block) ===
pub {
    var items: [64]i64;
    var count: i64 = 0;
    fn add_item(val: i64) { ... }
    fn sum() -> i64 { ... }
}

=== app.tape (rewritten) ===
  + import { items, count, add_item, sum } from "./store.tape";
  - 1 refactor block removed

Options

FlagDescription
--dry-runShow computed file contents without writing to disk
--forceOverwrite existing target files (default: error if target exists)
--humanHuman-readable output with color

Exit codes

CodeMeaning
0Success — files written
1Compile error in refactor boundary (same errors as tape check)
3I/O error (target file exists without --force, permission denied)

Relationship to other commands

tape refactor uses the same frontend pipeline as tape check — it stops after type checking and does not generate native code. The refactor boundaries are validated during normal tape build and tape check runs too, so errors appear immediately during development.

plaintext
tape check app.tape      # validates refactor boundaries (among everything else)
tape build app.tape      # also validates them, then builds
tape refactor app.tape   # materializes them into files

Generated file format

Target files are generated with:

  • Only the imports the moved code actually uses
  • The declarations inside a pub {} block (when every one is already pub: as written, at the top level)
  • The source file’s @profile pragma (if present)
  • No other boilerplate
tape
// store.tape (generated by tape refactor)
pub {
    var items: [64]i64;
    var count: i64 = 0;
    fn add_item(val: i64) { ... }
    fn sum() -> i64 { ... }
}

Error conditions

ConditionResult
Target file already exists (no --force)Exit 3: “file already exists”
Refactor block references host-local symbolExit 1: compile error (caught during any build)
Circular dependency between blocksExit 1: compile error (caught during any build)
No refactor blocks found in sourceExit 0: no-op, prints “no refactor blocks”

Last modified: