@@ -128,57 +128,7 @@ def visit_call_node(node)
128
128
end
129
129
130
130
if node . opening_loc . nil?
131
- # No opening_loc can mean an operator. It can also mean a
132
- # method call with no parentheses.
133
- if node . message . match? ( /^[[:punct:]]/ )
134
- left = visit ( node . receiver )
135
- if node . arguments &.arguments &.length == 1
136
- right = visit ( node . arguments . arguments . first )
137
-
138
- return on_binary ( left , node . name , right )
139
- elsif !node . arguments || node . arguments . empty?
140
- return on_unary ( node . name , left )
141
- else
142
- raise NotImplementedError , "More than two arguments for operator"
143
- end
144
- elsif node . call_operator_loc . nil?
145
- # In Ripper a method call like "puts myvar" with no parenthesis is a "command".
146
- bounds ( node . message_loc )
147
- ident_val = on_ident ( node . message )
148
- args = node . arguments . nil? ? nil : args_node_to_arguments ( node . arguments )
149
-
150
- # Unless it has a block, and then it's an fcall (e.g. "foo { bar }")
151
- if node . block
152
- block_val = visit ( node . block )
153
- # In these calls, even if node.arguments is nil, we still get an :args_new call.
154
- method_args_val = on_method_add_arg ( on_fcall ( ident_val ) , args_node_to_arguments ( node . arguments ) )
155
- return on_method_add_block ( method_args_val , on_brace_block ( nil , block_val ) )
156
- else
157
- return on_command ( ident_val , args )
158
- end
159
- else
160
- operator = node . call_operator_loc . slice
161
- if operator == "." || operator == "&."
162
- left_val = visit ( node . receiver )
163
-
164
- bounds ( node . call_operator_loc )
165
- operator_val = operator == "." ? on_period ( node . call_operator ) : on_op ( node . call_operator )
166
-
167
- bounds ( node . message_loc )
168
- right_val = on_ident ( node . message )
169
-
170
- call_val = on_call ( left_val , operator_val , right_val )
171
-
172
- if node . block
173
- block_val = visit ( node . block )
174
- return on_method_add_block ( call_val , on_brace_block ( nil , block_val ) )
175
- else
176
- return call_val
177
- end
178
- else
179
- raise NotImplementedError , "operator other than . or &. for call: #{ operator . inspect } "
180
- end
181
- end
131
+ return visit_no_paren_call ( node )
182
132
end
183
133
184
134
# A non-operator method call with parentheses
@@ -212,7 +162,7 @@ def visit_and_node(node)
212
162
visit_binary_operator ( node )
213
163
end
214
164
215
- # Visit an AndNode
165
+ # Visit an OrNode
216
166
def visit_or_node ( node )
217
167
visit_binary_operator ( node )
218
168
end
@@ -278,24 +228,6 @@ def visit_statements_node(node)
278
228
end
279
229
end
280
230
281
- private
282
-
283
- # Ripper generates an interesting format of argument list.
284
- # We'd like to convert an ArgumentsNode to one.
285
- def args_node_to_arguments ( args_node )
286
- return on_args_new if args_node . nil?
287
-
288
- args = on_args_new
289
- args_node . arguments . each do |arg |
290
- bounds ( arg . location )
291
- args = on_args_add ( args , visit ( arg ) )
292
- end
293
-
294
- on_args_add_block ( args , false )
295
- end
296
-
297
- public
298
-
299
231
############################################################################
300
232
# Entrypoints for subclasses
301
233
############################################################################
@@ -312,6 +244,72 @@ def self.sexp(source)
312
244
313
245
private
314
246
247
+ # Generate Ripper events for a CallNode with no opening_loc
248
+ def visit_no_paren_call ( node )
249
+ # No opening_loc can mean an operator. It can also mean a
250
+ # method call with no parentheses.
251
+ if node . message . match? ( /^[[:punct:]]/ )
252
+ left = visit ( node . receiver )
253
+ if node . arguments &.arguments &.length == 1
254
+ right = visit ( node . arguments . arguments . first )
255
+
256
+ return on_binary ( left , node . name , right )
257
+ elsif !node . arguments || node . arguments . empty?
258
+ return on_unary ( node . name , left )
259
+ else
260
+ raise NotImplementedError , "More than two arguments for operator"
261
+ end
262
+ elsif node . call_operator_loc . nil?
263
+ # In Ripper a method call like "puts myvar" with no parenthesis is a "command".
264
+ bounds ( node . message_loc )
265
+ ident_val = on_ident ( node . message )
266
+
267
+ # Unless it has a block, and then it's an fcall (e.g. "foo { bar }")
268
+ if node . block
269
+ block_val = visit ( node . block )
270
+ # In these calls, even if node.arguments is nil, we still get an :args_new call.
271
+ method_args_val = on_method_add_arg ( on_fcall ( ident_val ) , args_node_to_arguments ( node . arguments ) )
272
+ return on_method_add_block ( method_args_val , on_brace_block ( nil , block_val ) )
273
+ else
274
+ args = node . arguments . nil? ? nil : args_node_to_arguments ( node . arguments )
275
+ return on_command ( ident_val , args )
276
+ end
277
+ else
278
+ operator = node . call_operator_loc . slice
279
+ if operator == "." || operator == "&."
280
+ left_val = visit ( node . receiver )
281
+
282
+ bounds ( node . call_operator_loc )
283
+ operator_val = operator == "." ? on_period ( node . call_operator ) : on_op ( node . call_operator )
284
+
285
+ bounds ( node . message_loc )
286
+ right_val = on_ident ( node . message )
287
+
288
+ call_val = on_call ( left_val , operator_val , right_val )
289
+
290
+ if node . block
291
+ block_val = visit ( node . block )
292
+ return on_method_add_block ( call_val , on_brace_block ( nil , block_val ) )
293
+ else
294
+ return call_val
295
+ end
296
+ else
297
+ raise NotImplementedError , "operator other than . or &. for call: #{ operator . inspect } "
298
+ end
299
+ end
300
+ end
301
+
302
+ # Ripper generates an interesting format of argument list.
303
+ # It seems to be very location-specific. We should get rid of
304
+ # this method and make it clearer how it's done in each place.
305
+ def args_node_to_arguments ( args_node )
306
+ return on_args_new if args_node . nil?
307
+
308
+ args = visit_elements ( args_node . arguments )
309
+
310
+ on_args_add_block ( args , false )
311
+ end
312
+
315
313
# Visit a list of elements, like the elements of an array or arguments.
316
314
def visit_elements ( elements )
317
315
bounds ( elements . first . location )
@@ -331,13 +329,25 @@ def visit_number(node)
331
329
value = yield slice [ 1 ..-1 ]
332
330
333
331
bounds ( node . location )
334
- on_unary ( RUBY_ENGINE == "jruby" && JRUBY_VERSION < "9.4.6.0" ? :- : :-@ , value )
332
+ on_unary ( visit_unary_operator ( :-@ ) , value )
335
333
else
336
334
bounds ( location )
337
335
yield slice
338
336
end
339
337
end
340
338
339
+ if RUBY_ENGINE == "jruby" && Gem ::Version . new ( JRUBY_VERSION ) < Gem ::Version . new ( "9.4.6.0" )
340
+ # JRuby before 9.4.6.0 uses :- for unary minus instead of :-@
341
+ def visit_unary_operator ( value )
342
+ value == :-@ ? :- : value
343
+ end
344
+ else
345
+ # For most Rubies and JRuby after 9.4.6.0 this is a no-op.
346
+ def visit_unary_operator ( value )
347
+ value
348
+ end
349
+ end
350
+
341
351
# Visit a binary operator node like an AndNode or OrNode
342
352
def visit_binary_operator ( node )
343
353
left_val = visit ( node . left )
0 commit comments