Class: Opal::Rewriters::LogicalOperatorAssignment

Inherits:
Base
  • Object
show all
Defined in:
opal/lib/opal/rewriters/logical_operator_assignment.rb

Direct Known Subclasses

ConditionalSendHandler, SendHandler

Defined Under Namespace

Classes: ConditionalSendHandler, SendHandler

Constant Summary collapse

GET_SET =
->(get_type, set_type) {
  ->(lhs, rhs, root_type) {
    get_node = lhs.updated(get_type)              # lhs
    condition_node = s(root_type, get_node, rhs)  # lhs || rhs

    if %i[const cvar].include?(get_type) && root_type == :or
      # defined?(lhs)
      defined_node = s(:defined?, get_node)
      # LHS = defined?(LHS) ? (LHS || rhs) : rhs
      condition_node = s(:if, defined_node, s(:begin, condition_node), rhs)
    end

    lhs.updated(set_type, [*lhs, condition_node]) # lhs = lhs || rhs
  }
}
LocalVariableHandler =

Takes lhs ||= rhs Produces lhs = lhs || rhs

InstanceVariableHandler =

Takes @lhs ||= rhs Produces @lhs = @lhs || rhs

ConstantHandler =

Takes LHS ||= rhs Produces LHS = defined?(LHS) ? (LHS || rhs) : rhs

Takes LHS &&= rhs Produces LHS = LHS && rhs

GlobalVariableHandler =

Takes $lhs ||= rhs Produces $lhs = $lhs || rhs

ClassVariableHandler =

Takes @@lhs ||= rhs Produces @@lhs = defined?(@@lhs) ? (@@lhs || rhs) : rhs

Takes @@lhs &&= rhs Produces @@lhs = @@lhs && rhs

HANDLERS =
{
  lvasgn: LocalVariableHandler,
  ivasgn: InstanceVariableHandler,
  casgn:  ConstantHandler,
  gvasgn: GlobalVariableHandler,
  cvasgn: ClassVariableHandler,
  send:   SendHandler,
  csend:  ConditionalSendHandler
}.freeze
ASSIGNMENT_STRING_NODE =
s(:str, 'assignment')

Constants inherited from Base

Base::DUMMY_LOCATION

Instance Attribute Summary

Attributes inherited from Base

#current_node

Class Method Summary collapse

Instance Method Summary collapse

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

.new_tempObject



12
13
14
15
16
# File 'opal/lib/opal/rewriters/logical_operator_assignment.rb', line 12

def self.new_temp
  @@counter ||= 0
  @@counter += 1
  :"$logical_op_recvr_tmp_#{@@counter}"
end

.reset_tmp_counter!Object



8
9
10
# File 'opal/lib/opal/rewriters/logical_operator_assignment.rb', line 8

def self.reset_tmp_counter!
  @@counter = 0
end

Instance Method Details

#on_and_asgn(node) ⇒ Object

lhs &&= rhs



140
141
142
143
144
145
146
147
148
# File 'opal/lib/opal/rewriters/logical_operator_assignment.rb', line 140

def on_and_asgn(node)
  lhs, rhs = *node

  result = HANDLERS
           .fetch(lhs.type) { error "cannot handle LHS type: #{lhs.type}" }
           .call(lhs, rhs, :and)

  process(result)
end

#on_defined?(node) ⇒ Boolean

Rewrites any or_asgn and and_asgn node like defined?(a ||= 1) and defined?(a &&= 1) to a static "assignment" string node

Returns:

  • (Boolean)


157
158
159
160
161
162
163
164
# File 'opal/lib/opal/rewriters/logical_operator_assignment.rb', line 157

def on_defined?(node)
  inner, _ = *node
  if %i[or_asgn and_asgn].include?(inner.type)
    ASSIGNMENT_STRING_NODE
  else
    super(node)
  end
end

#on_or_asgn(node) ⇒ Object

lhs ||= rhs



129
130
131
132
133
134
135
136
137
# File 'opal/lib/opal/rewriters/logical_operator_assignment.rb', line 129

def on_or_asgn(node)
  lhs, rhs = *node

  result = HANDLERS
           .fetch(lhs.type) { error "cannot handle LHS type: #{lhs.type}" }
           .call(lhs, rhs, :or)

  process(result)
end