class Opal::Nodes::EnsureNode
def body_sexp
def body_sexp if wrap_in_closure? sexp = compiler.returns(begn) # 'rescue' is an edge case that should be compiled to # try { return function(){ ..rescue through try/catch.. }() } sexp.type == :rescue ? s(:js_return, sexp) : sexp else sexp = begn end end
def compile
def compile push "try {" in_ensure do line compiler.process(body_sexp, @level) end line "} finally {" indent do if has_rescue_else? # $no_errors indicates thate there were no error raised unshift "var $no_errors = true; " # when there's a begin;rescue;else;ensure;end statement, # ruby returns a result of the 'else' branch # but invokes it before 'ensure'. # so, here we # 1. save the result of calling else to $rescue_else_result # 2. call ensure # 2. return $rescue_else_result line "var $rescue_else_result;" line "if ($no_errors) { " indent do line "$rescue_else_result = (function() {" indent do line compiler.process(compiler.returns(scope.rescue_else_sexp), @level) end line "})();" end line "}" line compiler.process(ensr_sexp, @level) line "if ($no_errors) { return $rescue_else_result; }" else line compiler.process(ensr_sexp, @level) end end line "}" wrap '(function() { ', '; })()' if wrap_in_closure? end
def ensr_sexp
def ensr_sexp ensr || s(:nil) end
def wrap_in_closure?
def wrap_in_closure? recv? or expr? or has_rescue_else? end