Module: Opal::Nodes::Helpers

Included in:
Base
Defined in:
opal/lib/opal/nodes/helpers.rb

Instance Method Summary collapse

Instance Method Details

#current_indentObject

[View source]

33
34
35
# File 'opal/lib/opal/nodes/helpers.rb', line 33

def current_indent
  compiler.parser_indent
end

#empty_lineObject

[View source]

42
43
44
# File 'opal/lib/opal/nodes/helpers.rb', line 42

def empty_line
  push fragment("\n", loc: false)
end

#indent(&block) ⇒ Object

[View source]

29
30
31
# File 'opal/lib/opal/nodes/helpers.rb', line 29

def indent(&block)
  compiler.indent(&block)
end

#js_truthy(sexp) ⇒ Object

[View source]

46
47
48
49
50
51
52
53
# File 'opal/lib/opal/nodes/helpers.rb', line 46

def js_truthy(sexp)
  if optimize = js_truthy_optimize(sexp)
    return optimize
  end

  helper :truthy
  [fragment('$truthy('), expr(sexp), fragment(')')]
end

#js_truthy_optimize(sexp) ⇒ Object

[View source]

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'opal/lib/opal/nodes/helpers.rb', line 55

def js_truthy_optimize(sexp)
  case sexp.type
  when :send
    receiver, mid, *args = *sexp
    receiver_handler_class = receiver && compiler.handlers[receiver.type]

    # Only operator calls on the truthy_optimize? node classes should be optimized.
    # Monkey patch method calls might return 'self'/aka a bridged instance and need
    # the nil check - see discussion at https://github.com/opal/opal/pull/1097
    allow_optimization_on_type = Compiler::COMPARE.include?(mid.to_s) &&
                                 receiver_handler_class &&
                                 receiver_handler_class.truthy_optimize?

    if allow_optimization_on_type ||
       mid == :block_given?
      expr(sexp)
    elsif args.count == 1
      case mid
      when :==
        helper :eqeq
        compiler.record_method_call mid
        [fragment('$eqeq('), expr(receiver), fragment(', '), expr(args.first), fragment(')')]
      when :===
        helper :eqeqeq
        compiler.record_method_call mid
        [fragment('$eqeqeq('), expr(receiver), fragment(', '), expr(args.first), fragment(')')]
      when :!=
        helper :neqeq
        compiler.record_method_call mid
        [fragment('$neqeq('), expr(receiver), fragment(', '), expr(args.first), fragment(')')]
      end
    elsif args.count == 0
      case mid
      when :!
        helper :not
        compiler.record_method_call mid
        [fragment('$not('), expr(receiver), fragment(')')]
      end
    end
  when :begin
    if sexp.children.count == 1
      js_truthy_optimize(sexp.children.first)
    end
  when :if
    _test, true_body, false_body = *sexp
    if true_body == s(:true)
      # Ensure we recurse the js_truthy call on the `false_body` of the if `expr`.
      # This transforms an expression like:
      #
      # $truthy($truthy(a) || b)
      #
      # Into:
      #
      # $truthy(a) || $truthy(b)
      sexp.meta[:do_js_truthy_on_false_body] = true
      expr(sexp)
    elsif false_body == s(:false)
      sexp.meta[:do_js_truthy_on_true_body] = true
      expr(sexp)
    end
  end
end

#line(*strs) ⇒ Object

[View source]

37
38
39
40
# File 'opal/lib/opal/nodes/helpers.rb', line 37

def line(*strs)
  push fragment("\n#{current_indent}", loc: false)
  push(*strs)
end

#mid_to_jsid(mid) ⇒ Object

Converts a ruby method name into its javascript equivalent for a method/function call. All ruby method names get prefixed with a '$', and if the name is a valid javascript identifier, it will have a '.' prefix (for dot-calling), otherwise it will be wrapped in brackets to use reference notation calling.

[View source]

21
22
23
24
25
26
27
# File 'opal/lib/opal/nodes/helpers.rb', line 21

def mid_to_jsid(mid)
  if %r{\=|\+|\-|\*|\/|\!|\?|<|\>|\&|\||\^|\%|\~|\[|`} =~ mid.to_s
    "['$#{mid}']"
  else
    '.$' + mid
  end
end

#property(name) ⇒ Object

[View source]

8
9
10
# File 'opal/lib/opal/nodes/helpers.rb', line 8

def property(name)
  valid_name?(name) ? ".#{name}" : "[#{name.inspect}]"
end

#valid_name?(name) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

12
13
14
# File 'opal/lib/opal/nodes/helpers.rb', line 12

def valid_name?(name)
  Opal::Rewriters::JsReservedWords.valid_name?(name)
end