Class: Opal::Nodes::HashNode
Constant Summary
Constants included from Helpers
Opal::Nodes::Helpers::BASIC_IDENTIFIER_RULES, Opal::Nodes::Helpers::ES3_RESERVED_WORD_EXCLUSIVE, Opal::Nodes::Helpers::ES51_RESERVED_WORD, Opal::Nodes::Helpers::IMMUTABLE_PROPS, Opal::Nodes::Helpers::PROTO_SPECIAL_METHODS, Opal::Nodes::Helpers::PROTO_SPECIAL_PROPS, Opal::Nodes::Helpers::RESERVED_FUNCTION_NAMES
Instance Attribute Summary collapse
-
#has_kwsplat ⇒ Object
Returns the value of attribute has_kwsplat.
-
#keys ⇒ Object
Returns the value of attribute keys.
-
#values ⇒ Object
Returns the value of attribute values.
Attributes inherited from Base
Instance Method Summary collapse
- #compile ⇒ Object
-
#compile_hash ⇒ Object
Compiles a hash without kwsplats with complex keys.
-
#compile_hash2 ⇒ Object
Compiles a hash without kwsplats and containing only string/symbols as keys.
-
#compile_merge ⇒ Object
Compiles hashes containing kwsplats inside.
-
#extract_kv_pairs_and_kwsplats ⇒ Object
Splits keys/values/kwsplats.
-
#initialize ⇒ HashNode
constructor
A new instance of HashNode.
- #simple_keys? ⇒ Boolean
Methods inherited from Base
#add_gvar, #add_ivar, #add_local, #add_temp, children, #children, #compile_to_fragments, #error, #expr, #expr?, #expr_or_nil, #fragment, handle, handlers, #has_rescue_else?, #helper, #in_ensure, #in_ensure?, #in_while?, #process, #push, #recv, #recv?, #s, #scope, #stmt, #stmt?, truthy_optimize?, #unshift, #while_loop, #with_temp, #wrap
Methods included from Helpers
#current_indent, #empty_line, #indent, #ivar, #js_falsy, #js_truthy, #js_truthy_optimize, #line, #lvar_to_js, #mid_to_jsid, #property, #valid_ivar_name?, #valid_name?, #variable
Constructor Details
#initialize ⇒ HashNode
Returns a new instance of HashNode
10 11 12 13 14 15 |
# File 'opal/lib/opal/nodes/hash.rb', line 10 def initialize(*) super @has_kwsplat = false @keys = [] @values = [] end |
Instance Attribute Details
#has_kwsplat ⇒ Object
Returns the value of attribute has_kwsplat
8 9 10 |
# File 'opal/lib/opal/nodes/hash.rb', line 8 def has_kwsplat @has_kwsplat end |
#keys ⇒ Object
Returns the value of attribute keys
8 9 10 |
# File 'opal/lib/opal/nodes/hash.rb', line 8 def keys @keys end |
#values ⇒ Object
Returns the value of attribute values
8 9 10 |
# File 'opal/lib/opal/nodes/hash.rb', line 8 def values @values end |
Instance Method Details
#compile ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 |
# File 'opal/lib/opal/nodes/hash.rb', line 54 def compile extract_kv_pairs_and_kwsplats if has_kwsplat compile_merge elsif simple_keys? compile_hash2 else compile_hash end end |
#compile_hash ⇒ Object
Compiles a hash without kwsplats with complex keys.
103 104 105 106 107 108 109 110 111 112 |
# File 'opal/lib/opal/nodes/hash.rb', line 103 def compile_hash helper :hash children.each_with_index do |child, idx| push ', ' unless idx == 0 push expr(child) end wrap '$hash(', ')' end |
#compile_hash2 ⇒ Object
Compiles a hash without kwsplats and containing only string/symbols as keys.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'opal/lib/opal/nodes/hash.rb', line 116 def compile_hash2 hash_obj, hash_keys = {}, [] helper :hash2 keys.size.times do |idx| key = keys[idx][1].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 |
#compile_merge ⇒ Object
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
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'opal/lib/opal/nodes/hash.rb', line 72 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 |
#extract_kv_pairs_and_kwsplats ⇒ Object
Splits keys/values/kwsplats
hash like { **{ nested: 1 }, d: 2 } is represetned by sexp: (:hash, (:kwsplat, (:hash, (:sym, :nested), (:int, 1) ) ), (:sym, :d), (:int, 2), ) So k/v pairs and kwsplats can be mixed in any order.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'opal/lib/opal/nodes/hash.rb', line 32 def extract_kv_pairs_and_kwsplats found_key = false children.each do |obj| if obj.type == :kwsplat self.has_kwsplat = true elsif found_key values << obj found_key = false else keys << obj found_key = true end end [keys, values] end |
#simple_keys? ⇒ Boolean
50 51 52 |
# File 'opal/lib/opal/nodes/hash.rb', line 50 def simple_keys? keys.all? { |key| [:sym, :str].include?(key.type) } end |