Class: Opal::Nodes::CallNode

Inherits:
Base show all
Defined in:
opal/lib/opal/nodes/call.rb,
opal/lib/mspec/opal/rake_task.rb

Defined Under Namespace

Classes: DependencyResolver

Constant Summary

SPECIALS =
Set.new

Constants included from Helpers

Helpers::RESERVED

Instance Attribute Summary

Attributes inherited from Base

#compiler, #type

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

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

Methods included from Helpers

#current_indent, #empty_line, #indent, #js_falsy, #js_truthy, #js_truthy_optimize, #line, #lvar_to_js, #mid_to_jsid, #property, #reserved?, #variable

Constructor Details

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

Class Method Details

.add_special(name, &handler) ⇒ Object



14
15
16
17
# File 'opal/lib/opal/nodes/call.rb', line 14

def self.add_special(name, &handler)
  SPECIALS << name
  define_method("handle_#{name}", &handler)
end

Instance Method Details

#compileObject



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
# File 'opal/lib/opal/nodes/call.rb', line 19

def compile
  # if we handle this call specially, just do that and return early
  return if self.handle_special

  compiler.method_calls << meth.to_sym

  # if trying to access an lvar in irb mode
  return compile_irb_var if using_irb?

  mid = mid_to_jsid meth.to_s

  splat = arglist[1..-1].any? { |a| a.first == :splat }

  if Sexp === arglist.last and arglist.last.type == :block_pass
    block = arglist.pop
  elsif iter
    block = iter
  end

  tmpfunc = scope.new_temp if block
  tmprecv = scope.new_temp if splat || tmpfunc

  # must do this after assigning temp variables
  block = expr(block) if block

  recv_code = recv(recv_sexp)
  call_recv = s(:js_tmp, tmprecv || recv_code)

  if tmpfunc and !splat
    arglist.insert 1, call_recv
  end

  args = expr(arglist)

  if tmprecv
    push "(#{tmprecv} = ", recv_code, ")#{mid}"
  else
    push recv_code, mid
  end

  if tmpfunc
    unshift "(#{tmpfunc} = "
    push ", #{tmpfunc}._p = ", block, ", #{tmpfunc})"
  end

  if splat
    push ".apply(", (tmprecv || recv_code), ", ", args, ")"
  elsif tmpfunc
    push ".call(", args, ")"
  else
    push "(", args, ")"
  end

  scope.queue_temp tmpfunc if tmpfunc
end

#compile_irb_varObject

Used to generate the code to use this sexp as an ivar var reference



80
81
82
83
84
85
86
# File 'opal/lib/opal/nodes/call.rb', line 80

def compile_irb_var
  with_temp do |tmp|
    lvar = variable(meth)
    call = s(:call, s(:self), meth.intern, s(:arglist))
    push "((#{tmp} = $opal.irb_vars.#{lvar}) == null ? ", expr(call), " : #{tmp})"
  end
end

#handle_specialObject

Handle "special" method calls, e.g. require(). Subclasses can override this method. If this method returns nil, then the method will continue to be generated by CallNode.



97
98
99
100
101
102
103
104
105
106
107
# File 'opal/lib/opal/nodes/call.rb', line 97

def handle_special
  if SPECIALS.include? meth
    if result = __send__("handle_#{meth}")
      push result
    return true
    end
  elsif RuntimeHelpers.compatible?(recvr, meth, arglist)
    push(RuntimeHelpers.new(@sexp, @level, @compiler).compile)
    return true
  end
end

#recv_sexpObject



75
76
77
# File 'opal/lib/opal/nodes/call.rb', line 75

def recv_sexp
  recvr || s(:self)
end

#using_irb?Boolean

a variable reference in irb mode in top scope might be a var ref, or it might be a method call

Returns:

  • (Boolean)


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

def using_irb?
  @compiler.irb? and scope.top? and arglist == s(:arglist) and recvr.nil? and iter.nil?
end