summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Gibbs <[email protected]>2024-02-08 13:39:53 +0000
committergit <[email protected]>2024-02-09 19:49:27 +0000
commitf635b4dd0e8a54ebd0aff7fbabd729fb4ad26606 (patch)
tree1dc64c1e7b57590e4fc6f572765d48948296280a
parent717adb564b4dd4a7e34b7b4b734795d7eb272c89 (diff)
[ruby/prism] RipperCompat: add array-refs, assigns, symbols, strings
https://github.com/ruby/prism/commit/b771c7f2ec
-rw-r--r--lib/prism/ripper_compat.rb80
-rw-r--r--test/prism/ripper_compat_test.rb32
2 files changed, 112 insertions, 0 deletions
diff --git a/lib/prism/ripper_compat.rb b/lib/prism/ripper_compat.rb
index 6298fa8c0f..5d488c0960 100644
--- a/lib/prism/ripper_compat.rb
+++ b/lib/prism/ripper_compat.rb
@@ -120,6 +120,9 @@ module Prism
# nodes -- unary and binary operators, "command" calls with
# no parentheses, and call/fcall/vcall.
def visit_call_node(node)
+ return visit_aref_node(node) if node.name == :[]
+ return visit_aref_field_node(node) if node.name == :[]=
+
if node.variable_call?
raise NotImplementedError unless node.receiver.nil?
@@ -153,6 +156,13 @@ module Prism
end
end
+ # Visit a LocalVariableWriteNode.
+ def visit_local_variable_write_node(node)
+ bounds(node.name_loc)
+ ident_val = on_ident(node.name.to_s)
+ on_assign(on_var_field(ident_val), visit(node.value))
+ end
+
# Visit a LocalVariableAndWriteNode.
def visit_local_variable_and_write_node(node)
visit_binary_op_assign(node)
@@ -299,6 +309,59 @@ module Prism
visit_number(node) { |text| on_rational(text) }
end
+ # Visit a StringNode node.
+ def visit_string_node(node)
+ bounds(node.content_loc)
+ tstring_val = on_tstring_content(node.unescaped.to_s)
+ on_string_literal(on_string_add(on_string_content, tstring_val))
+ end
+
+ # Visit an XStringNode node.
+ def visit_x_string_node(node)
+ bounds(node.content_loc)
+ tstring_val = on_tstring_content(node.unescaped.to_s)
+ on_xstring_literal(on_xstring_add(on_xstring_new, tstring_val))
+ end
+
+ # Visit an InterpolatedStringNode node.
+ def visit_interpolated_string_node(node)
+ parts = node.parts.map do |part|
+ case part
+ when StringNode
+ bounds(part.content_loc)
+ on_tstring_content(part.content)
+ when EmbeddedStatementsNode
+ on_string_embexpr(visit(part))
+ else
+ raise NotImplementedError, "Unexpected node type in InterpolatedStringNode"
+ end
+ end
+
+ string_list = parts.inject(on_string_content) do |items, item|
+ on_string_add(items, item)
+ end
+
+ on_string_literal(string_list)
+ end
+
+ # Visit an EmbeddedStatementsNode node.
+ def visit_embedded_statements_node(node)
+ visit(node.statements)
+ end
+
+ # Visit a SymbolNode node.
+ def visit_symbol_node(node)
+ if node.opening && ['"', "'", "("].include?(node.opening[-1])
+ bounds(node.value_loc)
+ tstring_val = on_tstring_content(node.value.to_s)
+ return on_dyna_symbol(on_string_add(on_string_content, tstring_val))
+ end
+
+ bounds(node.value_loc)
+ ident_val = on_ident(node.value.to_s)
+ on_symbol_literal(on_symbol(ident_val))
+ end
+
# Visit a StatementsNode node.
def visit_statements_node(node)
bounds(node.location)
@@ -406,6 +469,23 @@ module Prism
on_opassign(on_var_field(ident_val), op_val, visit(node.value))
end
+ # In Prism this is a CallNode with :[] as the operator.
+ # In Ripper it's an :aref.
+ def visit_aref_node(node)
+ first_arg_val = visit(node.arguments.arguments[0])
+ args_val = on_args_add_block(on_args_add(on_args_new, first_arg_val), false)
+ on_aref(visit(node.receiver), args_val)
+ end
+
+ # In Prism this is a CallNode with :[]= as the operator.
+ # In Ripper it's an :aref_field.
+ def visit_aref_field_node(node)
+ first_arg_val = visit(node.arguments.arguments[0])
+ args_val = on_args_add_block(on_args_add(on_args_new, first_arg_val), false)
+ assign_val = visit(node.arguments.arguments[1])
+ on_assign(on_aref_field(visit(node.receiver), args_val), assign_val)
+ end
+
# Visit a node that represents a number. We need to explicitly handle the
# unary - operator.
def visit_number(node)
diff --git a/test/prism/ripper_compat_test.rb b/test/prism/ripper_compat_test.rb
index c8fc208dff..40c609d58c 100644
--- a/test/prism/ripper_compat_test.rb
+++ b/test/prism/ripper_compat_test.rb
@@ -110,6 +110,38 @@ module Prism
assert_equivalent("a /= b")
end
+ def test_arrays
+ assert_equivalent("[1, 2, 7]")
+ assert_equivalent("[1, [2, 7]]")
+ end
+
+ def test_array_refs
+ assert_equivalent("a[1]")
+ assert_equivalent("a[1] = 7")
+ end
+
+ def test_strings
+ assert_equivalent("'a'")
+ assert_equivalent("'a\01'")
+ assert_equivalent("`a`")
+ assert_equivalent("`a\07`")
+ assert_equivalent('"a#{1}c"')
+ assert_equivalent('"a#{1}b#{2}c"')
+ assert_equivalent("`f\oo`")
+ end
+
+ def test_symbols
+ assert_equivalent(":a")
+ assert_equivalent(":'a'")
+ assert_equivalent(':"a"')
+ assert_equivalent("%s(foo)")
+ end
+
+ def test_assign
+ assert_equivalent("a = b")
+ assert_equivalent("a = 1")
+ end
+
private
def assert_equivalent(source)