[フレーム]

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

#initializeThrowerFinder

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

AltStyle によって変換されたページ (->オリジナル) /