class Opal::Nodes::HashNode

def compile

def compile
  if has_kwsplat
    compile_merge
  elsif simple_keys?
    compile_hash2
  else
    compile_hash
  end
end

def compile_hash

with complex keys.
Compiles a hash without kwsplats
def compile_hash
  helper :hash
  children.each_with_index do |pair, idx|
    key, value = pair.children
    push ', ' unless idx == 0
    push expr(key), ', ', expr(value)
  end
  wrap '$hash(', ')'
end

def compile_hash2

and containing **only** string/symbols as keys.
Compiles a hash without kwsplats
def compile_hash2
  hash_obj, hash_keys = {}, []
  helper :hash2
  keys.size.times do |idx|
    key = keys[idx].children[0].to_s.inspect
    hash_keys << key unless hash_obj.include? key
    hash_obj[key] = expr(values[idx])
  end
  hash_keys.each_with_index do |key, idx|
    push ', ' unless idx == 0
    push "#{key}: "
    push hash_obj[key]
  end
  wrap "$hash2([#{hash_keys.join ', '}], {", '})'
end

def compile_merge

Hash k/v pairs override previously defined kwsplat values
Each kwsplat overrides previosly defined keys
{ nested: 1}.merge(a: 1).merge(nested: 2)
should be compiled to
hash like { **{ nested: 1 }, a: 1, **{ nested: 2} }
Compiles hashes containing kwsplats inside.
def compile_merge
  helper :hash
  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

def initialize(*)

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

def simple_keys?

def simple_keys?
  keys.all? { |key| %i[sym str].include?(key.type) }
end