Class: Opal::Rewriters::ThrowerFinder
  
  
  
  
  
    - Inherits:
- 
      Base
      
        
          - Object
- Parser::AST::Processor
- Base
- Opal::Rewriters::ThrowerFinder
 show all
    - Defined in:
- opal/lib/opal/rewriters/thrower_finder.rb
 
Overview
  
    ThrowerFinder attempts to track the presence of throwers, like
break, redo, so we can make an informed guess in the early
compilation phase before traversing other nodes whether we
want to track a closure. Tracking a closure is often a deoptimizing
step, so we want to get that knowledge earlier.
   
 
  
  Constant Summary
  
  Constants inherited
     from Base
  Base::DUMMY_LOCATION
  Instance Attribute Summary
  
  Attributes inherited from Base
  #current_node
  
    
      Instance Method Summary
      collapse
    
    
  
  
  
  
  
  
  
  
  
  Methods inherited from Base
  #append_to_body, #begin_with_stmts, #dynamic!, #error, #on_top, #prepend_to_body, #process, s, #s, #stmts_of
  
  Constructor Details
  
    
  
  
    Returns a new instance of ThrowerFinder.
   
 
  
  
    | 
12
13
14
15
16
17 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 12
def initialize
  @break_stack = []
  @redo_stack = []
  @retry_stack = []
  @rescue_else_stack = []
end | 
 
  
 
  
    Instance Method Details
    
      
  
  
    #on_break(node)  ⇒ Object 
  
  
  
  
    | 
19
20
21
22 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 19
def on_break(node)
  tracking(:break, @break_stack)
  super
end | 
 
    
      
  
  
    #on_defined(node)  ⇒ Object 
  
  
  
  
    ignore throwers inside defined
   
 
  
  
    | 
49
50
51
52
53
54
55 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 49
def on_defined(node)
  pushing(
    [@redo_stack, nil],
    [@break_stack, nil],
    [@retry_stack, nil]
  ) { super }
end | 
 
    
      
  
  
    #on_ensure(node)  ⇒ Object 
  
  
  
  
    In Opal we handle rescue-else either in ensure or in
rescue. If ensure is present, we handle it in ensure.
Otherwise we handle it in rescue. ensure is always
above a rescue. This logic is about tracking if a given
ensure node should expect a rescue-else inside a
rescue node.
   
 
  
  
    | 
63
64
65 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 63
def on_ensure(node)
  pushing([@rescue_else_stack, node]) { super }
end | 
 
    
      
  
  
    #on_for(node)  ⇒ Object 
  
  
  
  
    | 
42 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 42
def on_for(node);        on_loop(node) { super }; end | 
 
    
      
  
  
    #on_iter(node)  ⇒ Object 
  
  
  
  
    | 
34
35
36 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 34
def on_iter(node)
  pushing([@break_stack, node]) { super }
end | 
 
    
      
  
  
    #on_loop(node, &block)  ⇒ Object 
  
  
  
  
    | 
38
39
40 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 38
def on_loop(node, &block)
  pushing([@redo_stack, node], [@break_stack, nil], &block)
end | 
 
    
      
  
  
    #on_redo(node)  ⇒ Object 
  
  
  
  
    | 
24
25
26
27 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 24
def on_redo(node)
  tracking(:redo, @redo_stack)
  super
end | 
 
    
      
  
  
    #on_rescue(node)  ⇒ Object 
  
  
  
  
    | 
67
68
69
70
71
72
73 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 67
def on_rescue(node)
  if node.children[1..-1].detect { |sexp| sexp && sexp.type != :resbody }
    tracking(:rescue_else, @rescue_else_stack)
  end
  pushing([@rescue_else_stack, nil], [@retry_stack, node]) { super }
end | 
 
    
      
  
  
    #on_retry(node)  ⇒ Object 
  
  
  
  
    | 
29
30
31
32 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 29
def on_retry(node)
  tracking(:retry, @retry_stack)
  super
end | 
 
    
      
  
  
    #on_until(node)  ⇒ Object 
  
  
  
  
    | 
45 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 45
def on_until(node);      on_loop(node) { super }; end | 
 
    
      
  
  
    #on_until_post(node)  ⇒ Object 
  
  
  
  
    | 
46 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 46
def on_until_post(node); on_loop(node) { super }; end | 
 
    
      
  
  
    #on_while(node)  ⇒ Object 
  
  
  
  
    | 
43 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 43
def on_while(node);      on_loop(node) { super }; end | 
 
    
      
  
  
    #on_while_post(node)  ⇒ Object 
  
  
  
  
    | 
44 | # File 'opal/lib/opal/rewriters/thrower_finder.rb', line 44
def on_while_post(node); on_loop(node) { super }; end |