Skip to content

Commit 5d4f57f

Browse files
committed
Support 3.4-style symbols as hash keys
1 parent 77513c6 commit 5d4f57f

File tree

4 files changed

+148
-20
lines changed

4 files changed

+148
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## 3.0 (unreleased)
44
* Require Ruby 3
55
* Relax Ruby version requirement to allow Ruby 4.0
6-
* Support Ruby 3.4 hash inspects (TODO)
6+
* Support Ruby 3.4 hash inspects
77
* Support Ruby 4.0 changes (TODO)
88

99
## 2.2.2

lib/wirb/tokenizer.rb

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,18 @@ def self.run(str)
160160
end
161161

162162
when :class
163-
case c
164-
when /[a-z0-9_]/i
163+
if c =~ /[a-z0-9_]/i
165164
@token << c
166-
else
167-
if @token =~ /^(Infinity|NaN)$/
168-
set_state[:special_number, :repeat]
169-
elsif c ==':' && nc == ':'
170-
pass_state[]
171-
pass[:class_separator, '::']
172-
elsif !(c == ':' && lc == ':')
173-
pass_state[:remove, :repeat]
174-
end
165+
elsif c == ":" && get_previous_state[:hash]
166+
pass_custom_state[:symbol, :remove, :repeat]
167+
@refers_seen[-1] = true
168+
elsif @token =~ /^(Infinity|NaN)$/
169+
set_state[:special_number, :repeat]
170+
elsif c ==':' && nc == ':'
171+
pass_state[]
172+
pass[:class_separator, '::']
173+
elsif !(c == ':' && lc == ':')
174+
pass_state[:remove, :repeat]
175175
end
176176

177177
when :symbol
@@ -208,10 +208,15 @@ def self.run(str)
208208
end
209209

210210
when :string
211-
if c == '"' && ( !( @token =~ /\\+$/; $& ) || $&.size % 2 == 0 ) # allow escaping of " and
212-
pass[:open_string, '"'] # work around \\
213-
pass_state[:remove]
214-
pass[:close_string, '"']
211+
if c == '"' && ( !( @token =~ /\\+$/; $& ) || $&.size % 2 == 0 ) # allow escaping of " and work around \\
212+
if nc == ':' && get_previous_state[:hash]
213+
set_state[:symbol_string, :repeat]
214+
@refers_seen[-1] = true
215+
else
216+
pass[:open_string, '"']
217+
pass_state[:remove]
218+
pass[:close_string, '"']
219+
end
215220
else
216221
@token << c
217222
end
@@ -237,6 +242,9 @@ def self.run(str)
237242
if c =~ /[a-z0-9_]/i
238243
@token << c
239244
pass_custom_state[@token.to_sym, :remove] if %w[nil false true].include?(@token)
245+
elsif c == ":"
246+
pass_custom_state[:symbol, :remove, :repeat]
247+
@refers_seen[-1] = true
240248
else
241249
pass_state[:remove, :repeat]
242250
end

spec/tokenizer_hash_spec.rb

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,71 @@
6767
end
6868
end
6969

70-
please do check({:hallo => {1=>Set[2,3,4]}})
70+
please do check({:Symbol => :value})
7171
if symbol_hash_keys?
72-
fail
7372
tokens.should == [
74-
# TODO
73+
[:open_hash, "{"],
74+
[:symbol, "Symbol"],
75+
[:symbol_prefix, ":"],
76+
[:whitespace, " "],
77+
[:symbol_prefix, ":"],
78+
[:symbol, "value"],
79+
[:close_hash, "}"],
80+
]
81+
else
82+
tokens.should == [
83+
[:open_hash, "{"],
84+
[:symbol_prefix, ":"],
85+
[:symbol, "Symbol"],
86+
[:refers, "=>"],
87+
[:symbol_prefix, ":"],
88+
[:symbol, "value"],
89+
[:close_hash, "}"],
90+
]
91+
end
92+
end
93+
94+
please do check({Module => :value})
95+
tokens.should == [
96+
[:open_hash, "{"],
97+
[:class, "Module"],
98+
([:whitespace, " "] if spaced_hashes?),
99+
[:refers, "=>"],
100+
([:whitespace, " "] if spaced_hashes?),
101+
[:symbol_prefix, ":"],
102+
[:symbol, "value"],
103+
[:close_hash, "}"],
104+
].compact
105+
end
106+
107+
please do check({:hallo => {1=>Set[2,3,4]}})
108+
if symbol_hash_keys?
109+
tokens.should be_like [
110+
[:open_hash, "{"],
111+
[:symbol, "hallo"],
112+
[:symbol_prefix, ":"],
113+
([:whitespace, " "] if spaced_hashes?),
114+
[:open_hash, "{"],
115+
[:number, "1"],
116+
([:whitespace, " "] if spaced_hashes?),
117+
[:refers, "=>"],
118+
([:whitespace, " "] if spaced_hashes?),
119+
[:open_object, "#<"],
120+
[:object_class, "Set"],
121+
[:object_description_prefix, ":"],
122+
[:whitespace, " "],
123+
[:open_set, "{"],
124+
[:number, /\d+/],
125+
[:comma, ","],
126+
[:whitespace, " "],
127+
[:number, /\d+/],
128+
[:comma, ","],
129+
[:whitespace, " "],
130+
[:number, /\d+/],
131+
[:close_set, "}"],
132+
[:close_object, ">"],
133+
[:close_hash, "}"],
134+
[:close_hash, "}"],
75135
]
76136
else
77137
tokens.should be_like [

spec/tokenizer_symbol_spec.rb

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,67 @@
9999

100100
please do check [[:hallo],{:'hallo'=>:'test'}, {:'hallo='=>:'test='}, {:'<'=>9}, {:'<=>'=>9}, {:'<'=>:'<=>'}]
101101
if symbol_hash_keys?
102-
fail
102+
tokens.should == [
103+
[:open_array, "["],
104+
[:open_array, "["],
105+
[:symbol_prefix, ":"],
106+
[:symbol, "hallo"],
107+
[:close_array, "]"],
108+
[:comma, ","],
109+
[:whitespace, " "],
110+
[:open_hash, "{"],
111+
[:symbol, "hallo"],
112+
[:symbol_prefix, ":"],
113+
[:whitespace, " "],
114+
[:symbol_prefix, ":"],
115+
[:symbol, "test"],
116+
[:close_hash, "}"],
117+
[:comma, ","],
118+
[:whitespace, " "],
119+
[:open_hash, "{"],
120+
[:open_symbol_string, "\""],
121+
[:symbol_string, "hallo="],
122+
[:close_symbol_string, "\""],
123+
[:symbol_prefix, ":"],
124+
[:whitespace, " "],
125+
[:symbol_prefix, ":"],
126+
[:symbol, "test="],
127+
[:close_hash, "}"],
128+
[:comma, ","],
129+
[:whitespace, " "],
130+
[:open_hash, "{"],
131+
[:open_symbol_string, "\""],
132+
[:symbol_string, "<"],
133+
[:close_symbol_string, "\""],
134+
[:symbol_prefix, ":"],
135+
[:whitespace, " "],
136+
[:number, "9"],
137+
[:close_hash, "}"],
138+
[:comma, ","],
139+
[:whitespace, " "],
140+
[:open_hash, "{"],
141+
[:open_symbol_string, "\""],
142+
[:symbol_string, "<=>"],
143+
[:close_symbol_string, "\""],
144+
[:symbol_prefix, ":"],
145+
[:whitespace, " "],
146+
[:number, "9"],
147+
[:close_hash, "}"],
148+
[:comma, ","],
149+
[:whitespace, " "],
150+
[:open_hash, "{"],
151+
[:open_symbol_string, "\""],
152+
[:symbol_string, "<"],
153+
[:close_symbol_string, "\""],
154+
[:symbol_prefix, ":"],
155+
[:whitespace, " "],
156+
[:symbol_prefix, ":"],
157+
# [:symbol, "<=>"], # MAYBE fixme
158+
[:symbol, "<"],
159+
[:symbol, "=>"],
160+
[:close_hash, "}"],
161+
[:close_array, "]"],
162+
]
103163
else
104164
tokens.should == [
105165
[:open_array, "["],

0 commit comments

Comments
 (0)