Skip to content

Commit b771c7f

Browse files
committed
RipperCompat: add array-refs, assigns, symbols, strings
1 parent 4a09454 commit b771c7f

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

lib/prism/ripper_compat.rb

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ def visit_array_node(node)
120120
# nodes -- unary and binary operators, "command" calls with
121121
# no parentheses, and call/fcall/vcall.
122122
def visit_call_node(node)
123+
return visit_aref_node(node) if node.name == :[]
124+
return visit_aref_field_node(node) if node.name == :[]=
125+
123126
if node.variable_call?
124127
raise NotImplementedError unless node.receiver.nil?
125128

@@ -153,6 +156,13 @@ def visit_call_node(node)
153156
end
154157
end
155158

159+
# Visit a LocalVariableWriteNode.
160+
def visit_local_variable_write_node(node)
161+
bounds(node.name_loc)
162+
ident_val = on_ident(node.name.to_s)
163+
on_assign(on_var_field(ident_val), visit(node.value))
164+
end
165+
156166
# Visit a LocalVariableAndWriteNode.
157167
def visit_local_variable_and_write_node(node)
158168
visit_binary_op_assign(node)
@@ -299,6 +309,59 @@ def visit_rational_node(node)
299309
visit_number(node) { |text| on_rational(text) }
300310
end
301311

312+
# Visit a StringNode node.
313+
def visit_string_node(node)
314+
bounds(node.content_loc)
315+
tstring_val = on_tstring_content(node.unescaped.to_s)
316+
on_string_literal(on_string_add(on_string_content, tstring_val))
317+
end
318+
319+
# Visit an XStringNode node.
320+
def visit_x_string_node(node)
321+
bounds(node.content_loc)
322+
tstring_val = on_tstring_content(node.unescaped.to_s)
323+
on_xstring_literal(on_xstring_add(on_xstring_new, tstring_val))
324+
end
325+
326+
# Visit an InterpolatedStringNode node.
327+
def visit_interpolated_string_node(node)
328+
parts = node.parts.map do |part|
329+
case part
330+
when StringNode
331+
bounds(part.content_loc)
332+
on_tstring_content(part.content)
333+
when EmbeddedStatementsNode
334+
on_string_embexpr(visit(part))
335+
else
336+
raise NotImplementedError, "Unexpected node type in InterpolatedStringNode"
337+
end
338+
end
339+
340+
string_list = parts.inject(on_string_content) do |items, item|
341+
on_string_add(items, item)
342+
end
343+
344+
on_string_literal(string_list)
345+
end
346+
347+
# Visit an EmbeddedStatementsNode node.
348+
def visit_embedded_statements_node(node)
349+
visit(node.statements)
350+
end
351+
352+
# Visit a SymbolNode node.
353+
def visit_symbol_node(node)
354+
if node.opening && ['"', "'", "("].include?(node.opening[-1])
355+
bounds(node.value_loc)
356+
tstring_val = on_tstring_content(node.value.to_s)
357+
return on_dyna_symbol(on_string_add(on_string_content, tstring_val))
358+
end
359+
360+
bounds(node.value_loc)
361+
ident_val = on_ident(node.value.to_s)
362+
on_symbol_literal(on_symbol(ident_val))
363+
end
364+
302365
# Visit a StatementsNode node.
303366
def visit_statements_node(node)
304367
bounds(node.location)
@@ -406,6 +469,23 @@ def visit_binary_op_assign(node, operator: node.operator)
406469
on_opassign(on_var_field(ident_val), op_val, visit(node.value))
407470
end
408471

472+
# In Prism this is a CallNode with :[] as the operator.
473+
# In Ripper it's an :aref.
474+
def visit_aref_node(node)
475+
first_arg_val = visit(node.arguments.arguments[0])
476+
args_val = on_args_add_block(on_args_add(on_args_new, first_arg_val), false)
477+
on_aref(visit(node.receiver), args_val)
478+
end
479+
480+
# In Prism this is a CallNode with :[]= as the operator.
481+
# In Ripper it's an :aref_field.
482+
def visit_aref_field_node(node)
483+
first_arg_val = visit(node.arguments.arguments[0])
484+
args_val = on_args_add_block(on_args_add(on_args_new, first_arg_val), false)
485+
assign_val = visit(node.arguments.arguments[1])
486+
on_assign(on_aref_field(visit(node.receiver), args_val), assign_val)
487+
end
488+
409489
# Visit a node that represents a number. We need to explicitly handle the
410490
# unary - operator.
411491
def visit_number(node)

test/prism/ripper_compat_test.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,38 @@ def test_op_assign
110110
assert_equivalent("a /= b")
111111
end
112112

113+
def test_arrays
114+
assert_equivalent("[1, 2, 7]")
115+
assert_equivalent("[1, [2, 7]]")
116+
end
117+
118+
def test_array_refs
119+
assert_equivalent("a[1]")
120+
assert_equivalent("a[1] = 7")
121+
end
122+
123+
def test_strings
124+
assert_equivalent("'a'")
125+
assert_equivalent("'a\01'")
126+
assert_equivalent("`a`")
127+
assert_equivalent("`a\07`")
128+
assert_equivalent('"a#{1}c"')
129+
assert_equivalent('"a#{1}b#{2}c"')
130+
assert_equivalent("`f\oo`")
131+
end
132+
133+
def test_symbols
134+
assert_equivalent(":a")
135+
assert_equivalent(":'a'")
136+
assert_equivalent(':"a"')
137+
assert_equivalent("%s(foo)")
138+
end
139+
140+
def test_assign
141+
assert_equivalent("a = b")
142+
assert_equivalent("a = 1")
143+
end
144+
113145
private
114146

115147
def assert_equivalent(source)

0 commit comments

Comments
 (0)