class Opal::Nodes::HashNode

Attributes

has_kwsplat[RW]
keys[RW]
values[RW]

Public Class Methods

new(*) click to toggle source
Calls superclass method Opal::Nodes::Base::new
# File lib/opal/nodes/hash.rb, line 12
def initialize(*)
  super
  @has_kwsplat = false
  @keys = []
  @values = []

  children.each do |child|
    case child.type
    when :kwsplat
      @has_kwsplat = true
    when :pair
      @keys << child.children[0]
      @values << child.children[1]
    end
  end
end

Public Instance Methods

compile() click to toggle source
# File lib/opal/nodes/hash.rb, line 33
def compile
  if has_kwsplat
    compile_merge
  else
    compile_hash
  end
end
compile_hash() click to toggle source

Compiles a hash without kwsplats with simple or complex keys.

# File lib/opal/nodes/hash.rb, line 76
def compile_hash
  children.each_with_index do |pair, idx|
    key, value = pair.children
    push ', ' unless idx == 0
    if %i[sym str].include?(key.type)
      push "[#{key.children[0].to_s.inspect}", ', ', expr(value), ']'
    else
      push '[', expr(key), ', ', expr(value), ']'
    end
  end

  if keys.empty?
    push '(new Map())'
  elsif simple_keys?
    wrap '(new Map([', ']))'
  else
    helper :hash_rehash
    wrap '$hash_rehash(new Map([', ']))'
  end
end
compile_merge() click to toggle source

Compiles hashes containing kwsplats inside. hash like { **{ nested: 1 }, a: 1, **{ nested: 2} } should be compiled to { nested: 1}.merge(a: 1).merge(nested: 2) Each kwsplat overrides previosly defined keys Hash k/v pairs override previously defined kwsplat values

# File lib/opal/nodes/hash.rb, line 47
def compile_merge
  result, seq = [], []

  children.each do |child|
    if child.type == :kwsplat
      unless seq.empty?
        result << expr(s(:hash, *seq))
      end
      result << expr(child)
      seq = []
    else
      seq << child
    end
  end
  unless seq.empty?
    result << expr(s(:hash, *seq))
  end

  result.each_with_index do |fragment, idx|
    if idx == 0
      push fragment
    else
      push '.$merge(', fragment, ')'
    end
  end
end
simple_keys?() click to toggle source
# File lib/opal/nodes/hash.rb, line 29
def simple_keys?
  keys.all? { |key| %i[sym str int].include?(key.type) }
end