prism 0.18.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
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