VirtualTimeMigrate.Edits (GenServerVirtualTimeMigrate v1.1.1)

Copy Markdown View Source

The editable unit of a planned rewrite: a token at a line and column.

Two rewrites need this — moving GenServer code onto the virtual clock (VirtualTimeMigrate) and moving a project off the deprecated module names (VirtualTimeUpgrade) — so the machinery for collecting, checking and applying the edits lives here rather than in either of them.

Every edit carries the exact source text it expects to find at its position and is checked against the source before it joins the plan, so a plan can never be applied to text it does not describe.

Summary

Types

One replacement: from is the exact source text at column on line, and to is what replaces it.

Something the rewrite noticed but leaves alone.

Functions

Records that from, at meta's position, becomes to.

Applies a plan to the source it was planned from.

Starts collecting edits for source.

Records something worth telling the human about, without rewriting it.

The plan, in source order.

Types

edit()

@type edit() :: %{
  line: pos_integer(),
  column: pos_integer(),
  from: String.t(),
  to: String.t(),
  change: String.t()
}

One replacement: from is the exact source text at column on line, and to is what replaces it.

note()

@type note() :: %{line: pos_integer(), message: String.t()}

Something the rewrite noticed but leaves alone.

plan()

@type plan() :: %{edits: [edit()], notes: [note()]}

state()

@opaque state()

Functions

add(state, meta, from, to, change)

@spec add(state(), keyword(), String.t(), String.t(), String.t()) :: state()

Records that from, at meta's position, becomes to.

change is what the report prints. If the source does not have from there, a note is recorded instead: a wrong position is a bug in the plan, and a note is how it becomes visible rather than a silently mis-edited file.

apply(source, edits)

@spec apply(String.t(), [edit()]) :: String.t()

Applies a plan to the source it was planned from.

Edits are applied right to left within a line, so an earlier replacement never moves a later one.

new(source)

@spec new(String.t()) :: state()

Starts collecting edits for source.

note(state, meta, message)

@spec note(state(), keyword(), String.t()) :: state()

Records something worth telling the human about, without rewriting it.

to_plan(state)

@spec to_plan(state()) :: plan()

The plan, in source order.