class Opal::Nodes::EnsureNode

def compile

def compile
  push_closure if wrap_in_closure?
  push 'try {'
  in_ensure do
    line stmt(body_sexp)
  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 stmt(rescue_else_code)
        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 '}'
  pop_closure if wrap_in_closure?
  if wrap_in_closure?
    if scope.await_encountered
      wrap '(await (async function() { ', '; })())'
    else
      wrap '(function() { ', '; })()'
    end
  end
end