Class: Opal::Nodes::EnsureNode

Inherits:
Base
  • Object
show all
Defined in:
opal/lib/opal/nodes/rescue.rb

Constant Summary

Constants included from Helpers

Helpers::BASIC_IDENTIFIER_RULES, Helpers::ES3_RESERVED_WORD_EXCLUSIVE, Helpers::ES51_RESERVED_WORD, Helpers::IMMUTABLE_PROPS, Helpers::PROTO_SPECIAL_METHODS, Helpers::PROTO_SPECIAL_PROPS, Helpers::RESERVED_FUNCTION_NAMES

Instance Attribute Summary

Attributes inherited from Base

#compiler, #type

Instance Method Summary collapse

Methods inherited from Base

#add_gvar, #add_ivar, #add_local, #add_temp, #children, children, #compile_to_fragments, #error, #expr, #expr?, #expr_or_nil, #fragment, handle, handlers, #has_rescue_else?, #helper, #in_ensure, #in_ensure?, #in_while?, #initialize, #process, #push, #recv, #recv?, #s, #scope, #stmt, #stmt?, truthy_optimize?, #unshift, #while_loop, #with_temp, #wrap

Methods included from Helpers

#current_indent, #empty_line, #indent, #ivar, #js_falsy, #js_truthy, #js_truthy_optimize, #line, #lvar_to_js, #mid_to_jsid, #property, #valid_ivar_name?, #valid_name?, #variable

Constructor Details

This class inherits a constructor from Opal::Nodes::Base

Instance Method Details

#body_sexpObject



79
80
81
82
83
84
85
86
87
88
# File 'opal/lib/opal/nodes/rescue.rb', line 79

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

#compileObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'opal/lib/opal/nodes/rescue.rb', line 36

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

#ensr_sexpObject



90
91
92
# File 'opal/lib/opal/nodes/rescue.rb', line 90

def ensr_sexp
  ensr || s(:nil)
end

#wrap_in_closure?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'opal/lib/opal/nodes/rescue.rb', line 94

def wrap_in_closure?
  recv? or expr? or has_rescue_else?
end