Class: Parser::Source::TreeRewriter
- Extended by:
- Deprecation
- Defined in:
- sorbet/rbi/parser@3.3.7.4.rbi
Overview
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).
- wrap ':hello, ' with '(' and ')'
- wrap ', :world' with '(' and ')' => CloberringError
Overlapping deletions:
- remove ':hello, '
- remove ', :world'
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:
- 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 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:
- 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'.
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.
source://parser//lib/parser/source/tree_rewriter.rb#91
Defined Under Namespace
Classes: Action
Constant Summary collapse
- ACTIONS =
source://parser//lib/parser/source/tree_rewriter.rb#391
T.let(T.unsafe(nil), Array)
- DEPRECATION_WARNING =
source://parser//lib/parser/source/tree_rewriter.rb#356
T.let(T.unsafe(nil), String)
- POLICY_TO_LEVEL =
source://parser//lib/parser/source/tree_rewriter.rb#417
T.let(T.unsafe(nil), Hash)
Instance Method Summary collapse
-
#as_nested_actions ⇒ Array<(Symbol, Range, String{, String})>
Returns a representation of the rewriter as nested insertions (:wrap) and replacements.
-
#as_replacements ⇒ Array<Range, String>
Returns a representation of the rewriter as an ordered list of replacements.
-
#diagnostics ⇒ Diagnostic::Engine
source://parser//lib/parser/source/tree_rewriter.rb#93.
-
#empty? ⇒ Boolean
Returns true iff no (non trivial) update has been recorded.
-
#import!(foreign_rewriter, offset: T.unsafe(nil)) ⇒ Rewriter
For special cases where one needs to merge a rewriter attached to a different source_buffer or that needs to be offset.
-
#in_transaction? ⇒ Boolean
source://parser//lib/parser/source/tree_rewriter.rb#329.
-
#initialize(source_buffer, crossing_deletions: T.unsafe(nil), different_replacements: T.unsafe(nil), swallowed_insertions: T.unsafe(nil)) ⇒ TreeRewriter
constructor
source://parser//lib/parser/source/tree_rewriter.rb#98.
-
#insert_after(range, content) ⇒ Rewriter
Shortcut for
wrap(range, nil, content)
. -
#insert_after_multi(range, text) ⇒ Object
deprecated
private
Deprecated.
Use insert_after or wrap
-
#insert_before(range, content) ⇒ Rewriter
Shortcut for
wrap(range, content, nil)
. -
#insert_before_multi(range, text) ⇒ Object
deprecated
private
Deprecated.
Use insert_after or wrap
-
#merge(with) ⇒ Rewriter
Returns a new rewriter that consists of the updates of the received and the given argument.
-
#merge!(with) ⇒ Rewriter
Merges the updates of argument with the receiver.
-
#process ⇒ String
Applies all scheduled changes to the
source_buffer
and returns modified source as a new string. -
#remove(range) ⇒ Rewriter
Shortcut for
replace(range, '')
. -
#replace(range, content) ⇒ Rewriter
Replaces the code of the source range
range
withcontent
. -
#source_buffer ⇒ Source::Buffer
source://parser//lib/parser/source/tree_rewriter.rb#92.
-
#transaction ⇒ Object
Provides a protected block where a sequence of multiple rewrite actions are handled atomically.
-
#wrap(range, insert_before, insert_after) ⇒ Rewriter
Inserts the given strings before and after the given range.
Methods included from Deprecation
warn_of_deprecation, warned_of_deprecation=
Constructor Details
#initialize(source_buffer, crossing_deletions: T.unsafe(nil), different_replacements: T.unsafe(nil), swallowed_insertions: T.unsafe(nil)) ⇒ TreeRewriter
source://parser//lib/parser/source/tree_rewriter.rb#98
6706 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6706 def initialize(source_buffer, crossing_deletions: T.unsafe(nil), different_replacements: T.unsafe(nil), swallowed_insertions: T.unsafe(nil)); end |
Instance Method Details
#as_nested_actions ⇒ Array<(Symbol, Range, String{, String})>
Returns a representation of the rewriter as nested insertions (:wrap) and replacements.
rewriter.as_actions # =>[ [:wrap, 1...10, '(', ')'],
[:wrap, 2...6, '', '!'], # aka "insert_after"
[:replace, 2...4, 'foo'],
[:replace, 5...6, ''], # aka "removal"
],
Contrary to as_replacements
, this representation is sufficient to recreate exactly
the rewriter.
source://parser//lib/parser/source/tree_rewriter.rb#299
6723 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6723 def as_nested_actions; end |
#as_replacements ⇒ Array<Range, String>
Returns a representation of the rewriter as an ordered list of replacements.
rewriter.as_replacements # => [ [1...1, '('],
[2...4, 'foo'],
[5...6, ''],
[6...6, '!'],
[10...10, ')'],
]
This representation is sufficient to recreate the result of process
but it is
not sufficient to recreate completely the rewriter for further merging/actions.
See as_nested_actions
source://parser//lib/parser/source/tree_rewriter.rb#281
6742 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6742 def as_replacements; end |
#diagnostics ⇒ Diagnostic::Engine
source://parser//lib/parser/source/tree_rewriter.rb#93
6748 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6748 def diagnostics; end |
#empty? ⇒ Boolean
Returns true iff no (non trivial) update has been recorded
source://parser//lib/parser/source/tree_rewriter.rb#125
6756 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6756 def empty?; end |
#import!(foreign_rewriter, offset: T.unsafe(nil)) ⇒ Rewriter
For special cases where one needs to merge a rewriter attached to a different source_buffer or that needs to be offset. Policies of the receiver are used.
source://parser//lib/parser/source/tree_rewriter.rb#168
6768 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6768 def import!(foreign_rewriter, offset: T.unsafe(nil)); end |
#in_transaction? ⇒ Boolean
source://parser//lib/parser/source/tree_rewriter.rb#329
6774 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6774 def in_transaction?; end |
#insert_after(range, content) ⇒ Rewriter
Shortcut for wrap(range, nil, content)
source://parser//lib/parser/source/tree_rewriter.rb#242
6785 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6785 def insert_after(range, content); end |
#insert_after_multi(range, text) ⇒ Object
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Use insert_after or wrap
source://parser//lib/parser/source/tree_rewriter.rb#351
6791 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6791 def insert_after_multi(range, text); end |
#insert_before(range, content) ⇒ Rewriter
Shortcut for wrap(range, content, nil)
source://parser//lib/parser/source/tree_rewriter.rb#230
6802 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6802 def insert_before(range, content); end |
#insert_before_multi(range, text) ⇒ Object
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Use insert_after or wrap
source://parser//lib/parser/source/tree_rewriter.rb#342
6808 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6808 def insert_before_multi(range, text); end |
#merge(with) ⇒ Rewriter
Returns a new rewriter that consists of the updates of the received and the given argument. Policies of the receiver are used.
source://parser//lib/parser/source/tree_rewriter.rb#155
6824 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6824 def merge(with); end |
#merge!(with) ⇒ Rewriter
Merges the updates of argument with the receiver. Policies of the receiver are used. This action is atomic in that it won't change the receiver unless it succeeds.
source://parser//lib/parser/source/tree_rewriter.rb#139
6837 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6837 def merge!(with); end |
#process ⇒ String
Applies all scheduled changes to the source_buffer
and returns
modified source as a new string.
source://parser//lib/parser/source/tree_rewriter.rb#252
6846 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6846 def process; end |
#remove(range) ⇒ Rewriter
Shortcut for replace(range, '')
source://parser//lib/parser/source/tree_rewriter.rb#217
6856 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6856 def remove(range); end |
#replace(range, content) ⇒ Rewriter
Replaces the code of the source range range
with content
.
source://parser//lib/parser/source/tree_rewriter.rb#193
6867 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6867 def replace(range, content); end |
#source_buffer ⇒ Source::Buffer
source://parser//lib/parser/source/tree_rewriter.rb#92
6873 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6873 def source_buffer; end |
#transaction ⇒ Object
Provides a protected block where a sequence of multiple rewrite actions are handled atomically. If any of the actions failed by clobbering, all the actions are rolled back. Transactions can be nested.
source://parser//lib/parser/source/tree_rewriter.rb#310
6883 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6883 def transaction; end |
#wrap(range, insert_before, insert_after) ⇒ Rewriter
Inserts the given strings before and after the given range.
source://parser//lib/parser/source/tree_rewriter.rb#206
6895 |
# File 'sorbet/rbi/parser@3.3.7.4.rbi', line 6895 def wrap(range, insert_before, insert_after); end |