class Opal::Nodes::CallNode
def self.add_special(name, &handler)
def self.add_special(name, &handler) SPECIALS << name define_method("handle_#{name}", &handler) end
def compile
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
def compile_irb_var
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
def handle_special
this method. If this method returns nil, then the method will continue
Handle "special" method calls, e.g. require(). Subclasses can override
def handle_special if SPECIALS.include? meth if result = __send__("handle_#{meth}") push result return true end end end
def recv_sexp
def recv_sexp recvr || s(:self) end
def using_irb?
a variable reference in irb mode in top scope might be a var ref,
def using_irb? @compiler.irb? and scope.top? and arglist == s(:arglist) and recvr.nil? and iter.nil? end