@@ -469,44 +469,22 @@ def visit_break_node(node)
469
469
# foo.bar() {}
470
470
# ^^^^^^^^^^^^
471
471
def visit_call_node ( node )
472
- case node . name
473
- when :[]
474
- if node . opening == "["
472
+ if node . call_operator_loc . nil?
473
+ case node . name
474
+ when :[]
475
475
receiver = visit ( node . receiver )
476
- arguments = node . arguments &.arguments || [ ]
477
- block = node . block
478
-
479
- if block . is_a? ( BlockArgumentNode )
480
- arguments << block
481
- block = nil
482
- end
483
-
484
- arguments =
485
- if arguments . any?
486
- args = visit_arguments ( arguments )
487
-
488
- if node . block . is_a? ( BlockArgumentNode )
489
- args
490
- else
491
- bounds ( arguments . first . location )
492
- on_args_add_block ( args , false )
493
- end
494
- end
476
+ arguments , block = visit_call_node_arguments ( node . arguments , node . block )
495
477
496
478
bounds ( node . location )
497
479
call = on_aref ( receiver , arguments )
498
480
499
481
if block . nil?
500
- return call
482
+ call
501
483
else
502
- block = visit ( block )
503
-
504
484
bounds ( node . location )
505
- return on_method_add_block ( call , block )
485
+ on_method_add_block ( call , block )
506
486
end
507
- end
508
- when :[]=
509
- if node . opening == "["
487
+ when :[]=
510
488
receiver = visit ( node . receiver )
511
489
512
490
*arguments , last_argument = node . arguments . arguments
@@ -529,34 +507,107 @@ def visit_call_node(node)
529
507
530
508
value = visit ( last_argument )
531
509
bounds ( last_argument . location )
532
- return on_assign ( call , value )
510
+ on_assign ( call , value )
511
+ when :-@ , :+@ , :~@ , :! @
512
+ receiver = visit ( node . receiver )
513
+
514
+ bounds ( node . location )
515
+ on_unary ( node . message == "not" ? :not : node . name , receiver )
516
+ when :!= , :!~ , :=~ , :== , :=== , :<=> , :> , :>= , :< , :<= , :& , :| , :^ , :>> , :<< , :- , :+ , :% , :/ , :* , :**
517
+ receiver = visit ( node . receiver )
518
+ value = visit ( node . arguments . arguments . first )
519
+
520
+ bounds ( node . location )
521
+ on_binary ( receiver , node . name , value )
522
+ else
523
+ bounds ( node . message_loc )
524
+ message = on_ident ( node . message )
525
+
526
+ if node . variable_call?
527
+ on_vcall ( message )
528
+ else
529
+ arguments , block = visit_call_node_arguments ( node . arguments , node . block )
530
+ call =
531
+ if node . opening_loc . nil? && ( arguments &.any? || block . nil? )
532
+ bounds ( node . location )
533
+ on_command ( message , arguments )
534
+ elsif !node . opening_loc . nil?
535
+ bounds ( node . location )
536
+ on_method_add_arg ( on_fcall ( message ) , on_arg_paren ( arguments ) )
537
+ else
538
+ bounds ( node . location )
539
+ on_method_add_arg ( on_fcall ( message ) , on_args_new )
540
+ end
541
+
542
+ if block . nil?
543
+ call
544
+ else
545
+ bounds ( node . block . location )
546
+ on_method_add_block ( call , block )
547
+ end
548
+ end
533
549
end
534
- end
550
+ else
551
+ receiver = visit ( node . receiver )
552
+
553
+ bounds ( node . call_operator_loc )
554
+ call_operator = visit_token ( node . call_operator )
535
555
536
- if node . variable_call?
537
556
bounds ( node . message_loc )
538
- return on_vcall ( on_ident ( node . message ) )
539
- end
557
+ message = visit_token ( node . message )
540
558
541
- if node . opening_loc . nil?
542
- return visit_no_paren_call ( node )
543
- end
559
+ arguments , block = visit_call_node_arguments ( node . arguments , node . block )
560
+ call =
561
+ if node . opening_loc . nil?
562
+ bounds ( node . location )
544
563
545
- # A non-operator method call with parentheses
546
- args = on_arg_paren ( node . arguments . nil? ? nil : visit ( node . arguments ) )
564
+ if !arguments || arguments . empty?
565
+ on_call ( receiver , call_operator , message )
566
+ else
567
+ on_command_call ( receiver , call_operator , message , arguments )
568
+ end
569
+ else
570
+ bounds ( node . opening_loc )
571
+ arguments = on_arg_paren ( arguments )
547
572
548
- bounds ( node . message_loc )
549
- ident_val = on_ident ( node . message )
573
+ bounds ( node . location )
574
+ on_method_add_arg ( on_call ( receiver , call_operator , message ) , arguments )
575
+ end
550
576
551
- bounds ( node . location )
552
- args_call_val = on_method_add_arg ( on_fcall ( ident_val ) , args )
553
- if node . block
554
- block_val = visit ( node . block )
577
+ if block . nil?
578
+ call
579
+ else
580
+ bounds ( node . block . location )
581
+ on_method_add_block ( call , block )
582
+ end
583
+ end
584
+ end
555
585
556
- return on_method_add_block ( args_call_val , block_val )
557
- else
558
- return args_call_val
586
+ # Visit the arguments and block of a call node and return the arguments
587
+ # and block as they should be used.
588
+ private def visit_call_node_arguments ( arguments_node , block_node )
589
+ arguments = arguments_node &.arguments || [ ]
590
+ block = block_node
591
+
592
+ if block . is_a? ( BlockArgumentNode )
593
+ arguments << block
594
+ block = nil
559
595
end
596
+
597
+ arguments =
598
+ if arguments . any?
599
+ args = visit_arguments ( arguments )
600
+
601
+ if block . is_a? ( BlockArgumentNode )
602
+ args
603
+ else
604
+ bounds ( arguments . first . location )
605
+ on_args_add_block ( args , false )
606
+ end
607
+ end
608
+
609
+ block = visit ( block ) if !block . nil?
610
+ [ arguments , block ]
560
611
end
561
612
562
613
# foo.bar += baz
@@ -2427,70 +2478,6 @@ def visit_token(token)
2427
2478
end
2428
2479
end
2429
2480
2430
- # Generate Ripper events for a CallNode with no opening_loc
2431
- def visit_no_paren_call ( node )
2432
- # No opening_loc can mean an operator. It can also mean a
2433
- # method call with no parentheses.
2434
- if node . message . match? ( /^[[:punct:]]/ )
2435
- left = visit ( node . receiver )
2436
- if node . arguments &.arguments &.length == 1
2437
- right = visit ( node . arguments . arguments . first )
2438
-
2439
- return on_binary ( left , node . name , right )
2440
- elsif !node . arguments || node . arguments . empty?
2441
- return on_unary ( node . name , left )
2442
- else
2443
- raise NoMethodError , __method__ , "More than two arguments for operator"
2444
- end
2445
- elsif node . call_operator_loc . nil?
2446
- # In Ripper a method call like "puts myvar" with no parentheses is a "command".
2447
- bounds ( node . message_loc )
2448
- ident_val = on_ident ( node . message )
2449
-
2450
- # Unless it has a block, and then it's an fcall (e.g. "foo { bar }")
2451
- if node . block
2452
- block_val = visit ( node . block )
2453
- # In these calls, even if node.arguments is nil, we still get an :args_new call.
2454
- args = if node . arguments . nil?
2455
- on_args_new
2456
- else
2457
- on_args_add_block ( visit_arguments ( node . arguments . arguments ) )
2458
- end
2459
- method_args_val = on_method_add_arg ( on_fcall ( ident_val ) , args )
2460
- return on_method_add_block ( method_args_val , block_val )
2461
- else
2462
- if node . arguments . nil?
2463
- return on_command ( ident_val , nil )
2464
- else
2465
- args = on_args_add_block ( visit_arguments ( node . arguments . arguments ) , false )
2466
- return on_command ( ident_val , args )
2467
- end
2468
- end
2469
- else
2470
- operator = node . call_operator_loc . slice
2471
- if operator == "." || operator == "&."
2472
- left_val = visit ( node . receiver )
2473
-
2474
- bounds ( node . call_operator_loc )
2475
- operator_val = operator == "." ? on_period ( node . call_operator ) : on_op ( node . call_operator )
2476
-
2477
- bounds ( node . message_loc )
2478
- right_val = on_ident ( node . message )
2479
-
2480
- call_val = on_call ( left_val , operator_val , right_val )
2481
-
2482
- if node . block
2483
- block_val = visit ( node . block )
2484
- return on_method_add_block ( call_val , block_val )
2485
- else
2486
- return call_val
2487
- end
2488
- else
2489
- raise NoMethodError , __method__ , "operator other than . or &. for call: #{ operator . inspect } "
2490
- end
2491
- end
2492
- end
2493
-
2494
2481
# Ripper has several methods of emitting a symbol literal. Inside an alias
2495
2482
# sometimes it suppresses the [:symbol] wrapper around ident. If the symbol
2496
2483
# is also the name of a keyword (e.g. :if) it will emit a :@kw wrapper, not
0 commit comments