class Opal::Rewriters::ReturnableLogic
Public Instance Methods
free_tmp()
click to toggle source
# File lib/opal/rewriters/returnable_logic.rb, line 14 def free_tmp @counter -= 1 end
next_tmp()
click to toggle source
# File lib/opal/rewriters/returnable_logic.rb, line 8 def next_tmp @counter ||= 0 @counter += 1 "$ret_or_#{@counter}" end
on_and(node)
click to toggle source
‘a && b` / `a and b`
# File lib/opal/rewriters/returnable_logic.rb, line 63 def on_and(node) lhs, rhs = *node.children check_control_flow!(lhs) if node.meta[:if_test] lhs.meta[:if_test] = rhs.meta[:if_test] = true out = process(node.updated(:if, [lhs, rhs, s(:false)])) else lhs_tmp = next_tmp out = process(node.updated(:if, [s(:lvasgn, lhs_tmp, lhs), rhs, s(:js_tmp, lhs_tmp)])) free_tmp end out end
on_begin(node)
click to toggle source
Parser
sometimes generates parentheses as a begin node. If it’s a single node begin value, then let’s forward the if_test metadata.
Calls superclass method
# File lib/opal/rewriters/returnable_logic.rb, line 81 def on_begin(node) if node.meta[:if_test] && node.children.count == 1 node.children.first.meta[:if_test] = true end node.meta.delete(:if_test) super end
on_case(node)
click to toggle source
# File lib/opal/rewriters/returnable_logic.rb, line 33 def on_case(node) lhs, *whens, els = *node.children els ||= s(:nil) lhs_tmp = next_tmp if lhs out = build_if_from_when(node, lhs, lhs_tmp, whens, els) free_tmp if lhs out end
on_if(node)
click to toggle source
Calls superclass method
# File lib/opal/rewriters/returnable_logic.rb, line 22 def on_if(node) test, = *node.children check_control_flow!(test) # The if_test metadata signifies that we don't care about the return value except if it's # truthy or falsy. And those tests will be carried out by the respective $truthy helper calls. test.meta[:if_test] = true if test super end
on_or(node)
click to toggle source
‘a || b` / `a or b`
# File lib/opal/rewriters/returnable_logic.rb, line 44 def on_or(node) lhs, rhs = *node.children check_control_flow!(lhs) if node.meta[:if_test] # Let's forward the if_test to the lhs and rhs - since we don't care about the exact return # value of our or, we neither do care about a return value of our lhs or rhs. lhs.meta[:if_test] = rhs.meta[:if_test] = true out = process(node.updated(:if, [lhs, s(:true), rhs])) else lhs_tmp = next_tmp out = process(node.updated(:if, [s(:lvasgn, lhs_tmp, lhs), s(:js_tmp, lhs_tmp), rhs])) free_tmp end out end
reset_tmp_counter!()
click to toggle source
# File lib/opal/rewriters/returnable_logic.rb, line 18 def reset_tmp_counter! @counter = nil end
Private Instance Methods
build_if_from_when(node, lhs, lhs_tmp, whens, els)
click to toggle source
# File lib/opal/rewriters/returnable_logic.rb, line 98 def build_if_from_when(node, lhs, lhs_tmp, whens, els) first_when, *next_whens = *whens *parts, expr = *first_when.children rule = build_rule_from_parts(node, lhs, lhs_tmp, parts) first_when.updated(:if, [rule, process(expr), next_whens.empty? ? process(els) : build_if_from_when(nil, nil, lhs_tmp, next_whens, els)]) end
build_rule_from_parts(node, lhs, lhs_tmp, parts)
click to toggle source
# File lib/opal/rewriters/returnable_logic.rb, line 108 def build_rule_from_parts(node, lhs, lhs_tmp, parts) lhs = if node && lhs_tmp node.updated(:lvasgn, [lhs_tmp, process(lhs)]) else s(:js_tmp, lhs_tmp) end first_part, *next_parts = *parts subrule = if first_part.type == :splat splat_on = first_part.children.first iter_val = next_tmp block = s(:send, process(splat_on), :any?, s(:iter, s(:args, s(:arg, iter_val)), build_rule_from_parts(nil, nil, lhs_tmp, [s(:lvar, iter_val)]) ) ) if node && lhs_tmp s(:begin, lhs, block) else block end elsif lhs_tmp s(:send, process(first_part), :===, lhs) else process(first_part) end if next_parts.empty? subrule else s(:if, subrule, s(:true), build_rule_from_parts(nil, nil, lhs_tmp, next_parts)) end end
check_control_flow!(node)
click to toggle source
# File lib/opal/rewriters/returnable_logic.rb, line 91 def check_control_flow!(node) case node.type when :break, :next, :redo, :retry, :return error 'void value expression' end end