prism 0.18.0 → 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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -1
  3. data/README.md +2 -1
  4. data/config.yml +188 -55
  5. data/docs/building.md +9 -2
  6. data/docs/configuration.md +10 -9
  7. data/docs/encoding.md +24 -56
  8. data/docs/local_variable_depth.md +229 -0
  9. data/docs/ruby_api.md +2 -0
  10. data/docs/serialization.md +18 -13
  11. data/ext/prism/api_node.c +337 -195
  12. data/ext/prism/extconf.rb +13 -7
  13. data/ext/prism/extension.c +96 -32
  14. data/ext/prism/extension.h +1 -1
  15. data/include/prism/ast.h +340 -137
  16. data/include/prism/defines.h +17 -0
  17. data/include/prism/diagnostic.h +11 -5
  18. data/include/prism/encoding.h +248 -0
  19. data/include/prism/options.h +2 -2
  20. data/include/prism/parser.h +62 -42
  21. data/include/prism/regexp.h +2 -2
  22. data/include/prism/util/pm_buffer.h +9 -1
  23. data/include/prism/util/pm_memchr.h +2 -2
  24. data/include/prism/util/pm_strpbrk.h +3 -3
  25. data/include/prism/version.h +2 -2
  26. data/include/prism.h +13 -15
  27. data/lib/prism/compiler.rb +12 -0
  28. data/lib/prism/debug.rb +9 -4
  29. data/lib/prism/desugar_compiler.rb +3 -3
  30. data/lib/prism/dispatcher.rb +56 -0
  31. data/lib/prism/dot_visitor.rb +476 -198
  32. data/lib/prism/dsl.rb +66 -46
  33. data/lib/prism/ffi.rb +16 -3
  34. data/lib/prism/lex_compat.rb +19 -9
  35. data/lib/prism/mutation_compiler.rb +20 -0
  36. data/lib/prism/node.rb +1173 -450
  37. data/lib/prism/node_ext.rb +41 -16
  38. data/lib/prism/parse_result.rb +12 -15
  39. data/lib/prism/ripper_compat.rb +49 -34
  40. data/lib/prism/serialize.rb +242 -212
  41. data/lib/prism/visitor.rb +12 -0
  42. data/lib/prism.rb +20 -4
  43. data/prism.gemspec +4 -10
  44. data/rbi/prism.rbi +605 -230
  45. data/rbi/prism_static.rbi +3 -0
  46. data/sig/prism.rbs +379 -124
  47. data/sig/prism_static.rbs +1 -0
  48. data/src/diagnostic.c +228 -222
  49. data/src/encoding.c +5137 -0
  50. data/src/node.c +66 -0
  51. data/src/options.c +21 -2
  52. data/src/prettyprint.c +806 -406
  53. data/src/prism.c +1092 -700
  54. data/src/regexp.c +3 -3
  55. data/src/serialize.c +227 -157
  56. data/src/util/pm_buffer.c +10 -1
  57. data/src/util/pm_memchr.c +1 -1
  58. data/src/util/pm_strpbrk.c +4 -4
  59. metadata +5 -11
  60. data/include/prism/enc/pm_encoding.h +0 -227
  61. data/src/enc/pm_big5.c +0 -116
  62. data/src/enc/pm_cp51932.c +0 -57
  63. data/src/enc/pm_euc_jp.c +0 -69
  64. data/src/enc/pm_gbk.c +0 -65
  65. data/src/enc/pm_shift_jis.c +0 -57
  66. data/src/enc/pm_tables.c +0 -2073
  67. data/src/enc/pm_unicode.c +0 -2369
  68. data/src/enc/pm_windows_31j.c +0 -57
@@ -216,17 +216,21 @@ module Prism
216
216
  table = Table.new("ArgumentsNode")
217
217
  id = node_id(node)
218
218
 
219
- # arguments
220
- table.field("arguments", port: true)
219
+ # flags
220
+ table.field("flags", arguments_node_flags_inspect(node))
221
221
 
222
- waypoint = "#{id}_arguments"
223
- digraph.waypoint("#{waypoint};")
222
+ # arguments
223
+ if node.arguments.any?
224
+ table.field("arguments", port: true)
224
225
 
225
- digraph.edge("#{id}:arguments -> #{waypoint};")
226
- node.arguments.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
226
+ waypoint = "#{id}_arguments"
227
+ digraph.waypoint("#{waypoint};")
227
228
 
228
- # flags
229
- table.field("flags", arguments_node_flags_inspect(node))
229
+ digraph.edge("#{id}:arguments -> #{waypoint};")
230
+ node.arguments.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
231
+ else
232
+ table.field("arguments", "[]")
233
+ end
230
234
 
231
235
  digraph.nodes << <<~DOT
232
236
  #{id} [
@@ -242,14 +246,21 @@ module Prism
242
246
  table = Table.new("ArrayNode")
243
247
  id = node_id(node)
244
248
 
249
+ # flags
250
+ table.field("flags", array_node_flags_inspect(node))
251
+
245
252
  # elements
246
- table.field("elements", port: true)
253
+ if node.elements.any?
254
+ table.field("elements", port: true)
247
255
 
248
- waypoint = "#{id}_elements"
249
- digraph.waypoint("#{waypoint};")
256
+ waypoint = "#{id}_elements"
257
+ digraph.waypoint("#{waypoint};")
250
258
 
251
- digraph.edge("#{id}:elements -> #{waypoint};")
252
- node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
259
+ digraph.edge("#{id}:elements -> #{waypoint};")
260
+ node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
261
+ else
262
+ table.field("elements", "[]")
263
+ end
253
264
 
254
265
  # opening_loc
255
266
  unless (opening_loc = node.opening_loc).nil?
@@ -282,13 +293,17 @@ module Prism
282
293
  end
283
294
 
284
295
  # requireds
285
- table.field("requireds", port: true)
296
+ if node.requireds.any?
297
+ table.field("requireds", port: true)
286
298
 
287
- waypoint = "#{id}_requireds"
288
- digraph.waypoint("#{waypoint};")
299
+ waypoint = "#{id}_requireds"
300
+ digraph.waypoint("#{waypoint};")
289
301
 
290
- digraph.edge("#{id}:requireds -> #{waypoint};")
291
- node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
302
+ digraph.edge("#{id}:requireds -> #{waypoint};")
303
+ node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
304
+ else
305
+ table.field("requireds", "[]")
306
+ end
292
307
 
293
308
  # rest
294
309
  unless (rest = node.rest).nil?
@@ -297,13 +312,17 @@ module Prism
297
312
  end
298
313
 
299
314
  # posts
300
- table.field("posts", port: true)
315
+ if node.posts.any?
316
+ table.field("posts", port: true)
301
317
 
302
- waypoint = "#{id}_posts"
303
- digraph.waypoint("#{waypoint};")
318
+ waypoint = "#{id}_posts"
319
+ digraph.waypoint("#{waypoint};")
304
320
 
305
- digraph.edge("#{id}:posts -> #{waypoint};")
306
- node.posts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
321
+ digraph.edge("#{id}:posts -> #{waypoint};")
322
+ node.posts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
323
+ else
324
+ table.field("posts", "[]")
325
+ end
307
326
 
308
327
  # opening_loc
309
328
  unless (opening_loc = node.opening_loc).nil?
@@ -489,6 +508,9 @@ module Prism
489
508
  # locals
490
509
  table.field("locals", node.locals.inspect)
491
510
 
511
+ # locals_body_index
512
+ table.field("locals_body_index", node.locals_body_index.inspect)
513
+
492
514
  # parameters
493
515
  unless (parameters = node.parameters).nil?
494
516
  table.field("parameters", port: true)
@@ -553,13 +575,17 @@ module Prism
553
575
  end
554
576
 
555
577
  # locals
556
- table.field("locals", port: true)
578
+ if node.locals.any?
579
+ table.field("locals", port: true)
557
580
 
558
- waypoint = "#{id}_locals"
559
- digraph.waypoint("#{waypoint};")
581
+ waypoint = "#{id}_locals"
582
+ digraph.waypoint("#{waypoint};")
560
583
 
561
- digraph.edge("#{id}:locals -> #{waypoint};")
562
- node.locals.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
584
+ digraph.edge("#{id}:locals -> #{waypoint};")
585
+ node.locals.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
586
+ else
587
+ table.field("locals", "[]")
588
+ end
563
589
 
564
590
  # opening_loc
565
591
  unless (opening_loc = node.opening_loc).nil?
@@ -608,6 +634,9 @@ module Prism
608
634
  table = Table.new("CallAndWriteNode")
609
635
  id = node_id(node)
610
636
 
637
+ # flags
638
+ table.field("flags", call_node_flags_inspect(node))
639
+
611
640
  # receiver
612
641
  unless (receiver = node.receiver).nil?
613
642
  table.field("receiver", port: true)
@@ -624,9 +653,6 @@ module Prism
624
653
  table.field("message_loc", location_inspect(message_loc))
625
654
  end
626
655
 
627
- # flags
628
- table.field("flags", call_node_flags_inspect(node))
629
-
630
656
  # read_name
631
657
  table.field("read_name", node.read_name.inspect)
632
658
 
@@ -654,6 +680,9 @@ module Prism
654
680
  table = Table.new("CallNode")
655
681
  id = node_id(node)
656
682
 
683
+ # flags
684
+ table.field("flags", call_node_flags_inspect(node))
685
+
657
686
  # receiver
658
687
  unless (receiver = node.receiver).nil?
659
688
  table.field("receiver", port: true)
@@ -665,6 +694,9 @@ module Prism
665
694
  table.field("call_operator_loc", location_inspect(call_operator_loc))
666
695
  end
667
696
 
697
+ # name
698
+ table.field("name", node.name.inspect)
699
+
668
700
  # message_loc
669
701
  unless (message_loc = node.message_loc).nil?
670
702
  table.field("message_loc", location_inspect(message_loc))
@@ -692,12 +724,6 @@ module Prism
692
724
  digraph.edge("#{id}:block -> #{node_id(block)};")
693
725
  end
694
726
 
695
- # flags
696
- table.field("flags", call_node_flags_inspect(node))
697
-
698
- # name
699
- table.field("name", node.name.inspect)
700
-
701
727
  digraph.nodes << <<~DOT
702
728
  #{id} [
703
729
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -712,6 +738,9 @@ module Prism
712
738
  table = Table.new("CallOperatorWriteNode")
713
739
  id = node_id(node)
714
740
 
741
+ # flags
742
+ table.field("flags", call_node_flags_inspect(node))
743
+
715
744
  # receiver
716
745
  unless (receiver = node.receiver).nil?
717
746
  table.field("receiver", port: true)
@@ -728,9 +757,6 @@ module Prism
728
757
  table.field("message_loc", location_inspect(message_loc))
729
758
  end
730
759
 
731
- # flags
732
- table.field("flags", call_node_flags_inspect(node))
733
-
734
760
  # read_name
735
761
  table.field("read_name", node.read_name.inspect)
736
762
 
@@ -761,6 +787,9 @@ module Prism
761
787
  table = Table.new("CallOrWriteNode")
762
788
  id = node_id(node)
763
789
 
790
+ # flags
791
+ table.field("flags", call_node_flags_inspect(node))
792
+
764
793
  # receiver
765
794
  unless (receiver = node.receiver).nil?
766
795
  table.field("receiver", port: true)
@@ -777,9 +806,6 @@ module Prism
777
806
  table.field("message_loc", location_inspect(message_loc))
778
807
  end
779
808
 
780
- # flags
781
- table.field("flags", call_node_flags_inspect(node))
782
-
783
809
  # read_name
784
810
  table.field("read_name", node.read_name.inspect)
785
811
 
@@ -802,6 +828,36 @@ module Prism
802
828
  super
803
829
  end
804
830
 
831
+ # Visit a CallTargetNode node.
832
+ def visit_call_target_node(node)
833
+ table = Table.new("CallTargetNode")
834
+ id = node_id(node)
835
+
836
+ # flags
837
+ table.field("flags", call_node_flags_inspect(node))
838
+
839
+ # receiver
840
+ table.field("receiver", port: true)
841
+ digraph.edge("#{id}:receiver -> #{node_id(node.receiver)};")
842
+
843
+ # call_operator_loc
844
+ table.field("call_operator_loc", location_inspect(node.call_operator_loc))
845
+
846
+ # name
847
+ table.field("name", node.name.inspect)
848
+
849
+ # message_loc
850
+ table.field("message_loc", location_inspect(node.message_loc))
851
+
852
+ digraph.nodes << <<~DOT
853
+ #{id} [
854
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
855
+ ];
856
+ DOT
857
+
858
+ super
859
+ end
860
+
805
861
  # Visit a CapturePatternNode node.
806
862
  def visit_capture_pattern_node(node)
807
863
  table = Table.new("CapturePatternNode")
@@ -839,13 +895,17 @@ module Prism
839
895
  end
840
896
 
841
897
  # conditions
842
- table.field("conditions", port: true)
898
+ if node.conditions.any?
899
+ table.field("conditions", port: true)
843
900
 
844
- waypoint = "#{id}_conditions"
845
- digraph.waypoint("#{waypoint};")
901
+ waypoint = "#{id}_conditions"
902
+ digraph.waypoint("#{waypoint};")
846
903
 
847
- digraph.edge("#{id}:conditions -> #{waypoint};")
848
- node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
904
+ digraph.edge("#{id}:conditions -> #{waypoint};")
905
+ node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
906
+ else
907
+ table.field("conditions", "[]")
908
+ end
849
909
 
850
910
  # consequent
851
911
  unless (consequent = node.consequent).nil?
@@ -880,13 +940,17 @@ module Prism
880
940
  end
881
941
 
882
942
  # conditions
883
- table.field("conditions", port: true)
943
+ if node.conditions.any?
944
+ table.field("conditions", port: true)
884
945
 
885
- waypoint = "#{id}_conditions"
886
- digraph.waypoint("#{waypoint};")
946
+ waypoint = "#{id}_conditions"
947
+ digraph.waypoint("#{waypoint};")
887
948
 
888
- digraph.edge("#{id}:conditions -> #{waypoint};")
889
- node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
949
+ digraph.edge("#{id}:conditions -> #{waypoint};")
950
+ node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
951
+ else
952
+ table.field("conditions", "[]")
953
+ end
890
954
 
891
955
  # consequent
892
956
  unless (consequent = node.consequent).nil?
@@ -1437,6 +1501,9 @@ module Prism
1437
1501
  # locals
1438
1502
  table.field("locals", node.locals.inspect)
1439
1503
 
1504
+ # locals_body_index
1505
+ table.field("locals_body_index", node.locals_body_index.inspect)
1506
+
1440
1507
  # def_keyword_loc
1441
1508
  table.field("def_keyword_loc", location_inspect(node.def_keyword_loc))
1442
1509
 
@@ -1636,13 +1703,17 @@ module Prism
1636
1703
  digraph.edge("#{id}:left -> #{node_id(node.left)};")
1637
1704
 
1638
1705
  # requireds
1639
- table.field("requireds", port: true)
1706
+ if node.requireds.any?
1707
+ table.field("requireds", port: true)
1640
1708
 
1641
- waypoint = "#{id}_requireds"
1642
- digraph.waypoint("#{waypoint};")
1709
+ waypoint = "#{id}_requireds"
1710
+ digraph.waypoint("#{waypoint};")
1643
1711
 
1644
- digraph.edge("#{id}:requireds -> #{waypoint};")
1645
- node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
1712
+ digraph.edge("#{id}:requireds -> #{waypoint};")
1713
+ node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
1714
+ else
1715
+ table.field("requireds", "[]")
1716
+ end
1646
1717
 
1647
1718
  # right
1648
1719
  table.field("right", port: true)
@@ -1672,6 +1743,9 @@ module Prism
1672
1743
  table = Table.new("FlipFlopNode")
1673
1744
  id = node_id(node)
1674
1745
 
1746
+ # flags
1747
+ table.field("flags", range_flags_inspect(node))
1748
+
1675
1749
  # left
1676
1750
  unless (left = node.left).nil?
1677
1751
  table.field("left", port: true)
@@ -1687,9 +1761,6 @@ module Prism
1687
1761
  # operator_loc
1688
1762
  table.field("operator_loc", location_inspect(node.operator_loc))
1689
1763
 
1690
- # flags
1691
- table.field("flags", range_flags_inspect(node))
1692
-
1693
1764
  digraph.nodes << <<~DOT
1694
1765
  #{id} [
1695
1766
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -1957,13 +2028,17 @@ module Prism
1957
2028
  table.field("opening_loc", location_inspect(node.opening_loc))
1958
2029
 
1959
2030
  # elements
1960
- table.field("elements", port: true)
2031
+ if node.elements.any?
2032
+ table.field("elements", port: true)
1961
2033
 
1962
- waypoint = "#{id}_elements"
1963
- digraph.waypoint("#{waypoint};")
2034
+ waypoint = "#{id}_elements"
2035
+ digraph.waypoint("#{waypoint};")
1964
2036
 
1965
- digraph.edge("#{id}:elements -> #{waypoint};")
1966
- node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2037
+ digraph.edge("#{id}:elements -> #{waypoint};")
2038
+ node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2039
+ else
2040
+ table.field("elements", "[]")
2041
+ end
1967
2042
 
1968
2043
  # closing_loc
1969
2044
  table.field("closing_loc", location_inspect(node.closing_loc))
@@ -1989,13 +2064,17 @@ module Prism
1989
2064
  end
1990
2065
 
1991
2066
  # elements
1992
- table.field("elements", port: true)
2067
+ if node.elements.any?
2068
+ table.field("elements", port: true)
1993
2069
 
1994
- waypoint = "#{id}_elements"
1995
- digraph.waypoint("#{waypoint};")
2070
+ waypoint = "#{id}_elements"
2071
+ digraph.waypoint("#{waypoint};")
1996
2072
 
1997
- digraph.edge("#{id}:elements -> #{waypoint};")
1998
- node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2073
+ digraph.edge("#{id}:elements -> #{waypoint};")
2074
+ node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2075
+ else
2076
+ table.field("elements", "[]")
2077
+ end
1999
2078
 
2000
2079
  # rest
2001
2080
  unless (rest = node.rest).nil?
@@ -2103,6 +2182,20 @@ module Prism
2103
2182
  super
2104
2183
  end
2105
2184
 
2185
+ # Visit a ImplicitRestNode node.
2186
+ def visit_implicit_rest_node(node)
2187
+ table = Table.new("ImplicitRestNode")
2188
+ id = node_id(node)
2189
+
2190
+ digraph.nodes << <<~DOT
2191
+ #{id} [
2192
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2193
+ ];
2194
+ DOT
2195
+
2196
+ super
2197
+ end
2198
+
2106
2199
  # Visit a InNode node.
2107
2200
  def visit_in_node(node)
2108
2201
  table = Table.new("InNode")
@@ -2140,6 +2233,9 @@ module Prism
2140
2233
  table = Table.new("IndexAndWriteNode")
2141
2234
  id = node_id(node)
2142
2235
 
2236
+ # flags
2237
+ table.field("flags", call_node_flags_inspect(node))
2238
+
2143
2239
  # receiver
2144
2240
  unless (receiver = node.receiver).nil?
2145
2241
  table.field("receiver", port: true)
@@ -2169,9 +2265,6 @@ module Prism
2169
2265
  digraph.edge("#{id}:block -> #{node_id(block)};")
2170
2266
  end
2171
2267
 
2172
- # flags
2173
- table.field("flags", call_node_flags_inspect(node))
2174
-
2175
2268
  # operator_loc
2176
2269
  table.field("operator_loc", location_inspect(node.operator_loc))
2177
2270
 
@@ -2193,6 +2286,9 @@ module Prism
2193
2286
  table = Table.new("IndexOperatorWriteNode")
2194
2287
  id = node_id(node)
2195
2288
 
2289
+ # flags
2290
+ table.field("flags", call_node_flags_inspect(node))
2291
+
2196
2292
  # receiver
2197
2293
  unless (receiver = node.receiver).nil?
2198
2294
  table.field("receiver", port: true)
@@ -2222,9 +2318,6 @@ module Prism
2222
2318
  digraph.edge("#{id}:block -> #{node_id(block)};")
2223
2319
  end
2224
2320
 
2225
- # flags
2226
- table.field("flags", call_node_flags_inspect(node))
2227
-
2228
2321
  # operator
2229
2322
  table.field("operator", node.operator.inspect)
2230
2323
 
@@ -2249,6 +2342,9 @@ module Prism
2249
2342
  table = Table.new("IndexOrWriteNode")
2250
2343
  id = node_id(node)
2251
2344
 
2345
+ # flags
2346
+ table.field("flags", call_node_flags_inspect(node))
2347
+
2252
2348
  # receiver
2253
2349
  unless (receiver = node.receiver).nil?
2254
2350
  table.field("receiver", port: true)
@@ -2278,9 +2374,6 @@ module Prism
2278
2374
  digraph.edge("#{id}:block -> #{node_id(block)};")
2279
2375
  end
2280
2376
 
2281
- # flags
2282
- table.field("flags", call_node_flags_inspect(node))
2283
-
2284
2377
  # operator_loc
2285
2378
  table.field("operator_loc", location_inspect(node.operator_loc))
2286
2379
 
@@ -2297,6 +2390,45 @@ module Prism
2297
2390
  super
2298
2391
  end
2299
2392
 
2393
+ # Visit a IndexTargetNode node.
2394
+ def visit_index_target_node(node)
2395
+ table = Table.new("IndexTargetNode")
2396
+ id = node_id(node)
2397
+
2398
+ # flags
2399
+ table.field("flags", call_node_flags_inspect(node))
2400
+
2401
+ # receiver
2402
+ table.field("receiver", port: true)
2403
+ digraph.edge("#{id}:receiver -> #{node_id(node.receiver)};")
2404
+
2405
+ # opening_loc
2406
+ table.field("opening_loc", location_inspect(node.opening_loc))
2407
+
2408
+ # arguments
2409
+ unless (arguments = node.arguments).nil?
2410
+ table.field("arguments", port: true)
2411
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
2412
+ end
2413
+
2414
+ # closing_loc
2415
+ table.field("closing_loc", location_inspect(node.closing_loc))
2416
+
2417
+ # block
2418
+ unless (block = node.block).nil?
2419
+ table.field("block", port: true)
2420
+ digraph.edge("#{id}:block -> #{node_id(block)};")
2421
+ end
2422
+
2423
+ digraph.nodes << <<~DOT
2424
+ #{id} [
2425
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2426
+ ];
2427
+ DOT
2428
+
2429
+ super
2430
+ end
2431
+
2300
2432
  # Visit a InstanceVariableAndWriteNode node.
2301
2433
  def visit_instance_variable_and_write_node(node)
2302
2434
  table = Table.new("InstanceVariableAndWriteNode")
@@ -2464,24 +2596,28 @@ module Prism
2464
2596
  table = Table.new("InterpolatedMatchLastLineNode")
2465
2597
  id = node_id(node)
2466
2598
 
2599
+ # flags
2600
+ table.field("flags", regular_expression_flags_inspect(node))
2601
+
2467
2602
  # opening_loc
2468
2603
  table.field("opening_loc", location_inspect(node.opening_loc))
2469
2604
 
2470
2605
  # parts
2471
- table.field("parts", port: true)
2606
+ if node.parts.any?
2607
+ table.field("parts", port: true)
2472
2608
 
2473
- waypoint = "#{id}_parts"
2474
- digraph.waypoint("#{waypoint};")
2609
+ waypoint = "#{id}_parts"
2610
+ digraph.waypoint("#{waypoint};")
2475
2611
 
2476
- digraph.edge("#{id}:parts -> #{waypoint};")
2477
- node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2612
+ digraph.edge("#{id}:parts -> #{waypoint};")
2613
+ node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2614
+ else
2615
+ table.field("parts", "[]")
2616
+ end
2478
2617
 
2479
2618
  # closing_loc
2480
2619
  table.field("closing_loc", location_inspect(node.closing_loc))
2481
2620
 
2482
- # flags
2483
- table.field("flags", regular_expression_flags_inspect(node))
2484
-
2485
2621
  digraph.nodes << <<~DOT
2486
2622
  #{id} [
2487
2623
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -2496,24 +2632,28 @@ module Prism
2496
2632
  table = Table.new("InterpolatedRegularExpressionNode")
2497
2633
  id = node_id(node)
2498
2634
 
2635
+ # flags
2636
+ table.field("flags", regular_expression_flags_inspect(node))
2637
+
2499
2638
  # opening_loc
2500
2639
  table.field("opening_loc", location_inspect(node.opening_loc))
2501
2640
 
2502
2641
  # parts
2503
- table.field("parts", port: true)
2642
+ if node.parts.any?
2643
+ table.field("parts", port: true)
2504
2644
 
2505
- waypoint = "#{id}_parts"
2506
- digraph.waypoint("#{waypoint};")
2645
+ waypoint = "#{id}_parts"
2646
+ digraph.waypoint("#{waypoint};")
2507
2647
 
2508
- digraph.edge("#{id}:parts -> #{waypoint};")
2509
- node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2648
+ digraph.edge("#{id}:parts -> #{waypoint};")
2649
+ node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2650
+ else
2651
+ table.field("parts", "[]")
2652
+ end
2510
2653
 
2511
2654
  # closing_loc
2512
2655
  table.field("closing_loc", location_inspect(node.closing_loc))
2513
2656
 
2514
- # flags
2515
- table.field("flags", regular_expression_flags_inspect(node))
2516
-
2517
2657
  digraph.nodes << <<~DOT
2518
2658
  #{id} [
2519
2659
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -2534,13 +2674,17 @@ module Prism
2534
2674
  end
2535
2675
 
2536
2676
  # parts
2537
- table.field("parts", port: true)
2677
+ if node.parts.any?
2678
+ table.field("parts", port: true)
2538
2679
 
2539
- waypoint = "#{id}_parts"
2540
- digraph.waypoint("#{waypoint};")
2680
+ waypoint = "#{id}_parts"
2681
+ digraph.waypoint("#{waypoint};")
2541
2682
 
2542
- digraph.edge("#{id}:parts -> #{waypoint};")
2543
- node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2683
+ digraph.edge("#{id}:parts -> #{waypoint};")
2684
+ node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2685
+ else
2686
+ table.field("parts", "[]")
2687
+ end
2544
2688
 
2545
2689
  # closing_loc
2546
2690
  unless (closing_loc = node.closing_loc).nil?
@@ -2567,13 +2711,17 @@ module Prism
2567
2711
  end
2568
2712
 
2569
2713
  # parts
2570
- table.field("parts", port: true)
2714
+ if node.parts.any?
2715
+ table.field("parts", port: true)
2571
2716
 
2572
- waypoint = "#{id}_parts"
2573
- digraph.waypoint("#{waypoint};")
2717
+ waypoint = "#{id}_parts"
2718
+ digraph.waypoint("#{waypoint};")
2574
2719
 
2575
- digraph.edge("#{id}:parts -> #{waypoint};")
2576
- node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2720
+ digraph.edge("#{id}:parts -> #{waypoint};")
2721
+ node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2722
+ else
2723
+ table.field("parts", "[]")
2724
+ end
2577
2725
 
2578
2726
  # closing_loc
2579
2727
  unless (closing_loc = node.closing_loc).nil?
@@ -2598,13 +2746,17 @@ module Prism
2598
2746
  table.field("opening_loc", location_inspect(node.opening_loc))
2599
2747
 
2600
2748
  # parts
2601
- table.field("parts", port: true)
2749
+ if node.parts.any?
2750
+ table.field("parts", port: true)
2602
2751
 
2603
- waypoint = "#{id}_parts"
2604
- digraph.waypoint("#{waypoint};")
2752
+ waypoint = "#{id}_parts"
2753
+ digraph.waypoint("#{waypoint};")
2605
2754
 
2606
- digraph.edge("#{id}:parts -> #{waypoint};")
2607
- node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2755
+ digraph.edge("#{id}:parts -> #{waypoint};")
2756
+ node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2757
+ else
2758
+ table.field("parts", "[]")
2759
+ end
2608
2760
 
2609
2761
  # closing_loc
2610
2762
  table.field("closing_loc", location_inspect(node.closing_loc))
@@ -2623,14 +2775,21 @@ module Prism
2623
2775
  table = Table.new("KeywordHashNode")
2624
2776
  id = node_id(node)
2625
2777
 
2778
+ # flags
2779
+ table.field("flags", keyword_hash_node_flags_inspect(node))
2780
+
2626
2781
  # elements
2627
- table.field("elements", port: true)
2782
+ if node.elements.any?
2783
+ table.field("elements", port: true)
2628
2784
 
2629
- waypoint = "#{id}_elements"
2630
- digraph.waypoint("#{waypoint};")
2785
+ waypoint = "#{id}_elements"
2786
+ digraph.waypoint("#{waypoint};")
2631
2787
 
2632
- digraph.edge("#{id}:elements -> #{waypoint};")
2633
- node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2788
+ digraph.edge("#{id}:elements -> #{waypoint};")
2789
+ node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
2790
+ else
2791
+ table.field("elements", "[]")
2792
+ end
2634
2793
 
2635
2794
  digraph.nodes << <<~DOT
2636
2795
  #{id} [
@@ -2674,6 +2833,9 @@ module Prism
2674
2833
  # locals
2675
2834
  table.field("locals", node.locals.inspect)
2676
2835
 
2836
+ # locals_body_index
2837
+ table.field("locals_body_index", node.locals_body_index.inspect)
2838
+
2677
2839
  # operator_loc
2678
2840
  table.field("operator_loc", location_inspect(node.operator_loc))
2679
2841
 
@@ -2872,6 +3034,9 @@ module Prism
2872
3034
  table = Table.new("MatchLastLineNode")
2873
3035
  id = node_id(node)
2874
3036
 
3037
+ # flags
3038
+ table.field("flags", regular_expression_flags_inspect(node))
3039
+
2875
3040
  # opening_loc
2876
3041
  table.field("opening_loc", location_inspect(node.opening_loc))
2877
3042
 
@@ -2884,9 +3049,6 @@ module Prism
2884
3049
  # unescaped
2885
3050
  table.field("unescaped", node.unescaped.inspect)
2886
3051
 
2887
- # flags
2888
- table.field("flags", regular_expression_flags_inspect(node))
2889
-
2890
3052
  digraph.nodes << <<~DOT
2891
3053
  #{id} [
2892
3054
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -2956,13 +3118,17 @@ module Prism
2956
3118
  digraph.edge("#{id}:call -> #{node_id(node.call)};")
2957
3119
 
2958
3120
  # targets
2959
- table.field("targets", port: true)
3121
+ if node.targets.any?
3122
+ table.field("targets", port: true)
2960
3123
 
2961
- waypoint = "#{id}_targets"
2962
- digraph.waypoint("#{waypoint};")
3124
+ waypoint = "#{id}_targets"
3125
+ digraph.waypoint("#{waypoint};")
2963
3126
 
2964
- digraph.edge("#{id}:targets -> #{waypoint};")
2965
- node.targets.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3127
+ digraph.edge("#{id}:targets -> #{waypoint};")
3128
+ node.targets.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3129
+ else
3130
+ table.field("targets", "[]")
3131
+ end
2966
3132
 
2967
3133
  digraph.nodes << <<~DOT
2968
3134
  #{id} [
@@ -3029,13 +3195,17 @@ module Prism
3029
3195
  id = node_id(node)
3030
3196
 
3031
3197
  # lefts
3032
- table.field("lefts", port: true)
3198
+ if node.lefts.any?
3199
+ table.field("lefts", port: true)
3033
3200
 
3034
- waypoint = "#{id}_lefts"
3035
- digraph.waypoint("#{waypoint};")
3201
+ waypoint = "#{id}_lefts"
3202
+ digraph.waypoint("#{waypoint};")
3036
3203
 
3037
- digraph.edge("#{id}:lefts -> #{waypoint};")
3038
- node.lefts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3204
+ digraph.edge("#{id}:lefts -> #{waypoint};")
3205
+ node.lefts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3206
+ else
3207
+ table.field("lefts", "[]")
3208
+ end
3039
3209
 
3040
3210
  # rest
3041
3211
  unless (rest = node.rest).nil?
@@ -3044,13 +3214,17 @@ module Prism
3044
3214
  end
3045
3215
 
3046
3216
  # rights
3047
- table.field("rights", port: true)
3217
+ if node.rights.any?
3218
+ table.field("rights", port: true)
3048
3219
 
3049
- waypoint = "#{id}_rights"
3050
- digraph.waypoint("#{waypoint};")
3220
+ waypoint = "#{id}_rights"
3221
+ digraph.waypoint("#{waypoint};")
3051
3222
 
3052
- digraph.edge("#{id}:rights -> #{waypoint};")
3053
- node.rights.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3223
+ digraph.edge("#{id}:rights -> #{waypoint};")
3224
+ node.rights.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3225
+ else
3226
+ table.field("rights", "[]")
3227
+ end
3054
3228
 
3055
3229
  # lparen_loc
3056
3230
  unless (lparen_loc = node.lparen_loc).nil?
@@ -3077,13 +3251,17 @@ module Prism
3077
3251
  id = node_id(node)
3078
3252
 
3079
3253
  # lefts
3080
- table.field("lefts", port: true)
3254
+ if node.lefts.any?
3255
+ table.field("lefts", port: true)
3081
3256
 
3082
- waypoint = "#{id}_lefts"
3083
- digraph.waypoint("#{waypoint};")
3257
+ waypoint = "#{id}_lefts"
3258
+ digraph.waypoint("#{waypoint};")
3084
3259
 
3085
- digraph.edge("#{id}:lefts -> #{waypoint};")
3086
- node.lefts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3260
+ digraph.edge("#{id}:lefts -> #{waypoint};")
3261
+ node.lefts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3262
+ else
3263
+ table.field("lefts", "[]")
3264
+ end
3087
3265
 
3088
3266
  # rest
3089
3267
  unless (rest = node.rest).nil?
@@ -3092,13 +3270,17 @@ module Prism
3092
3270
  end
3093
3271
 
3094
3272
  # rights
3095
- table.field("rights", port: true)
3273
+ if node.rights.any?
3274
+ table.field("rights", port: true)
3096
3275
 
3097
- waypoint = "#{id}_rights"
3098
- digraph.waypoint("#{waypoint};")
3276
+ waypoint = "#{id}_rights"
3277
+ digraph.waypoint("#{waypoint};")
3099
3278
 
3100
- digraph.edge("#{id}:rights -> #{waypoint};")
3101
- node.rights.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3279
+ digraph.edge("#{id}:rights -> #{waypoint};")
3280
+ node.rights.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3281
+ else
3282
+ table.field("rights", "[]")
3283
+ end
3102
3284
 
3103
3285
  # lparen_loc
3104
3286
  unless (lparen_loc = node.lparen_loc).nil?
@@ -3183,6 +3365,23 @@ module Prism
3183
3365
  super
3184
3366
  end
3185
3367
 
3368
+ # Visit a NumberedParametersNode node.
3369
+ def visit_numbered_parameters_node(node)
3370
+ table = Table.new("NumberedParametersNode")
3371
+ id = node_id(node)
3372
+
3373
+ # maximum
3374
+ table.field("maximum", node.maximum.inspect)
3375
+
3376
+ digraph.nodes << <<~DOT
3377
+ #{id} [
3378
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3379
+ ];
3380
+ DOT
3381
+
3382
+ super
3383
+ end
3384
+
3186
3385
  # Visit a NumberedReferenceReadNode node.
3187
3386
  def visit_numbered_reference_read_node(node)
3188
3387
  table = Table.new("NumberedReferenceReadNode")
@@ -3282,22 +3481,30 @@ module Prism
3282
3481
  id = node_id(node)
3283
3482
 
3284
3483
  # requireds
3285
- table.field("requireds", port: true)
3484
+ if node.requireds.any?
3485
+ table.field("requireds", port: true)
3286
3486
 
3287
- waypoint = "#{id}_requireds"
3288
- digraph.waypoint("#{waypoint};")
3487
+ waypoint = "#{id}_requireds"
3488
+ digraph.waypoint("#{waypoint};")
3289
3489
 
3290
- digraph.edge("#{id}:requireds -> #{waypoint};")
3291
- node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3490
+ digraph.edge("#{id}:requireds -> #{waypoint};")
3491
+ node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3492
+ else
3493
+ table.field("requireds", "[]")
3494
+ end
3292
3495
 
3293
3496
  # optionals
3294
- table.field("optionals", port: true)
3497
+ if node.optionals.any?
3498
+ table.field("optionals", port: true)
3295
3499
 
3296
- waypoint = "#{id}_optionals"
3297
- digraph.waypoint("#{waypoint};")
3500
+ waypoint = "#{id}_optionals"
3501
+ digraph.waypoint("#{waypoint};")
3298
3502
 
3299
- digraph.edge("#{id}:optionals -> #{waypoint};")
3300
- node.optionals.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3503
+ digraph.edge("#{id}:optionals -> #{waypoint};")
3504
+ node.optionals.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3505
+ else
3506
+ table.field("optionals", "[]")
3507
+ end
3301
3508
 
3302
3509
  # rest
3303
3510
  unless (rest = node.rest).nil?
@@ -3306,22 +3513,30 @@ module Prism
3306
3513
  end
3307
3514
 
3308
3515
  # posts
3309
- table.field("posts", port: true)
3516
+ if node.posts.any?
3517
+ table.field("posts", port: true)
3310
3518
 
3311
- waypoint = "#{id}_posts"
3312
- digraph.waypoint("#{waypoint};")
3519
+ waypoint = "#{id}_posts"
3520
+ digraph.waypoint("#{waypoint};")
3313
3521
 
3314
- digraph.edge("#{id}:posts -> #{waypoint};")
3315
- node.posts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3522
+ digraph.edge("#{id}:posts -> #{waypoint};")
3523
+ node.posts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3524
+ else
3525
+ table.field("posts", "[]")
3526
+ end
3316
3527
 
3317
3528
  # keywords
3318
- table.field("keywords", port: true)
3529
+ if node.keywords.any?
3530
+ table.field("keywords", port: true)
3319
3531
 
3320
- waypoint = "#{id}_keywords"
3321
- digraph.waypoint("#{waypoint};")
3532
+ waypoint = "#{id}_keywords"
3533
+ digraph.waypoint("#{waypoint};")
3322
3534
 
3323
- digraph.edge("#{id}:keywords -> #{waypoint};")
3324
- node.keywords.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3535
+ digraph.edge("#{id}:keywords -> #{waypoint};")
3536
+ node.keywords.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3537
+ else
3538
+ table.field("keywords", "[]")
3539
+ end
3325
3540
 
3326
3541
  # keyword_rest
3327
3542
  unless (keyword_rest = node.keyword_rest).nil?
@@ -3502,6 +3717,9 @@ module Prism
3502
3717
  table = Table.new("RangeNode")
3503
3718
  id = node_id(node)
3504
3719
 
3720
+ # flags
3721
+ table.field("flags", range_flags_inspect(node))
3722
+
3505
3723
  # left
3506
3724
  unless (left = node.left).nil?
3507
3725
  table.field("left", port: true)
@@ -3517,9 +3735,6 @@ module Prism
3517
3735
  # operator_loc
3518
3736
  table.field("operator_loc", location_inspect(node.operator_loc))
3519
3737
 
3520
- # flags
3521
- table.field("flags", range_flags_inspect(node))
3522
-
3523
3738
  digraph.nodes << <<~DOT
3524
3739
  #{id} [
3525
3740
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -3566,6 +3781,9 @@ module Prism
3566
3781
  table = Table.new("RegularExpressionNode")
3567
3782
  id = node_id(node)
3568
3783
 
3784
+ # flags
3785
+ table.field("flags", regular_expression_flags_inspect(node))
3786
+
3569
3787
  # opening_loc
3570
3788
  table.field("opening_loc", location_inspect(node.opening_loc))
3571
3789
 
@@ -3578,9 +3796,6 @@ module Prism
3578
3796
  # unescaped
3579
3797
  table.field("unescaped", node.unescaped.inspect)
3580
3798
 
3581
- # flags
3582
- table.field("flags", regular_expression_flags_inspect(node))
3583
-
3584
3799
  digraph.nodes << <<~DOT
3585
3800
  #{id} [
3586
3801
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -3661,13 +3876,17 @@ module Prism
3661
3876
  table.field("keyword_loc", location_inspect(node.keyword_loc))
3662
3877
 
3663
3878
  # exceptions
3664
- table.field("exceptions", port: true)
3879
+ if node.exceptions.any?
3880
+ table.field("exceptions", port: true)
3665
3881
 
3666
- waypoint = "#{id}_exceptions"
3667
- digraph.waypoint("#{waypoint};")
3882
+ waypoint = "#{id}_exceptions"
3883
+ digraph.waypoint("#{waypoint};")
3668
3884
 
3669
- digraph.edge("#{id}:exceptions -> #{waypoint};")
3670
- node.exceptions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3885
+ digraph.edge("#{id}:exceptions -> #{waypoint};")
3886
+ node.exceptions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
3887
+ else
3888
+ table.field("exceptions", "[]")
3889
+ end
3671
3890
 
3672
3891
  # operator_loc
3673
3892
  unless (operator_loc = node.operator_loc).nil?
@@ -3887,13 +4106,17 @@ module Prism
3887
4106
  id = node_id(node)
3888
4107
 
3889
4108
  # body
3890
- table.field("body", port: true)
4109
+ if node.body.any?
4110
+ table.field("body", port: true)
3891
4111
 
3892
- waypoint = "#{id}_body"
3893
- digraph.waypoint("#{waypoint};")
4112
+ waypoint = "#{id}_body"
4113
+ digraph.waypoint("#{waypoint};")
3894
4114
 
3895
- digraph.edge("#{id}:body -> #{waypoint};")
3896
- node.body.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
4115
+ digraph.edge("#{id}:body -> #{waypoint};")
4116
+ node.body.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
4117
+ else
4118
+ table.field("body", "[]")
4119
+ end
3897
4120
 
3898
4121
  digraph.nodes << <<~DOT
3899
4122
  #{id} [
@@ -3981,6 +4204,9 @@ module Prism
3981
4204
  table = Table.new("SymbolNode")
3982
4205
  id = node_id(node)
3983
4206
 
4207
+ # flags
4208
+ table.field("flags", symbol_flags_inspect(node))
4209
+
3984
4210
  # opening_loc
3985
4211
  unless (opening_loc = node.opening_loc).nil?
3986
4212
  table.field("opening_loc", location_inspect(opening_loc))
@@ -4028,13 +4254,17 @@ module Prism
4028
4254
  id = node_id(node)
4029
4255
 
4030
4256
  # names
4031
- table.field("names", port: true)
4257
+ if node.names.any?
4258
+ table.field("names", port: true)
4032
4259
 
4033
- waypoint = "#{id}_names"
4034
- digraph.waypoint("#{waypoint};")
4260
+ waypoint = "#{id}_names"
4261
+ digraph.waypoint("#{waypoint};")
4035
4262
 
4036
- digraph.edge("#{id}:names -> #{waypoint};")
4037
- node.names.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
4263
+ digraph.edge("#{id}:names -> #{waypoint};")
4264
+ node.names.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
4265
+ else
4266
+ table.field("names", "[]")
4267
+ end
4038
4268
 
4039
4269
  # keyword_loc
4040
4270
  table.field("keyword_loc", location_inspect(node.keyword_loc))
@@ -4096,6 +4326,9 @@ module Prism
4096
4326
  table = Table.new("UntilNode")
4097
4327
  id = node_id(node)
4098
4328
 
4329
+ # flags
4330
+ table.field("flags", loop_flags_inspect(node))
4331
+
4099
4332
  # keyword_loc
4100
4333
  table.field("keyword_loc", location_inspect(node.keyword_loc))
4101
4334
 
@@ -4114,9 +4347,6 @@ module Prism
4114
4347
  digraph.edge("#{id}:statements -> #{node_id(statements)};")
4115
4348
  end
4116
4349
 
4117
- # flags
4118
- table.field("flags", loop_flags_inspect(node))
4119
-
4120
4350
  digraph.nodes << <<~DOT
4121
4351
  #{id} [
4122
4352
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -4135,13 +4365,17 @@ module Prism
4135
4365
  table.field("keyword_loc", location_inspect(node.keyword_loc))
4136
4366
 
4137
4367
  # conditions
4138
- table.field("conditions", port: true)
4368
+ if node.conditions.any?
4369
+ table.field("conditions", port: true)
4139
4370
 
4140
- waypoint = "#{id}_conditions"
4141
- digraph.waypoint("#{waypoint};")
4371
+ waypoint = "#{id}_conditions"
4372
+ digraph.waypoint("#{waypoint};")
4142
4373
 
4143
- digraph.edge("#{id}:conditions -> #{waypoint};")
4144
- node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
4374
+ digraph.edge("#{id}:conditions -> #{waypoint};")
4375
+ node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") }
4376
+ else
4377
+ table.field("conditions", "[]")
4378
+ end
4145
4379
 
4146
4380
  # statements
4147
4381
  unless (statements = node.statements).nil?
@@ -4163,6 +4397,9 @@ module Prism
4163
4397
  table = Table.new("WhileNode")
4164
4398
  id = node_id(node)
4165
4399
 
4400
+ # flags
4401
+ table.field("flags", loop_flags_inspect(node))
4402
+
4166
4403
  # keyword_loc
4167
4404
  table.field("keyword_loc", location_inspect(node.keyword_loc))
4168
4405
 
@@ -4181,9 +4418,6 @@ module Prism
4181
4418
  digraph.edge("#{id}:statements -> #{node_id(statements)};")
4182
4419
  end
4183
4420
 
4184
- # flags
4185
- table.field("flags", loop_flags_inspect(node))
4186
-
4187
4421
  digraph.nodes << <<~DOT
4188
4422
  #{id} [
4189
4423
  label=<#{table.to_dot.gsub(/\n/, "\n ")}>
@@ -4198,6 +4432,9 @@ module Prism
4198
4432
  table = Table.new("XStringNode")
4199
4433
  id = node_id(node)
4200
4434
 
4435
+ # flags
4436
+ table.field("flags", encoding_flags_inspect(node))
4437
+
4201
4438
  # opening_loc
4202
4439
  table.field("opening_loc", location_inspect(node.opening_loc))
4203
4440
 
@@ -4268,7 +4505,15 @@ module Prism
4268
4505
  # comma-separated list.
4269
4506
  def arguments_node_flags_inspect(node)
4270
4507
  flags = []
4271
- flags << "keyword_splat" if node.keyword_splat?
4508
+ flags << "contains_keyword_splat" if node.contains_keyword_splat?
4509
+ flags.join(", ")
4510
+ end
4511
+
4512
+ # Inspect a node that has array_node_flags flags to display the flags as a
4513
+ # comma-separated list.
4514
+ def array_node_flags_inspect(node)
4515
+ flags = []
4516
+ flags << "contains_splat" if node.contains_splat?
4272
4517
  flags.join(", ")
4273
4518
  end
4274
4519
 
@@ -4278,6 +4523,16 @@ module Prism
4278
4523
  flags = []
4279
4524
  flags << "safe_navigation" if node.safe_navigation?
4280
4525
  flags << "variable_call" if node.variable_call?
4526
+ flags << "attribute_write" if node.attribute_write?
4527
+ flags.join(", ")
4528
+ end
4529
+
4530
+ # Inspect a node that has encoding_flags flags to display the flags as a
4531
+ # comma-separated list.
4532
+ def encoding_flags_inspect(node)
4533
+ flags = []
4534
+ flags << "forced_utf8_encoding" if node.forced_utf8_encoding?
4535
+ flags << "forced_binary_encoding" if node.forced_binary_encoding?
4281
4536
  flags.join(", ")
4282
4537
  end
4283
4538
 
@@ -4286,12 +4541,20 @@ module Prism
4286
4541
  def integer_base_flags_inspect(node)
4287
4542
  flags = []
4288
4543
  flags << "binary" if node.binary?
4289
- flags << "octal" if node.octal?
4290
4544
  flags << "decimal" if node.decimal?
4545
+ flags << "octal" if node.octal?
4291
4546
  flags << "hexadecimal" if node.hexadecimal?
4292
4547
  flags.join(", ")
4293
4548
  end
4294
4549
 
4550
+ # Inspect a node that has keyword_hash_node_flags flags to display the flags as a
4551
+ # comma-separated list.
4552
+ def keyword_hash_node_flags_inspect(node)
4553
+ flags = []
4554
+ flags << "static_keys" if node.static_keys?
4555
+ flags.join(", ")
4556
+ end
4557
+
4295
4558
  # Inspect a node that has loop_flags flags to display the flags as a
4296
4559
  # comma-separated list.
4297
4560
  def loop_flags_inspect(node)
@@ -4320,6 +4583,9 @@ module Prism
4320
4583
  flags << "ascii_8bit" if node.ascii_8bit?
4321
4584
  flags << "windows_31j" if node.windows_31j?
4322
4585
  flags << "utf_8" if node.utf_8?
4586
+ flags << "forced_utf8_encoding" if node.forced_utf8_encoding?
4587
+ flags << "forced_binary_encoding" if node.forced_binary_encoding?
4588
+ flags << "forced_us_ascii_encoding" if node.forced_us_ascii_encoding?
4323
4589
  flags.join(", ")
4324
4590
  end
4325
4591
 
@@ -4327,8 +4593,20 @@ module Prism
4327
4593
  # comma-separated list.
4328
4594
  def string_flags_inspect(node)
4329
4595
  flags = []
4596
+ flags << "forced_utf8_encoding" if node.forced_utf8_encoding?
4597
+ flags << "forced_binary_encoding" if node.forced_binary_encoding?
4330
4598
  flags << "frozen" if node.frozen?
4331
4599
  flags.join(", ")
4332
4600
  end
4601
+
4602
+ # Inspect a node that has symbol_flags flags to display the flags as a
4603
+ # comma-separated list.
4604
+ def symbol_flags_inspect(node)
4605
+ flags = []
4606
+ flags << "forced_utf8_encoding" if node.forced_utf8_encoding?
4607
+ flags << "forced_binary_encoding" if node.forced_binary_encoding?
4608
+ flags << "forced_us_ascii_encoding" if node.forced_us_ascii_encoding?
4609
+ flags.join(", ")
4610
+ end
4333
4611
  end
4334
4612
  end