prism 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/prism/node.rb CHANGED
@@ -1018,8 +1018,12 @@ module Prism
1018
1018
  # $'
1019
1019
  # ^^
1020
1020
  class BackReferenceReadNode < Node
1021
- # def initialize: (location: Location) -> void
1022
- def initialize(location)
1021
+ # attr_reader name: Symbol
1022
+ attr_reader :name
1023
+
1024
+ # def initialize: (name: Symbol, location: Location) -> void
1025
+ def initialize(name, location)
1026
+ @name = name
1023
1027
  @location = location
1024
1028
  end
1025
1029
 
@@ -1046,6 +1050,7 @@ module Prism
1046
1050
  # def copy: (**params) -> BackReferenceReadNode
1047
1051
  def copy(**params)
1048
1052
  BackReferenceReadNode.new(
1053
+ params.fetch(:name) { name },
1049
1054
  params.fetch(:location) { location },
1050
1055
  )
1051
1056
  end
@@ -1055,11 +1060,12 @@ module Prism
1055
1060
 
1056
1061
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
1057
1062
  def deconstruct_keys(keys)
1058
- { location: location }
1063
+ { name: name, location: location }
1059
1064
  end
1060
1065
 
1061
1066
  def inspect(inspector = NodeInspector.new)
1062
1067
  inspector << inspector.header(self)
1068
+ inspector << "└── name: #{name.inspect}\n"
1063
1069
  inspector.to_str
1064
1070
  end
1065
1071
 
@@ -1913,15 +1919,6 @@ module Prism
1913
1919
  # attr_reader message_loc: Location?
1914
1920
  attr_reader :message_loc
1915
1921
 
1916
- # attr_reader opening_loc: Location?
1917
- attr_reader :opening_loc
1918
-
1919
- # attr_reader arguments: ArgumentsNode?
1920
- attr_reader :arguments
1921
-
1922
- # attr_reader closing_loc: Location?
1923
- attr_reader :closing_loc
1924
-
1925
1922
  # attr_reader flags: Integer
1926
1923
  private attr_reader :flags
1927
1924
 
@@ -1937,14 +1934,11 @@ module Prism
1937
1934
  # attr_reader value: Node
1938
1935
  attr_reader :value
1939
1936
 
1940
- # def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> void
1941
- def initialize(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator_loc, value, location)
1937
+ # def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> void
1938
+ def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
1942
1939
  @receiver = receiver
1943
1940
  @call_operator_loc = call_operator_loc
1944
1941
  @message_loc = message_loc
1945
- @opening_loc = opening_loc
1946
- @arguments = arguments
1947
- @closing_loc = closing_loc
1948
1942
  @flags = flags
1949
1943
  @read_name = read_name
1950
1944
  @write_name = write_name
@@ -1960,21 +1954,20 @@ module Prism
1960
1954
 
1961
1955
  # def child_nodes: () -> Array[nil | Node]
1962
1956
  def child_nodes
1963
- [receiver, arguments, value]
1957
+ [receiver, value]
1964
1958
  end
1965
1959
 
1966
1960
  # def compact_child_nodes: () -> Array[Node]
1967
1961
  def compact_child_nodes
1968
1962
  compact = []
1969
1963
  compact << receiver if receiver
1970
- compact << arguments if arguments
1971
1964
  compact << value
1972
1965
  compact
1973
1966
  end
1974
1967
 
1975
1968
  # def comment_targets: () -> Array[Node | Location]
1976
1969
  def comment_targets
1977
- [*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, operator_loc, value]
1970
+ [*receiver, *call_operator_loc, *message_loc, operator_loc, value]
1978
1971
  end
1979
1972
 
1980
1973
  # def copy: (**params) -> CallAndWriteNode
@@ -1983,9 +1976,6 @@ module Prism
1983
1976
  params.fetch(:receiver) { receiver },
1984
1977
  params.fetch(:call_operator_loc) { call_operator_loc },
1985
1978
  params.fetch(:message_loc) { message_loc },
1986
- params.fetch(:opening_loc) { opening_loc },
1987
- params.fetch(:arguments) { arguments },
1988
- params.fetch(:closing_loc) { closing_loc },
1989
1979
  params.fetch(:flags) { flags },
1990
1980
  params.fetch(:read_name) { read_name },
1991
1981
  params.fetch(:write_name) { write_name },
@@ -2000,7 +1990,7 @@ module Prism
2000
1990
 
2001
1991
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2002
1992
  def deconstruct_keys(keys)
2003
- { receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, flags: flags, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value, location: location }
1993
+ { receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, flags: flags, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value, location: location }
2004
1994
  end
2005
1995
 
2006
1996
  # def call_operator: () -> String?
@@ -2013,16 +2003,6 @@ module Prism
2013
2003
  message_loc&.slice
2014
2004
  end
2015
2005
 
2016
- # def opening: () -> String?
2017
- def opening
2018
- opening_loc&.slice
2019
- end
2020
-
2021
- # def closing: () -> String?
2022
- def closing
2023
- closing_loc&.slice
2024
- end
2025
-
2026
2006
  # def safe_navigation?: () -> bool
2027
2007
  def safe_navigation?
2028
2008
  flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
@@ -2048,14 +2028,6 @@ module Prism
2048
2028
  end
2049
2029
  inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
2050
2030
  inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
2051
- inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
2052
- if (arguments = self.arguments).nil?
2053
- inspector << "├── arguments: ∅\n"
2054
- else
2055
- inspector << "├── arguments:\n"
2056
- inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
2057
- end
2058
- inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
2059
2031
  flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
2060
2032
  inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2061
2033
  inspector << "├── read_name: #{read_name.inspect}\n"
@@ -2307,15 +2279,6 @@ module Prism
2307
2279
  # attr_reader message_loc: Location?
2308
2280
  attr_reader :message_loc
2309
2281
 
2310
- # attr_reader opening_loc: Location?
2311
- attr_reader :opening_loc
2312
-
2313
- # attr_reader arguments: ArgumentsNode?
2314
- attr_reader :arguments
2315
-
2316
- # attr_reader closing_loc: Location?
2317
- attr_reader :closing_loc
2318
-
2319
2282
  # attr_reader flags: Integer
2320
2283
  private attr_reader :flags
2321
2284
 
@@ -2334,14 +2297,11 @@ module Prism
2334
2297
  # attr_reader value: Node
2335
2298
  attr_reader :value
2336
2299
 
2337
- # def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator: Symbol, operator_loc: Location, value: Node, location: Location) -> void
2338
- def initialize(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator, operator_loc, value, location)
2300
+ # def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator: Symbol, operator_loc: Location, value: Node, location: Location) -> void
2301
+ def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator, operator_loc, value, location)
2339
2302
  @receiver = receiver
2340
2303
  @call_operator_loc = call_operator_loc
2341
2304
  @message_loc = message_loc
2342
- @opening_loc = opening_loc
2343
- @arguments = arguments
2344
- @closing_loc = closing_loc
2345
2305
  @flags = flags
2346
2306
  @read_name = read_name
2347
2307
  @write_name = write_name
@@ -2358,21 +2318,20 @@ module Prism
2358
2318
 
2359
2319
  # def child_nodes: () -> Array[nil | Node]
2360
2320
  def child_nodes
2361
- [receiver, arguments, value]
2321
+ [receiver, value]
2362
2322
  end
2363
2323
 
2364
2324
  # def compact_child_nodes: () -> Array[Node]
2365
2325
  def compact_child_nodes
2366
2326
  compact = []
2367
2327
  compact << receiver if receiver
2368
- compact << arguments if arguments
2369
2328
  compact << value
2370
2329
  compact
2371
2330
  end
2372
2331
 
2373
2332
  # def comment_targets: () -> Array[Node | Location]
2374
2333
  def comment_targets
2375
- [*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, operator_loc, value]
2334
+ [*receiver, *call_operator_loc, *message_loc, operator_loc, value]
2376
2335
  end
2377
2336
 
2378
2337
  # def copy: (**params) -> CallOperatorWriteNode
@@ -2381,9 +2340,6 @@ module Prism
2381
2340
  params.fetch(:receiver) { receiver },
2382
2341
  params.fetch(:call_operator_loc) { call_operator_loc },
2383
2342
  params.fetch(:message_loc) { message_loc },
2384
- params.fetch(:opening_loc) { opening_loc },
2385
- params.fetch(:arguments) { arguments },
2386
- params.fetch(:closing_loc) { closing_loc },
2387
2343
  params.fetch(:flags) { flags },
2388
2344
  params.fetch(:read_name) { read_name },
2389
2345
  params.fetch(:write_name) { write_name },
@@ -2399,7 +2355,7 @@ module Prism
2399
2355
 
2400
2356
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2401
2357
  def deconstruct_keys(keys)
2402
- { receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, flags: flags, read_name: read_name, write_name: write_name, operator: operator, operator_loc: operator_loc, value: value, location: location }
2358
+ { receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, flags: flags, read_name: read_name, write_name: write_name, operator: operator, operator_loc: operator_loc, value: value, location: location }
2403
2359
  end
2404
2360
 
2405
2361
  # def call_operator: () -> String?
@@ -2412,16 +2368,6 @@ module Prism
2412
2368
  message_loc&.slice
2413
2369
  end
2414
2370
 
2415
- # def opening: () -> String?
2416
- def opening
2417
- opening_loc&.slice
2418
- end
2419
-
2420
- # def closing: () -> String?
2421
- def closing
2422
- closing_loc&.slice
2423
- end
2424
-
2425
2371
  # def safe_navigation?: () -> bool
2426
2372
  def safe_navigation?
2427
2373
  flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
@@ -2442,14 +2388,6 @@ module Prism
2442
2388
  end
2443
2389
  inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
2444
2390
  inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
2445
- inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
2446
- if (arguments = self.arguments).nil?
2447
- inspector << "├── arguments: ∅\n"
2448
- else
2449
- inspector << "├── arguments:\n"
2450
- inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
2451
- end
2452
- inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
2453
2391
  flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
2454
2392
  inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2455
2393
  inspector << "├── read_name: #{read_name.inspect}\n"
@@ -2504,15 +2442,6 @@ module Prism
2504
2442
  # attr_reader message_loc: Location?
2505
2443
  attr_reader :message_loc
2506
2444
 
2507
- # attr_reader opening_loc: Location?
2508
- attr_reader :opening_loc
2509
-
2510
- # attr_reader arguments: ArgumentsNode?
2511
- attr_reader :arguments
2512
-
2513
- # attr_reader closing_loc: Location?
2514
- attr_reader :closing_loc
2515
-
2516
2445
  # attr_reader flags: Integer
2517
2446
  private attr_reader :flags
2518
2447
 
@@ -2528,14 +2457,11 @@ module Prism
2528
2457
  # attr_reader value: Node
2529
2458
  attr_reader :value
2530
2459
 
2531
- # def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> void
2532
- def initialize(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, flags, read_name, write_name, operator_loc, value, location)
2460
+ # def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> void
2461
+ def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
2533
2462
  @receiver = receiver
2534
2463
  @call_operator_loc = call_operator_loc
2535
2464
  @message_loc = message_loc
2536
- @opening_loc = opening_loc
2537
- @arguments = arguments
2538
- @closing_loc = closing_loc
2539
2465
  @flags = flags
2540
2466
  @read_name = read_name
2541
2467
  @write_name = write_name
@@ -2551,21 +2477,20 @@ module Prism
2551
2477
 
2552
2478
  # def child_nodes: () -> Array[nil | Node]
2553
2479
  def child_nodes
2554
- [receiver, arguments, value]
2480
+ [receiver, value]
2555
2481
  end
2556
2482
 
2557
2483
  # def compact_child_nodes: () -> Array[Node]
2558
2484
  def compact_child_nodes
2559
2485
  compact = []
2560
2486
  compact << receiver if receiver
2561
- compact << arguments if arguments
2562
2487
  compact << value
2563
2488
  compact
2564
2489
  end
2565
2490
 
2566
2491
  # def comment_targets: () -> Array[Node | Location]
2567
2492
  def comment_targets
2568
- [*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, operator_loc, value]
2493
+ [*receiver, *call_operator_loc, *message_loc, operator_loc, value]
2569
2494
  end
2570
2495
 
2571
2496
  # def copy: (**params) -> CallOrWriteNode
@@ -2574,9 +2499,6 @@ module Prism
2574
2499
  params.fetch(:receiver) { receiver },
2575
2500
  params.fetch(:call_operator_loc) { call_operator_loc },
2576
2501
  params.fetch(:message_loc) { message_loc },
2577
- params.fetch(:opening_loc) { opening_loc },
2578
- params.fetch(:arguments) { arguments },
2579
- params.fetch(:closing_loc) { closing_loc },
2580
2502
  params.fetch(:flags) { flags },
2581
2503
  params.fetch(:read_name) { read_name },
2582
2504
  params.fetch(:write_name) { write_name },
@@ -2591,7 +2513,7 @@ module Prism
2591
2513
 
2592
2514
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2593
2515
  def deconstruct_keys(keys)
2594
- { receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, flags: flags, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value, location: location }
2516
+ { receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, flags: flags, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value, location: location }
2595
2517
  end
2596
2518
 
2597
2519
  # def call_operator: () -> String?
@@ -2604,16 +2526,6 @@ module Prism
2604
2526
  message_loc&.slice
2605
2527
  end
2606
2528
 
2607
- # def opening: () -> String?
2608
- def opening
2609
- opening_loc&.slice
2610
- end
2611
-
2612
- # def closing: () -> String?
2613
- def closing
2614
- closing_loc&.slice
2615
- end
2616
-
2617
2529
  # def safe_navigation?: () -> bool
2618
2530
  def safe_navigation?
2619
2531
  flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
@@ -2639,14 +2551,6 @@ module Prism
2639
2551
  end
2640
2552
  inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
2641
2553
  inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
2642
- inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
2643
- if (arguments = self.arguments).nil?
2644
- inspector << "├── arguments: ∅\n"
2645
- else
2646
- inspector << "├── arguments:\n"
2647
- inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
2648
- end
2649
- inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
2650
2554
  flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
2651
2555
  inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2652
2556
  inspector << "├── read_name: #{read_name.inspect}\n"
@@ -7826,6 +7730,562 @@ module Prism
7826
7730
  end
7827
7731
  end
7828
7732
 
7733
+ # Represents the use of the `&&=` operator on a call to the `[]` method.
7734
+ #
7735
+ # foo.bar[baz] &&= value
7736
+ # ^^^^^^^^^^^^^^^^^^^^^^
7737
+ class IndexAndWriteNode < Node
7738
+ # attr_reader receiver: Node?
7739
+ attr_reader :receiver
7740
+
7741
+ # attr_reader call_operator_loc: Location?
7742
+ attr_reader :call_operator_loc
7743
+
7744
+ # attr_reader opening_loc: Location
7745
+ attr_reader :opening_loc
7746
+
7747
+ # attr_reader arguments: ArgumentsNode?
7748
+ attr_reader :arguments
7749
+
7750
+ # attr_reader closing_loc: Location
7751
+ attr_reader :closing_loc
7752
+
7753
+ # attr_reader block: Node?
7754
+ attr_reader :block
7755
+
7756
+ # attr_reader flags: Integer
7757
+ private attr_reader :flags
7758
+
7759
+ # attr_reader operator_loc: Location
7760
+ attr_reader :operator_loc
7761
+
7762
+ # attr_reader value: Node
7763
+ attr_reader :value
7764
+
7765
+ # def initialize: (receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, flags: Integer, operator_loc: Location, value: Node, location: Location) -> void
7766
+ def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
7767
+ @receiver = receiver
7768
+ @call_operator_loc = call_operator_loc
7769
+ @opening_loc = opening_loc
7770
+ @arguments = arguments
7771
+ @closing_loc = closing_loc
7772
+ @block = block
7773
+ @flags = flags
7774
+ @operator_loc = operator_loc
7775
+ @value = value
7776
+ @location = location
7777
+ end
7778
+
7779
+ # def accept: (visitor: Visitor) -> void
7780
+ def accept(visitor)
7781
+ visitor.visit_index_and_write_node(self)
7782
+ end
7783
+
7784
+ # def child_nodes: () -> Array[nil | Node]
7785
+ def child_nodes
7786
+ [receiver, arguments, block, value]
7787
+ end
7788
+
7789
+ # def compact_child_nodes: () -> Array[Node]
7790
+ def compact_child_nodes
7791
+ compact = []
7792
+ compact << receiver if receiver
7793
+ compact << arguments if arguments
7794
+ compact << block if block
7795
+ compact << value
7796
+ compact
7797
+ end
7798
+
7799
+ # def comment_targets: () -> Array[Node | Location]
7800
+ def comment_targets
7801
+ [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value]
7802
+ end
7803
+
7804
+ # def copy: (**params) -> IndexAndWriteNode
7805
+ def copy(**params)
7806
+ IndexAndWriteNode.new(
7807
+ params.fetch(:receiver) { receiver },
7808
+ params.fetch(:call_operator_loc) { call_operator_loc },
7809
+ params.fetch(:opening_loc) { opening_loc },
7810
+ params.fetch(:arguments) { arguments },
7811
+ params.fetch(:closing_loc) { closing_loc },
7812
+ params.fetch(:block) { block },
7813
+ params.fetch(:flags) { flags },
7814
+ params.fetch(:operator_loc) { operator_loc },
7815
+ params.fetch(:value) { value },
7816
+ params.fetch(:location) { location },
7817
+ )
7818
+ end
7819
+
7820
+ # def deconstruct: () -> Array[nil | Node]
7821
+ alias deconstruct child_nodes
7822
+
7823
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
7824
+ def deconstruct_keys(keys)
7825
+ { receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, operator_loc: operator_loc, value: value, location: location }
7826
+ end
7827
+
7828
+ # def call_operator: () -> String?
7829
+ def call_operator
7830
+ call_operator_loc&.slice
7831
+ end
7832
+
7833
+ # def opening: () -> String
7834
+ def opening
7835
+ opening_loc.slice
7836
+ end
7837
+
7838
+ # def closing: () -> String
7839
+ def closing
7840
+ closing_loc.slice
7841
+ end
7842
+
7843
+ # def safe_navigation?: () -> bool
7844
+ def safe_navigation?
7845
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
7846
+ end
7847
+
7848
+ # def variable_call?: () -> bool
7849
+ def variable_call?
7850
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
7851
+ end
7852
+
7853
+ # def operator: () -> String
7854
+ def operator
7855
+ operator_loc.slice
7856
+ end
7857
+
7858
+ def inspect(inspector = NodeInspector.new)
7859
+ inspector << inspector.header(self)
7860
+ if (receiver = self.receiver).nil?
7861
+ inspector << "├── receiver: ∅\n"
7862
+ else
7863
+ inspector << "├── receiver:\n"
7864
+ inspector << receiver.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
7865
+ end
7866
+ inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
7867
+ inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
7868
+ if (arguments = self.arguments).nil?
7869
+ inspector << "├── arguments: ∅\n"
7870
+ else
7871
+ inspector << "├── arguments:\n"
7872
+ inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
7873
+ end
7874
+ inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
7875
+ if (block = self.block).nil?
7876
+ inspector << "├── block: ∅\n"
7877
+ else
7878
+ inspector << "├── block:\n"
7879
+ inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
7880
+ end
7881
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
7882
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
7883
+ inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
7884
+ inspector << "└── value:\n"
7885
+ inspector << inspector.child_node(value, " ")
7886
+ inspector.to_str
7887
+ end
7888
+
7889
+ # Sometimes you want to check an instance of a node against a list of
7890
+ # classes to see what kind of behavior to perform. Usually this is done by
7891
+ # calling `[cls1, cls2].include?(node.class)` or putting the node into a
7892
+ # case statement and doing `case node; when cls1; when cls2; end`. Both of
7893
+ # these approaches are relatively slow because of the constant lookups,
7894
+ # method calls, and/or array allocations.
7895
+ #
7896
+ # Instead, you can call #type, which will return to you a symbol that you
7897
+ # can use for comparison. This is faster than the other approaches because
7898
+ # it uses a single integer comparison, but also because if you're on CRuby
7899
+ # you can take advantage of the fact that case statements with all symbol
7900
+ # keys will use a jump table.
7901
+ #
7902
+ # def type: () -> Symbol
7903
+ def type
7904
+ :index_and_write_node
7905
+ end
7906
+
7907
+ # Similar to #type, this method returns a symbol that you can use for
7908
+ # splitting on the type of the node without having to do a long === chain.
7909
+ # Note that like #type, it will still be slower than using == for a single
7910
+ # class, but should be faster in a case statement or an array comparison.
7911
+ #
7912
+ # def self.type: () -> Symbol
7913
+ def self.type
7914
+ :index_and_write_node
7915
+ end
7916
+ end
7917
+
7918
+ # Represents the use of an assignment operator on a call to `[]`.
7919
+ #
7920
+ # foo.bar[baz] += value
7921
+ # ^^^^^^^^^^^^^^^^^^^^^
7922
+ class IndexOperatorWriteNode < Node
7923
+ # attr_reader receiver: Node?
7924
+ attr_reader :receiver
7925
+
7926
+ # attr_reader call_operator_loc: Location?
7927
+ attr_reader :call_operator_loc
7928
+
7929
+ # attr_reader opening_loc: Location
7930
+ attr_reader :opening_loc
7931
+
7932
+ # attr_reader arguments: ArgumentsNode?
7933
+ attr_reader :arguments
7934
+
7935
+ # attr_reader closing_loc: Location
7936
+ attr_reader :closing_loc
7937
+
7938
+ # attr_reader block: Node?
7939
+ attr_reader :block
7940
+
7941
+ # attr_reader flags: Integer
7942
+ private attr_reader :flags
7943
+
7944
+ # attr_reader operator: Symbol
7945
+ attr_reader :operator
7946
+
7947
+ # attr_reader operator_loc: Location
7948
+ attr_reader :operator_loc
7949
+
7950
+ # attr_reader value: Node
7951
+ attr_reader :value
7952
+
7953
+ # def initialize: (receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, flags: Integer, operator: Symbol, operator_loc: Location, value: Node, location: Location) -> void
7954
+ def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator, operator_loc, value, location)
7955
+ @receiver = receiver
7956
+ @call_operator_loc = call_operator_loc
7957
+ @opening_loc = opening_loc
7958
+ @arguments = arguments
7959
+ @closing_loc = closing_loc
7960
+ @block = block
7961
+ @flags = flags
7962
+ @operator = operator
7963
+ @operator_loc = operator_loc
7964
+ @value = value
7965
+ @location = location
7966
+ end
7967
+
7968
+ # def accept: (visitor: Visitor) -> void
7969
+ def accept(visitor)
7970
+ visitor.visit_index_operator_write_node(self)
7971
+ end
7972
+
7973
+ # def child_nodes: () -> Array[nil | Node]
7974
+ def child_nodes
7975
+ [receiver, arguments, block, value]
7976
+ end
7977
+
7978
+ # def compact_child_nodes: () -> Array[Node]
7979
+ def compact_child_nodes
7980
+ compact = []
7981
+ compact << receiver if receiver
7982
+ compact << arguments if arguments
7983
+ compact << block if block
7984
+ compact << value
7985
+ compact
7986
+ end
7987
+
7988
+ # def comment_targets: () -> Array[Node | Location]
7989
+ def comment_targets
7990
+ [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value]
7991
+ end
7992
+
7993
+ # def copy: (**params) -> IndexOperatorWriteNode
7994
+ def copy(**params)
7995
+ IndexOperatorWriteNode.new(
7996
+ params.fetch(:receiver) { receiver },
7997
+ params.fetch(:call_operator_loc) { call_operator_loc },
7998
+ params.fetch(:opening_loc) { opening_loc },
7999
+ params.fetch(:arguments) { arguments },
8000
+ params.fetch(:closing_loc) { closing_loc },
8001
+ params.fetch(:block) { block },
8002
+ params.fetch(:flags) { flags },
8003
+ params.fetch(:operator) { operator },
8004
+ params.fetch(:operator_loc) { operator_loc },
8005
+ params.fetch(:value) { value },
8006
+ params.fetch(:location) { location },
8007
+ )
8008
+ end
8009
+
8010
+ # def deconstruct: () -> Array[nil | Node]
8011
+ alias deconstruct child_nodes
8012
+
8013
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
8014
+ def deconstruct_keys(keys)
8015
+ { receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, operator: operator, operator_loc: operator_loc, value: value, location: location }
8016
+ end
8017
+
8018
+ # def call_operator: () -> String?
8019
+ def call_operator
8020
+ call_operator_loc&.slice
8021
+ end
8022
+
8023
+ # def opening: () -> String
8024
+ def opening
8025
+ opening_loc.slice
8026
+ end
8027
+
8028
+ # def closing: () -> String
8029
+ def closing
8030
+ closing_loc.slice
8031
+ end
8032
+
8033
+ # def safe_navigation?: () -> bool
8034
+ def safe_navigation?
8035
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
8036
+ end
8037
+
8038
+ # def variable_call?: () -> bool
8039
+ def variable_call?
8040
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
8041
+ end
8042
+
8043
+ def inspect(inspector = NodeInspector.new)
8044
+ inspector << inspector.header(self)
8045
+ if (receiver = self.receiver).nil?
8046
+ inspector << "├── receiver: ∅\n"
8047
+ else
8048
+ inspector << "├── receiver:\n"
8049
+ inspector << receiver.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8050
+ end
8051
+ inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
8052
+ inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
8053
+ if (arguments = self.arguments).nil?
8054
+ inspector << "├── arguments: ∅\n"
8055
+ else
8056
+ inspector << "├── arguments:\n"
8057
+ inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8058
+ end
8059
+ inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
8060
+ if (block = self.block).nil?
8061
+ inspector << "├── block: ∅\n"
8062
+ else
8063
+ inspector << "├── block:\n"
8064
+ inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8065
+ end
8066
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
8067
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
8068
+ inspector << "├── operator: #{operator.inspect}\n"
8069
+ inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
8070
+ inspector << "└── value:\n"
8071
+ inspector << inspector.child_node(value, " ")
8072
+ inspector.to_str
8073
+ end
8074
+
8075
+ # Sometimes you want to check an instance of a node against a list of
8076
+ # classes to see what kind of behavior to perform. Usually this is done by
8077
+ # calling `[cls1, cls2].include?(node.class)` or putting the node into a
8078
+ # case statement and doing `case node; when cls1; when cls2; end`. Both of
8079
+ # these approaches are relatively slow because of the constant lookups,
8080
+ # method calls, and/or array allocations.
8081
+ #
8082
+ # Instead, you can call #type, which will return to you a symbol that you
8083
+ # can use for comparison. This is faster than the other approaches because
8084
+ # it uses a single integer comparison, but also because if you're on CRuby
8085
+ # you can take advantage of the fact that case statements with all symbol
8086
+ # keys will use a jump table.
8087
+ #
8088
+ # def type: () -> Symbol
8089
+ def type
8090
+ :index_operator_write_node
8091
+ end
8092
+
8093
+ # Similar to #type, this method returns a symbol that you can use for
8094
+ # splitting on the type of the node without having to do a long === chain.
8095
+ # Note that like #type, it will still be slower than using == for a single
8096
+ # class, but should be faster in a case statement or an array comparison.
8097
+ #
8098
+ # def self.type: () -> Symbol
8099
+ def self.type
8100
+ :index_operator_write_node
8101
+ end
8102
+ end
8103
+
8104
+ # Represents the use of the `||=` operator on a call to `[]`.
8105
+ #
8106
+ # foo.bar[baz] ||= value
8107
+ # ^^^^^^^^^^^^^^^^^^^^^^
8108
+ class IndexOrWriteNode < Node
8109
+ # attr_reader receiver: Node?
8110
+ attr_reader :receiver
8111
+
8112
+ # attr_reader call_operator_loc: Location?
8113
+ attr_reader :call_operator_loc
8114
+
8115
+ # attr_reader opening_loc: Location
8116
+ attr_reader :opening_loc
8117
+
8118
+ # attr_reader arguments: ArgumentsNode?
8119
+ attr_reader :arguments
8120
+
8121
+ # attr_reader closing_loc: Location
8122
+ attr_reader :closing_loc
8123
+
8124
+ # attr_reader block: Node?
8125
+ attr_reader :block
8126
+
8127
+ # attr_reader flags: Integer
8128
+ private attr_reader :flags
8129
+
8130
+ # attr_reader operator_loc: Location
8131
+ attr_reader :operator_loc
8132
+
8133
+ # attr_reader value: Node
8134
+ attr_reader :value
8135
+
8136
+ # def initialize: (receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, flags: Integer, operator_loc: Location, value: Node, location: Location) -> void
8137
+ def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
8138
+ @receiver = receiver
8139
+ @call_operator_loc = call_operator_loc
8140
+ @opening_loc = opening_loc
8141
+ @arguments = arguments
8142
+ @closing_loc = closing_loc
8143
+ @block = block
8144
+ @flags = flags
8145
+ @operator_loc = operator_loc
8146
+ @value = value
8147
+ @location = location
8148
+ end
8149
+
8150
+ # def accept: (visitor: Visitor) -> void
8151
+ def accept(visitor)
8152
+ visitor.visit_index_or_write_node(self)
8153
+ end
8154
+
8155
+ # def child_nodes: () -> Array[nil | Node]
8156
+ def child_nodes
8157
+ [receiver, arguments, block, value]
8158
+ end
8159
+
8160
+ # def compact_child_nodes: () -> Array[Node]
8161
+ def compact_child_nodes
8162
+ compact = []
8163
+ compact << receiver if receiver
8164
+ compact << arguments if arguments
8165
+ compact << block if block
8166
+ compact << value
8167
+ compact
8168
+ end
8169
+
8170
+ # def comment_targets: () -> Array[Node | Location]
8171
+ def comment_targets
8172
+ [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value]
8173
+ end
8174
+
8175
+ # def copy: (**params) -> IndexOrWriteNode
8176
+ def copy(**params)
8177
+ IndexOrWriteNode.new(
8178
+ params.fetch(:receiver) { receiver },
8179
+ params.fetch(:call_operator_loc) { call_operator_loc },
8180
+ params.fetch(:opening_loc) { opening_loc },
8181
+ params.fetch(:arguments) { arguments },
8182
+ params.fetch(:closing_loc) { closing_loc },
8183
+ params.fetch(:block) { block },
8184
+ params.fetch(:flags) { flags },
8185
+ params.fetch(:operator_loc) { operator_loc },
8186
+ params.fetch(:value) { value },
8187
+ params.fetch(:location) { location },
8188
+ )
8189
+ end
8190
+
8191
+ # def deconstruct: () -> Array[nil | Node]
8192
+ alias deconstruct child_nodes
8193
+
8194
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
8195
+ def deconstruct_keys(keys)
8196
+ { receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, operator_loc: operator_loc, value: value, location: location }
8197
+ end
8198
+
8199
+ # def call_operator: () -> String?
8200
+ def call_operator
8201
+ call_operator_loc&.slice
8202
+ end
8203
+
8204
+ # def opening: () -> String
8205
+ def opening
8206
+ opening_loc.slice
8207
+ end
8208
+
8209
+ # def closing: () -> String
8210
+ def closing
8211
+ closing_loc.slice
8212
+ end
8213
+
8214
+ # def safe_navigation?: () -> bool
8215
+ def safe_navigation?
8216
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
8217
+ end
8218
+
8219
+ # def variable_call?: () -> bool
8220
+ def variable_call?
8221
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
8222
+ end
8223
+
8224
+ # def operator: () -> String
8225
+ def operator
8226
+ operator_loc.slice
8227
+ end
8228
+
8229
+ def inspect(inspector = NodeInspector.new)
8230
+ inspector << inspector.header(self)
8231
+ if (receiver = self.receiver).nil?
8232
+ inspector << "├── receiver: ∅\n"
8233
+ else
8234
+ inspector << "├── receiver:\n"
8235
+ inspector << receiver.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8236
+ end
8237
+ inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
8238
+ inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
8239
+ if (arguments = self.arguments).nil?
8240
+ inspector << "├── arguments: ∅\n"
8241
+ else
8242
+ inspector << "├── arguments:\n"
8243
+ inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8244
+ end
8245
+ inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
8246
+ if (block = self.block).nil?
8247
+ inspector << "├── block: ∅\n"
8248
+ else
8249
+ inspector << "├── block:\n"
8250
+ inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8251
+ end
8252
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
8253
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
8254
+ inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
8255
+ inspector << "└── value:\n"
8256
+ inspector << inspector.child_node(value, " ")
8257
+ inspector.to_str
8258
+ end
8259
+
8260
+ # Sometimes you want to check an instance of a node against a list of
8261
+ # classes to see what kind of behavior to perform. Usually this is done by
8262
+ # calling `[cls1, cls2].include?(node.class)` or putting the node into a
8263
+ # case statement and doing `case node; when cls1; when cls2; end`. Both of
8264
+ # these approaches are relatively slow because of the constant lookups,
8265
+ # method calls, and/or array allocations.
8266
+ #
8267
+ # Instead, you can call #type, which will return to you a symbol that you
8268
+ # can use for comparison. This is faster than the other approaches because
8269
+ # it uses a single integer comparison, but also because if you're on CRuby
8270
+ # you can take advantage of the fact that case statements with all symbol
8271
+ # keys will use a jump table.
8272
+ #
8273
+ # def type: () -> Symbol
8274
+ def type
8275
+ :index_or_write_node
8276
+ end
8277
+
8278
+ # Similar to #type, this method returns a symbol that you can use for
8279
+ # splitting on the type of the node without having to do a long === chain.
8280
+ # Note that like #type, it will still be slower than using == for a single
8281
+ # class, but should be faster in a case statement or an array comparison.
8282
+ #
8283
+ # def self.type: () -> Symbol
8284
+ def self.type
8285
+ :index_or_write_node
8286
+ end
8287
+ end
8288
+
7829
8289
  # Represents the use of the `&&=` operator for assignment to an instance variable.
7830
8290
  #
7831
8291
  # @target &&= value