8000 [ruby/prism] More visitors and tests for RipperCompat · ruby/ruby@e34505c · GitHub
[go: up one dir, main page]

Skip to content

Commit e34505c

Browse files
noahgibbsmatzbot
authored andcommitted
[ruby/prism] More visitors and tests for RipperCompat
Part of issue #2354 ruby/prism@cb28edae34
1 parent ae13f85 commit e34505c

File tree

2 files changed

+88
-7
lines changed

2 files changed

+88
-7
lines changed

lib/prism/ripper_compat.rb

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,51 @@ def parse
108108

109109
# Visit a CallNode node.
110110
def visit_call_node(node)
111-
if !node.message.match?(/^[[:alpha:]_]/) && node.opening_loc.nil? && node.arguments&.arguments&.length == 1
111+
bounds(node.location)
112+
113+
if node.message.match?(/^[[:alpha:]_]/)
114+
val = on_ident(node.message)
115+
116+
return on_vcall(val)
117+
end
118+
119+
if node.opening_loc.nil?
112120
left = visit(node.receiver)
113-
right = visit(node.arguments.arguments.first)
121+
if node.arguments&.arguments&.length == 1
122+
right = visit(node.arguments.arguments.first)
123+
124+
on_binary(left, node.name, right)
125+
elsif !node.arguments || node.arguments.empty?
126+
on_unary(node.name, left)
127+
else
128+
raise NotImplementedError, "More than two arguments for operator"
129+
end
130+
else
131+
# This is a method call, not an operator
132+
raise NotImplementedError, "Non-nil opening_loc"
133+
end
134+
end
114135

115-
bounds(node.location)
116-
on_binary(left, node.name, right)
136+
# Visit a RangeNode
137+
def visit_range_node(node)
138+
bounds(node.location)
139+
left = visit(node.left)
140+
right = visit(node.right)
141+
142+
if node.operator_loc.slice == "..."
143+
on_dot3(left, right)
117144
else
118-
raise NotImplementedError
145+
on_dot2(left, right)
119146
end
120147
end
121148

149+
# Visit a ParenthesesNode
150+
def visit_parentheses_node(node)
151+
bounds(node.location)
152+
val = visit(node.body)
153+
on_paren(val)
154+
end
155+
122156
# Visit a FloatNode node.
123157
def visit_float_node(node)
124158
bounds(node.location)
@@ -133,8 +167,22 @@ def visit_imaginary_node(node)
133167

134168
# Visit an IntegerNode node.
135169
def visit_integer_node(node)
136-
bounds(node.location)
137-
on_int(node.slice)
170+
text = node.slice
171+
loc = node.location
172+
if text[0] == "-"
173+
# TODO: This is ugly. We test that a newline between - and 7 doesn't give an error, but this could still be bad somehow.
174+
bounds_line_col(loc.start_line, loc.start_column + 1)
175+
on_int_val = on_int(text[1..-1])
176+
bounds(node.location)
177+
if RUBY_ENGINE == "jruby"
178+
on_unary(:-, on_int_val)
179+
else
180+
on_unary(:-@, on_int_val)
181+
end
182+
else
183+
bounds(node.location)
184+
on_int(text)
185+
end
138186
end
139187

140188
# Visit a RationalNode node.
@@ -184,6 +232,13 @@ def bounds(location)
184232
@column = location.start_column
185233
end
186234

235+
# If we need to do something unusual, we can directly update the line number
236+
# and column to reflect the current node.
237+
def bounds_line_col(lineno, column)
238+
@lineno = lineno
239+
@column = column
240+
end
241+
187242
# Lazily initialize the parse result.
188243
def result
189244
@result ||= Prism.parse(source)

test/prism/ripper_compat_test.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,32 @@ def test_binary
1010
assert_equivalent("6 / 7; 8 % 9")
1111
end
1212

13+
def test_unary
14+
assert_equivalent("-7")
15+
end
16+
17+
def test_unary_parens
18+
assert_equivalent("-(7)")
19+
assert_equivalent("(-7)")
20+
assert_equivalent("(-\n7)")
21+
end
22+
23+
def test_binary_parens
24+
assert_equivalent("(3 + 7) * 4")
25+
end
26+
27+
def test_ident
28+
assert_equivalent("foo")
29+
end
30+
31+
def test_range
32+
assert_equivalent("(...2)")
33+
assert_equivalent("(..2)")
34+
assert_equivalent("(1...2)")
35+
assert_equivalent("(1..2)")
36+
assert_equivalent("(foo..-7)")
37+
end
38+
1339
private
1440

1541
def assert_equivalent(source)

0 commit comments

Comments
 (0)
0