summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-02-06 21:31:12 -0500
committergit <svn-admin@ruby-lang.org>2024-02-07 03:21:02 +0000
commit2dba441397d338617e1b605104d8b42b5311a482 (patch)
treed5ea76a529cdd2b46c7c3b45e0045058c1146739
parent64b6a018a38f200c957fdbbe7d0cbe0e64781c9f (diff)
[ruby/prism] Even more ripper compat
https://github.com/ruby/prism/commit/47a602dc1c
-rw-r--r--lib/prism/ripper_compat.rb127
-rw-r--r--test/prism/ripper_compat_test.rb18
2 files changed, 92 insertions, 53 deletions
diff --git a/lib/prism/ripper_compat.rb b/lib/prism/ripper_compat.rb
index 739d587541..912114cfef 100644
--- a/lib/prism/ripper_compat.rb
+++ b/lib/prism/ripper_compat.rb
@@ -97,6 +97,8 @@ module Prism
result.errors.each do |error|
on_parse_error(error.message)
end
+
+ nil
else
result.value.accept(self)
end
@@ -106,14 +108,22 @@ module Prism
# Visitor methods
############################################################################
- # Visit a CallNode node.
- def visit_call_node(node)
+ # Visit an ArrayNode node.
+ def visit_array_node(node)
+ elements = visit_elements(node.elements) unless node.elements.empty?
bounds(node.location)
+ on_array(elements)
+ end
- if node.message.match?(/^[[:alpha:]_]/)
- val = on_ident(node.message)
+ # Visit a CallNode node.
+ def visit_call_node(node)
+ if node.variable_call?
+ if node.message.match?(/^[[:alpha:]_]/)
+ bounds(node.message_loc)
+ return on_vcall(on_ident(node.message))
+ end
- return on_vcall(val)
+ raise NotImplementedError, "Non-alpha variable call"
end
if node.opening_loc.nil?
@@ -128,67 +138,61 @@ module Prism
raise NotImplementedError, "More than two arguments for operator"
end
else
- # This is a method call, not an operator
raise NotImplementedError, "Non-nil opening_loc"
end
end
- # Visit a RangeNode
- def visit_range_node(node)
- bounds(node.location)
- left = visit(node.left)
- right = visit(node.right)
-
- if node.operator_loc.slice == "..."
- on_dot3(left, right)
- else
- on_dot2(left, right)
- end
- end
-
- # Visit a ParenthesesNode
- def visit_parentheses_node(node)
- bounds(node.location)
- val = visit(node.body)
- on_paren(val)
- end
-
# Visit a FloatNode node.
def visit_float_node(node)
- bounds(node.location)
- on_float(node.slice)
+ visit_number(node) { |text| on_float(text) }
end
# Visit a ImaginaryNode node.
def visit_imaginary_node(node)
- bounds(node.location)
- on_imaginary(node.slice)
+ visit_number(node) { |text| on_imaginary(text) }
end
# Visit an IntegerNode node.
def visit_integer_node(node)
- text = node.slice
- loc = node.location
- if text[0] == "-"
- # TODO: This is ugly. We test that a newline between - and 7 doesn't give an error, but this could still be bad somehow.
- bounds_line_col(loc.start_line, loc.start_column + 1)
- on_int_val = on_int(text[1..-1])
- bounds(node.location)
- if RUBY_ENGINE == "jruby"
- on_unary(:-, on_int_val)
+ visit_number(node) { |text| on_int(text) }
+ end
+
+ # Visit a ParenthesesNode node.
+ def visit_parentheses_node(node)
+ body =
+ if node.body.nil?
+ on_stmts_add(on_stmts_new, on_void_stmt)
else
- on_unary(:-@, on_int_val)
+ visit(node.body)
end
+
+ bounds(node.location)
+ on_paren(body)
+ end
+
+ # Visit a ProgramNode node.
+ def visit_program_node(node)
+ statements = visit(node.statements)
+ bounds(node.location)
+ on_program(statements)
+ end
+
+ # Visit a RangeNode node.
+ def visit_range_node(node)
+ left = visit(node.left)
+ right = visit(node.right)
+
+ bounds(node.location)
+ if node.exclude_end?
+ on_dot3(left, right)
else
- bounds(node.location)
- on_int(text)
+ on_dot2(left, right)
end
end
# Visit a RationalNode node.
def visit_rational_node(node)
- bounds(node.location)
- on_rational(node.slice)
+ visit_number(node) { |text| on_rational(text) }
end
# Visit a StatementsNode node.
@@ -199,13 +203,6 @@ module Prism
end
end
- # Visit a ProgramNode node.
- def visit_program_node(node)
- statements = visit(node.statements)
- bounds(node.location)
- on_program(statements)
- end
-
############################################################################
# Entrypoints for subclasses
############################################################################
@@ -222,6 +219,32 @@ module Prism
private
+ # Visit a list of elements, like the elements of an array or arguments.
+ def visit_elements(elements)
+ bounds(elements.first.location)
+ elements.inject(on_args_new) do |args, element|
+ on_args_add(args, visit(element))
+ end
+ end
+
+ # Visit a node that represents a number. We need to explicitly handle the
+ # unary - operator.
+ def visit_number(node)
+ slice = node.slice
+ location = node.location
+
+ if slice[0] == "-"
+ bounds_values(location.start_line, location.start_column + 1)
+ value = yield slice[1..-1]
+
+ bounds(node.location)
+ on_unary(RUBY_ENGINE == "jruby" ? :- : :-@, value)
+ else
+ bounds(location)
+ yield slice
+ end
+ end
+
# This method is responsible for updating lineno and column information
# to reflect the current node.
#
@@ -234,7 +257,7 @@ module Prism
# If we need to do something unusual, we can directly update the line number
# and column to reflect the current node.
- def bounds_line_col(lineno, column)
+ def bounds_values(lineno, column)
@lineno = lineno
@column = column
end
diff --git a/test/prism/ripper_compat_test.rb b/test/prism/ripper_compat_test.rb
index 0bdef53038..8ca8545add 100644
--- a/test/prism/ripper_compat_test.rb
+++ b/test/prism/ripper_compat_test.rb
@@ -36,10 +36,26 @@ module Prism
assert_equivalent("(foo..-7)")
end
+ def test_parentheses
+ assert_equivalent("()")
+ assert_equivalent("(1)")
+ assert_equivalent("(1; 2)")
+ end
+
+ def test_numbers
+ assert_equivalent("[1, -1, +1, 1.0, -1.0, +1.0]")
+ assert_equivalent("[1r, -1r, +1r, 1.5r, -1.5r, +1.5r]")
+ assert_equivalent("[1i, -1i, +1i, 1.5i, -1.5i, +1.5i]")
+ assert_equivalent("[1ri, -1ri, +1ri, 1.5ri, -1.5ri, +1.5ri]")
+ end
+
private
def assert_equivalent(source)
- assert_equal Ripper.sexp_raw(source), RipperCompat.sexp_raw(source)
+ expected = Ripper.sexp_raw(source)
+
+ refute_nil expected
+ assert_equal expected, RipperCompat.sexp_raw(source)
end
end
end