prism 0.17.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -1
  3. data/Makefile +5 -5
  4. data/README.md +4 -3
  5. data/config.yml +214 -68
  6. data/docs/build_system.md +6 -6
  7. data/docs/building.md +10 -3
  8. data/docs/configuration.md +11 -9
  9. data/docs/encoding.md +92 -88
  10. data/docs/heredocs.md +1 -1
  11. data/docs/javascript.md +29 -1
  12. data/docs/local_variable_depth.md +229 -0
  13. data/docs/ruby_api.md +16 -0
  14. data/docs/serialization.md +18 -13
  15. data/ext/prism/api_node.c +411 -240
  16. data/ext/prism/extconf.rb +97 -127
  17. data/ext/prism/extension.c +97 -33
  18. data/ext/prism/extension.h +1 -1
  19. data/include/prism/ast.h +377 -159
  20. data/include/prism/defines.h +17 -0
  21. data/include/prism/diagnostic.h +38 -6
  22. data/include/prism/{enc/pm_encoding.h → encoding.h} +126 -64
  23. data/include/prism/options.h +2 -2
  24. data/include/prism/parser.h +62 -36
  25. data/include/prism/regexp.h +2 -2
  26. data/include/prism/util/pm_buffer.h +9 -1
  27. data/include/prism/util/pm_memchr.h +2 -2
  28. data/include/prism/util/pm_strpbrk.h +3 -3
  29. data/include/prism/version.h +3 -3
  30. data/include/prism.h +13 -15
  31. data/lib/prism/compiler.rb +15 -3
  32. data/lib/prism/debug.rb +13 -4
  33. data/lib/prism/desugar_compiler.rb +4 -3
  34. data/lib/prism/dispatcher.rb +70 -14
  35. data/lib/prism/dot_visitor.rb +4612 -0
  36. data/lib/prism/dsl.rb +77 -57
  37. data/lib/prism/ffi.rb +19 -6
  38. data/lib/prism/lex_compat.rb +19 -9
  39. data/lib/prism/mutation_compiler.rb +26 -6
  40. data/lib/prism/node.rb +1314 -522
  41. data/lib/prism/node_ext.rb +102 -19
  42. data/lib/prism/parse_result.rb +58 -27
  43. data/lib/prism/ripper_compat.rb +49 -34
  44. data/lib/prism/serialize.rb +251 -227
  45. data/lib/prism/visitor.rb +15 -3
  46. data/lib/prism.rb +21 -4
  47. data/prism.gemspec +7 -9
  48. data/rbi/prism.rbi +688 -284
  49. data/rbi/prism_static.rbi +3 -0
  50. data/sig/prism.rbs +426 -156
  51. data/sig/prism_static.rbs +1 -0
  52. data/src/diagnostic.c +280 -216
  53. data/src/encoding.c +5137 -0
  54. data/src/node.c +99 -21
  55. data/src/options.c +21 -2
  56. data/src/prettyprint.c +1743 -1241
  57. data/src/prism.c +1774 -831
  58. data/src/regexp.c +15 -15
  59. data/src/serialize.c +261 -164
  60. data/src/util/pm_buffer.c +10 -1
  61. data/src/util/pm_memchr.c +1 -1
  62. data/src/util/pm_strpbrk.c +4 -4
  63. metadata +8 -10
  64. data/src/enc/pm_big5.c +0 -53
  65. data/src/enc/pm_euc_jp.c +0 -59
  66. data/src/enc/pm_gbk.c +0 -62
  67. data/src/enc/pm_shift_jis.c +0 -57
  68. data/src/enc/pm_tables.c +0 -743
  69. data/src/enc/pm_unicode.c +0 -2369
  70. data/src/enc/pm_windows_31j.c +0 -57
data/lib/prism/node.rb CHANGED
@@ -38,6 +38,11 @@ module Prism
38
38
  end
39
39
  q.current_group.break
40
40
  end
41
+
42
+ # Convert this node into a graphviz dot graph string.
43
+ def to_dot
44
+ DotVisitor.new.tap { |visitor| accept(visitor) }.to_dot
45
+ end
41
46
  end
42
47
 
43
48
  # Represents the use of the `alias` keyword to alias a global variable.
@@ -465,16 +470,16 @@ module Prism
465
470
  # return foo, bar, baz
466
471
  # ^^^^^^^^^^^^^
467
472
  class ArgumentsNode < Node
468
- # attr_reader arguments: Array[Node]
469
- attr_reader :arguments
470
-
471
473
  # attr_reader flags: Integer
472
474
  private attr_reader :flags
473
475
 
474
- # def initialize: (arguments: Array[Node], flags: Integer, location: Location) -> void
475
- def initialize(arguments, flags, location)
476
- @arguments = arguments
476
+ # attr_reader arguments: Array[Node]
477
+ attr_reader :arguments
478
+
479
+ # def initialize: (flags: Integer, arguments: Array[Node], location: Location) -> void
480
+ def initialize(flags, arguments, location)
477
481
  @flags = flags
482
+ @arguments = arguments
478
483
  @location = location
479
484
  end
480
485
 
@@ -501,8 +506,8 @@ module Prism
501
506
  # def copy: (**params) -> ArgumentsNode
502
507
  def copy(**params)
503
508
  ArgumentsNode.new(
504
- params.fetch(:arguments) { arguments },
505
509
  params.fetch(:flags) { flags },
510
+ params.fetch(:arguments) { arguments },
506
511
  params.fetch(:location) { location },
507
512
  )
508
513
  end
@@ -512,20 +517,20 @@ module Prism
512
517
 
513
518
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
514
519
  def deconstruct_keys(keys)
515
- { arguments: arguments, flags: flags, location: location }
520
+ { flags: flags, arguments: arguments, location: location }
516
521
  end
517
522
 
518
- # def keyword_splat?: () -> bool
519
- def keyword_splat?
520
- flags.anybits?(ArgumentsNodeFlags::KEYWORD_SPLAT)
523
+ # def contains_keyword_splat?: () -> bool
524
+ def contains_keyword_splat?
525
+ flags.anybits?(ArgumentsNodeFlags::CONTAINS_KEYWORD_SPLAT)
521
526
  end
522
527
 
523
528
  # def inspect(inspector: NodeInspector) -> String
524
529
  def inspect(inspector = NodeInspector.new)
525
530
  inspector << inspector.header(self)
526
- inspector << "├── arguments: #{inspector.list("#{inspector.prefix}│ ", arguments)}"
527
- flags = [("keyword_splat" if keyword_splat?)].compact
528
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
531
+ flags = [("contains_keyword_splat" if contains_keyword_splat?)].compact
532
+ inspector << "├── flags: #{flags.empty? ? "" : flags.join(", ")}\n"
533
+ inspector << "└── arguments: #{inspector.list("#{inspector.prefix} ", arguments)}"
529
534
  inspector.to_str
530
535
  end
531
536
 
@@ -564,6 +569,9 @@ module Prism
564
569
  # [1, 2, 3]
565
570
  # ^^^^^^^^^
566
571
  class ArrayNode < Node
572
+ # attr_reader flags: Integer
573
+ private attr_reader :flags
574
+
567
575
  # attr_reader elements: Array[Node]
568
576
  attr_reader :elements
569
577
 
@@ -573,8 +581,9 @@ module Prism
573
581
  # attr_reader closing_loc: Location?
574
582
  attr_reader :closing_loc
575
583
 
576
- # def initialize: (elements: Array[Node], opening_loc: Location?, closing_loc: Location?, location: Location) -> void
577
- def initialize(elements, opening_loc, closing_loc, location)
584
+ # def initialize: (flags: Integer, elements: Array[Node], opening_loc: Location?, closing_loc: Location?, location: Location) -> void
585
+ def initialize(flags, elements, opening_loc, closing_loc, location)
586
+ @flags = flags
578
587
  @elements = elements
579
588
  @opening_loc = opening_loc
580
589
  @closing_loc = closing_loc
@@ -604,6 +613,7 @@ module Prism
604
613
  # def copy: (**params) -> ArrayNode
605
614
  def copy(**params)
606
615
  ArrayNode.new(
616
+ params.fetch(:flags) { flags },
607
617
  params.fetch(:elements) { elements },
608
618
  params.fetch(:opening_loc) { opening_loc },
609
619
  params.fetch(:closing_loc) { closing_loc },
@@ -616,7 +626,12 @@ module Prism
616
626
 
617
627
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
618
628
  def deconstruct_keys(keys)
619
- { elements: elements, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
629
+ { flags: flags, elements: elements, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
630
+ end
631
+
632
+ # def contains_splat?: () -> bool
633
+ def contains_splat?
634
+ flags.anybits?(ArrayNodeFlags::CONTAINS_SPLAT)
620
635
  end
621
636
 
622
637
  # def opening: () -> String?
@@ -632,6 +647,8 @@ module Prism
632
647
  # def inspect(inspector: NodeInspector) -> String
633
648
  def inspect(inspector = NodeInspector.new)
634
649
  inspector << inspector.header(self)
650
+ flags = [("contains_splat" if contains_splat?)].compact
651
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
635
652
  inspector << "├── elements: #{inspector.list("#{inspector.prefix}│ ", elements)}"
636
653
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
637
654
  inspector << "└── closing_loc: #{inspector.location(closing_loc)}\n"
@@ -1477,7 +1494,10 @@ module Prism
1477
1494
  # attr_reader locals: Array[Symbol]
1478
1495
  attr_reader :locals
1479
1496
 
1480
- # attr_reader parameters: BlockParametersNode?
1497
+ # attr_reader locals_body_index: Integer
1498
+ attr_reader :locals_body_index
1499
+
1500
+ # attr_reader parameters: Node?
1481
1501
  attr_reader :parameters
1482
1502
 
1483
1503
  # attr_reader body: Node?
@@ -1489,9 +1509,10 @@ module Prism
1489
1509
  # attr_reader closing_loc: Location
1490
1510
  attr_reader :closing_loc
1491
1511
 
1492
- # def initialize: (locals: Array[Symbol], parameters: BlockParametersNode?, body: Node?, opening_loc: Location, closing_loc: Location, location: Location) -> void
1493
- def initialize(locals, parameters, body, opening_loc, closing_loc, location)
1512
+ # def initialize: (locals: Array[Symbol], locals_body_index: Integer, parameters: Node?, body: Node?, opening_loc: Location, closing_loc: Location, location: Location) -> void
1513
+ def initialize(locals, locals_body_index, parameters, body, opening_loc, closing_loc, location)
1494
1514
  @locals = locals
1515
+ @locals_body_index = locals_body_index
1495
1516
  @parameters = parameters
1496
1517
  @body = body
1497
1518
  @opening_loc = opening_loc
@@ -1526,6 +1547,7 @@ module Prism
1526
1547
  def copy(**params)
1527
1548
  BlockNode.new(
1528
1549
  params.fetch(:locals) { locals },
1550
+ params.fetch(:locals_body_index) { locals_body_index },
1529
1551
  params.fetch(:parameters) { parameters },
1530
1552
  params.fetch(:body) { body },
1531
1553
  params.fetch(:opening_loc) { opening_loc },
@@ -1539,7 +1561,7 @@ module Prism
1539
1561
 
1540
1562
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
1541
1563
  def deconstruct_keys(keys)
1542
- { locals: locals, parameters: parameters, body: body, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
1564
+ { locals: locals, locals_body_index: locals_body_index, parameters: parameters, body: body, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
1543
1565
  end
1544
1566
 
1545
1567
  # def opening: () -> String
@@ -1556,6 +1578,7 @@ module Prism
1556
1578
  def inspect(inspector = NodeInspector.new)
1557
1579
  inspector << inspector.header(self)
1558
1580
  inspector << "├── locals: #{locals.inspect}\n"
1581
+ inspector << "├── locals_body_index: #{locals_body_index.inspect}\n"
1559
1582
  if (parameters = self.parameters).nil?
1560
1583
  inspector << "├── parameters: ∅\n"
1561
1584
  else
@@ -1945,6 +1968,9 @@ module Prism
1945
1968
  # foo.bar &&= value
1946
1969
  # ^^^^^^^^^^^^^^^^^
1947
1970
  class CallAndWriteNode < Node
1971
+ # attr_reader flags: Integer
1972
+ private attr_reader :flags
1973
+
1948
1974
  # attr_reader receiver: Node?
1949
1975
  attr_reader :receiver
1950
1976
 
@@ -1954,9 +1980,6 @@ module Prism
1954
1980
  # attr_reader message_loc: Location?
1955
1981
  attr_reader :message_loc
1956
1982
 
1957
- # attr_reader flags: Integer
1958
- private attr_reader :flags
1959
-
1960
1983
  # attr_reader read_name: Symbol
1961
1984
  attr_reader :read_name
1962
1985
 
@@ -1969,12 +1992,12 @@ module Prism
1969
1992
  # attr_reader value: Node
1970
1993
  attr_reader :value
1971
1994
 
1972
- # 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
1973
- def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
1995
+ # def initialize: (flags: Integer, receiver: Node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> void
1996
+ def initialize(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value, location)
1997
+ @flags = flags
1974
1998
  @receiver = receiver
1975
1999
  @call_operator_loc = call_operator_loc
1976
2000
  @message_loc = message_loc
1977
- @flags = flags
1978
2001
  @read_name = read_name
1979
2002
  @write_name = write_name
1980
2003
  @operator_loc = operator_loc
@@ -2008,10 +2031,10 @@ module Prism
2008
2031
  # def copy: (**params) -> CallAndWriteNode
2009
2032
  def copy(**params)
2010
2033
  CallAndWriteNode.new(
2034
+ params.fetch(:flags) { flags },
2011
2035
  params.fetch(:receiver) { receiver },
2012
2036
  params.fetch(:call_operator_loc) { call_operator_loc },
2013
2037
  params.fetch(:message_loc) { message_loc },
2014
- params.fetch(:flags) { flags },
2015
2038
  params.fetch(:read_name) { read_name },
2016
2039
  params.fetch(:write_name) { write_name },
2017
2040
  params.fetch(:operator_loc) { operator_loc },
@@ -2025,17 +2048,7 @@ module Prism
2025
2048
 
2026
2049
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2027
2050
  def deconstruct_keys(keys)
2028
- { 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 }
2029
- end
2030
-
2031
- # def call_operator: () -> String?
2032
- def call_operator
2033
- call_operator_loc&.slice
2034
- end
2035
-
2036
- # def message: () -> String?
2037
- def message
2038
- message_loc&.slice
2051
+ { flags: flags, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value, location: location }
2039
2052
  end
2040
2053
 
2041
2054
  # def safe_navigation?: () -> bool
@@ -2048,6 +2061,21 @@ module Prism
2048
2061
  flags.anybits?(CallNodeFlags::VARIABLE_CALL)
2049
2062
  end
2050
2063
 
2064
+ # def attribute_write?: () -> bool
2065
+ def attribute_write?
2066
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
2067
+ end
2068
+
2069
+ # def call_operator: () -> String?
2070
+ def call_operator
2071
+ call_operator_loc&.slice
2072
+ end
2073
+
2074
+ # def message: () -> String?
2075
+ def message
2076
+ message_loc&.slice
2077
+ end
2078
+
2051
2079
  # def operator: () -> String
2052
2080
  def operator
2053
2081
  operator_loc.slice
@@ -2056,6 +2084,8 @@ module Prism
2056
2084
  # def inspect(inspector: NodeInspector) -> String
2057
2085
  def inspect(inspector = NodeInspector.new)
2058
2086
  inspector << inspector.header(self)
2087
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
2088
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2059
2089
  if (receiver = self.receiver).nil?
2060
2090
  inspector << "├── receiver: ∅\n"
2061
2091
  else
@@ -2064,8 +2094,6 @@ module Prism
2064
2094
  end
2065
2095
  inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
2066
2096
  inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
2067
- flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
2068
- inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2069
2097
  inspector << "├── read_name: #{read_name.inspect}\n"
2070
2098
  inspector << "├── write_name: #{write_name.inspect}\n"
2071
2099
  inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
@@ -2123,12 +2151,18 @@ module Prism
2123
2151
  # foo&.bar
2124
2152
  # ^^^^^^^^
2125
2153
  class CallNode < Node
2154
+ # attr_reader flags: Integer
2155
+ private attr_reader :flags
2156
+
2126
2157
  # attr_reader receiver: Node?
2127
2158
  attr_reader :receiver
2128
2159
 
2129
2160
  # attr_reader call_operator_loc: Location?
2130
2161
  attr_reader :call_operator_loc
2131
2162
 
2163
+ # attr_reader name: Symbol
2164
+ attr_reader :name
2165
+
2132
2166
  # attr_reader message_loc: Location?
2133
2167
  attr_reader :message_loc
2134
2168
 
@@ -2144,23 +2178,17 @@ module Prism
2144
2178
  # attr_reader block: Node?
2145
2179
  attr_reader :block
2146
2180
 
2147
- # attr_reader flags: Integer
2148
- private attr_reader :flags
2149
-
2150
- # attr_reader name: Symbol
2151
- attr_reader :name
2152
-
2153
- # def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, block: Node?, flags: Integer, name: Symbol, location: Location) -> void
2154
- def initialize(receiver, call_operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, location)
2181
+ # def initialize: (flags: Integer, receiver: Node?, call_operator_loc: Location?, name: Symbol, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, block: Node?, location: Location) -> void
2182
+ def initialize(flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block, location)
2183
+ @flags = flags
2155
2184
  @receiver = receiver
2156
2185
  @call_operator_loc = call_operator_loc
2186
+ @name = name
2157
2187
  @message_loc = message_loc
2158
2188
  @opening_loc = opening_loc
2159
2189
  @arguments = arguments
2160
2190
  @closing_loc = closing_loc
2161
2191
  @block = block
2162
- @flags = flags
2163
- @name = name
2164
2192
  @location = location
2165
2193
  end
2166
2194
 
@@ -2191,15 +2219,15 @@ module Prism
2191
2219
  # def copy: (**params) -> CallNode
2192
2220
  def copy(**params)
2193
2221
  CallNode.new(
2222
+ params.fetch(:flags) { flags },
2194
2223
  params.fetch(:receiver) { receiver },
2195
2224
  params.fetch(:call_operator_loc) { call_operator_loc },
2225
+ params.fetch(:name) { name },
2196
2226
  params.fetch(:message_loc) { message_loc },
2197
2227
  params.fetch(:opening_loc) { opening_loc },
2198
2228
  params.fetch(:arguments) { arguments },
2199
2229
  params.fetch(:closing_loc) { closing_loc },
2200
2230
  params.fetch(:block) { block },
2201
- params.fetch(:flags) { flags },
2202
- params.fetch(:name) { name },
2203
2231
  params.fetch(:location) { location },
2204
2232
  )
2205
2233
  end
@@ -2209,7 +2237,22 @@ module Prism
2209
2237
 
2210
2238
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2211
2239
  def deconstruct_keys(keys)
2212
- { receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, name: name, location: location }
2240
+ { flags: flags, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, location: location }
2241
+ end
2242
+
2243
+ # def safe_navigation?: () -> bool
2244
+ def safe_navigation?
2245
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
2246
+ end
2247
+
2248
+ # def variable_call?: () -> bool
2249
+ def variable_call?
2250
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
2251
+ end
2252
+
2253
+ # def attribute_write?: () -> bool
2254
+ def attribute_write?
2255
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
2213
2256
  end
2214
2257
 
2215
2258
  # def call_operator: () -> String?
@@ -2232,19 +2275,11 @@ module Prism
2232
2275
  closing_loc&.slice
2233
2276
  end
2234
2277
 
2235
- # def safe_navigation?: () -> bool
2236
- def safe_navigation?
2237
- flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
2238
- end
2239
-
2240
- # def variable_call?: () -> bool
2241
- def variable_call?
2242
- flags.anybits?(CallNodeFlags::VARIABLE_CALL)
2243
- end
2244
-
2245
2278
  # def inspect(inspector: NodeInspector) -> String
2246
2279
  def inspect(inspector = NodeInspector.new)
2247
2280
  inspector << inspector.header(self)
2281
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
2282
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2248
2283
  if (receiver = self.receiver).nil?
2249
2284
  inspector << "├── receiver: ∅\n"
2250
2285
  else
@@ -2252,6 +2287,7 @@ module Prism
2252
2287
  inspector << receiver.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
2253
2288
  end
2254
2289
  inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
2290
+ inspector << "├── name: #{name.inspect}\n"
2255
2291
  inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
2256
2292
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
2257
2293
  if (arguments = self.arguments).nil?
@@ -2262,14 +2298,11 @@ module Prism
2262
2298
  end
2263
2299
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
2264
2300
  if (block = self.block).nil?
2265
- inspector << "├── block: ∅\n"
2301
+ inspector << "└── block: ∅\n"
2266
2302
  else
2267
- inspector << "├── block:\n"
2268
- inspector << block.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
2303
+ inspector << "└── block:\n"
2304
+ inspector << block.inspect(inspector.child_inspector(" ")).delete_prefix(inspector.prefix)
2269
2305
  end
2270
- flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
2271
- inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2272
- inspector << "└── name: #{name.inspect}\n"
2273
2306
  inspector.to_str
2274
2307
  end
2275
2308
 
@@ -2307,6 +2340,9 @@ module Prism
2307
2340
  # foo.bar += baz
2308
2341
  # ^^^^^^^^^^^^^^
2309
2342
  class CallOperatorWriteNode < Node
2343
+ # attr_reader flags: Integer
2344
+ private attr_reader :flags
2345
+
2310
2346
  # attr_reader receiver: Node?
2311
2347
  attr_reader :receiver
2312
2348
 
@@ -2316,9 +2352,6 @@ module Prism
2316
2352
  # attr_reader message_loc: Location?
2317
2353
  attr_reader :message_loc
2318
2354
 
2319
- # attr_reader flags: Integer
2320
- private attr_reader :flags
2321
-
2322
2355
  # attr_reader read_name: Symbol
2323
2356
  attr_reader :read_name
2324
2357
 
@@ -2334,12 +2367,12 @@ module Prism
2334
2367
  # attr_reader value: Node
2335
2368
  attr_reader :value
2336
2369
 
2337
- # 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
2338
- def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator, operator_loc, value, location)
2370
+ # def initialize: (flags: Integer, receiver: Node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator: Symbol, operator_loc: Location, value: Node, location: Location) -> void
2371
+ def initialize(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator, operator_loc, value, location)
2372
+ @flags = flags
2339
2373
  @receiver = receiver
2340
2374
  @call_operator_loc = call_operator_loc
2341
2375
  @message_loc = message_loc
2342
- @flags = flags
2343
2376
  @read_name = read_name
2344
2377
  @write_name = write_name
2345
2378
  @operator = operator
@@ -2374,10 +2407,10 @@ module Prism
2374
2407
  # def copy: (**params) -> CallOperatorWriteNode
2375
2408
  def copy(**params)
2376
2409
  CallOperatorWriteNode.new(
2410
+ params.fetch(:flags) { flags },
2377
2411
  params.fetch(:receiver) { receiver },
2378
2412
  params.fetch(:call_operator_loc) { call_operator_loc },
2379
2413
  params.fetch(:message_loc) { message_loc },
2380
- params.fetch(:flags) { flags },
2381
2414
  params.fetch(:read_name) { read_name },
2382
2415
  params.fetch(:write_name) { write_name },
2383
2416
  params.fetch(:operator) { operator },
@@ -2392,17 +2425,7 @@ module Prism
2392
2425
 
2393
2426
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2394
2427
  def deconstruct_keys(keys)
2395
- { 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 }
2396
- end
2397
-
2398
- # def call_operator: () -> String?
2399
- def call_operator
2400
- call_operator_loc&.slice
2401
- end
2402
-
2403
- # def message: () -> String?
2404
- def message
2405
- message_loc&.slice
2428
+ { flags: flags, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, operator: operator, operator_loc: operator_loc, value: value, location: location }
2406
2429
  end
2407
2430
 
2408
2431
  # def safe_navigation?: () -> bool
@@ -2415,9 +2438,26 @@ module Prism
2415
2438
  flags.anybits?(CallNodeFlags::VARIABLE_CALL)
2416
2439
  end
2417
2440
 
2441
+ # def attribute_write?: () -> bool
2442
+ def attribute_write?
2443
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
2444
+ end
2445
+
2446
+ # def call_operator: () -> String?
2447
+ def call_operator
2448
+ call_operator_loc&.slice
2449
+ end
2450
+
2451
+ # def message: () -> String?
2452
+ def message
2453
+ message_loc&.slice
2454
+ end
2455
+
2418
2456
  # def inspect(inspector: NodeInspector) -> String
2419
2457
  def inspect(inspector = NodeInspector.new)
2420
2458
  inspector << inspector.header(self)
2459
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
2460
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2421
2461
  if (receiver = self.receiver).nil?
2422
2462
  inspector << "├── receiver: ∅\n"
2423
2463
  else
@@ -2426,8 +2466,6 @@ module Prism
2426
2466
  end
2427
2467
  inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
2428
2468
  inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
2429
- flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
2430
- inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2431
2469
  inspector << "├── read_name: #{read_name.inspect}\n"
2432
2470
  inspector << "├── write_name: #{write_name.inspect}\n"
2433
2471
  inspector << "├── operator: #{operator.inspect}\n"
@@ -2471,6 +2509,9 @@ module Prism
2471
2509
  # foo.bar ||= value
2472
2510
  # ^^^^^^^^^^^^^^^^^
2473
2511
  class CallOrWriteNode < Node
2512
+ # attr_reader flags: Integer
2513
+ private attr_reader :flags
2514
+
2474
2515
  # attr_reader receiver: Node?
2475
2516
  attr_reader :receiver
2476
2517
 
@@ -2480,9 +2521,6 @@ module Prism
2480
2521
  # attr_reader message_loc: Location?
2481
2522
  attr_reader :message_loc
2482
2523
 
2483
- # attr_reader flags: Integer
2484
- private attr_reader :flags
2485
-
2486
2524
  # attr_reader read_name: Symbol
2487
2525
  attr_reader :read_name
2488
2526
 
@@ -2495,12 +2533,12 @@ module Prism
2495
2533
  # attr_reader value: Node
2496
2534
  attr_reader :value
2497
2535
 
2498
- # 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
2499
- def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
2536
+ # def initialize: (flags: Integer, receiver: Node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> void
2537
+ def initialize(flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value, location)
2538
+ @flags = flags
2500
2539
  @receiver = receiver
2501
2540
  @call_operator_loc = call_operator_loc
2502
2541
  @message_loc = message_loc
2503
- @flags = flags
2504
2542
  @read_name = read_name
2505
2543
  @write_name = write_name
2506
2544
  @operator_loc = operator_loc
@@ -2534,10 +2572,10 @@ module Prism
2534
2572
  # def copy: (**params) -> CallOrWriteNode
2535
2573
  def copy(**params)
2536
2574
  CallOrWriteNode.new(
2575
+ params.fetch(:flags) { flags },
2537
2576
  params.fetch(:receiver) { receiver },
2538
2577
  params.fetch(:call_operator_loc) { call_operator_loc },
2539
2578
  params.fetch(:message_loc) { message_loc },
2540
- params.fetch(:flags) { flags },
2541
2579
  params.fetch(:read_name) { read_name },
2542
2580
  params.fetch(:write_name) { write_name },
2543
2581
  params.fetch(:operator_loc) { operator_loc },
@@ -2551,17 +2589,7 @@ module Prism
2551
2589
 
2552
2590
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2553
2591
  def deconstruct_keys(keys)
2554
- { 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 }
2555
- end
2556
-
2557
- # def call_operator: () -> String?
2558
- def call_operator
2559
- call_operator_loc&.slice
2560
- end
2561
-
2562
- # def message: () -> String?
2563
- def message
2564
- message_loc&.slice
2592
+ { flags: flags, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value, location: location }
2565
2593
  end
2566
2594
 
2567
2595
  # def safe_navigation?: () -> bool
@@ -2574,6 +2602,21 @@ module Prism
2574
2602
  flags.anybits?(CallNodeFlags::VARIABLE_CALL)
2575
2603
  end
2576
2604
 
2605
+ # def attribute_write?: () -> bool
2606
+ def attribute_write?
2607
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
2608
+ end
2609
+
2610
+ # def call_operator: () -> String?
2611
+ def call_operator
2612
+ call_operator_loc&.slice
2613
+ end
2614
+
2615
+ # def message: () -> String?
2616
+ def message
2617
+ message_loc&.slice
2618
+ end
2619
+
2577
2620
  # def operator: () -> String
2578
2621
  def operator
2579
2622
  operator_loc.slice
@@ -2582,6 +2625,8 @@ module Prism
2582
2625
  # def inspect(inspector: NodeInspector) -> String
2583
2626
  def inspect(inspector = NodeInspector.new)
2584
2627
  inspector << inspector.header(self)
2628
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
2629
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2585
2630
  if (receiver = self.receiver).nil?
2586
2631
  inspector << "├── receiver: ∅\n"
2587
2632
  else
@@ -2590,8 +2635,6 @@ module Prism
2590
2635
  end
2591
2636
  inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
2592
2637
  inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
2593
- flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
2594
- inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2595
2638
  inspector << "├── read_name: #{read_name.inspect}\n"
2596
2639
  inspector << "├── write_name: #{write_name.inspect}\n"
2597
2640
  inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
@@ -2629,54 +2672,72 @@ module Prism
2629
2672
  end
2630
2673
  end
2631
2674
 
2632
- # Represents assigning to a local variable in pattern matching.
2675
+ # Represents assigning to a method call.
2633
2676
  #
2634
- # foo => [bar => baz]
2635
- # ^^^^^^^^^^^^
2636
- class CapturePatternNode < Node
2637
- # attr_reader value: Node
2638
- attr_reader :value
2677
+ # foo.bar, = 1
2678
+ # ^^^^^^^
2679
+ #
2680
+ # begin
2681
+ # rescue => foo.bar
2682
+ # ^^^^^^^
2683
+ # end
2684
+ #
2685
+ # for foo.bar in baz do end
2686
+ # ^^^^^^^
2687
+ class CallTargetNode < Node
2688
+ # attr_reader flags: Integer
2689
+ private attr_reader :flags
2639
2690
 
2640
- # attr_reader target: Node
2641
- attr_reader :target
2691
+ # attr_reader receiver: Node
2692
+ attr_reader :receiver
2642
2693
 
2643
- # attr_reader operator_loc: Location
2644
- attr_reader :operator_loc
2694
+ # attr_reader call_operator_loc: Location
2695
+ attr_reader :call_operator_loc
2645
2696
 
2646
- # def initialize: (value: Node, target: Node, operator_loc: Location, location: Location) -> void
2647
- def initialize(value, target, operator_loc, location)
2648
- @value = value
2649
- @target = target
2650
- @operator_loc = operator_loc
2697
+ # attr_reader name: Symbol
2698
+ attr_reader :name
2699
+
2700
+ # attr_reader message_loc: Location
2701
+ attr_reader :message_loc
2702
+
2703
+ # def initialize: (flags: Integer, receiver: Node, call_operator_loc: Location, name: Symbol, message_loc: Location, location: Location) -> void
2704
+ def initialize(flags, receiver, call_operator_loc, name, message_loc, location)
2705
+ @flags = flags
2706
+ @receiver = receiver
2707
+ @call_operator_loc = call_operator_loc
2708
+ @name = name
2709
+ @message_loc = message_loc
2651
2710
  @location = location
2652
2711
  end
2653
2712
 
2654
2713
  # def accept: (visitor: Visitor) -> void
2655
2714
  def accept(visitor)
2656
- visitor.visit_capture_pattern_node(self)
2715
+ visitor.visit_call_target_node(self)
2657
2716
  end
2658
2717
 
2659
2718
  # def child_nodes: () -> Array[nil | Node]
2660
2719
  def child_nodes
2661
- [value, target]
2720
+ [receiver]
2662
2721
  end
2663
2722
 
2664
2723
  # def compact_child_nodes: () -> Array[Node]
2665
2724
  def compact_child_nodes
2666
- [value, target]
2725
+ [receiver]
2667
2726
  end
2668
2727
 
2669
2728
  # def comment_targets: () -> Array[Node | Location]
2670
2729
  def comment_targets
2671
- [value, target, operator_loc]
2730
+ [receiver, call_operator_loc, message_loc]
2672
2731
  end
2673
2732
 
2674
- # def copy: (**params) -> CapturePatternNode
2733
+ # def copy: (**params) -> CallTargetNode
2675
2734
  def copy(**params)
2676
- CapturePatternNode.new(
2677
- params.fetch(:value) { value },
2678
- params.fetch(:target) { target },
2679
- params.fetch(:operator_loc) { operator_loc },
2735
+ CallTargetNode.new(
2736
+ params.fetch(:flags) { flags },
2737
+ params.fetch(:receiver) { receiver },
2738
+ params.fetch(:call_operator_loc) { call_operator_loc },
2739
+ params.fetch(:name) { name },
2740
+ params.fetch(:message_loc) { message_loc },
2680
2741
  params.fetch(:location) { location },
2681
2742
  )
2682
2743
  end
@@ -2686,22 +2747,44 @@ module Prism
2686
2747
 
2687
2748
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2688
2749
  def deconstruct_keys(keys)
2689
- { value: value, target: target, operator_loc: operator_loc, location: location }
2750
+ { flags: flags, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc, location: location }
2690
2751
  end
2691
2752
 
2692
- # def operator: () -> String
2693
- def operator
2694
- operator_loc.slice
2753
+ # def safe_navigation?: () -> bool
2754
+ def safe_navigation?
2755
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
2756
+ end
2757
+
2758
+ # def variable_call?: () -> bool
2759
+ def variable_call?
2760
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
2761
+ end
2762
+
2763
+ # def attribute_write?: () -> bool
2764
+ def attribute_write?
2765
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
2766
+ end
2767
+
2768
+ # def call_operator: () -> String
2769
+ def call_operator
2770
+ call_operator_loc.slice
2771
+ end
2772
+
2773
+ # def message: () -> String
2774
+ def message
2775
+ message_loc.slice
2695
2776
  end
2696
2777
 
2697
2778
  # def inspect(inspector: NodeInspector) -> String
2698
2779
  def inspect(inspector = NodeInspector.new)
2699
2780
  inspector << inspector.header(self)
2700
- inspector << "├── value:\n"
2701
- inspector << inspector.child_node(value, "")
2702
- inspector << "├── target:\n"
2703
- inspector << inspector.child_node(target, "│ ")
2704
- inspector << "└── operator_loc: #{inspector.location(operator_loc)}\n"
2781
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
2782
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
2783
+ inspector << "├── receiver:\n"
2784
+ inspector << inspector.child_node(receiver, "│ ")
2785
+ inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
2786
+ inspector << "├── name: #{name.inspect}\n"
2787
+ inspector << "└── message_loc: #{inspector.location(message_loc)}\n"
2705
2788
  inspector.to_str
2706
2789
  end
2707
2790
 
@@ -2720,7 +2803,7 @@ module Prism
2720
2803
  #
2721
2804
  # def type: () -> Symbol
2722
2805
  def type
2723
- :capture_pattern_node
2806
+ :call_target_node
2724
2807
  end
2725
2808
 
2726
2809
  # Similar to #type, this method returns a symbol that you can use for
@@ -2730,11 +2813,252 @@ module Prism
2730
2813
  #
2731
2814
  # def self.type: () -> Symbol
2732
2815
  def self.type
2733
- :capture_pattern_node
2816
+ :call_target_node
2734
2817
  end
2735
2818
  end
2736
2819
 
2737
- # Represents the use of a case statement.
2820
+ # Represents assigning to a local variable in pattern matching.
2821
+ #
2822
+ # foo => [bar => baz]
2823
+ # ^^^^^^^^^^^^
2824
+ class CapturePatternNode < Node
2825
+ # attr_reader value: Node
2826
+ attr_reader :value
2827
+
2828
+ # attr_reader target: Node
2829
+ attr_reader :target
2830
+
2831
+ # attr_reader operator_loc: Location
2832
+ attr_reader :operator_loc
2833
+
2834
+ # def initialize: (value: Node, target: Node, operator_loc: Location, location: Location) -> void
2835
+ def initialize(value, target, operator_loc, location)
2836
+ @value = value
2837
+ @target = target
2838
+ @operator_loc = operator_loc
2839
+ @location = location
2840
+ end
2841
+
2842
+ # def accept: (visitor: Visitor) -> void
2843
+ def accept(visitor)
2844
+ visitor.visit_capture_pattern_node(self)
2845
+ end
2846
+
2847
+ # def child_nodes: () -> Array[nil | Node]
2848
+ def child_nodes
2849
+ [value, target]
2850
+ end
2851
+
2852
+ # def compact_child_nodes: () -> Array[Node]
2853
+ def compact_child_nodes
2854
+ [value, target]
2855
+ end
2856
+
2857
+ # def comment_targets: () -> Array[Node | Location]
2858
+ def comment_targets
2859
+ [value, target, operator_loc]
2860
+ end
2861
+
2862
+ # def copy: (**params) -> CapturePatternNode
2863
+ def copy(**params)
2864
+ CapturePatternNode.new(
2865
+ params.fetch(:value) { value },
2866
+ params.fetch(:target) { target },
2867
+ params.fetch(:operator_loc) { operator_loc },
2868
+ params.fetch(:location) { location },
2869
+ )
2870
+ end
2871
+
2872
+ # def deconstruct: () -> Array[nil | Node]
2873
+ alias deconstruct child_nodes
2874
+
2875
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2876
+ def deconstruct_keys(keys)
2877
+ { value: value, target: target, operator_loc: operator_loc, location: location }
2878
+ end
2879
+
2880
+ # def operator: () -> String
2881
+ def operator
2882
+ operator_loc.slice
2883
+ end
2884
+
2885
+ # def inspect(inspector: NodeInspector) -> String
2886
+ def inspect(inspector = NodeInspector.new)
2887
+ inspector << inspector.header(self)
2888
+ inspector << "├── value:\n"
2889
+ inspector << inspector.child_node(value, "│ ")
2890
+ inspector << "├── target:\n"
2891
+ inspector << inspector.child_node(target, "│ ")
2892
+ inspector << "└── operator_loc: #{inspector.location(operator_loc)}\n"
2893
+ inspector.to_str
2894
+ end
2895
+
2896
+ # Sometimes you want to check an instance of a node against a list of
2897
+ # classes to see what kind of behavior to perform. Usually this is done by
2898
+ # calling `[cls1, cls2].include?(node.class)` or putting the node into a
2899
+ # case statement and doing `case node; when cls1; when cls2; end`. Both of
2900
+ # these approaches are relatively slow because of the constant lookups,
2901
+ # method calls, and/or array allocations.
2902
+ #
2903
+ # Instead, you can call #type, which will return to you a symbol that you
2904
+ # can use for comparison. This is faster than the other approaches because
2905
+ # it uses a single integer comparison, but also because if you're on CRuby
2906
+ # you can take advantage of the fact that case statements with all symbol
2907
+ # keys will use a jump table.
2908
+ #
2909
+ # def type: () -> Symbol
2910
+ def type
2911
+ :capture_pattern_node
2912
+ end
2913
+
2914
+ # Similar to #type, this method returns a symbol that you can use for
2915
+ # splitting on the type of the node without having to do a long === chain.
2916
+ # Note that like #type, it will still be slower than using == for a single
2917
+ # class, but should be faster in a case statement or an array comparison.
2918
+ #
2919
+ # def self.type: () -> Symbol
2920
+ def self.type
2921
+ :capture_pattern_node
2922
+ end
2923
+ end
2924
+
2925
+ # Represents the use of a case statement for pattern matching.
2926
+ #
2927
+ # case true
2928
+ # in false
2929
+ # end
2930
+ # ^^^^^^^^^
2931
+ class CaseMatchNode < Node
2932
+ # attr_reader predicate: Node?
2933
+ attr_reader :predicate
2934
+
2935
+ # attr_reader conditions: Array[Node]
2936
+ attr_reader :conditions
2937
+
2938
+ # attr_reader consequent: ElseNode?
2939
+ attr_reader :consequent
2940
+
2941
+ # attr_reader case_keyword_loc: Location
2942
+ attr_reader :case_keyword_loc
2943
+
2944
+ # attr_reader end_keyword_loc: Location
2945
+ attr_reader :end_keyword_loc
2946
+
2947
+ # def initialize: (predicate: Node?, conditions: Array[Node], consequent: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location, location: Location) -> void
2948
+ def initialize(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location)
2949
+ @predicate = predicate
2950
+ @conditions = conditions
2951
+ @consequent = consequent
2952
+ @case_keyword_loc = case_keyword_loc
2953
+ @end_keyword_loc = end_keyword_loc
2954
+ @location = location
2955
+ end
2956
+
2957
+ # def accept: (visitor: Visitor) -> void
2958
+ def accept(visitor)
2959
+ visitor.visit_case_match_node(self)
2960
+ end
2961
+
2962
+ # def child_nodes: () -> Array[nil | Node]
2963
+ def child_nodes
2964
+ [predicate, *conditions, consequent]
2965
+ end
2966
+
2967
+ # def compact_child_nodes: () -> Array[Node]
2968
+ def compact_child_nodes
2969
+ compact = []
2970
+ compact << predicate if predicate
2971
+ compact.concat(conditions)
2972
+ compact << consequent if consequent
2973
+ compact
2974
+ end
2975
+
2976
+ # def comment_targets: () -> Array[Node | Location]
2977
+ def comment_targets
2978
+ [*predicate, *conditions, *consequent, case_keyword_loc, end_keyword_loc]
2979
+ end
2980
+
2981
+ # def copy: (**params) -> CaseMatchNode
2982
+ def copy(**params)
2983
+ CaseMatchNode.new(
2984
+ params.fetch(:predicate) { predicate },
2985
+ params.fetch(:conditions) { conditions },
2986
+ params.fetch(:consequent) { consequent },
2987
+ params.fetch(:case_keyword_loc) { case_keyword_loc },
2988
+ params.fetch(:end_keyword_loc) { end_keyword_loc },
2989
+ params.fetch(:location) { location },
2990
+ )
2991
+ end
2992
+
2993
+ # def deconstruct: () -> Array[nil | Node]
2994
+ alias deconstruct child_nodes
2995
+
2996
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
2997
+ def deconstruct_keys(keys)
2998
+ { predicate: predicate, conditions: conditions, consequent: consequent, case_keyword_loc: case_keyword_loc, end_keyword_loc: end_keyword_loc, location: location }
2999
+ end
3000
+
3001
+ # def case_keyword: () -> String
3002
+ def case_keyword
3003
+ case_keyword_loc.slice
3004
+ end
3005
+
3006
+ # def end_keyword: () -> String
3007
+ def end_keyword
3008
+ end_keyword_loc.slice
3009
+ end
3010
+
3011
+ # def inspect(inspector: NodeInspector) -> String
3012
+ def inspect(inspector = NodeInspector.new)
3013
+ inspector << inspector.header(self)
3014
+ if (predicate = self.predicate).nil?
3015
+ inspector << "├── predicate: ∅\n"
3016
+ else
3017
+ inspector << "├── predicate:\n"
3018
+ inspector << predicate.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
3019
+ end
3020
+ inspector << "├── conditions: #{inspector.list("#{inspector.prefix}│ ", conditions)}"
3021
+ if (consequent = self.consequent).nil?
3022
+ inspector << "├── consequent: ∅\n"
3023
+ else
3024
+ inspector << "├── consequent:\n"
3025
+ inspector << consequent.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
3026
+ end
3027
+ inspector << "├── case_keyword_loc: #{inspector.location(case_keyword_loc)}\n"
3028
+ inspector << "└── end_keyword_loc: #{inspector.location(end_keyword_loc)}\n"
3029
+ inspector.to_str
3030
+ end
3031
+
3032
+ # Sometimes you want to check an instance of a node against a list of
3033
+ # classes to see what kind of behavior to perform. Usually this is done by
3034
+ # calling `[cls1, cls2].include?(node.class)` or putting the node into a
3035
+ # case statement and doing `case node; when cls1; when cls2; end`. Both of
3036
+ # these approaches are relatively slow because of the constant lookups,
3037
+ # method calls, and/or array allocations.
3038
+ #
3039
+ # Instead, you can call #type, which will return to you a symbol that you
3040
+ # can use for comparison. This is faster than the other approaches because
3041
+ # it uses a single integer comparison, but also because if you're on CRuby
3042
+ # you can take advantage of the fact that case statements with all symbol
3043
+ # keys will use a jump table.
3044
+ #
3045
+ # def type: () -> Symbol
3046
+ def type
3047
+ :case_match_node
3048
+ end
3049
+
3050
+ # Similar to #type, this method returns a symbol that you can use for
3051
+ # splitting on the type of the node without having to do a long === chain.
3052
+ # Note that like #type, it will still be slower than using == for a single
3053
+ # class, but should be faster in a case statement or an array comparison.
3054
+ #
3055
+ # def self.type: () -> Symbol
3056
+ def self.type
3057
+ :case_match_node
3058
+ end
3059
+ end
3060
+
3061
+ # Represents the use of a case statement.
2738
3062
  #
2739
3063
  # case true
2740
3064
  # when false
@@ -4929,6 +5253,9 @@ module Prism
4929
5253
  # attr_reader locals: Array[Symbol]
4930
5254
  attr_reader :locals
4931
5255
 
5256
+ # attr_reader locals_body_index: Integer
5257
+ attr_reader :locals_body_index
5258
+
4932
5259
  # attr_reader def_keyword_loc: Location
4933
5260
  attr_reader :def_keyword_loc
4934
5261
 
@@ -4947,14 +5274,15 @@ module Prism
4947
5274
  # attr_reader end_keyword_loc: Location?
4948
5275
  attr_reader :end_keyword_loc
4949
5276
 
4950
- # def initialize: (name: Symbol, name_loc: Location, receiver: Node?, parameters: ParametersNode?, body: Node?, locals: Array[Symbol], def_keyword_loc: Location, operator_loc: Location?, lparen_loc: Location?, rparen_loc: Location?, equal_loc: Location?, end_keyword_loc: Location?, location: Location) -> void
4951
- def initialize(name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location)
5277
+ # def initialize: (name: Symbol, name_loc: Location, receiver: Node?, parameters: ParametersNode?, body: Node?, locals: Array[Symbol], locals_body_index: Integer, def_keyword_loc: Location, operator_loc: Location?, lparen_loc: Location?, rparen_loc: Location?, equal_loc: Location?, end_keyword_loc: Location?, location: Location) -> void
5278
+ def initialize(name, name_loc, receiver, parameters, body, locals, locals_body_index, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location)
4952
5279
  @name = name
4953
5280
  @name_loc = name_loc
4954
5281
  @receiver = receiver
4955
5282
  @parameters = parameters
4956
5283
  @body = body
4957
5284
  @locals = locals
5285
+ @locals_body_index = locals_body_index
4958
5286
  @def_keyword_loc = def_keyword_loc
4959
5287
  @operator_loc = operator_loc
4960
5288
  @lparen_loc = lparen_loc
@@ -4997,6 +5325,7 @@ module Prism
4997
5325
  params.fetch(:parameters) { parameters },
4998
5326
  params.fetch(:body) { body },
4999
5327
  params.fetch(:locals) { locals },
5328
+ params.fetch(:locals_body_index) { locals_body_index },
5000
5329
  params.fetch(:def_keyword_loc) { def_keyword_loc },
5001
5330
  params.fetch(:operator_loc) { operator_loc },
5002
5331
  params.fetch(:lparen_loc) { lparen_loc },
@@ -5012,7 +5341,7 @@ module Prism
5012
5341
 
5013
5342
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
5014
5343
  def deconstruct_keys(keys)
5015
- { name: name, name_loc: name_loc, receiver: receiver, parameters: parameters, body: body, locals: locals, def_keyword_loc: def_keyword_loc, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc, equal_loc: equal_loc, end_keyword_loc: end_keyword_loc, location: location }
5344
+ { name: name, name_loc: name_loc, receiver: receiver, parameters: parameters, body: body, locals: locals, locals_body_index: locals_body_index, def_keyword_loc: def_keyword_loc, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc, equal_loc: equal_loc, end_keyword_loc: end_keyword_loc, location: location }
5016
5345
  end
5017
5346
 
5018
5347
  # def def_keyword: () -> String
@@ -5069,6 +5398,7 @@ module Prism
5069
5398
  inspector << body.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
5070
5399
  end
5071
5400
  inspector << "├── locals: #{locals.inspect}\n"
5401
+ inspector << "├── locals_body_index: #{locals_body_index.inspect}\n"
5072
5402
  inspector << "├── def_keyword_loc: #{inspector.location(def_keyword_loc)}\n"
5073
5403
  inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
5074
5404
  inspector << "├── lparen_loc: #{inspector.location(lparen_loc)}\n"
@@ -5903,6 +6233,9 @@ module Prism
5903
6233
  # baz if foo .. bar
5904
6234
  # ^^^^^^^^^^
5905
6235
  class FlipFlopNode < Node
6236
+ # attr_reader flags: Integer
6237
+ private attr_reader :flags
6238
+
5906
6239
  # attr_reader left: Node?
5907
6240
  attr_reader :left
5908
6241
 
@@ -5912,15 +6245,12 @@ module Prism
5912
6245
  # attr_reader operator_loc: Location
5913
6246
  attr_reader :operator_loc
5914
6247
 
5915
- # attr_reader flags: Integer
5916
- private attr_reader :flags
5917
-
5918
- # def initialize: (left: Node?, right: Node?, operator_loc: Location, flags: Integer, location: Location) -> void
5919
- def initialize(left, right, operator_loc, flags, location)
6248
+ # def initialize: (flags: Integer, left: Node?, right: Node?, operator_loc: Location, location: Location) -> void
6249
+ def initialize(flags, left, right, operator_loc, location)
6250
+ @flags = flags
5920
6251
  @left = left
5921
6252
  @right = right
5922
6253
  @operator_loc = operator_loc
5923
- @flags = flags
5924
6254
  @location = location
5925
6255
  end
5926
6256
 
@@ -5950,10 +6280,10 @@ module Prism
5950
6280
  # def copy: (**params) -> FlipFlopNode
5951
6281
  def copy(**params)
5952
6282
  FlipFlopNode.new(
6283
+ params.fetch(:flags) { flags },
5953
6284
  params.fetch(:left) { left },
5954
6285
  params.fetch(:right) { right },
5955
6286
  params.fetch(:operator_loc) { operator_loc },
5956
- params.fetch(:flags) { flags },
5957
6287
  params.fetch(:location) { location },
5958
6288
  )
5959
6289
  end
@@ -5963,12 +6293,7 @@ module Prism
5963
6293
 
5964
6294
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
5965
6295
  def deconstruct_keys(keys)
5966
- { left: left, right: right, operator_loc: operator_loc, flags: flags, location: location }
5967
- end
5968
-
5969
- # def operator: () -> String
5970
- def operator
5971
- operator_loc.slice
6296
+ { flags: flags, left: left, right: right, operator_loc: operator_loc, location: location }
5972
6297
  end
5973
6298
 
5974
6299
  # def exclude_end?: () -> bool
@@ -5976,10 +6301,17 @@ module Prism
5976
6301
  flags.anybits?(RangeFlags::EXCLUDE_END)
5977
6302
  end
5978
6303
 
6304
+ # def operator: () -> String
6305
+ def operator
6306
+ operator_loc.slice
6307
+ end
6308
+
5979
6309
  # def inspect(inspector: NodeInspector) -> String
5980
6310
  def inspect(inspector = NodeInspector.new)
5981
6311
  inspector << inspector.header(self)
5982
- if (left = self.left).nil?
6312
+ flags = [("exclude_end" if exclude_end?)].compact
6313
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
6314
+ if (left = self.left).nil?
5983
6315
  inspector << "├── left: ∅\n"
5984
6316
  else
5985
6317
  inspector << "├── left:\n"
@@ -5991,9 +6323,7 @@ module Prism
5991
6323
  inspector << "├── right:\n"
5992
6324
  inspector << right.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
5993
6325
  end
5994
- inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
5995
- flags = [("exclude_end" if exclude_end?)].compact
5996
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
6326
+ inspector << "└── operator_loc: #{inspector.location(operator_loc)}\n"
5997
6327
  inspector.to_str
5998
6328
  end
5999
6329
 
@@ -7387,6 +7717,9 @@ module Prism
7387
7717
  # attr_reader predicate: Node
7388
7718
  attr_reader :predicate
7389
7719
 
7720
+ # attr_reader then_keyword_loc: Location?
7721
+ attr_reader :then_keyword_loc
7722
+
7390
7723
  # attr_reader statements: StatementsNode?
7391
7724
  attr_reader :statements
7392
7725
 
@@ -7396,10 +7729,11 @@ module Prism
7396
7729
  # attr_reader end_keyword_loc: Location?
7397
7730
  attr_reader :end_keyword_loc
7398
7731
 
7399
- # def initialize: (if_keyword_loc: Location?, predicate: Node, statements: StatementsNode?, consequent: Node?, end_keyword_loc: Location?, location: Location) -> void
7400
- def initialize(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, location)
7732
+ # def initialize: (if_keyword_loc: Location?, predicate: Node, then_keyword_loc: Location?, statements: StatementsNode?, consequent: Node?, end_keyword_loc: Location?, location: Location) -> void
7733
+ def initialize(if_keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location)
7401
7734
  @if_keyword_loc = if_keyword_loc
7402
7735
  @predicate = predicate
7736
+ @then_keyword_loc = then_keyword_loc
7403
7737
  @statements = statements
7404
7738
  @consequent = consequent
7405
7739
  @end_keyword_loc = end_keyword_loc
@@ -7431,7 +7765,7 @@ module Prism
7431
7765
 
7432
7766
  # def comment_targets: () -> Array[Node | Location]
7433
7767
  def comment_targets
7434
- [*if_keyword_loc, predicate, *statements, *consequent, *end_keyword_loc]
7768
+ [*if_keyword_loc, predicate, *then_keyword_loc, *statements, *consequent, *end_keyword_loc]
7435
7769
  end
7436
7770
 
7437
7771
  # def copy: (**params) -> IfNode
@@ -7439,6 +7773,7 @@ module Prism
7439
7773
  IfNode.new(
7440
7774
  params.fetch(:if_keyword_loc) { if_keyword_loc },
7441
7775
  params.fetch(:predicate) { predicate },
7776
+ params.fetch(:then_keyword_loc) { then_keyword_loc },
7442
7777
  params.fetch(:statements) { statements },
7443
7778
  params.fetch(:consequent) { consequent },
7444
7779
  params.fetch(:end_keyword_loc) { end_keyword_loc },
@@ -7451,7 +7786,7 @@ module Prism
7451
7786
 
7452
7787
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
7453
7788
  def deconstruct_keys(keys)
7454
- { if_keyword_loc: if_keyword_loc, predicate: predicate, statements: statements, consequent: consequent, end_keyword_loc: end_keyword_loc, location: location }
7789
+ { if_keyword_loc: if_keyword_loc, predicate: predicate, then_keyword_loc: then_keyword_loc, statements: statements, consequent: consequent, end_keyword_loc: end_keyword_loc, location: location }
7455
7790
  end
7456
7791
 
7457
7792
  # def if_keyword: () -> String?
@@ -7459,6 +7794,11 @@ module Prism
7459
7794
  if_keyword_loc&.slice
7460
7795
  end
7461
7796
 
7797
+ # def then_keyword: () -> String?
7798
+ def then_keyword
7799
+ then_keyword_loc&.slice
7800
+ end
7801
+
7462
7802
  # def end_keyword: () -> String?
7463
7803
  def end_keyword
7464
7804
  end_keyword_loc&.slice
@@ -7470,6 +7810,7 @@ module Prism
7470
7810
  inspector << "├── if_keyword_loc: #{inspector.location(if_keyword_loc)}\n"
7471
7811
  inspector << "├── predicate:\n"
7472
7812
  inspector << inspector.child_node(predicate, "│ ")
7813
+ inspector << "├── then_keyword_loc: #{inspector.location(then_keyword_loc)}\n"
7473
7814
  if (statements = self.statements).nil?
7474
7815
  inspector << "├── statements: ∅\n"
7475
7816
  else
@@ -7693,6 +8034,95 @@ module Prism
7693
8034
  end
7694
8035
  end
7695
8036
 
8037
+ # Represents using a trailing comma to indicate an implicit rest parameter.
8038
+ #
8039
+ # foo { |bar,| }
8040
+ # ^
8041
+ #
8042
+ # foo in [bar,]
8043
+ # ^
8044
+ #
8045
+ # for foo, in bar do end
8046
+ # ^
8047
+ #
8048
+ # foo, = bar
8049
+ # ^
8050
+ class ImplicitRestNode < Node
8051
+ # def initialize: (location: Location) -> void
8052
+ def initialize(location)
8053
+ @location = location
8054
+ end
8055
+
8056
+ # def accept: (visitor: Visitor) -> void
8057
+ def accept(visitor)
8058
+ visitor.visit_implicit_rest_node(self)
8059
+ end
8060
+
8061
+ # def child_nodes: () -> Array[nil | Node]
8062
+ def child_nodes
8063
+ []
8064
+ end
8065
+
8066
+ # def compact_child_nodes: () -> Array[Node]
8067
+ def compact_child_nodes
8068
+ []
8069
+ end
8070
+
8071
+ # def comment_targets: () -> Array[Node | Location]
8072
+ def comment_targets
8073
+ []
8074
+ end
8075
+
8076
+ # def copy: (**params) -> ImplicitRestNode
8077
+ def copy(**params)
8078
+ ImplicitRestNode.new(
8079
+ params.fetch(:location) { location },
8080
+ )
8081
+ end
8082
+
8083
+ # def deconstruct: () -> Array[nil | Node]
8084
+ alias deconstruct child_nodes
8085
+
8086
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
8087
+ def deconstruct_keys(keys)
8088
+ { location: location }
8089
+ end
8090
+
8091
+ # def inspect(inspector: NodeInspector) -> String
8092
+ def inspect(inspector = NodeInspector.new)
8093
+ inspector << inspector.header(self)
8094
+ inspector.to_str
8095
+ end
8096
+
8097
+ # Sometimes you want to check an instance of a node against a list of
8098
+ # classes to see what kind of behavior to perform. Usually this is done by
8099
+ # calling `[cls1, cls2].include?(node.class)` or putting the node into a
8100
+ # case statement and doing `case node; when cls1; when cls2; end`. Both of
8101
+ # these approaches are relatively slow because of the constant lookups,
8102
+ # method calls, and/or array allocations.
8103
+ #
8104
+ # Instead, you can call #type, which will return to you a symbol that you
8105
+ # can use for comparison. This is faster than the other approaches because
8106
+ # it uses a single integer comparison, but also because if you're on CRuby
8107
+ # you can take advantage of the fact that case statements with all symbol
8108
+ # keys will use a jump table.
8109
+ #
8110
+ # def type: () -> Symbol
8111
+ def type
8112
+ :implicit_rest_node
8113
+ end
8114
+
8115
+ # Similar to #type, this method returns a symbol that you can use for
8116
+ # splitting on the type of the node without having to do a long === chain.
8117
+ # Note that like #type, it will still be slower than using == for a single
8118
+ # class, but should be faster in a case statement or an array comparison.
8119
+ #
8120
+ # def self.type: () -> Symbol
8121
+ def self.type
8122
+ :implicit_rest_node
8123
+ end
8124
+ end
8125
+
7696
8126
  # Represents the use of the `in` keyword in a case statement.
7697
8127
  #
7698
8128
  # case a; in b then c end
@@ -7821,6 +8251,9 @@ module Prism
7821
8251
  # foo.bar[baz] &&= value
7822
8252
  # ^^^^^^^^^^^^^^^^^^^^^^
7823
8253
  class IndexAndWriteNode < Node
8254
+ # attr_reader flags: Integer
8255
+ private attr_reader :flags
8256
+
7824
8257
  # attr_reader receiver: Node?
7825
8258
  attr_reader :receiver
7826
8259
 
@@ -7839,24 +8272,21 @@ module Prism
7839
8272
  # attr_reader block: Node?
7840
8273
  attr_reader :block
7841
8274
 
7842
- # attr_reader flags: Integer
7843
- private attr_reader :flags
7844
-
7845
8275
  # attr_reader operator_loc: Location
7846
8276
  attr_reader :operator_loc
7847
8277
 
7848
8278
  # attr_reader value: Node
7849
8279
  attr_reader :value
7850
8280
 
7851
- # 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
7852
- def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
8281
+ # def initialize: (flags: Integer, receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, operator_loc: Location, value: Node, location: Location) -> void
8282
+ def initialize(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value, location)
8283
+ @flags = flags
7853
8284
  @receiver = receiver
7854
8285
  @call_operator_loc = call_operator_loc
7855
8286
  @opening_loc = opening_loc
7856
8287
  @arguments = arguments
7857
8288
  @closing_loc = closing_loc
7858
8289
  @block = block
7859
- @flags = flags
7860
8290
  @operator_loc = operator_loc
7861
8291
  @value = value
7862
8292
  @location = location
@@ -7890,13 +8320,13 @@ module Prism
7890
8320
  # def copy: (**params) -> IndexAndWriteNode
7891
8321
  def copy(**params)
7892
8322
  IndexAndWriteNode.new(
8323
+ params.fetch(:flags) { flags },
7893
8324
  params.fetch(:receiver) { receiver },
7894
8325
  params.fetch(:call_operator_loc) { call_operator_loc },
7895
8326
  params.fetch(:opening_loc) { opening_loc },
7896
8327
  params.fetch(:arguments) { arguments },
7897
8328
  params.fetch(:closing_loc) { closing_loc },
7898
8329
  params.fetch(:block) { block },
7899
- params.fetch(:flags) { flags },
7900
8330
  params.fetch(:operator_loc) { operator_loc },
7901
8331
  params.fetch(:value) { value },
7902
8332
  params.fetch(:location) { location },
@@ -7908,7 +8338,22 @@ module Prism
7908
8338
 
7909
8339
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
7910
8340
  def deconstruct_keys(keys)
7911
- { 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 }
8341
+ { flags: flags, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, operator_loc: operator_loc, value: value, location: location }
8342
+ end
8343
+
8344
+ # def safe_navigation?: () -> bool
8345
+ def safe_navigation?
8346
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
8347
+ end
8348
+
8349
+ # def variable_call?: () -> bool
8350
+ def variable_call?
8351
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
8352
+ end
8353
+
8354
+ # def attribute_write?: () -> bool
8355
+ def attribute_write?
8356
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
7912
8357
  end
7913
8358
 
7914
8359
  # def call_operator: () -> String?
@@ -7926,16 +8371,6 @@ module Prism
7926
8371
  closing_loc.slice
7927
8372
  end
7928
8373
 
7929
- # def safe_navigation?: () -> bool
7930
- def safe_navigation?
7931
- flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
7932
- end
7933
-
7934
- # def variable_call?: () -> bool
7935
- def variable_call?
7936
- flags.anybits?(CallNodeFlags::VARIABLE_CALL)
7937
- end
7938
-
7939
8374
  # def operator: () -> String
7940
8375
  def operator
7941
8376
  operator_loc.slice
@@ -7944,6 +8379,8 @@ module Prism
7944
8379
  # def inspect(inspector: NodeInspector) -> String
7945
8380
  def inspect(inspector = NodeInspector.new)
7946
8381
  inspector << inspector.header(self)
8382
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
8383
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
7947
8384
  if (receiver = self.receiver).nil?
7948
8385
  inspector << "├── receiver: ∅\n"
7949
8386
  else
@@ -7965,8 +8402,6 @@ module Prism
7965
8402
  inspector << "├── block:\n"
7966
8403
  inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
7967
8404
  end
7968
- flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
7969
- inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
7970
8405
  inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
7971
8406
  inspector << "└── value:\n"
7972
8407
  inspector << inspector.child_node(value, " ")
@@ -8007,6 +8442,9 @@ module Prism
8007
8442
  # foo.bar[baz] += value
8008
8443
  # ^^^^^^^^^^^^^^^^^^^^^
8009
8444
  class IndexOperatorWriteNode < Node
8445
+ # attr_reader flags: Integer
8446
+ private attr_reader :flags
8447
+
8010
8448
  # attr_reader receiver: Node?
8011
8449
  attr_reader :receiver
8012
8450
 
@@ -8025,9 +8463,6 @@ module Prism
8025
8463
  # attr_reader block: Node?
8026
8464
  attr_reader :block
8027
8465
 
8028
- # attr_reader flags: Integer
8029
- private attr_reader :flags
8030
-
8031
8466
  # attr_reader operator: Symbol
8032
8467
  attr_reader :operator
8033
8468
 
@@ -8037,15 +8472,15 @@ module Prism
8037
8472
  # attr_reader value: Node
8038
8473
  attr_reader :value
8039
8474
 
8040
- # 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
8041
- def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator, operator_loc, value, location)
8475
+ # def initialize: (flags: Integer, receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, operator: Symbol, operator_loc: Location, value: Node, location: Location) -> void
8476
+ def initialize(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator, operator_loc, value, location)
8477
+ @flags = flags
8042
8478
  @receiver = receiver
8043
8479
  @call_operator_loc = call_operator_loc
8044
8480
  @opening_loc = opening_loc
8045
8481
  @arguments = arguments
8046
8482
  @closing_loc = closing_loc
8047
8483
  @block = block
8048
- @flags = flags
8049
8484
  @operator = operator
8050
8485
  @operator_loc = operator_loc
8051
8486
  @value = value
@@ -8080,13 +8515,13 @@ module Prism
8080
8515
  # def copy: (**params) -> IndexOperatorWriteNode
8081
8516
  def copy(**params)
8082
8517
  IndexOperatorWriteNode.new(
8518
+ params.fetch(:flags) { flags },
8083
8519
  params.fetch(:receiver) { receiver },
8084
8520
  params.fetch(:call_operator_loc) { call_operator_loc },
8085
8521
  params.fetch(:opening_loc) { opening_loc },
8086
8522
  params.fetch(:arguments) { arguments },
8087
8523
  params.fetch(:closing_loc) { closing_loc },
8088
8524
  params.fetch(:block) { block },
8089
- params.fetch(:flags) { flags },
8090
8525
  params.fetch(:operator) { operator },
8091
8526
  params.fetch(:operator_loc) { operator_loc },
8092
8527
  params.fetch(:value) { value },
@@ -8099,7 +8534,22 @@ module Prism
8099
8534
 
8100
8535
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
8101
8536
  def deconstruct_keys(keys)
8102
- { 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 }
8537
+ { flags: flags, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, operator: operator, operator_loc: operator_loc, value: value, location: location }
8538
+ end
8539
+
8540
+ # def safe_navigation?: () -> bool
8541
+ def safe_navigation?
8542
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
8543
+ end
8544
+
8545
+ # def variable_call?: () -> bool
8546
+ def variable_call?
8547
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
8548
+ end
8549
+
8550
+ # def attribute_write?: () -> bool
8551
+ def attribute_write?
8552
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
8103
8553
  end
8104
8554
 
8105
8555
  # def call_operator: () -> String?
@@ -8117,19 +8567,11 @@ module Prism
8117
8567
  closing_loc.slice
8118
8568
  end
8119
8569
 
8120
- # def safe_navigation?: () -> bool
8121
- def safe_navigation?
8122
- flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
8123
- end
8124
-
8125
- # def variable_call?: () -> bool
8126
- def variable_call?
8127
- flags.anybits?(CallNodeFlags::VARIABLE_CALL)
8128
- end
8129
-
8130
8570
  # def inspect(inspector: NodeInspector) -> String
8131
8571
  def inspect(inspector = NodeInspector.new)
8132
8572
  inspector << inspector.header(self)
8573
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
8574
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
8133
8575
  if (receiver = self.receiver).nil?
8134
8576
  inspector << "├── receiver: ∅\n"
8135
8577
  else
@@ -8151,8 +8593,6 @@ module Prism
8151
8593
  inspector << "├── block:\n"
8152
8594
  inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8153
8595
  end
8154
- flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
8155
- inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
8156
8596
  inspector << "├── operator: #{operator.inspect}\n"
8157
8597
  inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
8158
8598
  inspector << "└── value:\n"
@@ -8194,6 +8634,9 @@ module Prism
8194
8634
  # foo.bar[baz] ||= value
8195
8635
  # ^^^^^^^^^^^^^^^^^^^^^^
8196
8636
  class IndexOrWriteNode < Node
8637
+ # attr_reader flags: Integer
8638
+ private attr_reader :flags
8639
+
8197
8640
  # attr_reader receiver: Node?
8198
8641
  attr_reader :receiver
8199
8642
 
@@ -8212,24 +8655,21 @@ module Prism
8212
8655
  # attr_reader block: Node?
8213
8656
  attr_reader :block
8214
8657
 
8215
- # attr_reader flags: Integer
8216
- private attr_reader :flags
8217
-
8218
8658
  # attr_reader operator_loc: Location
8219
8659
  attr_reader :operator_loc
8220
8660
 
8221
8661
  # attr_reader value: Node
8222
8662
  attr_reader :value
8223
8663
 
8224
- # 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
8225
- def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
8664
+ # def initialize: (flags: Integer, receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, operator_loc: Location, value: Node, location: Location) -> void
8665
+ def initialize(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value, location)
8666
+ @flags = flags
8226
8667
  @receiver = receiver
8227
8668
  @call_operator_loc = call_operator_loc
8228
8669
  @opening_loc = opening_loc
8229
8670
  @arguments = arguments
8230
8671
  @closing_loc = closing_loc
8231
8672
  @block = block
8232
- @flags = flags
8233
8673
  @operator_loc = operator_loc
8234
8674
  @value = value
8235
8675
  @location = location
@@ -8263,13 +8703,13 @@ module Prism
8263
8703
  # def copy: (**params) -> IndexOrWriteNode
8264
8704
  def copy(**params)
8265
8705
  IndexOrWriteNode.new(
8706
+ params.fetch(:flags) { flags },
8266
8707
  params.fetch(:receiver) { receiver },
8267
8708
  params.fetch(:call_operator_loc) { call_operator_loc },
8268
8709
  params.fetch(:opening_loc) { opening_loc },
8269
8710
  params.fetch(:arguments) { arguments },
8270
8711
  params.fetch(:closing_loc) { closing_loc },
8271
8712
  params.fetch(:block) { block },
8272
- params.fetch(:flags) { flags },
8273
8713
  params.fetch(:operator_loc) { operator_loc },
8274
8714
  params.fetch(:value) { value },
8275
8715
  params.fetch(:location) { location },
@@ -8281,7 +8721,22 @@ module Prism
8281
8721
 
8282
8722
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
8283
8723
  def deconstruct_keys(keys)
8284
- { 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 }
8724
+ { flags: flags, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, operator_loc: operator_loc, value: value, location: location }
8725
+ end
8726
+
8727
+ # def safe_navigation?: () -> bool
8728
+ def safe_navigation?
8729
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
8730
+ end
8731
+
8732
+ # def variable_call?: () -> bool
8733
+ def variable_call?
8734
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
8735
+ end
8736
+
8737
+ # def attribute_write?: () -> bool
8738
+ def attribute_write?
8739
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
8285
8740
  end
8286
8741
 
8287
8742
  # def call_operator: () -> String?
@@ -8299,16 +8754,6 @@ module Prism
8299
8754
  closing_loc.slice
8300
8755
  end
8301
8756
 
8302
- # def safe_navigation?: () -> bool
8303
- def safe_navigation?
8304
- flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
8305
- end
8306
-
8307
- # def variable_call?: () -> bool
8308
- def variable_call?
8309
- flags.anybits?(CallNodeFlags::VARIABLE_CALL)
8310
- end
8311
-
8312
8757
  # def operator: () -> String
8313
8758
  def operator
8314
8759
  operator_loc.slice
@@ -8317,6 +8762,8 @@ module Prism
8317
8762
  # def inspect(inspector: NodeInspector) -> String
8318
8763
  def inspect(inspector = NodeInspector.new)
8319
8764
  inspector << inspector.header(self)
8765
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
8766
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
8320
8767
  if (receiver = self.receiver).nil?
8321
8768
  inspector << "├── receiver: ∅\n"
8322
8769
  else
@@ -8333,16 +8780,179 @@ module Prism
8333
8780
  end
8334
8781
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
8335
8782
  if (block = self.block).nil?
8336
- inspector << "├── block: ∅\n"
8783
+ inspector << "├── block: ∅\n"
8784
+ else
8785
+ inspector << "├── block:\n"
8786
+ inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8787
+ end
8788
+ inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
8789
+ inspector << "└── value:\n"
8790
+ inspector << inspector.child_node(value, " ")
8791
+ inspector.to_str
8792
+ end
8793
+
8794
+ # Sometimes you want to check an instance of a node against a list of
8795
+ # classes to see what kind of behavior to perform. Usually this is done by
8796
+ # calling `[cls1, cls2].include?(node.class)` or putting the node into a
8797
+ # case statement and doing `case node; when cls1; when cls2; end`. Both of
8798
+ # these approaches are relatively slow because of the constant lookups,
8799
+ # method calls, and/or array allocations.
8800
+ #
8801
+ # Instead, you can call #type, which will return to you a symbol that you
8802
+ # can use for comparison. This is faster than the other approaches because
8803
+ # it uses a single integer comparison, but also because if you're on CRuby
8804
+ # you can take advantage of the fact that case statements with all symbol
8805
+ # keys will use a jump table.
8806
+ #
8807
+ # def type: () -> Symbol
8808
+ def type
8809
+ :index_or_write_node
8810
+ end
8811
+
8812
+ # Similar to #type, this method returns a symbol that you can use for
8813
+ # splitting on the type of the node without having to do a long === chain.
8814
+ # Note that like #type, it will still be slower than using == for a single
8815
+ # class, but should be faster in a case statement or an array comparison.
8816
+ #
8817
+ # def self.type: () -> Symbol
8818
+ def self.type
8819
+ :index_or_write_node
8820
+ end
8821
+ end
8822
+
8823
+ # Represents assigning to an index.
8824
+ #
8825
+ # foo[bar], = 1
8826
+ # ^^^^^^^^
8827
+ #
8828
+ # begin
8829
+ # rescue => foo[bar]
8830
+ # ^^^^^^^^
8831
+ # end
8832
+ #
8833
+ # for foo[bar] in baz do end
8834
+ # ^^^^^^^^
8835
+ class IndexTargetNode < Node
8836
+ # attr_reader flags: Integer
8837
+ private attr_reader :flags
8838
+
8839
+ # attr_reader receiver: Node
8840
+ attr_reader :receiver
8841
+
8842
+ # attr_reader opening_loc: Location
8843
+ attr_reader :opening_loc
8844
+
8845
+ # attr_reader arguments: ArgumentsNode?
8846
+ attr_reader :arguments
8847
+
8848
+ # attr_reader closing_loc: Location
8849
+ attr_reader :closing_loc
8850
+
8851
+ # attr_reader block: Node?
8852
+ attr_reader :block
8853
+
8854
+ # def initialize: (flags: Integer, receiver: Node, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, location: Location) -> void
8855
+ def initialize(flags, receiver, opening_loc, arguments, closing_loc, block, location)
8856
+ @flags = flags
8857
+ @receiver = receiver
8858
+ @opening_loc = opening_loc
8859
+ @arguments = arguments
8860
+ @closing_loc = closing_loc
8861
+ @block = block
8862
+ @location = location
8863
+ end
8864
+
8865
+ # def accept: (visitor: Visitor) -> void
8866
+ def accept(visitor)
8867
+ visitor.visit_index_target_node(self)
8868
+ end
8869
+
8870
+ # def child_nodes: () -> Array[nil | Node]
8871
+ def child_nodes
8872
+ [receiver, arguments, block]
8873
+ end
8874
+
8875
+ # def compact_child_nodes: () -> Array[Node]
8876
+ def compact_child_nodes
8877
+ compact = []
8878
+ compact << receiver
8879
+ compact << arguments if arguments
8880
+ compact << block if block
8881
+ compact
8882
+ end
8883
+
8884
+ # def comment_targets: () -> Array[Node | Location]
8885
+ def comment_targets
8886
+ [receiver, opening_loc, *arguments, closing_loc, *block]
8887
+ end
8888
+
8889
+ # def copy: (**params) -> IndexTargetNode
8890
+ def copy(**params)
8891
+ IndexTargetNode.new(
8892
+ params.fetch(:flags) { flags },
8893
+ params.fetch(:receiver) { receiver },
8894
+ params.fetch(:opening_loc) { opening_loc },
8895
+ params.fetch(:arguments) { arguments },
8896
+ params.fetch(:closing_loc) { closing_loc },
8897
+ params.fetch(:block) { block },
8898
+ params.fetch(:location) { location },
8899
+ )
8900
+ end
8901
+
8902
+ # def deconstruct: () -> Array[nil | Node]
8903
+ alias deconstruct child_nodes
8904
+
8905
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
8906
+ def deconstruct_keys(keys)
8907
+ { flags: flags, receiver: receiver, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, location: location }
8908
+ end
8909
+
8910
+ # def safe_navigation?: () -> bool
8911
+ def safe_navigation?
8912
+ flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
8913
+ end
8914
+
8915
+ # def variable_call?: () -> bool
8916
+ def variable_call?
8917
+ flags.anybits?(CallNodeFlags::VARIABLE_CALL)
8918
+ end
8919
+
8920
+ # def attribute_write?: () -> bool
8921
+ def attribute_write?
8922
+ flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
8923
+ end
8924
+
8925
+ # def opening: () -> String
8926
+ def opening
8927
+ opening_loc.slice
8928
+ end
8929
+
8930
+ # def closing: () -> String
8931
+ def closing
8932
+ closing_loc.slice
8933
+ end
8934
+
8935
+ # def inspect(inspector: NodeInspector) -> String
8936
+ def inspect(inspector = NodeInspector.new)
8937
+ inspector << inspector.header(self)
8938
+ flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
8939
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
8940
+ inspector << "├── receiver:\n"
8941
+ inspector << inspector.child_node(receiver, "│ ")
8942
+ inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
8943
+ if (arguments = self.arguments).nil?
8944
+ inspector << "├── arguments: ∅\n"
8945
+ else
8946
+ inspector << "├── arguments:\n"
8947
+ inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
8948
+ end
8949
+ inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
8950
+ if (block = self.block).nil?
8951
+ inspector << "└── block: ∅\n"
8337
8952
  else
8338
- inspector << "├── block:\n"
8339
- inspector << block.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
8953
+ inspector << "└── block:\n"
8954
+ inspector << block.inspect(inspector.child_inspector(" ")).delete_prefix(inspector.prefix)
8340
8955
  end
8341
- flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
8342
- inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
8343
- inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
8344
- inspector << "└── value:\n"
8345
- inspector << inspector.child_node(value, " ")
8346
8956
  inspector.to_str
8347
8957
  end
8348
8958
 
@@ -8361,7 +8971,7 @@ module Prism
8361
8971
  #
8362
8972
  # def type: () -> Symbol
8363
8973
  def type
8364
- :index_or_write_node
8974
+ :index_target_node
8365
8975
  end
8366
8976
 
8367
8977
  # Similar to #type, this method returns a symbol that you can use for
@@ -8371,7 +8981,7 @@ module Prism
8371
8981
  #
8372
8982
  # def self.type: () -> Symbol
8373
8983
  def self.type
8374
- :index_or_write_node
8984
+ :index_target_node
8375
8985
  end
8376
8986
  end
8377
8987
 
@@ -9043,16 +9653,16 @@ module Prism
9043
9653
  flags.anybits?(IntegerBaseFlags::BINARY)
9044
9654
  end
9045
9655
 
9046
- # def octal?: () -> bool
9047
- def octal?
9048
- flags.anybits?(IntegerBaseFlags::OCTAL)
9049
- end
9050
-
9051
9656
  # def decimal?: () -> bool
9052
9657
  def decimal?
9053
9658
  flags.anybits?(IntegerBaseFlags::DECIMAL)
9054
9659
  end
9055
9660
 
9661
+ # def octal?: () -> bool
9662
+ def octal?
9663
+ flags.anybits?(IntegerBaseFlags::OCTAL)
9664
+ end
9665
+
9056
9666
  # def hexadecimal?: () -> bool
9057
9667
  def hexadecimal?
9058
9668
  flags.anybits?(IntegerBaseFlags::HEXADECIMAL)
@@ -9061,7 +9671,7 @@ module Prism
9061
9671
  # def inspect(inspector: NodeInspector) -> String
9062
9672
  def inspect(inspector = NodeInspector.new)
9063
9673
  inspector << inspector.header(self)
9064
- flags = [("binary" if binary?), ("octal" if octal?), ("decimal" if decimal?), ("hexadecimal" if hexadecimal?)].compact
9674
+ flags = [("binary" if binary?), ("decimal" if decimal?), ("octal" if octal?), ("hexadecimal" if hexadecimal?)].compact
9065
9675
  inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
9066
9676
  inspector.to_str
9067
9677
  end
@@ -9102,6 +9712,9 @@ module Prism
9102
9712
  # if /foo #{bar} baz/ then end
9103
9713
  # ^^^^^^^^^^^^^^^^
9104
9714
  class InterpolatedMatchLastLineNode < Node
9715
+ # attr_reader flags: Integer
9716
+ private attr_reader :flags
9717
+
9105
9718
  # attr_reader opening_loc: Location
9106
9719
  attr_reader :opening_loc
9107
9720
 
@@ -9111,15 +9724,12 @@ module Prism
9111
9724
  # attr_reader closing_loc: Location
9112
9725
  attr_reader :closing_loc
9113
9726
 
9114
- # attr_reader flags: Integer
9115
- private attr_reader :flags
9116
-
9117
- # def initialize: (opening_loc: Location, parts: Array[Node], closing_loc: Location, flags: Integer, location: Location) -> void
9118
- def initialize(opening_loc, parts, closing_loc, flags, location)
9727
+ # def initialize: (flags: Integer, opening_loc: Location, parts: Array[Node], closing_loc: Location, location: Location) -> void
9728
+ def initialize(flags, opening_loc, parts, closing_loc, location)
9729
+ @flags = flags
9119
9730
  @opening_loc = opening_loc
9120
9731
  @parts = parts
9121
9732
  @closing_loc = closing_loc
9122
- @flags = flags
9123
9733
  @location = location
9124
9734
  end
9125
9735
 
@@ -9151,10 +9761,10 @@ module Prism
9151
9761
  # def copy: (**params) -> InterpolatedMatchLastLineNode
9152
9762
  def copy(**params)
9153
9763
  InterpolatedMatchLastLineNode.new(
9764
+ params.fetch(:flags) { flags },
9154
9765
  params.fetch(:opening_loc) { opening_loc },
9155
9766
  params.fetch(:parts) { parts },
9156
9767
  params.fetch(:closing_loc) { closing_loc },
9157
- params.fetch(:flags) { flags },
9158
9768
  params.fetch(:location) { location },
9159
9769
  )
9160
9770
  end
@@ -9164,17 +9774,7 @@ module Prism
9164
9774
 
9165
9775
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
9166
9776
  def deconstruct_keys(keys)
9167
- { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, flags: flags, location: location }
9168
- end
9169
-
9170
- # def opening: () -> String
9171
- def opening
9172
- opening_loc.slice
9173
- end
9174
-
9175
- # def closing: () -> String
9176
- def closing
9177
- closing_loc.slice
9777
+ { flags: flags, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, location: location }
9178
9778
  end
9179
9779
 
9180
9780
  # def ignore_case?: () -> bool
@@ -9217,14 +9817,39 @@ module Prism
9217
9817
  flags.anybits?(RegularExpressionFlags::UTF_8)
9218
9818
  end
9219
9819
 
9820
+ # def forced_utf8_encoding?: () -> bool
9821
+ def forced_utf8_encoding?
9822
+ flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING)
9823
+ end
9824
+
9825
+ # def forced_binary_encoding?: () -> bool
9826
+ def forced_binary_encoding?
9827
+ flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING)
9828
+ end
9829
+
9830
+ # def forced_us_ascii_encoding?: () -> bool
9831
+ def forced_us_ascii_encoding?
9832
+ flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING)
9833
+ end
9834
+
9835
+ # def opening: () -> String
9836
+ def opening
9837
+ opening_loc.slice
9838
+ end
9839
+
9840
+ # def closing: () -> String
9841
+ def closing
9842
+ closing_loc.slice
9843
+ end
9844
+
9220
9845
  # def inspect(inspector: NodeInspector) -> String
9221
9846
  def inspect(inspector = NodeInspector.new)
9222
9847
  inspector << inspector.header(self)
9848
+ flags = [("ignore_case" if ignore_case?), ("extended" if extended?), ("multi_line" if multi_line?), ("once" if once?), ("euc_jp" if euc_jp?), ("ascii_8bit" if ascii_8bit?), ("windows_31j" if windows_31j?), ("utf_8" if utf_8?), ("forced_utf8_encoding" if forced_utf8_encoding?), ("forced_binary_encoding" if forced_binary_encoding?), ("forced_us_ascii_encoding" if forced_us_ascii_encoding?)].compact
9849
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
9223
9850
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
9224
9851
  inspector << "├── parts: #{inspector.list("#{inspector.prefix}│ ", parts)}"
9225
- inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
9226
- flags = [("ignore_case" if ignore_case?), ("extended" if extended?), ("multi_line" if multi_line?), ("once" if once?), ("euc_jp" if euc_jp?), ("ascii_8bit" if ascii_8bit?), ("windows_31j" if windows_31j?), ("utf_8" if utf_8?)].compact
9227
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
9852
+ inspector << "└── closing_loc: #{inspector.location(closing_loc)}\n"
9228
9853
  inspector.to_str
9229
9854
  end
9230
9855
 
@@ -9262,6 +9887,9 @@ module Prism
9262
9887
  # /foo #{bar} baz/
9263
9888
  # ^^^^^^^^^^^^^^^^
9264
9889
  class InterpolatedRegularExpressionNode < Node
9890
+ # attr_reader flags: Integer
9891
+ private attr_reader :flags
9892
+
9265
9893
  # attr_reader opening_loc: Location
9266
9894
  attr_reader :opening_loc
9267
9895
 
@@ -9271,15 +9899,12 @@ module Prism
9271
9899
  # attr_reader closing_loc: Location
9272
9900
  attr_reader :closing_loc
9273
9901
 
9274
- # attr_reader flags: Integer
9275
- private attr_reader :flags
9276
-
9277
- # def initialize: (opening_loc: Location, parts: Array[Node], closing_loc: Location, flags: Integer, location: Location) -> void
9278
- def initialize(opening_loc, parts, closing_loc, flags, location)
9902
+ # def initialize: (flags: Integer, opening_loc: Location, parts: Array[Node], closing_loc: Location, location: Location) -> void
9903
+ def initialize(flags, opening_loc, parts, closing_loc, location)
9904
+ @flags = flags
9279
9905
  @opening_loc = opening_loc
9280
9906
  @parts = parts
9281
9907
  @closing_loc = closing_loc
9282
- @flags = flags
9283
9908
  @location = location
9284
9909
  end
9285
9910
 
@@ -9311,10 +9936,10 @@ module Prism
9311
9936
  # def copy: (**params) -> InterpolatedRegularExpressionNode
9312
9937
  def copy(**params)
9313
9938
  InterpolatedRegularExpressionNode.new(
9939
+ params.fetch(:flags) { flags },
9314
9940
  params.fetch(:opening_loc) { opening_loc },
9315
9941
  params.fetch(:parts) { parts },
9316
9942
  params.fetch(:closing_loc) { closing_loc },
9317
- params.fetch(:flags) { flags },
9318
9943
  params.fetch(:location) { location },
9319
9944
  )
9320
9945
  end
@@ -9324,17 +9949,7 @@ module Prism
9324
9949
 
9325
9950
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
9326
9951
  def deconstruct_keys(keys)
9327
- { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, flags: flags, location: location }
9328
- end
9329
-
9330
- # def opening: () -> String
9331
- def opening
9332
- opening_loc.slice
9333
- end
9334
-
9335
- # def closing: () -> String
9336
- def closing
9337
- closing_loc.slice
9952
+ { flags: flags, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, location: location }
9338
9953
  end
9339
9954
 
9340
9955
  # def ignore_case?: () -> bool
@@ -9377,14 +9992,39 @@ module Prism
9377
9992
  flags.anybits?(RegularExpressionFlags::UTF_8)
9378
9993
  end
9379
9994
 
9995
+ # def forced_utf8_encoding?: () -> bool
9996
+ def forced_utf8_encoding?
9997
+ flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING)
9998
+ end
9999
+
10000
+ # def forced_binary_encoding?: () -> bool
10001
+ def forced_binary_encoding?
10002
+ flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING)
10003
+ end
10004
+
10005
+ # def forced_us_ascii_encoding?: () -> bool
10006
+ def forced_us_ascii_encoding?
10007
+ flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING)
10008
+ end
10009
+
10010
+ # def opening: () -> String
10011
+ def opening
10012
+ opening_loc.slice
10013
+ end
10014
+
10015
+ # def closing: () -> String
10016
+ def closing
10017
+ closing_loc.slice
10018
+ end
10019
+
9380
10020
  # def inspect(inspector: NodeInspector) -> String
9381
10021
  def inspect(inspector = NodeInspector.new)
9382
10022
  inspector << inspector.header(self)
10023
+ flags = [("ignore_case" if ignore_case?), ("extended" if extended?), ("multi_line" if multi_line?), ("once" if once?), ("euc_jp" if euc_jp?), ("ascii_8bit" if ascii_8bit?), ("windows_31j" if windows_31j?), ("utf_8" if utf_8?), ("forced_utf8_encoding" if forced_utf8_encoding?), ("forced_binary_encoding" if forced_binary_encoding?), ("forced_us_ascii_encoding" if forced_us_ascii_encoding?)].compact
10024
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
9383
10025
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
9384
10026
  inspector << "├── parts: #{inspector.list("#{inspector.prefix}│ ", parts)}"
9385
- inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
9386
- flags = [("ignore_case" if ignore_case?), ("extended" if extended?), ("multi_line" if multi_line?), ("once" if once?), ("euc_jp" if euc_jp?), ("ascii_8bit" if ascii_8bit?), ("windows_31j" if windows_31j?), ("utf_8" if utf_8?)].compact
9387
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
10027
+ inspector << "└── closing_loc: #{inspector.location(closing_loc)}\n"
9388
10028
  inspector.to_str
9389
10029
  end
9390
10030
 
@@ -9761,11 +10401,15 @@ module Prism
9761
10401
  # foo(a: b)
9762
10402
  # ^^^^
9763
10403
  class KeywordHashNode < Node
10404
+ # attr_reader flags: Integer
10405
+ private attr_reader :flags
10406
+
9764
10407
  # attr_reader elements: Array[Node]
9765
10408
  attr_reader :elements
9766
10409
 
9767
- # def initialize: (elements: Array[Node], location: Location) -> void
9768
- def initialize(elements, location)
10410
+ # def initialize: (flags: Integer, elements: Array[Node], location: Location) -> void
10411
+ def initialize(flags, elements, location)
10412
+ @flags = flags
9769
10413
  @elements = elements
9770
10414
  @location = location
9771
10415
  end
@@ -9793,6 +10437,7 @@ module Prism
9793
10437
  # def copy: (**params) -> KeywordHashNode
9794
10438
  def copy(**params)
9795
10439
  KeywordHashNode.new(
10440
+ params.fetch(:flags) { flags },
9796
10441
  params.fetch(:elements) { elements },
9797
10442
  params.fetch(:location) { location },
9798
10443
  )
@@ -9803,12 +10448,19 @@ module Prism
9803
10448
 
9804
10449
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
9805
10450
  def deconstruct_keys(keys)
9806
- { elements: elements, location: location }
10451
+ { flags: flags, elements: elements, location: location }
10452
+ end
10453
+
10454
+ # def static_keys?: () -> bool
10455
+ def static_keys?
10456
+ flags.anybits?(KeywordHashNodeFlags::STATIC_KEYS)
9807
10457
  end
9808
10458
 
9809
10459
  # def inspect(inspector: NodeInspector) -> String
9810
10460
  def inspect(inspector = NodeInspector.new)
9811
10461
  inspector << inspector.header(self)
10462
+ flags = [("static_keys" if static_keys?)].compact
10463
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
9812
10464
  inspector << "└── elements: #{inspector.list("#{inspector.prefix} ", elements)}"
9813
10465
  inspector.to_str
9814
10466
  end
@@ -9958,6 +10610,9 @@ module Prism
9958
10610
  # attr_reader locals: Array[Symbol]
9959
10611
  attr_reader :locals
9960
10612
 
10613
+ # attr_reader locals_body_index: Integer
10614
+ attr_reader :locals_body_index
10615
+
9961
10616
  # attr_reader operator_loc: Location
9962
10617
  attr_reader :operator_loc
9963
10618
 
@@ -9967,15 +10622,16 @@ module Prism
9967
10622
  # attr_reader closing_loc: Location
9968
10623
  attr_reader :closing_loc
9969
10624
 
9970
- # attr_reader parameters: BlockParametersNode?
10625
+ # attr_reader parameters: Node?
9971
10626
  attr_reader :parameters
9972
10627
 
9973
10628
  # attr_reader body: Node?
9974
10629
  attr_reader :body
9975
10630
 
9976
- # def initialize: (locals: Array[Symbol], operator_loc: Location, opening_loc: Location, closing_loc: Location, parameters: BlockParametersNode?, body: Node?, location: Location) -> void
9977
- def initialize(locals, operator_loc, opening_loc, closing_loc, parameters, body, location)
10631
+ # def initialize: (locals: Array[Symbol], locals_body_index: Integer, operator_loc: Location, opening_loc: Location, closing_loc: Location, parameters: Node?, body: Node?, location: Location) -> void
10632
+ def initialize(locals, locals_body_index, operator_loc, opening_loc, closing_loc, parameters, body, location)
9978
10633
  @locals = locals
10634
+ @locals_body_index = locals_body_index
9979
10635
  @operator_loc = operator_loc
9980
10636
  @opening_loc = opening_loc
9981
10637
  @closing_loc = closing_loc
@@ -10011,6 +10667,7 @@ module Prism
10011
10667
  def copy(**params)
10012
10668
  LambdaNode.new(
10013
10669
  params.fetch(:locals) { locals },
10670
+ params.fetch(:locals_body_index) { locals_body_index },
10014
10671
  params.fetch(:operator_loc) { operator_loc },
10015
10672
  params.fetch(:opening_loc) { opening_loc },
10016
10673
  params.fetch(:closing_loc) { closing_loc },
@@ -10025,7 +10682,7 @@ module Prism
10025
10682
 
10026
10683
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
10027
10684
  def deconstruct_keys(keys)
10028
- { locals: locals, operator_loc: operator_loc, opening_loc: opening_loc, closing_loc: closing_loc, parameters: parameters, body: body, location: location }
10685
+ { locals: locals, locals_body_index: locals_body_index, operator_loc: operator_loc, opening_loc: opening_loc, closing_loc: closing_loc, parameters: parameters, body: body, location: location }
10029
10686
  end
10030
10687
 
10031
10688
  # def operator: () -> String
@@ -10047,6 +10704,7 @@ module Prism
10047
10704
  def inspect(inspector = NodeInspector.new)
10048
10705
  inspector << inspector.header(self)
10049
10706
  inspector << "├── locals: #{locals.inspect}\n"
10707
+ inspector << "├── locals_body_index: #{locals_body_index.inspect}\n"
10050
10708
  inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
10051
10709
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
10052
10710
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
@@ -10752,6 +11410,9 @@ module Prism
10752
11410
  # if /foo/i then end
10753
11411
  # ^^^^^^
10754
11412
  class MatchLastLineNode < Node
11413
+ # attr_reader flags: Integer
11414
+ private attr_reader :flags
11415
+
10755
11416
  # attr_reader opening_loc: Location
10756
11417
  attr_reader :opening_loc
10757
11418
 
@@ -10764,16 +11425,13 @@ module Prism
10764
11425
  # attr_reader unescaped: String
10765
11426
  attr_reader :unescaped
10766
11427
 
10767
- # attr_reader flags: Integer
10768
- private attr_reader :flags
10769
-
10770
- # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, flags: Integer, location: Location) -> void
10771
- def initialize(opening_loc, content_loc, closing_loc, unescaped, flags, location)
11428
+ # def initialize: (flags: Integer, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, location: Location) -> void
11429
+ def initialize(flags, opening_loc, content_loc, closing_loc, unescaped, location)
11430
+ @flags = flags
10772
11431
  @opening_loc = opening_loc
10773
11432
  @content_loc = content_loc
10774
11433
  @closing_loc = closing_loc
10775
11434
  @unescaped = unescaped
10776
- @flags = flags
10777
11435
  @location = location
10778
11436
  end
10779
11437
 
@@ -10800,11 +11458,11 @@ module Prism
10800
11458
  # def copy: (**params) -> MatchLastLineNode
10801
11459
  def copy(**params)
10802
11460
  MatchLastLineNode.new(
11461
+ params.fetch(:flags) { flags },
10803
11462
  params.fetch(:opening_loc) { opening_loc },
10804
11463
  params.fetch(:content_loc) { content_loc },
10805
11464
  params.fetch(:closing_loc) { closing_loc },
10806
11465
  params.fetch(:unescaped) { unescaped },
10807
- params.fetch(:flags) { flags },
10808
11466
  params.fetch(:location) { location },
10809
11467
  )
10810
11468
  end
@@ -10814,22 +11472,7 @@ module Prism
10814
11472
 
10815
11473
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
10816
11474
  def deconstruct_keys(keys)
10817
- { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, flags: flags, location: location }
10818
- end
10819
-
10820
- # def opening: () -> String
10821
- def opening
10822
- opening_loc.slice
10823
- end
10824
-
10825
- # def content: () -> String
10826
- def content
10827
- content_loc.slice
10828
- end
10829
-
10830
- # def closing: () -> String
10831
- def closing
10832
- closing_loc.slice
11475
+ { flags: flags, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
10833
11476
  end
10834
11477
 
10835
11478
  # def ignore_case?: () -> bool
@@ -10872,15 +11515,45 @@ module Prism
10872
11515
  flags.anybits?(RegularExpressionFlags::UTF_8)
10873
11516
  end
10874
11517
 
11518
+ # def forced_utf8_encoding?: () -> bool
11519
+ def forced_utf8_encoding?
11520
+ flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING)
11521
+ end
11522
+
11523
+ # def forced_binary_encoding?: () -> bool
11524
+ def forced_binary_encoding?
11525
+ flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING)
11526
+ end
11527
+
11528
+ # def forced_us_ascii_encoding?: () -> bool
11529
+ def forced_us_ascii_encoding?
11530
+ flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING)
11531
+ end
11532
+
11533
+ # def opening: () -> String
11534
+ def opening
11535
+ opening_loc.slice
11536
+ end
11537
+
11538
+ # def content: () -> String
11539
+ def content
11540
+ content_loc.slice
11541
+ end
11542
+
11543
+ # def closing: () -> String
11544
+ def closing
11545
+ closing_loc.slice
11546
+ end
11547
+
10875
11548
  # def inspect(inspector: NodeInspector) -> String
10876
11549
  def inspect(inspector = NodeInspector.new)
10877
11550
  inspector << inspector.header(self)
11551
+ flags = [("ignore_case" if ignore_case?), ("extended" if extended?), ("multi_line" if multi_line?), ("once" if once?), ("euc_jp" if euc_jp?), ("ascii_8bit" if ascii_8bit?), ("windows_31j" if windows_31j?), ("utf_8" if utf_8?), ("forced_utf8_encoding" if forced_utf8_encoding?), ("forced_binary_encoding" if forced_binary_encoding?), ("forced_us_ascii_encoding" if forced_us_ascii_encoding?)].compact
11552
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
10878
11553
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
10879
11554
  inspector << "├── content_loc: #{inspector.location(content_loc)}\n"
10880
11555
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
10881
- inspector << "├── unescaped: #{unescaped.inspect}\n"
10882
- flags = [("ignore_case" if ignore_case?), ("extended" if extended?), ("multi_line" if multi_line?), ("once" if once?), ("euc_jp" if euc_jp?), ("ascii_8bit" if ascii_8bit?), ("windows_31j" if windows_31j?), ("utf_8" if utf_8?)].compact
10883
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
11556
+ inspector << "└── unescaped: #{unescaped.inspect}\n"
10884
11557
  inspector.to_str
10885
11558
  end
10886
11559
 
@@ -11132,13 +11805,13 @@ module Prism
11132
11805
  # attr_reader call: CallNode
11133
11806
  attr_reader :call
11134
11807
 
11135
- # attr_reader locals: Array[Symbol]
11136
- attr_reader :locals
11808
+ # attr_reader targets: Array[Node]
11809
+ attr_reader :targets
11137
11810
 
11138
- # def initialize: (call: CallNode, locals: Array[Symbol], location: Location) -> void
11139
- def initialize(call, locals, location)
11811
+ # def initialize: (call: CallNode, targets: Array[Node], location: Location) -> void
11812
+ def initialize(call, targets, location)
11140
11813
  @call = call
11141
- @locals = locals
11814
+ @targets = targets
11142
11815
  @location = location
11143
11816
  end
11144
11817
 
@@ -11149,24 +11822,24 @@ module Prism
11149
11822
 
11150
11823
  # def child_nodes: () -> Array[nil | Node]
11151
11824
  def child_nodes
11152
- [call]
11825
+ [call, *targets]
11153
11826
  end
11154
11827
 
11155
11828
  # def compact_child_nodes: () -> Array[Node]
11156
11829
  def compact_child_nodes
11157
- [call]
11830
+ [call, *targets]
11158
11831
  end
11159
11832
 
11160
11833
  # def comment_targets: () -> Array[Node | Location]
11161
11834
  def comment_targets
11162
- [call]
11835
+ [call, *targets]
11163
11836
  end
11164
11837
 
11165
11838
  # def copy: (**params) -> MatchWriteNode
11166
11839
  def copy(**params)
11167
11840
  MatchWriteNode.new(
11168
11841
  params.fetch(:call) { call },
11169
- params.fetch(:locals) { locals },
11842
+ params.fetch(:targets) { targets },
11170
11843
  params.fetch(:location) { location },
11171
11844
  )
11172
11845
  end
@@ -11176,7 +11849,7 @@ module Prism
11176
11849
 
11177
11850
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
11178
11851
  def deconstruct_keys(keys)
11179
- { call: call, locals: locals, location: location }
11852
+ { call: call, targets: targets, location: location }
11180
11853
  end
11181
11854
 
11182
11855
  # def inspect(inspector: NodeInspector) -> String
@@ -11184,7 +11857,7 @@ module Prism
11184
11857
  inspector << inspector.header(self)
11185
11858
  inspector << "├── call:\n"
11186
11859
  inspector << inspector.child_node(call, "│ ")
11187
- inspector << "└── locals: #{locals.inspect}\n"
11860
+ inspector << "└── targets: #{inspector.list("#{inspector.prefix} ", targets)}"
11188
11861
  inspector.to_str
11189
11862
  end
11190
11863
 
@@ -11994,6 +12667,93 @@ module Prism
11994
12667
  end
11995
12668
  end
11996
12669
 
12670
+ # Represents an implicit set of parameters through the use of numbered
12671
+ # parameters within a block or lambda.
12672
+ #
12673
+ # -> { _1 + _2 }
12674
+ # ^^^^^^^^^^^^^^
12675
+ class NumberedParametersNode < Node
12676
+ # attr_reader maximum: Integer
12677
+ attr_reader :maximum
12678
+
12679
+ # def initialize: (maximum: Integer, location: Location) -> void
12680
+ def initialize(maximum, location)
12681
+ @maximum = maximum
12682
+ @location = location
12683
+ end
12684
+
12685
+ # def accept: (visitor: Visitor) -> void
12686
+ def accept(visitor)
12687
+ visitor.visit_numbered_parameters_node(self)
12688
+ end
12689
+
12690
+ # def child_nodes: () -> Array[nil | Node]
12691
+ def child_nodes
12692
+ []
12693
+ end
12694
+
12695
+ # def compact_child_nodes: () -> Array[Node]
12696
+ def compact_child_nodes
12697
+ []
12698
+ end
12699
+
12700
+ # def comment_targets: () -> Array[Node | Location]
12701
+ def comment_targets
12702
+ []
12703
+ end
12704
+
12705
+ # def copy: (**params) -> NumberedParametersNode
12706
+ def copy(**params)
12707
+ NumberedParametersNode.new(
12708
+ params.fetch(:maximum) { maximum },
12709
+ params.fetch(:location) { location },
12710
+ )
12711
+ end
12712
+
12713
+ # def deconstruct: () -> Array[nil | Node]
12714
+ alias deconstruct child_nodes
12715
+
12716
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
12717
+ def deconstruct_keys(keys)
12718
+ { maximum: maximum, location: location }
12719
+ end
12720
+
12721
+ # def inspect(inspector: NodeInspector) -> String
12722
+ def inspect(inspector = NodeInspector.new)
12723
+ inspector << inspector.header(self)
12724
+ inspector << "└── maximum: #{maximum.inspect}\n"
12725
+ inspector.to_str
12726
+ end
12727
+
12728
+ # Sometimes you want to check an instance of a node against a list of
12729
+ # classes to see what kind of behavior to perform. Usually this is done by
12730
+ # calling `[cls1, cls2].include?(node.class)` or putting the node into a
12731
+ # case statement and doing `case node; when cls1; when cls2; end`. Both of
12732
+ # these approaches are relatively slow because of the constant lookups,
12733
+ # method calls, and/or array allocations.
12734
+ #
12735
+ # Instead, you can call #type, which will return to you a symbol that you
12736
+ # can use for comparison. This is faster than the other approaches because
12737
+ # it uses a single integer comparison, but also because if you're on CRuby
12738
+ # you can take advantage of the fact that case statements with all symbol
12739
+ # keys will use a jump table.
12740
+ #
12741
+ # def type: () -> Symbol
12742
+ def type
12743
+ :numbered_parameters_node
12744
+ end
12745
+
12746
+ # Similar to #type, this method returns a symbol that you can use for
12747
+ # splitting on the type of the node without having to do a long === chain.
12748
+ # Note that like #type, it will still be slower than using == for a single
12749
+ # class, but should be faster in a case statement or an array comparison.
12750
+ #
12751
+ # def self.type: () -> Symbol
12752
+ def self.type
12753
+ :numbered_parameters_node
12754
+ end
12755
+ end
12756
+
11997
12757
  # Represents reading a numbered reference to a capture in the previous match.
11998
12758
  #
11999
12759
  # $1
@@ -12408,7 +13168,7 @@ module Prism
12408
13168
  # attr_reader optionals: Array[Node]
12409
13169
  attr_reader :optionals
12410
13170
 
12411
- # attr_reader rest: RestParameterNode?
13171
+ # attr_reader rest: Node?
12412
13172
  attr_reader :rest
12413
13173
 
12414
13174
  # attr_reader posts: Array[Node]
@@ -12423,7 +13183,7 @@ module Prism
12423
13183
  # attr_reader block: BlockParameterNode?
12424
13184
  attr_reader :block
12425
13185
 
12426
- # def initialize: (requireds: Array[Node], optionals: Array[Node], rest: RestParameterNode?, posts: Array[Node], keywords: Array[Node], keyword_rest: Node?, block: BlockParameterNode?, location: Location) -> void
13186
+ # def initialize: (requireds: Array[Node], optionals: Array[Node], rest: Node?, posts: Array[Node], keywords: Array[Node], keyword_rest: Node?, block: BlockParameterNode?, location: Location) -> void
12427
13187
  def initialize(requireds, optionals, rest, posts, keywords, keyword_rest, block, location)
12428
13188
  @requireds = requireds
12429
13189
  @optionals = optionals
@@ -13231,6 +13991,9 @@ module Prism
13231
13991
  # c if a =~ /left/ ... b =~ /right/
13232
13992
  # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13233
13993
  class RangeNode < Node
13994
+ # attr_reader flags: Integer
13995
+ private attr_reader :flags
13996
+
13234
13997
  # attr_reader left: Node?
13235
13998
  attr_reader :left
13236
13999
 
@@ -13240,15 +14003,12 @@ module Prism
13240
14003
  # attr_reader operator_loc: Location
13241
14004
  attr_reader :operator_loc
13242
14005
 
13243
- # attr_reader flags: Integer
13244
- private attr_reader :flags
13245
-
13246
- # def initialize: (left: Node?, right: Node?, operator_loc: Location, flags: Integer, location: Location) -> void
13247
- def initialize(left, right, operator_loc, flags, location)
14006
+ # def initialize: (flags: Integer, left: Node?, right: Node?, operator_loc: Location, location: Location) -> void
14007
+ def initialize(flags, left, right, operator_loc, location)
14008
+ @flags = flags
13248
14009
  @left = left
13249
14010
  @right = right
13250
14011
  @operator_loc = operator_loc
13251
- @flags = flags
13252
14012
  @location = location
13253
14013
  end
13254
14014
 
@@ -13278,10 +14038,10 @@ module Prism
13278
14038
  # def copy: (**params) -> RangeNode
13279
14039
  def copy(**params)
13280
14040
  RangeNode.new(
14041
+ params.fetch(:flags) { flags },
13281
14042
  params.fetch(:left) { left },
13282
14043
  params.fetch(:right) { right },
13283
14044
  params.fetch(:operator_loc) { operator_loc },
13284
- params.fetch(:flags) { flags },
13285
14045
  params.fetch(:location) { location },
13286
14046
  )
13287
14047
  end
@@ -13290,13 +14050,8 @@ module Prism
13290
14050
  alias deconstruct child_nodes
13291
14051
 
13292
14052
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
13293
- def deconstruct_keys(keys)
13294
- { left: left, right: right, operator_loc: operator_loc, flags: flags, location: location }
13295
- end
13296
-
13297
- # def operator: () -> String
13298
- def operator
13299
- operator_loc.slice
14053
+ def deconstruct_keys(keys)
14054
+ { flags: flags, left: left, right: right, operator_loc: operator_loc, location: location }
13300
14055
  end
13301
14056
 
13302
14057
  # def exclude_end?: () -> bool
@@ -13304,9 +14059,16 @@ module Prism
13304
14059
  flags.anybits?(RangeFlags::EXCLUDE_END)
13305
14060
  end
13306
14061
 
14062
+ # def operator: () -> String
14063
+ def operator
14064
+ operator_loc.slice
14065
+ end
14066
+
13307
14067
  # def inspect(inspector: NodeInspector) -> String
13308
14068
  def inspect(inspector = NodeInspector.new)
13309
14069
  inspector << inspector.header(self)
14070
+ flags = [("exclude_end" if exclude_end?)].compact
14071
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
13310
14072
  if (left = self.left).nil?
13311
14073
  inspector << "├── left: ∅\n"
13312
14074
  else
@@ -13319,9 +14081,7 @@ module Prism
13319
14081
  inspector << "├── right:\n"
13320
14082
  inspector << right.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
13321
14083
  end
13322
- inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
13323
- flags = [("exclude_end" if exclude_end?)].compact
13324
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
14084
+ inspector << "└── operator_loc: #{inspector.location(operator_loc)}\n"
13325
14085
  inspector.to_str
13326
14086
  end
13327
14087
 
@@ -13526,6 +14286,9 @@ module Prism
13526
14286
  # /foo/i
13527
14287
  # ^^^^^^
13528
14288
  class RegularExpressionNode < Node
14289
+ # attr_reader flags: Integer
14290
+ private attr_reader :flags
14291
+
13529
14292
  # attr_reader opening_loc: Location
13530
14293
  attr_reader :opening_loc
13531
14294
 
@@ -13538,16 +14301,13 @@ module Prism
13538
14301
  # attr_reader unescaped: String
13539
14302
  attr_reader :unescaped
13540
14303
 
13541
- # attr_reader flags: Integer
13542
- private attr_reader :flags
13543
-
13544
- # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, flags: Integer, location: Location) -> void
13545
- def initialize(opening_loc, content_loc, closing_loc, unescaped, flags, location)
14304
+ # def initialize: (flags: Integer, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, location: Location) -> void
14305
+ def initialize(flags, opening_loc, content_loc, closing_loc, unescaped, location)
14306
+ @flags = flags
13546
14307
  @opening_loc = opening_loc
13547
14308
  @content_loc = content_loc
13548
14309
  @closing_loc = closing_loc
13549
14310
  @unescaped = unescaped
13550
- @flags = flags
13551
14311
  @location = location
13552
14312
  end
13553
14313
 
@@ -13574,11 +14334,11 @@ module Prism
13574
14334
  # def copy: (**params) -> RegularExpressionNode
13575
14335
  def copy(**params)
13576
14336
  RegularExpressionNode.new(
14337
+ params.fetch(:flags) { flags },
13577
14338
  params.fetch(:opening_loc) { opening_loc },
13578
14339
  params.fetch(:content_loc) { content_loc },
13579
14340
  params.fetch(:closing_loc) { closing_loc },
13580
14341
  params.fetch(:unescaped) { unescaped },
13581
- params.fetch(:flags) { flags },
13582
14342
  params.fetch(:location) { location },
13583
14343
  )
13584
14344
  end
@@ -13588,22 +14348,7 @@ module Prism
13588
14348
 
13589
14349
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
13590
14350
  def deconstruct_keys(keys)
13591
- { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, flags: flags, location: location }
13592
- end
13593
-
13594
- # def opening: () -> String
13595
- def opening
13596
- opening_loc.slice
13597
- end
13598
-
13599
- # def content: () -> String
13600
- def content
13601
- content_loc.slice
13602
- end
13603
-
13604
- # def closing: () -> String
13605
- def closing
13606
- closing_loc.slice
14351
+ { flags: flags, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
13607
14352
  end
13608
14353
 
13609
14354
  # def ignore_case?: () -> bool
@@ -13646,15 +14391,45 @@ module Prism
13646
14391
  flags.anybits?(RegularExpressionFlags::UTF_8)
13647
14392
  end
13648
14393
 
14394
+ # def forced_utf8_encoding?: () -> bool
14395
+ def forced_utf8_encoding?
14396
+ flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING)
14397
+ end
14398
+
14399
+ # def forced_binary_encoding?: () -> bool
14400
+ def forced_binary_encoding?
14401
+ flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING)
14402
+ end
14403
+
14404
+ # def forced_us_ascii_encoding?: () -> bool
14405
+ def forced_us_ascii_encoding?
14406
+ flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING)
14407
+ end
14408
+
14409
+ # def opening: () -> String
14410
+ def opening
14411
+ opening_loc.slice
14412
+ end
14413
+
14414
+ # def content: () -> String
14415
+ def content
14416
+ content_loc.slice
14417
+ end
14418
+
14419
+ # def closing: () -> String
14420
+ def closing
14421
+ closing_loc.slice
14422
+ end
14423
+
13649
14424
  # def inspect(inspector: NodeInspector) -> String
13650
14425
  def inspect(inspector = NodeInspector.new)
13651
14426
  inspector << inspector.header(self)
14427
+ flags = [("ignore_case" if ignore_case?), ("extended" if extended?), ("multi_line" if multi_line?), ("once" if once?), ("euc_jp" if euc_jp?), ("ascii_8bit" if ascii_8bit?), ("windows_31j" if windows_31j?), ("utf_8" if utf_8?), ("forced_utf8_encoding" if forced_utf8_encoding?), ("forced_binary_encoding" if forced_binary_encoding?), ("forced_us_ascii_encoding" if forced_us_ascii_encoding?)].compact
14428
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
13652
14429
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
13653
14430
  inspector << "├── content_loc: #{inspector.location(content_loc)}\n"
13654
14431
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
13655
- inspector << "├── unescaped: #{unescaped.inspect}\n"
13656
- flags = [("ignore_case" if ignore_case?), ("extended" if extended?), ("multi_line" if multi_line?), ("once" if once?), ("euc_jp" if euc_jp?), ("ascii_8bit" if ascii_8bit?), ("windows_31j" if windows_31j?), ("utf_8" if utf_8?)].compact
13657
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
14432
+ inspector << "└── unescaped: #{unescaped.inspect}\n"
13658
14433
  inspector.to_str
13659
14434
  end
13660
14435
 
@@ -15076,100 +15851,6 @@ module Prism
15076
15851
  end
15077
15852
  end
15078
15853
 
15079
- # Represents the use of compile-time string concatenation.
15080
- #
15081
- # "foo" "bar"
15082
- # ^^^^^^^^^^^
15083
- class StringConcatNode < Node
15084
- # attr_reader left: Node
15085
- attr_reader :left
15086
-
15087
- # attr_reader right: Node
15088
- attr_reader :right
15089
-
15090
- # def initialize: (left: Node, right: Node, location: Location) -> void
15091
- def initialize(left, right, location)
15092
- @left = left
15093
- @right = right
15094
- @location = location
15095
- end
15096
-
15097
- # def accept: (visitor: Visitor) -> void
15098
- def accept(visitor)
15099
- visitor.visit_string_concat_node(self)
15100
- end
15101
-
15102
- # def child_nodes: () -> Array[nil | Node]
15103
- def child_nodes
15104
- [left, right]
15105
- end
15106
-
15107
- # def compact_child_nodes: () -> Array[Node]
15108
- def compact_child_nodes
15109
- [left, right]
15110
- end
15111
-
15112
- # def comment_targets: () -> Array[Node | Location]
15113
- def comment_targets
15114
- [left, right]
15115
- end
15116
-
15117
- # def copy: (**params) -> StringConcatNode
15118
- def copy(**params)
15119
- StringConcatNode.new(
15120
- params.fetch(:left) { left },
15121
- params.fetch(:right) { right },
15122
- params.fetch(:location) { location },
15123
- )
15124
- end
15125
-
15126
- # def deconstruct: () -> Array[nil | Node]
15127
- alias deconstruct child_nodes
15128
-
15129
- # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
15130
- def deconstruct_keys(keys)
15131
- { left: left, right: right, location: location }
15132
- end
15133
-
15134
- # def inspect(inspector: NodeInspector) -> String
15135
- def inspect(inspector = NodeInspector.new)
15136
- inspector << inspector.header(self)
15137
- inspector << "├── left:\n"
15138
- inspector << inspector.child_node(left, "│ ")
15139
- inspector << "└── right:\n"
15140
- inspector << inspector.child_node(right, " ")
15141
- inspector.to_str
15142
- end
15143
-
15144
- # Sometimes you want to check an instance of a node against a list of
15145
- # classes to see what kind of behavior to perform. Usually this is done by
15146
- # calling `[cls1, cls2].include?(node.class)` or putting the node into a
15147
- # case statement and doing `case node; when cls1; when cls2; end`. Both of
15148
- # these approaches are relatively slow because of the constant lookups,
15149
- # method calls, and/or array allocations.
15150
- #
15151
- # Instead, you can call #type, which will return to you a symbol that you
15152
- # can use for comparison. This is faster than the other approaches because
15153
- # it uses a single integer comparison, but also because if you're on CRuby
15154
- # you can take advantage of the fact that case statements with all symbol
15155
- # keys will use a jump table.
15156
- #
15157
- # def type: () -> Symbol
15158
- def type
15159
- :string_concat_node
15160
- end
15161
-
15162
- # Similar to #type, this method returns a symbol that you can use for
15163
- # splitting on the type of the node without having to do a long === chain.
15164
- # Note that like #type, it will still be slower than using == for a single
15165
- # class, but should be faster in a case statement or an array comparison.
15166
- #
15167
- # def self.type: () -> Symbol
15168
- def self.type
15169
- :string_concat_node
15170
- end
15171
- end
15172
-
15173
15854
  # Represents a string literal, a string contained within a `%w` list, or
15174
15855
  # plain string content within an interpolated string.
15175
15856
  #
@@ -15247,6 +15928,16 @@ module Prism
15247
15928
  { flags: flags, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
15248
15929
  end
15249
15930
 
15931
+ # def forced_utf8_encoding?: () -> bool
15932
+ def forced_utf8_encoding?
15933
+ flags.anybits?(StringFlags::FORCED_UTF8_ENCODING)
15934
+ end
15935
+
15936
+ # def forced_binary_encoding?: () -> bool
15937
+ def forced_binary_encoding?
15938
+ flags.anybits?(StringFlags::FORCED_BINARY_ENCODING)
15939
+ end
15940
+
15250
15941
  # def frozen?: () -> bool
15251
15942
  def frozen?
15252
15943
  flags.anybits?(StringFlags::FROZEN)
@@ -15270,7 +15961,7 @@ module Prism
15270
15961
  # def inspect(inspector: NodeInspector) -> String
15271
15962
  def inspect(inspector = NodeInspector.new)
15272
15963
  inspector << inspector.header(self)
15273
- flags = [("frozen" if frozen?)].compact
15964
+ flags = [("forced_utf8_encoding" if forced_utf8_encoding?), ("forced_binary_encoding" if forced_binary_encoding?), ("frozen" if frozen?)].compact
15274
15965
  inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
15275
15966
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
15276
15967
  inspector << "├── content_loc: #{inspector.location(content_loc)}\n"
@@ -15457,6 +16148,9 @@ module Prism
15457
16148
  # %i[foo]
15458
16149
  # ^^^
15459
16150
  class SymbolNode < Node
16151
+ # attr_reader flags: Integer
16152
+ private attr_reader :flags
16153
+
15460
16154
  # attr_reader opening_loc: Location?
15461
16155
  attr_reader :opening_loc
15462
16156
 
@@ -15469,8 +16163,9 @@ module Prism
15469
16163
  # attr_reader unescaped: String
15470
16164
  attr_reader :unescaped
15471
16165
 
15472
- # def initialize: (opening_loc: Location?, value_loc: Location?, closing_loc: Location?, unescaped: String, location: Location) -> void
15473
- def initialize(opening_loc, value_loc, closing_loc, unescaped, location)
16166
+ # def initialize: (flags: Integer, opening_loc: Location?, value_loc: Location?, closing_loc: Location?, unescaped: String, location: Location) -> void
16167
+ def initialize(flags, opening_loc, value_loc, closing_loc, unescaped, location)
16168
+ @flags = flags
15474
16169
  @opening_loc = opening_loc
15475
16170
  @value_loc = value_loc
15476
16171
  @closing_loc = closing_loc
@@ -15501,6 +16196,7 @@ module Prism
15501
16196
  # def copy: (**params) -> SymbolNode
15502
16197
  def copy(**params)
15503
16198
  SymbolNode.new(
16199
+ params.fetch(:flags) { flags },
15504
16200
  params.fetch(:opening_loc) { opening_loc },
15505
16201
  params.fetch(:value_loc) { value_loc },
15506
16202
  params.fetch(:closing_loc) { closing_loc },
@@ -15514,7 +16210,22 @@ module Prism
15514
16210
 
15515
16211
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
15516
16212
  def deconstruct_keys(keys)
15517
- { opening_loc: opening_loc, value_loc: value_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
16213
+ { flags: flags, opening_loc: opening_loc, value_loc: value_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
16214
+ end
16215
+
16216
+ # def forced_utf8_encoding?: () -> bool
16217
+ def forced_utf8_encoding?
16218
+ flags.anybits?(SymbolFlags::FORCED_UTF8_ENCODING)
16219
+ end
16220
+
16221
+ # def forced_binary_encoding?: () -> bool
16222
+ def forced_binary_encoding?
16223
+ flags.anybits?(SymbolFlags::FORCED_BINARY_ENCODING)
16224
+ end
16225
+
16226
+ # def forced_us_ascii_encoding?: () -> bool
16227
+ def forced_us_ascii_encoding?
16228
+ flags.anybits?(SymbolFlags::FORCED_US_ASCII_ENCODING)
15518
16229
  end
15519
16230
 
15520
16231
  # def opening: () -> String?
@@ -15535,6 +16246,8 @@ module Prism
15535
16246
  # def inspect(inspector: NodeInspector) -> String
15536
16247
  def inspect(inspector = NodeInspector.new)
15537
16248
  inspector << inspector.header(self)
16249
+ flags = [("forced_utf8_encoding" if forced_utf8_encoding?), ("forced_binary_encoding" if forced_binary_encoding?), ("forced_us_ascii_encoding" if forced_us_ascii_encoding?)].compact
16250
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
15538
16251
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
15539
16252
  inspector << "├── value_loc: #{inspector.location(value_loc)}\n"
15540
16253
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
@@ -15762,6 +16475,9 @@ module Prism
15762
16475
  # attr_reader predicate: Node
15763
16476
  attr_reader :predicate
15764
16477
 
16478
+ # attr_reader then_keyword_loc: Location?
16479
+ attr_reader :then_keyword_loc
16480
+
15765
16481
  # attr_reader statements: StatementsNode?
15766
16482
  attr_reader :statements
15767
16483
 
@@ -15771,10 +16487,11 @@ module Prism
15771
16487
  # attr_reader end_keyword_loc: Location?
15772
16488
  attr_reader :end_keyword_loc
15773
16489
 
15774
- # def initialize: (keyword_loc: Location, predicate: Node, statements: StatementsNode?, consequent: ElseNode?, end_keyword_loc: Location?, location: Location) -> void
15775
- def initialize(keyword_loc, predicate, statements, consequent, end_keyword_loc, location)
16490
+ # def initialize: (keyword_loc: Location, predicate: Node, then_keyword_loc: Location?, statements: StatementsNode?, consequent: ElseNode?, end_keyword_loc: Location?, location: Location) -> void
16491
+ def initialize(keyword_loc, predicate, then_keyword_loc, statements, consequent, end_keyword_loc, location)
15776
16492
  @keyword_loc = keyword_loc
15777
16493
  @predicate = predicate
16494
+ @then_keyword_loc = then_keyword_loc
15778
16495
  @statements = statements
15779
16496
  @consequent = consequent
15780
16497
  @end_keyword_loc = end_keyword_loc
@@ -15806,7 +16523,7 @@ module Prism
15806
16523
 
15807
16524
  # def comment_targets: () -> Array[Node | Location]
15808
16525
  def comment_targets
15809
- [keyword_loc, predicate, *statements, *consequent, *end_keyword_loc]
16526
+ [keyword_loc, predicate, *then_keyword_loc, *statements, *consequent, *end_keyword_loc]
15810
16527
  end
15811
16528
 
15812
16529
  # def copy: (**params) -> UnlessNode
@@ -15814,6 +16531,7 @@ module Prism
15814
16531
  UnlessNode.new(
15815
16532
  params.fetch(:keyword_loc) { keyword_loc },
15816
16533
  params.fetch(:predicate) { predicate },
16534
+ params.fetch(:then_keyword_loc) { then_keyword_loc },
15817
16535
  params.fetch(:statements) { statements },
15818
16536
  params.fetch(:consequent) { consequent },
15819
16537
  params.fetch(:end_keyword_loc) { end_keyword_loc },
@@ -15826,7 +16544,7 @@ module Prism
15826
16544
 
15827
16545
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
15828
16546
  def deconstruct_keys(keys)
15829
- { keyword_loc: keyword_loc, predicate: predicate, statements: statements, consequent: consequent, end_keyword_loc: end_keyword_loc, location: location }
16547
+ { keyword_loc: keyword_loc, predicate: predicate, then_keyword_loc: then_keyword_loc, statements: statements, consequent: consequent, end_keyword_loc: end_keyword_loc, location: location }
15830
16548
  end
15831
16549
 
15832
16550
  # def keyword: () -> String
@@ -15834,6 +16552,11 @@ module Prism
15834
16552
  keyword_loc.slice
15835
16553
  end
15836
16554
 
16555
+ # def then_keyword: () -> String?
16556
+ def then_keyword
16557
+ then_keyword_loc&.slice
16558
+ end
16559
+
15837
16560
  # def end_keyword: () -> String?
15838
16561
  def end_keyword
15839
16562
  end_keyword_loc&.slice
@@ -15845,6 +16568,7 @@ module Prism
15845
16568
  inspector << "├── keyword_loc: #{inspector.location(keyword_loc)}\n"
15846
16569
  inspector << "├── predicate:\n"
15847
16570
  inspector << inspector.child_node(predicate, "│ ")
16571
+ inspector << "├── then_keyword_loc: #{inspector.location(then_keyword_loc)}\n"
15848
16572
  if (statements = self.statements).nil?
15849
16573
  inspector << "├── statements: ∅\n"
15850
16574
  else
@@ -15898,6 +16622,9 @@ module Prism
15898
16622
  # until foo do bar end
15899
16623
  # ^^^^^^^^^^^^^^^^^^^^
15900
16624
  class UntilNode < Node
16625
+ # attr_reader flags: Integer
16626
+ private attr_reader :flags
16627
+
15901
16628
  # attr_reader keyword_loc: Location
15902
16629
  attr_reader :keyword_loc
15903
16630
 
@@ -15910,16 +16637,13 @@ module Prism
15910
16637
  # attr_reader statements: StatementsNode?
15911
16638
  attr_reader :statements
15912
16639
 
15913
- # attr_reader flags: Integer
15914
- private attr_reader :flags
15915
-
15916
- # def initialize: (keyword_loc: Location, closing_loc: Location?, predicate: Node, statements: StatementsNode?, flags: Integer, location: Location) -> void
15917
- def initialize(keyword_loc, closing_loc, predicate, statements, flags, location)
16640
+ # def initialize: (flags: Integer, keyword_loc: Location, closing_loc: Location?, predicate: Node, statements: StatementsNode?, location: Location) -> void
16641
+ def initialize(flags, keyword_loc, closing_loc, predicate, statements, location)
16642
+ @flags = flags
15918
16643
  @keyword_loc = keyword_loc
15919
16644
  @closing_loc = closing_loc
15920
16645
  @predicate = predicate
15921
16646
  @statements = statements
15922
- @flags = flags
15923
16647
  @location = location
15924
16648
  end
15925
16649
 
@@ -15953,11 +16677,11 @@ module Prism
15953
16677
  # def copy: (**params) -> UntilNode
15954
16678
  def copy(**params)
15955
16679
  UntilNode.new(
16680
+ params.fetch(:flags) { flags },
15956
16681
  params.fetch(:keyword_loc) { keyword_loc },
15957
16682
  params.fetch(:closing_loc) { closing_loc },
15958
16683
  params.fetch(:predicate) { predicate },
15959
16684
  params.fetch(:statements) { statements },
15960
- params.fetch(:flags) { flags },
15961
16685
  params.fetch(:location) { location },
15962
16686
  )
15963
16687
  end
@@ -15967,7 +16691,12 @@ module Prism
15967
16691
 
15968
16692
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
15969
16693
  def deconstruct_keys(keys)
15970
- { keyword_loc: keyword_loc, closing_loc: closing_loc, predicate: predicate, statements: statements, flags: flags, location: location }
16694
+ { flags: flags, keyword_loc: keyword_loc, closing_loc: closing_loc, predicate: predicate, statements: statements, location: location }
16695
+ end
16696
+
16697
+ # def begin_modifier?: () -> bool
16698
+ def begin_modifier?
16699
+ flags.anybits?(LoopFlags::BEGIN_MODIFIER)
15971
16700
  end
15972
16701
 
15973
16702
  # def keyword: () -> String
@@ -15980,26 +16709,21 @@ module Prism
15980
16709
  closing_loc&.slice
15981
16710
  end
15982
16711
 
15983
- # def begin_modifier?: () -> bool
15984
- def begin_modifier?
15985
- flags.anybits?(LoopFlags::BEGIN_MODIFIER)
15986
- end
15987
-
15988
16712
  # def inspect(inspector: NodeInspector) -> String
15989
16713
  def inspect(inspector = NodeInspector.new)
15990
16714
  inspector << inspector.header(self)
16715
+ flags = [("begin_modifier" if begin_modifier?)].compact
16716
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
15991
16717
  inspector << "├── keyword_loc: #{inspector.location(keyword_loc)}\n"
15992
16718
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
15993
16719
  inspector << "├── predicate:\n"
15994
16720
  inspector << inspector.child_node(predicate, "│ ")
15995
16721
  if (statements = self.statements).nil?
15996
- inspector << "├── statements: ∅\n"
16722
+ inspector << "└── statements: ∅\n"
15997
16723
  else
15998
- inspector << "├── statements:\n"
15999
- inspector << statements.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
16724
+ inspector << "└── statements:\n"
16725
+ inspector << statements.inspect(inspector.child_inspector(" ")).delete_prefix(inspector.prefix)
16000
16726
  end
16001
- flags = [("begin_modifier" if begin_modifier?)].compact
16002
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
16003
16727
  inspector.to_str
16004
16728
  end
16005
16729
 
@@ -16153,6 +16877,9 @@ module Prism
16153
16877
  # while foo do bar end
16154
16878
  # ^^^^^^^^^^^^^^^^^^^^
16155
16879
  class WhileNode < Node
16880
+ # attr_reader flags: Integer
16881
+ private attr_reader :flags
16882
+
16156
16883
  # attr_reader keyword_loc: Location
16157
16884
  attr_reader :keyword_loc
16158
16885
 
@@ -16165,16 +16892,13 @@ module Prism
16165
16892
  # attr_reader statements: StatementsNode?
16166
16893
  attr_reader :statements
16167
16894
 
16168
- # attr_reader flags: Integer
16169
- private attr_reader :flags
16170
-
16171
- # def initialize: (keyword_loc: Location, closing_loc: Location?, predicate: Node, statements: StatementsNode?, flags: Integer, location: Location) -> void
16172
- def initialize(keyword_loc, closing_loc, predicate, statements, flags, location)
16895
+ # def initialize: (flags: Integer, keyword_loc: Location, closing_loc: Location?, predicate: Node, statements: StatementsNode?, location: Location) -> void
16896
+ def initialize(flags, keyword_loc, closing_loc, predicate, statements, location)
16897
+ @flags = flags
16173
16898
  @keyword_loc = keyword_loc
16174
16899
  @closing_loc = closing_loc
16175
16900
  @predicate = predicate
16176
16901
  @statements = statements
16177
- @flags = flags
16178
16902
  @location = location
16179
16903
  end
16180
16904
 
@@ -16208,11 +16932,11 @@ module Prism
16208
16932
  # def copy: (**params) -> WhileNode
16209
16933
  def copy(**params)
16210
16934
  WhileNode.new(
16935
+ params.fetch(:flags) { flags },
16211
16936
  params.fetch(:keyword_loc) { keyword_loc },
16212
16937
  params.fetch(:closing_loc) { closing_loc },
16213
16938
  params.fetch(:predicate) { predicate },
16214
16939
  params.fetch(:statements) { statements },
16215
- params.fetch(:flags) { flags },
16216
16940
  params.fetch(:location) { location },
16217
16941
  )
16218
16942
  end
@@ -16222,7 +16946,12 @@ module Prism
16222
16946
 
16223
16947
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
16224
16948
  def deconstruct_keys(keys)
16225
- { keyword_loc: keyword_loc, closing_loc: closing_loc, predicate: predicate, statements: statements, flags: flags, location: location }
16949
+ { flags: flags, keyword_loc: keyword_loc, closing_loc: closing_loc, predicate: predicate, statements: statements, location: location }
16950
+ end
16951
+
16952
+ # def begin_modifier?: () -> bool
16953
+ def begin_modifier?
16954
+ flags.anybits?(LoopFlags::BEGIN_MODIFIER)
16226
16955
  end
16227
16956
 
16228
16957
  # def keyword: () -> String
@@ -16235,26 +16964,21 @@ module Prism
16235
16964
  closing_loc&.slice
16236
16965
  end
16237
16966
 
16238
- # def begin_modifier?: () -> bool
16239
- def begin_modifier?
16240
- flags.anybits?(LoopFlags::BEGIN_MODIFIER)
16241
- end
16242
-
16243
16967
  # def inspect(inspector: NodeInspector) -> String
16244
16968
  def inspect(inspector = NodeInspector.new)
16245
16969
  inspector << inspector.header(self)
16970
+ flags = [("begin_modifier" if begin_modifier?)].compact
16971
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
16246
16972
  inspector << "├── keyword_loc: #{inspector.location(keyword_loc)}\n"
16247
16973
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
16248
16974
  inspector << "├── predicate:\n"
16249
16975
  inspector << inspector.child_node(predicate, "│ ")
16250
16976
  if (statements = self.statements).nil?
16251
- inspector << "├── statements: ∅\n"
16977
+ inspector << "└── statements: ∅\n"
16252
16978
  else
16253
- inspector << "├── statements:\n"
16254
- inspector << statements.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
16979
+ inspector << "└── statements:\n"
16980
+ inspector << statements.inspect(inspector.child_inspector(" ")).delete_prefix(inspector.prefix)
16255
16981
  end
16256
- flags = [("begin_modifier" if begin_modifier?)].compact
16257
- inspector << "└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
16258
16982
  inspector.to_str
16259
16983
  end
16260
16984
 
@@ -16292,6 +17016,9 @@ module Prism
16292
17016
  # `foo`
16293
17017
  # ^^^^^
16294
17018
  class XStringNode < Node
17019
+ # attr_reader flags: Integer
17020
+ private attr_reader :flags
17021
+
16295
17022
  # attr_reader opening_loc: Location
16296
17023
  attr_reader :opening_loc
16297
17024
 
@@ -16304,8 +17031,9 @@ module Prism
16304
17031
  # attr_reader unescaped: String
16305
17032
  attr_reader :unescaped
16306
17033
 
16307
- # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, location: Location) -> void
16308
- def initialize(opening_loc, content_loc, closing_loc, unescaped, location)
17034
+ # def initialize: (flags: Integer, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, location: Location) -> void
17035
+ def initialize(flags, opening_loc, content_loc, closing_loc, unescaped, location)
17036
+ @flags = flags
16309
17037
  @opening_loc = opening_loc
16310
17038
  @content_loc = content_loc
16311
17039
  @closing_loc = closing_loc
@@ -16336,6 +17064,7 @@ module Prism
16336
17064
  # def copy: (**params) -> XStringNode
16337
17065
  def copy(**params)
16338
17066
  XStringNode.new(
17067
+ params.fetch(:flags) { flags },
16339
17068
  params.fetch(:opening_loc) { opening_loc },
16340
17069
  params.fetch(:content_loc) { content_loc },
16341
17070
  params.fetch(:closing_loc) { closing_loc },
@@ -16349,7 +17078,17 @@ module Prism
16349
17078
 
16350
17079
  # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
16351
17080
  def deconstruct_keys(keys)
16352
- { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
17081
+ { flags: flags, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
17082
+ end
17083
+
17084
+ # def forced_utf8_encoding?: () -> bool
17085
+ def forced_utf8_encoding?
17086
+ flags.anybits?(EncodingFlags::FORCED_UTF8_ENCODING)
17087
+ end
17088
+
17089
+ # def forced_binary_encoding?: () -> bool
17090
+ def forced_binary_encoding?
17091
+ flags.anybits?(EncodingFlags::FORCED_BINARY_ENCODING)
16353
17092
  end
16354
17093
 
16355
17094
  # def opening: () -> String
@@ -16370,6 +17109,8 @@ module Prism
16370
17109
  # def inspect(inspector: NodeInspector) -> String
16371
17110
  def inspect(inspector = NodeInspector.new)
16372
17111
  inspector << inspector.header(self)
17112
+ flags = [("forced_utf8_encoding" if forced_utf8_encoding?), ("forced_binary_encoding" if forced_binary_encoding?)].compact
17113
+ inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
16373
17114
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
16374
17115
  inspector << "├── content_loc: #{inspector.location(content_loc)}\n"
16375
17116
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
@@ -16535,7 +17276,13 @@ module Prism
16535
17276
  # Flags for arguments nodes.
16536
17277
  module ArgumentsNodeFlags
16537
17278
  # if arguments contain keyword splat
16538
- KEYWORD_SPLAT = 1 << 0
17279
+ CONTAINS_KEYWORD_SPLAT = 1 << 0
17280
+ end
17281
+
17282
+ # Flags for array nodes.
17283
+ module ArrayNodeFlags
17284
+ # if array contains splat nodes
17285
+ CONTAINS_SPLAT = 1 << 0
16539
17286
  end
16540
17287
 
16541
17288
  # Flags for call nodes.
@@ -16545,6 +17292,18 @@ module Prism
16545
17292
 
16546
17293
  # a call that could have been a local variable
16547
17294
  VARIABLE_CALL = 1 << 1
17295
+
17296
+ # a call that is an attribute write, so the value being written should be returned
17297
+ ATTRIBUTE_WRITE = 1 << 2
17298
+ end
17299
+
17300
+ # Flags for nodes that have unescaped content.
17301
+ module EncodingFlags
17302
+ # internal bytes forced the encoding to UTF-8
17303
+ FORCED_UTF8_ENCODING = 1 << 0
17304
+
17305
+ # internal bytes forced the encoding to binary
17306
+ FORCED_BINARY_ENCODING = 1 << 1
16548
17307
  end
16549
17308
 
16550
17309
  # Flags for integer nodes that correspond to the base of the integer.
@@ -16552,16 +17311,22 @@ module Prism
16552
17311
  # 0b prefix
16553
17312
  BINARY = 1 << 0
16554
17313
 
16555
- # 0o or 0 prefix
16556
- OCTAL = 1 << 1
16557
-
16558
17314
  # 0d or no prefix
16559
- DECIMAL = 1 << 2
17315
+ DECIMAL = 1 << 1
17316
+
17317
+ # 0o or 0 prefix
17318
+ OCTAL = 1 << 2
16560
17319
 
16561
17320
  # 0x prefix
16562
17321
  HEXADECIMAL = 1 << 3
16563
17322
  end
16564
17323
 
17324
+ # Flags for keyword hash nodes.
17325
+ module KeywordHashNodeFlags
17326
+ # a keyword hash which only has `AssocNode` elements all with static literal keys, which means the elements can be treated as keyword arguments
17327
+ STATIC_KEYS = 1 << 0
17328
+ end
17329
+
16565
17330
  # Flags for while and until loop nodes.
16566
17331
  module LoopFlags
16567
17332
  # a loop after a begin statement, so the body is executed first before the condition
@@ -16599,11 +17364,38 @@ module Prism
16599
17364
 
16600
17365
  # u - forces the UTF-8 encoding
16601
17366
  UTF_8 = 1 << 7
17367
+
17368
+ # internal bytes forced the encoding to UTF-8
17369
+ FORCED_UTF8_ENCODING = 1 << 8
17370
+
17371
+ # internal bytes forced the encoding to binary
17372
+ FORCED_BINARY_ENCODING = 1 << 9
17373
+
17374
+ # internal bytes forced the encoding to US-ASCII
17375
+ FORCED_US_ASCII_ENCODING = 1 << 10
16602
17376
  end
16603
17377
 
16604
17378
  # Flags for string nodes.
16605
17379
  module StringFlags
17380
+ # internal bytes forced the encoding to UTF-8
17381
+ FORCED_UTF8_ENCODING = 1 << 0
17382
+
17383
+ # internal bytes forced the encoding to binary
17384
+ FORCED_BINARY_ENCODING = 1 << 1
17385
+
16606
17386
  # frozen by virtue of a `frozen_string_literal` comment
16607
- FROZEN = 1 << 0
17387
+ FROZEN = 1 << 2
17388
+ end
17389
+
17390
+ # Flags for symbol nodes.
17391
+ module SymbolFlags
17392
+ # internal bytes forced the encoding to UTF-8
17393
+ FORCED_UTF8_ENCODING = 1 << 0
17394
+
17395
+ # internal bytes forced the encoding to binary
17396
+ FORCED_BINARY_ENCODING = 1 << 1
17397
+
17398
+ # internal bytes forced the encoding to US-ASCII
17399
+ FORCED_US_ASCII_ENCODING = 1 << 2
16608
17400
  end
16609
17401
  end