Ameba::Source::Rewriter - ameba 1.7.0

# class Ameba::Source::Rewriter

- Ameba::Source::Rewriter
- Reference
- Object

##
Overview

This class 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 the first two arguments; for clarity, examples below use English sentences and a string of raw code instead.

##
Overlapping deletions:

- remove `:hello,`
- remove `, :world`

The overlapping ranges are merged and `:hello, :world` will be removed.

##
Multiple actions at the same end points:

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

Example:

- replace `,` by `=>`
- wrap `:hello, :world` with `{` and `}`
- replace `:world` with `:everybody`
- wrap `:world` with `[`, `]`

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

##
Multiple wraps on same range:

- wrap `:hello` with `(` and `)`
- wrap `:hello` with `[` and `]`

The wraps are combined in order given and results would be `puts([(:hello)], :world)`.

##
Multiple replacements on same range:

- replace `:hello` by `:hi`, then
- replace `:hello` by `:hey`

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

##
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`.

##
Implementation

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

##
Defined in:

ameba/source/rewriter.cr
ameba/source/rewriter/action.cr

##
Constructors

- .new(code : String)

##
Instance Method Summary

- #code : String
- #empty?

  Returns `true` if no (non trivial) update has been recorded

- #insert_after(begin_pos, end_pos, content)

  Shortcut for `#wrap(begin_pos, end_pos, nil, content)`

- #insert_after(pos, content)

  Shortcut for `#insert_after(pos, pos, content)`

- #insert_before(begin_pos, end_pos, content)

  Shortcut for `#wrap(begin_pos, end_pos, content, nil)`

- #insert_before(pos, content)

  Shortcut for `#insert_before(pos, pos, content)`

- #process

  Applies all scheduled changes and returns modified source as a new string.

- #remove(begin_pos, end_pos)

  Shortcut for `#replace(begin_pos, end_pos, "")`

- #replace(begin_pos, end_pos, content)

  Replaces the code of the given range with content.

- #wrap(begin_pos, end_pos, insert_before, insert_after)

  Inserts the given strings before and after the given range.

##
Constructor Detail

def self.new(code : String) #

##
Instance Method Detail

def code : String #
def empty? #

Returns `true` if no (non trivial) update has been recorded

def insert_after(begin_pos, end_pos, content) #

Shortcut for `#wrap(begin_pos, end_pos, nil, content)`

def insert_after(pos, content) #

Shortcut for `#insert_after(pos, pos, content)`

def insert_before(begin_pos, end_pos, content) #

Shortcut for `#wrap(begin_pos, end_pos, content, nil)`

def insert_before(pos, content) #

Shortcut for `#insert_before(pos, pos, content)`

def process #

Applies all scheduled changes and returns modified source as a new string.

def remove(begin_pos, end_pos) #

Shortcut for `#replace(begin_pos, end_pos, "")`

def replace(begin_pos, end_pos, content) #

Replaces the code of the given range with content.

def wrap(begin_pos, end_pos, insert_before, insert_after) #

Inserts the given strings before and after the given range.