Class: Opal::Rewriters::LogicalOperatorAssignment::SendHandler

Inherits:
Opal::Rewriters::LogicalOperatorAssignment show all
Defined in:
opal/lib/opal/rewriters/logical_operator_assignment.rb

Overview

Takes recvr.meth ||= rhs Produces recvr.meth || recvr.meth = rhs (lhs is a recvr.meth)

Constant Summary

Constants inherited from Opal::Rewriters::LogicalOperatorAssignment

ASSIGNMENT_STRING_NODE, ClassVariableHandler, ConstantHandler, GET_SET, GlobalVariableHandler, HANDLERS, InstanceVariableHandler, LocalVariableHandler

Constants inherited from Base

Base::DUMMY_LOCATION

Instance Attribute Summary

Attributes inherited from Base

#current_node

Class Method Summary collapse

Methods inherited from Opal::Rewriters::LogicalOperatorAssignment

new_temp, #on_and_asgn, #on_defined?, #on_or_asgn, reset_tmp_counter!

Methods inherited from Base

#append_to_body, #begin_with_stmts, #dynamic!, #error, #on_top, #prepend_to_body, #process, s, #s, #stmts_of

Class Method Details

.call(lhs, rhs, root_type) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'opal/lib/opal/rewriters/logical_operator_assignment.rb', line 64

def self.call(lhs, rhs, root_type)
  recvr, reader_method, *args = *lhs

  # If recvr is a complex expression it must be cached.
  # MRI calls recvr in `recvr.meth ||= rhs` only once.
  if recvr && recvr.type == :send
    recvr_tmp = new_temp
    cache_recvr = s(:lvasgn, recvr_tmp, recvr)                         # $tmp = recvr
    recvr = s(:js_tmp, recvr_tmp)
  end

  writer_method = :"#{reader_method}="

  call_reader = lhs.updated(:send, [recvr, reader_method, *args])      # $tmp.meth
  call_writer = lhs.updated(:send, [recvr, writer_method, *args, rhs]) # $tmp.meth = rhs
  get_or_set = s(root_type, call_reader, call_writer)

  if cache_recvr
    s(:begin, cache_recvr, get_or_set)
  else
    get_or_set
  end
end