Class: Parser::Source::TreeRewriter
- Extended by:
 - Deprecation
 
- Defined in:
 - sorbet/rbi/parser@3.3.8.0.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_bufferand 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
rangewithcontent. - 
  
    
      #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
      6712  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6712 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
      6729  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6729 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
      6748  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6748 def as_replacements; end  | 
  
#diagnostics ⇒ Diagnostic::Engine
source://parser//lib/parser/source/tree_rewriter.rb#93
      6754  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6754 def diagnostics; end  | 
  
#empty? ⇒ Boolean
Returns true iff no (non trivial) update has been recorded
source://parser//lib/parser/source/tree_rewriter.rb#125
      6762  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6762 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
      6774  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6774 def import!(foreign_rewriter, offset: T.unsafe(nil)); end  | 
  
#in_transaction? ⇒ Boolean
source://parser//lib/parser/source/tree_rewriter.rb#329
      6780  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6780 def in_transaction?; end  | 
  
#insert_after(range, content) ⇒ Rewriter
Shortcut for wrap(range, nil, content)
source://parser//lib/parser/source/tree_rewriter.rb#242
      6791  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6791 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
      6797  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6797 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
      6808  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6808 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
      6814  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6814 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
      6830  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6830 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
      6843  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6843 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
      6852  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6852 def process; end  | 
  
#remove(range) ⇒ Rewriter
Shortcut for replace(range, '')
source://parser//lib/parser/source/tree_rewriter.rb#217
      6862  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6862 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
      6873  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6873 def replace(range, content); end  | 
  
#source_buffer ⇒ Source::Buffer
source://parser//lib/parser/source/tree_rewriter.rb#92
      6879  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6879 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
      6889  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6889 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
      6901  | 
    
      # File 'sorbet/rbi/parser@3.3.8.0.rbi', line 6901 def wrap(range, insert_before, insert_after); end  |