class Parser::Source::TreeRewriter

{TreeRewriter} performs the heavy lifting in the source rewriting process. It schedules code updates to be performed in the correct order.

For simple cases, the resulting source will be obvious.

Examples for more complex cases follow. Assume these examples are acting on the source ‘’puts(:hello, :world)‘. The methods wrap, remove, etc. receive a Range as first argument; for clarity, examples below use english sentences and a string of raw code instead.

## Overlapping ranges:

Any two rewriting actions on overlapping ranges will fail and raise a ‘ClobberingError`, unless they are both deletions (covered next).

=> CloberringError

## Overlapping deletions:

The overlapping ranges are merged and ‘’:hello, :world’‘ will be removed. This policy can be changed. `:crossing_deletions` defaults to `:accept` but can be set to `:warn` or `:raise`.

## Multiple actions at the same end points:

Results will always be independent on the order they were given. Exception: rewriting actions done on exactly the same range (covered next).

Example:

The resulting string will be ‘’puts({:hello => [:everybody]})‘` and this result is independent on the order the instructions were given in.

Note that if the two “replace” were given as a single replacement of ‘, :world’ for ‘ => :everybody’, the result would be a ‘ClobberingError` because of the wrap in square brackets.

## Multiple wraps on same range:

The wraps are combined in order given and results would be ‘’puts(, :world)‘`.

## Multiple replacements on same range:

The replacements are made in the order given, so the latter replacement supersedes the former and ‘:hello’ will be replaced by ‘:hey’.

This policy can be changed. ‘:different_replacements` defaults to `:accept` but can be set to `:warn` or `:raise`.

## Swallowed insertions: wrap ‘world’ by ‘__’, ‘__’ replace ‘:hello, :world’ with ‘:hi’

A containing replacement will swallow the contained rewriting actions and ‘’:hello, :world’‘ will be replaced by `’:hi’‘.

This policy can be changed for swallowed insertions. ‘:swallowed_insertions` defaults to `:accept` but can be set to `:warn` or `:raise`

## Implementation The updates are organized in a tree, according to the ranges they act on (where children are strictly contained by their parent), hence the name.

@!attribute [r] source_buffer

@return [Source::Buffer]

@!attribute [r] diagnostics

@return [Diagnostic::Engine]

@api public