Module: Ruby2JS::Filter::Functions

Includes:
SEXP
Defined in:
lib/ruby2js/filter/functions.rb

Instance Method Summary collapse

Methods included from SEXP

#s

Instance Method Details

#on_send(node) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/ruby2js/filter/functions.rb', line 8

def on_send(node)
  target = process(node.children.first)
  args = process_all(node.children[2..-1])

  if node.children[1] == :to_s
    s(:send, target, :toString, *args)

  elsif node.children[1] == :to_i
    node.updated nil, [nil, :parseInt, target, *args]

  elsif node.children[1] == :to_f
    node.updated nil, [nil, :parseFloat, target, *args]

  elsif node.children[1] == :sub and node.children.length == 4
    source, method, before, after = node.children
    node.updated nil, [source, :replace, before, after]

  elsif node.children[1] == :gsub and node.children.length == 4
    source, method, before, after = node.children
    if before.type == :regexp
      before = s(:regexp, before.children.first,
        s(:regopt, :g, *before.children[1]))
    elsif before.type == :str
      before = s(:regexp, s(:str, Regexp.escape(before.children.first)),
        s(:regopt, :g))
    end
    node.updated nil, [source, :replace, before, after]

  elsif node.children[1] == :each
    if @each # disable `each` mapping, see jquery filter for an example
      super
    else
      node.updated nil, [target, :forEach, *args]
    end

  elsif node.children[0..1] == [nil, :puts]
    s(:send, s(:attr, nil, :console), :log, *node.children[2..-1])

  elsif node.children[1..-1] == [:first]
    node.updated nil, [node.children[0], :[], s(:int, 0)]

  elsif node.children[1..-1] == [:last]
    on_send node.updated nil, [node.children[0], :[], s(:int, -1)]

  elsif node.children[1] == :[] and node.children.length == 3
    source = node.children[0]
    index = node.children[2]

    # resolve negative literal indexes
    i = proc do |index|
      if index.type == :int and index.children.first < 0
        s(:send, s(:attr, source, :length), :-, 
          s(:int, -index.children.first))
      else
        index
      end
    end

    if index.type == :int and index.children.first < 0
      node.updated nil, [source, :[], i.(index)]

    elsif index.type == :erange
      start, finish = index.children
      node.updated nil, [source, :slice, i.(start), i.(finish)]

    elsif index.type == :irange
      start, finish = index.children
      start = i.(start)
      if finish.type == :int
        if finish.children.first == -1
          finish = s(:attr, source, :length)
        else
          finish = i.(s(:int, finish.children.first+1))
        end
      else
        finish = s(:send, finish, :+, s(:int, 1))
      end
      node.updated nil, [source, :slice, start, finish]

    else
      super
    end

  elsif node.children[1] == :each_with_index
    node.updated nil, [target, :forEach, *args]

  else
    super
  end
end