compiler/mir/treechangesets

  Source   Edit

This module implements the TreeChangeset API, which is the main way of modifying a MirTree after its initial construction.

Instead of modifying a MirTree directly, the changes (which can be insertions, replacements, or removals) are first recorded into a TreeChangeset. This allows for recording changes independent of each other concurrently and later applying the changes all at once.

Before applying a TreeChangeset to a MirTree, it has to be prepared via a call to prepare first, after which the TreeChangeset is sealed and no further changes can be recorded. prepare is responsible from normalizing the internal representation of the Changeset and is required for the later application to work.

Applying the PreparedChangeset is done via apply. This integrates all recorded changes into the applied-to tree.

Order of application

Nodes are inserted before the node at the insertion position, meaning that it is allowed for an insertion to overlap with a removal/replacement at the start position. All other forms of overlapping changes are disallowed. If there exist two or more insertion at the same position, they are applied in the order the changes were recorded. That is, the nodes from the insertion recorded first are inserted first, then that of the second recorded, then the third one's, etc.

Types

PreparedChangeset = object
  nodes: seq[MirNode]
  rows: seq[Row]
  diff: int                  ## the number of additions/removals
  stagingSize: int ## the minimum amount of nodes the working area must be
                   ## able to hold
  
  Source   Edit
TreeChangeset = object
  nodes: seq[MirNode]
  rows: seq[Row]
Represents a set of changes to be applied to a MirTree.   Source   Edit

Procs

func apply(tree: var MirTree; c: sink PreparedChangeset) {....raises: [], tags: [].}
Applies the changeset c to the tree, modifying the tree in-place. The tree's underlying sequence is resized 0 to 2 times.   Source   Edit
func changeTree(c: var Changeset; tree: MirTree; at: NodePosition;
                with: sink MirNode) {....raises: [], tags: [].}
Replaces the sub-tree at at with with while keeping all child trees. The origin and length information is taken from the replaced node.   Source   Edit
func insert(c: var Changeset; at: NodePosition; n: sink MirNode) {....raises: [],
    tags: [].}
Records the insertion of n at at. The info field on the node is not modified.   Source   Edit
func prepare(c: sink Changeset): PreparedChangeset {....raises: [], tags: [].}
Prepares c for being applied   Source   Edit
func remove(c: var Changeset; tree: MirTree; at: NodePosition) {....raises: [],
    tags: [].}
Records the removal of the node or sub-tree at at.   Source   Edit
func replace(c: var Changeset; tree: MirTree; at: NodePosition;
             with: sink MirNode) {....raises: [], tags: [].}
Records replacing the node or sub-tree at at with with. The origin information is taken from the replaced node.   Source   Edit

Templates

template insert(c: var Changeset; at: NodePosition; name: untyped; body: untyped)
Records an insertion at the at position, providing direct access to the internal node buffer inside body via an injected variable of the name name. source is the node to inherit the source/origin information from   Source   Edit
template replaceMulti(c: var Changeset; tree: MirTree; at: NodePosition;
                      name, body: untyped)
Records a replacement of the node or sub-tree at the at position, providing direct access to the internal node buffer inside body via an injected variable of the name name.   Source   Edit