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
@@ -0,0 +1,4612 @@
1
+ # frozen_string_literal: true
2
+ =begin
3
+ This file is generated by the templates/template.rb script and should not be
4
+ modified manually. See templates/lib/prism/dot_visitor.rb.erb
5
+ if you are looking to modify the template
6
+ =end
7
+
8
+ require "cgi"
9
+
10
+ module Prism
11
+ # This visitor provides the ability to call Node#to_dot, which converts a
12
+ # subtree into a graphviz dot graph.
13
+ class DotVisitor < Visitor
14
+ class Field # :nodoc:
15
+ attr_reader :name, :value, :port
16
+
17
+ def initialize(name, value, port)
18
+ @name = name
19
+ @value = value
20
+ @port = port
21
+ end
22
+
23
+ def to_dot
24
+ if port
25
+ "<tr><td align=\"left\" colspan=\"2\" port=\"#{name}\">#{name}</td></tr>"
26
+ else
27
+ "<tr><td align=\"left\">#{name}</td><td>#{CGI.escapeHTML(value)}</td></tr>"
28
+ end
29
+ end
30
+ end
31
+
32
+ class Table # :nodoc:
33
+ attr_reader :name, :fields
34
+
35
+ def initialize(name)
36
+ @name = name
37
+ @fields = []
38
+ end
39
+
40
+ def field(name, value = nil, port: false)
41
+ fields << Field.new(name, value, port)
42
+ end
43
+
44
+ def to_dot
45
+ dot = <<~DOT
46
+ <table border="0" cellborder="1" cellspacing="0" cellpadding="4">
47
+ <tr><td colspan="2"><b>#{name}</b></td></tr>
48
+ DOT
49
+
50
+ if fields.any?
51
+ "#{dot} #{fields.map(&:to_dot).join("\n ")}\n</table>"
52
+ else
53
+ "#{dot}</table>"
54
+ end
55
+ end
56
+ end
57
+
58
+ class Digraph # :nodoc:
59
+ attr_reader :nodes, :waypoints, :edges
60
+
61
+ def initialize
62
+ @nodes = []
63
+ @waypoints = []
64
+ @edges = []
65
+ end
66
+
67
+ def node(value)
68
+ nodes << value
69
+ end
70
+
71
+ def waypoint(value)
72
+ waypoints << value
73
+ end
74
+
75
+ def edge(value)
76
+ edges << value
77
+ end
78
+
79
+ def to_dot
80
+ <<~DOT
81
+ digraph "Prism" {
82
+ node [
83
+ fontname=\"Courier New\"
84
+ shape=plain
85
+ style=filled
86
+ fillcolor=gray95
87
+ ];
88
+
89
+ #{nodes.map { |node| node.gsub(/\n/, "\n ") }.join("\n ")}
90
+ node [shape=point];
91
+ #{waypoints.join("\n ")}
92
+
93
+ #{edges.join("\n ")}
94
+ }
95
+ DOT
96
+ end
97
+ end
98
+
99
+ private_constant :Field, :Table, :Digraph
100
+
101
+ # The digraph that is being built.
102
+ attr_reader :digraph
103
+
104
+ # Initialize a new dot visitor.
105
+ def initialize
106
+ @digraph = Digraph.new
107
+ end
108
+
109
+ # Convert this visitor into a graphviz dot graph string.
110
+ def to_dot
111
+ digraph.to_dot
112
+ end
113
+
114
+ # Visit a AliasGlobalVariableNode node.
115
+ def visit_alias_global_variable_node(node)
116
+ table = Table.new("AliasGlobalVariableNode")
117
+ id = node_id(node)
118
+
119
+ # new_name
120
+ table.field("new_name", port: true)
121
+ digraph.edge("#{id}:new_name -> #{node_id(node.new_name)};")
122
+
123
+ # old_name
124
+ table.field("old_name", port: true)
125
+ digraph.edge("#{id}:old_name -> #{node_id(node.old_name)};")
126
+
127
+ # keyword_loc
128
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
129
+
130
+ digraph.nodes << <<~DOT
131
+ #{id} [
132
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
133
+ ];
134
+ DOT
135
+
136
+ super
137
+ end
138
+
139
+ # Visit a AliasMethodNode node.
140
+ def visit_alias_method_node(node)
141
+ table = Table.new("AliasMethodNode")
142
+ id = node_id(node)
143
+
144
+ # new_name
145
+ table.field("new_name", port: true)
146
+ digraph.edge("#{id}:new_name -> #{node_id(node.new_name)};")
147
+
148
+ # old_name
149
+ table.field("old_name", port: true)
150
+ digraph.edge("#{id}:old_name -> #{node_id(node.old_name)};")
151
+
152
+ # keyword_loc
153
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
154
+
155
+ digraph.nodes << <<~DOT
156
+ #{id} [
157
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
158
+ ];
159
+ DOT
160
+
161
+ super
162
+ end
163
+
164
+ # Visit a AlternationPatternNode node.
165
+ def visit_alternation_pattern_node(node)
166
+ table = Table.new("AlternationPatternNode")
167
+ id = node_id(node)
168
+
169
+ # left
170
+ table.field("left", port: true)
171
+ digraph.edge("#{id}:left -> #{node_id(node.left)};")
172
+
173
+ # right
174
+ table.field("right", port: true)
175
+ digraph.edge("#{id}:right -> #{node_id(node.right)};")
176
+
177
+ # operator_loc
178
+ table.field("operator_loc", location_inspect(node.operator_loc))
179
+
180
+ digraph.nodes << <<~DOT
181
+ #{id} [
182
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
183
+ ];
184
+ DOT
185
+
186
+ super
187
+ end
188
+
189
+ # Visit a AndNode node.
190
+ def visit_and_node(node)
191
+ table = Table.new("AndNode")
192
+ id = node_id(node)
193
+
194
+ # left
195
+ table.field("left", port: true)
196
+ digraph.edge("#{id}:left -> #{node_id(node.left)};")
197
+
198
+ # right
199
+ table.field("right", port: true)
200
+ digraph.edge("#{id}:right -> #{node_id(node.right)};")
201
+
202
+ # operator_loc
203
+ table.field("operator_loc", location_inspect(node.operator_loc))
204
+
205
+ digraph.nodes << <<~DOT
206
+ #{id} [
207
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
208
+ ];
209
+ DOT
210
+
211
+ super
212
+ end
213
+
214
+ # Visit a ArgumentsNode node.
215
+ def visit_arguments_node(node)
216
+ table = Table.new("ArgumentsNode")
217
+ id = node_id(node)
218
+
219
+ # flags
220
+ table.field("flags", arguments_node_flags_inspect(node))
221
+
222
+ # arguments
223
+ if node.arguments.any?
224
+ table.field("arguments", port: true)
225
+
226
+ waypoint = "#{id}_arguments"
227
+ digraph.waypoint("#{waypoint};")
228
+
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
234
+
235
+ digraph.nodes << <<~DOT
236
+ #{id} [
237
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
238
+ ];
239
+ DOT
240
+
241
+ super
242
+ end
243
+
244
+ # Visit a ArrayNode node.
245
+ def visit_array_node(node)
246
+ table = Table.new("ArrayNode")
247
+ id = node_id(node)
248
+
249
+ # flags
250
+ table.field("flags", array_node_flags_inspect(node))
251
+
252
+ # elements
253
+ if node.elements.any?
254
+ table.field("elements", port: true)
255
+
256
+ waypoint = "#{id}_elements"
257
+ digraph.waypoint("#{waypoint};")
258
+
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
264
+
265
+ # opening_loc
266
+ unless (opening_loc = node.opening_loc).nil?
267
+ table.field("opening_loc", location_inspect(opening_loc))
268
+ end
269
+
270
+ # closing_loc
271
+ unless (closing_loc = node.closing_loc).nil?
272
+ table.field("closing_loc", location_inspect(closing_loc))
273
+ end
274
+
275
+ digraph.nodes << <<~DOT
276
+ #{id} [
277
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
278
+ ];
279
+ DOT
280
+
281
+ super
282
+ end
283
+
284
+ # Visit a ArrayPatternNode node.
285
+ def visit_array_pattern_node(node)
286
+ table = Table.new("ArrayPatternNode")
287
+ id = node_id(node)
288
+
289
+ # constant
290
+ unless (constant = node.constant).nil?
291
+ table.field("constant", port: true)
292
+ digraph.edge("#{id}:constant -> #{node_id(constant)};")
293
+ end
294
+
295
+ # requireds
296
+ if node.requireds.any?
297
+ table.field("requireds", port: true)
298
+
299
+ waypoint = "#{id}_requireds"
300
+ digraph.waypoint("#{waypoint};")
301
+
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
307
+
308
+ # rest
309
+ unless (rest = node.rest).nil?
310
+ table.field("rest", port: true)
311
+ digraph.edge("#{id}:rest -> #{node_id(rest)};")
312
+ end
313
+
314
+ # posts
315
+ if node.posts.any?
316
+ table.field("posts", port: true)
317
+
318
+ waypoint = "#{id}_posts"
319
+ digraph.waypoint("#{waypoint};")
320
+
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
326
+
327
+ # opening_loc
328
+ unless (opening_loc = node.opening_loc).nil?
329
+ table.field("opening_loc", location_inspect(opening_loc))
330
+ end
331
+
332
+ # closing_loc
333
+ unless (closing_loc = node.closing_loc).nil?
334
+ table.field("closing_loc", location_inspect(closing_loc))
335
+ end
336
+
337
+ digraph.nodes << <<~DOT
338
+ #{id} [
339
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
340
+ ];
341
+ DOT
342
+
343
+ super
344
+ end
345
+
346
+ # Visit a AssocNode node.
347
+ def visit_assoc_node(node)
348
+ table = Table.new("AssocNode")
349
+ id = node_id(node)
350
+
351
+ # key
352
+ table.field("key", port: true)
353
+ digraph.edge("#{id}:key -> #{node_id(node.key)};")
354
+
355
+ # value
356
+ unless (value = node.value).nil?
357
+ table.field("value", port: true)
358
+ digraph.edge("#{id}:value -> #{node_id(value)};")
359
+ end
360
+
361
+ # operator_loc
362
+ unless (operator_loc = node.operator_loc).nil?
363
+ table.field("operator_loc", location_inspect(operator_loc))
364
+ end
365
+
366
+ digraph.nodes << <<~DOT
367
+ #{id} [
368
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
369
+ ];
370
+ DOT
371
+
372
+ super
373
+ end
374
+
375
+ # Visit a AssocSplatNode node.
376
+ def visit_assoc_splat_node(node)
377
+ table = Table.new("AssocSplatNode")
378
+ id = node_id(node)
379
+
380
+ # value
381
+ unless (value = node.value).nil?
382
+ table.field("value", port: true)
383
+ digraph.edge("#{id}:value -> #{node_id(value)};")
384
+ end
385
+
386
+ # operator_loc
387
+ table.field("operator_loc", location_inspect(node.operator_loc))
388
+
389
+ digraph.nodes << <<~DOT
390
+ #{id} [
391
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
392
+ ];
393
+ DOT
394
+
395
+ super
396
+ end
397
+
398
+ # Visit a BackReferenceReadNode node.
399
+ def visit_back_reference_read_node(node)
400
+ table = Table.new("BackReferenceReadNode")
401
+ id = node_id(node)
402
+
403
+ # name
404
+ table.field("name", node.name.inspect)
405
+
406
+ digraph.nodes << <<~DOT
407
+ #{id} [
408
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
409
+ ];
410
+ DOT
411
+
412
+ super
413
+ end
414
+
415
+ # Visit a BeginNode node.
416
+ def visit_begin_node(node)
417
+ table = Table.new("BeginNode")
418
+ id = node_id(node)
419
+
420
+ # begin_keyword_loc
421
+ unless (begin_keyword_loc = node.begin_keyword_loc).nil?
422
+ table.field("begin_keyword_loc", location_inspect(begin_keyword_loc))
423
+ end
424
+
425
+ # statements
426
+ unless (statements = node.statements).nil?
427
+ table.field("statements", port: true)
428
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
429
+ end
430
+
431
+ # rescue_clause
432
+ unless (rescue_clause = node.rescue_clause).nil?
433
+ table.field("rescue_clause", port: true)
434
+ digraph.edge("#{id}:rescue_clause -> #{node_id(rescue_clause)};")
435
+ end
436
+
437
+ # else_clause
438
+ unless (else_clause = node.else_clause).nil?
439
+ table.field("else_clause", port: true)
440
+ digraph.edge("#{id}:else_clause -> #{node_id(else_clause)};")
441
+ end
442
+
443
+ # ensure_clause
444
+ unless (ensure_clause = node.ensure_clause).nil?
445
+ table.field("ensure_clause", port: true)
446
+ digraph.edge("#{id}:ensure_clause -> #{node_id(ensure_clause)};")
447
+ end
448
+
449
+ # end_keyword_loc
450
+ unless (end_keyword_loc = node.end_keyword_loc).nil?
451
+ table.field("end_keyword_loc", location_inspect(end_keyword_loc))
452
+ end
453
+
454
+ digraph.nodes << <<~DOT
455
+ #{id} [
456
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
457
+ ];
458
+ DOT
459
+
460
+ super
461
+ end
462
+
463
+ # Visit a BlockArgumentNode node.
464
+ def visit_block_argument_node(node)
465
+ table = Table.new("BlockArgumentNode")
466
+ id = node_id(node)
467
+
468
+ # expression
469
+ unless (expression = node.expression).nil?
470
+ table.field("expression", port: true)
471
+ digraph.edge("#{id}:expression -> #{node_id(expression)};")
472
+ end
473
+
474
+ # operator_loc
475
+ table.field("operator_loc", location_inspect(node.operator_loc))
476
+
477
+ digraph.nodes << <<~DOT
478
+ #{id} [
479
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
480
+ ];
481
+ DOT
482
+
483
+ super
484
+ end
485
+
486
+ # Visit a BlockLocalVariableNode node.
487
+ def visit_block_local_variable_node(node)
488
+ table = Table.new("BlockLocalVariableNode")
489
+ id = node_id(node)
490
+
491
+ # name
492
+ table.field("name", node.name.inspect)
493
+
494
+ digraph.nodes << <<~DOT
495
+ #{id} [
496
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
497
+ ];
498
+ DOT
499
+
500
+ super
501
+ end
502
+
503
+ # Visit a BlockNode node.
504
+ def visit_block_node(node)
505
+ table = Table.new("BlockNode")
506
+ id = node_id(node)
507
+
508
+ # locals
509
+ table.field("locals", node.locals.inspect)
510
+
511
+ # locals_body_index
512
+ table.field("locals_body_index", node.locals_body_index.inspect)
513
+
514
+ # parameters
515
+ unless (parameters = node.parameters).nil?
516
+ table.field("parameters", port: true)
517
+ digraph.edge("#{id}:parameters -> #{node_id(parameters)};")
518
+ end
519
+
520
+ # body
521
+ unless (body = node.body).nil?
522
+ table.field("body", port: true)
523
+ digraph.edge("#{id}:body -> #{node_id(body)};")
524
+ end
525
+
526
+ # opening_loc
527
+ table.field("opening_loc", location_inspect(node.opening_loc))
528
+
529
+ # closing_loc
530
+ table.field("closing_loc", location_inspect(node.closing_loc))
531
+
532
+ digraph.nodes << <<~DOT
533
+ #{id} [
534
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
535
+ ];
536
+ DOT
537
+
538
+ super
539
+ end
540
+
541
+ # Visit a BlockParameterNode node.
542
+ def visit_block_parameter_node(node)
543
+ table = Table.new("BlockParameterNode")
544
+ id = node_id(node)
545
+
546
+ # name
547
+ table.field("name", node.name.inspect)
548
+
549
+ # name_loc
550
+ unless (name_loc = node.name_loc).nil?
551
+ table.field("name_loc", location_inspect(name_loc))
552
+ end
553
+
554
+ # operator_loc
555
+ table.field("operator_loc", location_inspect(node.operator_loc))
556
+
557
+ digraph.nodes << <<~DOT
558
+ #{id} [
559
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
560
+ ];
561
+ DOT
562
+
563
+ super
564
+ end
565
+
566
+ # Visit a BlockParametersNode node.
567
+ def visit_block_parameters_node(node)
568
+ table = Table.new("BlockParametersNode")
569
+ id = node_id(node)
570
+
571
+ # parameters
572
+ unless (parameters = node.parameters).nil?
573
+ table.field("parameters", port: true)
574
+ digraph.edge("#{id}:parameters -> #{node_id(parameters)};")
575
+ end
576
+
577
+ # locals
578
+ if node.locals.any?
579
+ table.field("locals", port: true)
580
+
581
+ waypoint = "#{id}_locals"
582
+ digraph.waypoint("#{waypoint};")
583
+
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
589
+
590
+ # opening_loc
591
+ unless (opening_loc = node.opening_loc).nil?
592
+ table.field("opening_loc", location_inspect(opening_loc))
593
+ end
594
+
595
+ # closing_loc
596
+ unless (closing_loc = node.closing_loc).nil?
597
+ table.field("closing_loc", location_inspect(closing_loc))
598
+ end
599
+
600
+ digraph.nodes << <<~DOT
601
+ #{id} [
602
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
603
+ ];
604
+ DOT
605
+
606
+ super
607
+ end
608
+
609
+ # Visit a BreakNode node.
610
+ def visit_break_node(node)
611
+ table = Table.new("BreakNode")
612
+ id = node_id(node)
613
+
614
+ # arguments
615
+ unless (arguments = node.arguments).nil?
616
+ table.field("arguments", port: true)
617
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
618
+ end
619
+
620
+ # keyword_loc
621
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
622
+
623
+ digraph.nodes << <<~DOT
624
+ #{id} [
625
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
626
+ ];
627
+ DOT
628
+
629
+ super
630
+ end
631
+
632
+ # Visit a CallAndWriteNode node.
633
+ def visit_call_and_write_node(node)
634
+ table = Table.new("CallAndWriteNode")
635
+ id = node_id(node)
636
+
637
+ # flags
638
+ table.field("flags", call_node_flags_inspect(node))
639
+
640
+ # receiver
641
+ unless (receiver = node.receiver).nil?
642
+ table.field("receiver", port: true)
643
+ digraph.edge("#{id}:receiver -> #{node_id(receiver)};")
644
+ end
645
+
646
+ # call_operator_loc
647
+ unless (call_operator_loc = node.call_operator_loc).nil?
648
+ table.field("call_operator_loc", location_inspect(call_operator_loc))
649
+ end
650
+
651
+ # message_loc
652
+ unless (message_loc = node.message_loc).nil?
653
+ table.field("message_loc", location_inspect(message_loc))
654
+ end
655
+
656
+ # read_name
657
+ table.field("read_name", node.read_name.inspect)
658
+
659
+ # write_name
660
+ table.field("write_name", node.write_name.inspect)
661
+
662
+ # operator_loc
663
+ table.field("operator_loc", location_inspect(node.operator_loc))
664
+
665
+ # value
666
+ table.field("value", port: true)
667
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
668
+
669
+ digraph.nodes << <<~DOT
670
+ #{id} [
671
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
672
+ ];
673
+ DOT
674
+
675
+ super
676
+ end
677
+
678
+ # Visit a CallNode node.
679
+ def visit_call_node(node)
680
+ table = Table.new("CallNode")
681
+ id = node_id(node)
682
+
683
+ # flags
684
+ table.field("flags", call_node_flags_inspect(node))
685
+
686
+ # receiver
687
+ unless (receiver = node.receiver).nil?
688
+ table.field("receiver", port: true)
689
+ digraph.edge("#{id}:receiver -> #{node_id(receiver)};")
690
+ end
691
+
692
+ # call_operator_loc
693
+ unless (call_operator_loc = node.call_operator_loc).nil?
694
+ table.field("call_operator_loc", location_inspect(call_operator_loc))
695
+ end
696
+
697
+ # name
698
+ table.field("name", node.name.inspect)
699
+
700
+ # message_loc
701
+ unless (message_loc = node.message_loc).nil?
702
+ table.field("message_loc", location_inspect(message_loc))
703
+ end
704
+
705
+ # opening_loc
706
+ unless (opening_loc = node.opening_loc).nil?
707
+ table.field("opening_loc", location_inspect(opening_loc))
708
+ end
709
+
710
+ # arguments
711
+ unless (arguments = node.arguments).nil?
712
+ table.field("arguments", port: true)
713
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
714
+ end
715
+
716
+ # closing_loc
717
+ unless (closing_loc = node.closing_loc).nil?
718
+ table.field("closing_loc", location_inspect(closing_loc))
719
+ end
720
+
721
+ # block
722
+ unless (block = node.block).nil?
723
+ table.field("block", port: true)
724
+ digraph.edge("#{id}:block -> #{node_id(block)};")
725
+ end
726
+
727
+ digraph.nodes << <<~DOT
728
+ #{id} [
729
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
730
+ ];
731
+ DOT
732
+
733
+ super
734
+ end
735
+
736
+ # Visit a CallOperatorWriteNode node.
737
+ def visit_call_operator_write_node(node)
738
+ table = Table.new("CallOperatorWriteNode")
739
+ id = node_id(node)
740
+
741
+ # flags
742
+ table.field("flags", call_node_flags_inspect(node))
743
+
744
+ # receiver
745
+ unless (receiver = node.receiver).nil?
746
+ table.field("receiver", port: true)
747
+ digraph.edge("#{id}:receiver -> #{node_id(receiver)};")
748
+ end
749
+
750
+ # call_operator_loc
751
+ unless (call_operator_loc = node.call_operator_loc).nil?
752
+ table.field("call_operator_loc", location_inspect(call_operator_loc))
753
+ end
754
+
755
+ # message_loc
756
+ unless (message_loc = node.message_loc).nil?
757
+ table.field("message_loc", location_inspect(message_loc))
758
+ end
759
+
760
+ # read_name
761
+ table.field("read_name", node.read_name.inspect)
762
+
763
+ # write_name
764
+ table.field("write_name", node.write_name.inspect)
765
+
766
+ # operator
767
+ table.field("operator", node.operator.inspect)
768
+
769
+ # operator_loc
770
+ table.field("operator_loc", location_inspect(node.operator_loc))
771
+
772
+ # value
773
+ table.field("value", port: true)
774
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
775
+
776
+ digraph.nodes << <<~DOT
777
+ #{id} [
778
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
779
+ ];
780
+ DOT
781
+
782
+ super
783
+ end
784
+
785
+ # Visit a CallOrWriteNode node.
786
+ def visit_call_or_write_node(node)
787
+ table = Table.new("CallOrWriteNode")
788
+ id = node_id(node)
789
+
790
+ # flags
791
+ table.field("flags", call_node_flags_inspect(node))
792
+
793
+ # receiver
794
+ unless (receiver = node.receiver).nil?
795
+ table.field("receiver", port: true)
796
+ digraph.edge("#{id}:receiver -> #{node_id(receiver)};")
797
+ end
798
+
799
+ # call_operator_loc
800
+ unless (call_operator_loc = node.call_operator_loc).nil?
801
+ table.field("call_operator_loc", location_inspect(call_operator_loc))
802
+ end
803
+
804
+ # message_loc
805
+ unless (message_loc = node.message_loc).nil?
806
+ table.field("message_loc", location_inspect(message_loc))
807
+ end
808
+
809
+ # read_name
810
+ table.field("read_name", node.read_name.inspect)
811
+
812
+ # write_name
813
+ table.field("write_name", node.write_name.inspect)
814
+
815
+ # operator_loc
816
+ table.field("operator_loc", location_inspect(node.operator_loc))
817
+
818
+ # value
819
+ table.field("value", port: true)
820
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
821
+
822
+ digraph.nodes << <<~DOT
823
+ #{id} [
824
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
825
+ ];
826
+ DOT
827
+
828
+ super
829
+ end
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
+
861
+ # Visit a CapturePatternNode node.
862
+ def visit_capture_pattern_node(node)
863
+ table = Table.new("CapturePatternNode")
864
+ id = node_id(node)
865
+
866
+ # value
867
+ table.field("value", port: true)
868
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
869
+
870
+ # target
871
+ table.field("target", port: true)
872
+ digraph.edge("#{id}:target -> #{node_id(node.target)};")
873
+
874
+ # operator_loc
875
+ table.field("operator_loc", location_inspect(node.operator_loc))
876
+
877
+ digraph.nodes << <<~DOT
878
+ #{id} [
879
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
880
+ ];
881
+ DOT
882
+
883
+ super
884
+ end
885
+
886
+ # Visit a CaseMatchNode node.
887
+ def visit_case_match_node(node)
888
+ table = Table.new("CaseMatchNode")
889
+ id = node_id(node)
890
+
891
+ # predicate
892
+ unless (predicate = node.predicate).nil?
893
+ table.field("predicate", port: true)
894
+ digraph.edge("#{id}:predicate -> #{node_id(predicate)};")
895
+ end
896
+
897
+ # conditions
898
+ if node.conditions.any?
899
+ table.field("conditions", port: true)
900
+
901
+ waypoint = "#{id}_conditions"
902
+ digraph.waypoint("#{waypoint};")
903
+
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
909
+
910
+ # consequent
911
+ unless (consequent = node.consequent).nil?
912
+ table.field("consequent", port: true)
913
+ digraph.edge("#{id}:consequent -> #{node_id(consequent)};")
914
+ end
915
+
916
+ # case_keyword_loc
917
+ table.field("case_keyword_loc", location_inspect(node.case_keyword_loc))
918
+
919
+ # end_keyword_loc
920
+ table.field("end_keyword_loc", location_inspect(node.end_keyword_loc))
921
+
922
+ digraph.nodes << <<~DOT
923
+ #{id} [
924
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
925
+ ];
926
+ DOT
927
+
928
+ super
929
+ end
930
+
931
+ # Visit a CaseNode node.
932
+ def visit_case_node(node)
933
+ table = Table.new("CaseNode")
934
+ id = node_id(node)
935
+
936
+ # predicate
937
+ unless (predicate = node.predicate).nil?
938
+ table.field("predicate", port: true)
939
+ digraph.edge("#{id}:predicate -> #{node_id(predicate)};")
940
+ end
941
+
942
+ # conditions
943
+ if node.conditions.any?
944
+ table.field("conditions", port: true)
945
+
946
+ waypoint = "#{id}_conditions"
947
+ digraph.waypoint("#{waypoint};")
948
+
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
954
+
955
+ # consequent
956
+ unless (consequent = node.consequent).nil?
957
+ table.field("consequent", port: true)
958
+ digraph.edge("#{id}:consequent -> #{node_id(consequent)};")
959
+ end
960
+
961
+ # case_keyword_loc
962
+ table.field("case_keyword_loc", location_inspect(node.case_keyword_loc))
963
+
964
+ # end_keyword_loc
965
+ table.field("end_keyword_loc", location_inspect(node.end_keyword_loc))
966
+
967
+ digraph.nodes << <<~DOT
968
+ #{id} [
969
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
970
+ ];
971
+ DOT
972
+
973
+ super
974
+ end
975
+
976
+ # Visit a ClassNode node.
977
+ def visit_class_node(node)
978
+ table = Table.new("ClassNode")
979
+ id = node_id(node)
980
+
981
+ # locals
982
+ table.field("locals", node.locals.inspect)
983
+
984
+ # class_keyword_loc
985
+ table.field("class_keyword_loc", location_inspect(node.class_keyword_loc))
986
+
987
+ # constant_path
988
+ table.field("constant_path", port: true)
989
+ digraph.edge("#{id}:constant_path -> #{node_id(node.constant_path)};")
990
+
991
+ # inheritance_operator_loc
992
+ unless (inheritance_operator_loc = node.inheritance_operator_loc).nil?
993
+ table.field("inheritance_operator_loc", location_inspect(inheritance_operator_loc))
994
+ end
995
+
996
+ # superclass
997
+ unless (superclass = node.superclass).nil?
998
+ table.field("superclass", port: true)
999
+ digraph.edge("#{id}:superclass -> #{node_id(superclass)};")
1000
+ end
1001
+
1002
+ # body
1003
+ unless (body = node.body).nil?
1004
+ table.field("body", port: true)
1005
+ digraph.edge("#{id}:body -> #{node_id(body)};")
1006
+ end
1007
+
1008
+ # end_keyword_loc
1009
+ table.field("end_keyword_loc", location_inspect(node.end_keyword_loc))
1010
+
1011
+ # name
1012
+ table.field("name", node.name.inspect)
1013
+
1014
+ digraph.nodes << <<~DOT
1015
+ #{id} [
1016
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1017
+ ];
1018
+ DOT
1019
+
1020
+ super
1021
+ end
1022
+
1023
+ # Visit a ClassVariableAndWriteNode node.
1024
+ def visit_class_variable_and_write_node(node)
1025
+ table = Table.new("ClassVariableAndWriteNode")
1026
+ id = node_id(node)
1027
+
1028
+ # name
1029
+ table.field("name", node.name.inspect)
1030
+
1031
+ # name_loc
1032
+ table.field("name_loc", location_inspect(node.name_loc))
1033
+
1034
+ # operator_loc
1035
+ table.field("operator_loc", location_inspect(node.operator_loc))
1036
+
1037
+ # value
1038
+ table.field("value", port: true)
1039
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1040
+
1041
+ digraph.nodes << <<~DOT
1042
+ #{id} [
1043
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1044
+ ];
1045
+ DOT
1046
+
1047
+ super
1048
+ end
1049
+
1050
+ # Visit a ClassVariableOperatorWriteNode node.
1051
+ def visit_class_variable_operator_write_node(node)
1052
+ table = Table.new("ClassVariableOperatorWriteNode")
1053
+ id = node_id(node)
1054
+
1055
+ # name
1056
+ table.field("name", node.name.inspect)
1057
+
1058
+ # name_loc
1059
+ table.field("name_loc", location_inspect(node.name_loc))
1060
+
1061
+ # operator_loc
1062
+ table.field("operator_loc", location_inspect(node.operator_loc))
1063
+
1064
+ # value
1065
+ table.field("value", port: true)
1066
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1067
+
1068
+ # operator
1069
+ table.field("operator", node.operator.inspect)
1070
+
1071
+ digraph.nodes << <<~DOT
1072
+ #{id} [
1073
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1074
+ ];
1075
+ DOT
1076
+
1077
+ super
1078
+ end
1079
+
1080
+ # Visit a ClassVariableOrWriteNode node.
1081
+ def visit_class_variable_or_write_node(node)
1082
+ table = Table.new("ClassVariableOrWriteNode")
1083
+ id = node_id(node)
1084
+
1085
+ # name
1086
+ table.field("name", node.name.inspect)
1087
+
1088
+ # name_loc
1089
+ table.field("name_loc", location_inspect(node.name_loc))
1090
+
1091
+ # operator_loc
1092
+ table.field("operator_loc", location_inspect(node.operator_loc))
1093
+
1094
+ # value
1095
+ table.field("value", port: true)
1096
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1097
+
1098
+ digraph.nodes << <<~DOT
1099
+ #{id} [
1100
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1101
+ ];
1102
+ DOT
1103
+
1104
+ super
1105
+ end
1106
+
1107
+ # Visit a ClassVariableReadNode node.
1108
+ def visit_class_variable_read_node(node)
1109
+ table = Table.new("ClassVariableReadNode")
1110
+ id = node_id(node)
1111
+
1112
+ # name
1113
+ table.field("name", node.name.inspect)
1114
+
1115
+ digraph.nodes << <<~DOT
1116
+ #{id} [
1117
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1118
+ ];
1119
+ DOT
1120
+
1121
+ super
1122
+ end
1123
+
1124
+ # Visit a ClassVariableTargetNode node.
1125
+ def visit_class_variable_target_node(node)
1126
+ table = Table.new("ClassVariableTargetNode")
1127
+ id = node_id(node)
1128
+
1129
+ # name
1130
+ table.field("name", node.name.inspect)
1131
+
1132
+ digraph.nodes << <<~DOT
1133
+ #{id} [
1134
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1135
+ ];
1136
+ DOT
1137
+
1138
+ super
1139
+ end
1140
+
1141
+ # Visit a ClassVariableWriteNode node.
1142
+ def visit_class_variable_write_node(node)
1143
+ table = Table.new("ClassVariableWriteNode")
1144
+ id = node_id(node)
1145
+
1146
+ # name
1147
+ table.field("name", node.name.inspect)
1148
+
1149
+ # name_loc
1150
+ table.field("name_loc", location_inspect(node.name_loc))
1151
+
1152
+ # value
1153
+ table.field("value", port: true)
1154
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1155
+
1156
+ # operator_loc
1157
+ unless (operator_loc = node.operator_loc).nil?
1158
+ table.field("operator_loc", location_inspect(operator_loc))
1159
+ end
1160
+
1161
+ digraph.nodes << <<~DOT
1162
+ #{id} [
1163
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1164
+ ];
1165
+ DOT
1166
+
1167
+ super
1168
+ end
1169
+
1170
+ # Visit a ConstantAndWriteNode node.
1171
+ def visit_constant_and_write_node(node)
1172
+ table = Table.new("ConstantAndWriteNode")
1173
+ id = node_id(node)
1174
+
1175
+ # name
1176
+ table.field("name", node.name.inspect)
1177
+
1178
+ # name_loc
1179
+ table.field("name_loc", location_inspect(node.name_loc))
1180
+
1181
+ # operator_loc
1182
+ table.field("operator_loc", location_inspect(node.operator_loc))
1183
+
1184
+ # value
1185
+ table.field("value", port: true)
1186
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1187
+
1188
+ digraph.nodes << <<~DOT
1189
+ #{id} [
1190
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1191
+ ];
1192
+ DOT
1193
+
1194
+ super
1195
+ end
1196
+
1197
+ # Visit a ConstantOperatorWriteNode node.
1198
+ def visit_constant_operator_write_node(node)
1199
+ table = Table.new("ConstantOperatorWriteNode")
1200
+ id = node_id(node)
1201
+
1202
+ # name
1203
+ table.field("name", node.name.inspect)
1204
+
1205
+ # name_loc
1206
+ table.field("name_loc", location_inspect(node.name_loc))
1207
+
1208
+ # operator_loc
1209
+ table.field("operator_loc", location_inspect(node.operator_loc))
1210
+
1211
+ # value
1212
+ table.field("value", port: true)
1213
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1214
+
1215
+ # operator
1216
+ table.field("operator", node.operator.inspect)
1217
+
1218
+ digraph.nodes << <<~DOT
1219
+ #{id} [
1220
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1221
+ ];
1222
+ DOT
1223
+
1224
+ super
1225
+ end
1226
+
1227
+ # Visit a ConstantOrWriteNode node.
1228
+ def visit_constant_or_write_node(node)
1229
+ table = Table.new("ConstantOrWriteNode")
1230
+ id = node_id(node)
1231
+
1232
+ # name
1233
+ table.field("name", node.name.inspect)
1234
+
1235
+ # name_loc
1236
+ table.field("name_loc", location_inspect(node.name_loc))
1237
+
1238
+ # operator_loc
1239
+ table.field("operator_loc", location_inspect(node.operator_loc))
1240
+
1241
+ # value
1242
+ table.field("value", port: true)
1243
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1244
+
1245
+ digraph.nodes << <<~DOT
1246
+ #{id} [
1247
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1248
+ ];
1249
+ DOT
1250
+
1251
+ super
1252
+ end
1253
+
1254
+ # Visit a ConstantPathAndWriteNode node.
1255
+ def visit_constant_path_and_write_node(node)
1256
+ table = Table.new("ConstantPathAndWriteNode")
1257
+ id = node_id(node)
1258
+
1259
+ # target
1260
+ table.field("target", port: true)
1261
+ digraph.edge("#{id}:target -> #{node_id(node.target)};")
1262
+
1263
+ # operator_loc
1264
+ table.field("operator_loc", location_inspect(node.operator_loc))
1265
+
1266
+ # value
1267
+ table.field("value", port: true)
1268
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1269
+
1270
+ digraph.nodes << <<~DOT
1271
+ #{id} [
1272
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1273
+ ];
1274
+ DOT
1275
+
1276
+ super
1277
+ end
1278
+
1279
+ # Visit a ConstantPathNode node.
1280
+ def visit_constant_path_node(node)
1281
+ table = Table.new("ConstantPathNode")
1282
+ id = node_id(node)
1283
+
1284
+ # parent
1285
+ unless (parent = node.parent).nil?
1286
+ table.field("parent", port: true)
1287
+ digraph.edge("#{id}:parent -> #{node_id(parent)};")
1288
+ end
1289
+
1290
+ # child
1291
+ table.field("child", port: true)
1292
+ digraph.edge("#{id}:child -> #{node_id(node.child)};")
1293
+
1294
+ # delimiter_loc
1295
+ table.field("delimiter_loc", location_inspect(node.delimiter_loc))
1296
+
1297
+ digraph.nodes << <<~DOT
1298
+ #{id} [
1299
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1300
+ ];
1301
+ DOT
1302
+
1303
+ super
1304
+ end
1305
+
1306
+ # Visit a ConstantPathOperatorWriteNode node.
1307
+ def visit_constant_path_operator_write_node(node)
1308
+ table = Table.new("ConstantPathOperatorWriteNode")
1309
+ id = node_id(node)
1310
+
1311
+ # target
1312
+ table.field("target", port: true)
1313
+ digraph.edge("#{id}:target -> #{node_id(node.target)};")
1314
+
1315
+ # operator_loc
1316
+ table.field("operator_loc", location_inspect(node.operator_loc))
1317
+
1318
+ # value
1319
+ table.field("value", port: true)
1320
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1321
+
1322
+ # operator
1323
+ table.field("operator", node.operator.inspect)
1324
+
1325
+ digraph.nodes << <<~DOT
1326
+ #{id} [
1327
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1328
+ ];
1329
+ DOT
1330
+
1331
+ super
1332
+ end
1333
+
1334
+ # Visit a ConstantPathOrWriteNode node.
1335
+ def visit_constant_path_or_write_node(node)
1336
+ table = Table.new("ConstantPathOrWriteNode")
1337
+ id = node_id(node)
1338
+
1339
+ # target
1340
+ table.field("target", port: true)
1341
+ digraph.edge("#{id}:target -> #{node_id(node.target)};")
1342
+
1343
+ # operator_loc
1344
+ table.field("operator_loc", location_inspect(node.operator_loc))
1345
+
1346
+ # value
1347
+ table.field("value", port: true)
1348
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1349
+
1350
+ digraph.nodes << <<~DOT
1351
+ #{id} [
1352
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1353
+ ];
1354
+ DOT
1355
+
1356
+ super
1357
+ end
1358
+
1359
+ # Visit a ConstantPathTargetNode node.
1360
+ def visit_constant_path_target_node(node)
1361
+ table = Table.new("ConstantPathTargetNode")
1362
+ id = node_id(node)
1363
+
1364
+ # parent
1365
+ unless (parent = node.parent).nil?
1366
+ table.field("parent", port: true)
1367
+ digraph.edge("#{id}:parent -> #{node_id(parent)};")
1368
+ end
1369
+
1370
+ # child
1371
+ table.field("child", port: true)
1372
+ digraph.edge("#{id}:child -> #{node_id(node.child)};")
1373
+
1374
+ # delimiter_loc
1375
+ table.field("delimiter_loc", location_inspect(node.delimiter_loc))
1376
+
1377
+ digraph.nodes << <<~DOT
1378
+ #{id} [
1379
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1380
+ ];
1381
+ DOT
1382
+
1383
+ super
1384
+ end
1385
+
1386
+ # Visit a ConstantPathWriteNode node.
1387
+ def visit_constant_path_write_node(node)
1388
+ table = Table.new("ConstantPathWriteNode")
1389
+ id = node_id(node)
1390
+
1391
+ # target
1392
+ table.field("target", port: true)
1393
+ digraph.edge("#{id}:target -> #{node_id(node.target)};")
1394
+
1395
+ # operator_loc
1396
+ table.field("operator_loc", location_inspect(node.operator_loc))
1397
+
1398
+ # value
1399
+ table.field("value", port: true)
1400
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1401
+
1402
+ digraph.nodes << <<~DOT
1403
+ #{id} [
1404
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1405
+ ];
1406
+ DOT
1407
+
1408
+ super
1409
+ end
1410
+
1411
+ # Visit a ConstantReadNode node.
1412
+ def visit_constant_read_node(node)
1413
+ table = Table.new("ConstantReadNode")
1414
+ id = node_id(node)
1415
+
1416
+ # name
1417
+ table.field("name", node.name.inspect)
1418
+
1419
+ digraph.nodes << <<~DOT
1420
+ #{id} [
1421
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1422
+ ];
1423
+ DOT
1424
+
1425
+ super
1426
+ end
1427
+
1428
+ # Visit a ConstantTargetNode node.
1429
+ def visit_constant_target_node(node)
1430
+ table = Table.new("ConstantTargetNode")
1431
+ id = node_id(node)
1432
+
1433
+ # name
1434
+ table.field("name", node.name.inspect)
1435
+
1436
+ digraph.nodes << <<~DOT
1437
+ #{id} [
1438
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1439
+ ];
1440
+ DOT
1441
+
1442
+ super
1443
+ end
1444
+
1445
+ # Visit a ConstantWriteNode node.
1446
+ def visit_constant_write_node(node)
1447
+ table = Table.new("ConstantWriteNode")
1448
+ id = node_id(node)
1449
+
1450
+ # name
1451
+ table.field("name", node.name.inspect)
1452
+
1453
+ # name_loc
1454
+ table.field("name_loc", location_inspect(node.name_loc))
1455
+
1456
+ # value
1457
+ table.field("value", port: true)
1458
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1459
+
1460
+ # operator_loc
1461
+ table.field("operator_loc", location_inspect(node.operator_loc))
1462
+
1463
+ digraph.nodes << <<~DOT
1464
+ #{id} [
1465
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1466
+ ];
1467
+ DOT
1468
+
1469
+ super
1470
+ end
1471
+
1472
+ # Visit a DefNode node.
1473
+ def visit_def_node(node)
1474
+ table = Table.new("DefNode")
1475
+ id = node_id(node)
1476
+
1477
+ # name
1478
+ table.field("name", node.name.inspect)
1479
+
1480
+ # name_loc
1481
+ table.field("name_loc", location_inspect(node.name_loc))
1482
+
1483
+ # receiver
1484
+ unless (receiver = node.receiver).nil?
1485
+ table.field("receiver", port: true)
1486
+ digraph.edge("#{id}:receiver -> #{node_id(receiver)};")
1487
+ end
1488
+
1489
+ # parameters
1490
+ unless (parameters = node.parameters).nil?
1491
+ table.field("parameters", port: true)
1492
+ digraph.edge("#{id}:parameters -> #{node_id(parameters)};")
1493
+ end
1494
+
1495
+ # body
1496
+ unless (body = node.body).nil?
1497
+ table.field("body", port: true)
1498
+ digraph.edge("#{id}:body -> #{node_id(body)};")
1499
+ end
1500
+
1501
+ # locals
1502
+ table.field("locals", node.locals.inspect)
1503
+
1504
+ # locals_body_index
1505
+ table.field("locals_body_index", node.locals_body_index.inspect)
1506
+
1507
+ # def_keyword_loc
1508
+ table.field("def_keyword_loc", location_inspect(node.def_keyword_loc))
1509
+
1510
+ # operator_loc
1511
+ unless (operator_loc = node.operator_loc).nil?
1512
+ table.field("operator_loc", location_inspect(operator_loc))
1513
+ end
1514
+
1515
+ # lparen_loc
1516
+ unless (lparen_loc = node.lparen_loc).nil?
1517
+ table.field("lparen_loc", location_inspect(lparen_loc))
1518
+ end
1519
+
1520
+ # rparen_loc
1521
+ unless (rparen_loc = node.rparen_loc).nil?
1522
+ table.field("rparen_loc", location_inspect(rparen_loc))
1523
+ end
1524
+
1525
+ # equal_loc
1526
+ unless (equal_loc = node.equal_loc).nil?
1527
+ table.field("equal_loc", location_inspect(equal_loc))
1528
+ end
1529
+
1530
+ # end_keyword_loc
1531
+ unless (end_keyword_loc = node.end_keyword_loc).nil?
1532
+ table.field("end_keyword_loc", location_inspect(end_keyword_loc))
1533
+ end
1534
+
1535
+ digraph.nodes << <<~DOT
1536
+ #{id} [
1537
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1538
+ ];
1539
+ DOT
1540
+
1541
+ super
1542
+ end
1543
+
1544
+ # Visit a DefinedNode node.
1545
+ def visit_defined_node(node)
1546
+ table = Table.new("DefinedNode")
1547
+ id = node_id(node)
1548
+
1549
+ # lparen_loc
1550
+ unless (lparen_loc = node.lparen_loc).nil?
1551
+ table.field("lparen_loc", location_inspect(lparen_loc))
1552
+ end
1553
+
1554
+ # value
1555
+ table.field("value", port: true)
1556
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1557
+
1558
+ # rparen_loc
1559
+ unless (rparen_loc = node.rparen_loc).nil?
1560
+ table.field("rparen_loc", location_inspect(rparen_loc))
1561
+ end
1562
+
1563
+ # keyword_loc
1564
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
1565
+
1566
+ digraph.nodes << <<~DOT
1567
+ #{id} [
1568
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1569
+ ];
1570
+ DOT
1571
+
1572
+ super
1573
+ end
1574
+
1575
+ # Visit a ElseNode node.
1576
+ def visit_else_node(node)
1577
+ table = Table.new("ElseNode")
1578
+ id = node_id(node)
1579
+
1580
+ # else_keyword_loc
1581
+ table.field("else_keyword_loc", location_inspect(node.else_keyword_loc))
1582
+
1583
+ # statements
1584
+ unless (statements = node.statements).nil?
1585
+ table.field("statements", port: true)
1586
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
1587
+ end
1588
+
1589
+ # end_keyword_loc
1590
+ unless (end_keyword_loc = node.end_keyword_loc).nil?
1591
+ table.field("end_keyword_loc", location_inspect(end_keyword_loc))
1592
+ end
1593
+
1594
+ digraph.nodes << <<~DOT
1595
+ #{id} [
1596
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1597
+ ];
1598
+ DOT
1599
+
1600
+ super
1601
+ end
1602
+
1603
+ # Visit a EmbeddedStatementsNode node.
1604
+ def visit_embedded_statements_node(node)
1605
+ table = Table.new("EmbeddedStatementsNode")
1606
+ id = node_id(node)
1607
+
1608
+ # opening_loc
1609
+ table.field("opening_loc", location_inspect(node.opening_loc))
1610
+
1611
+ # statements
1612
+ unless (statements = node.statements).nil?
1613
+ table.field("statements", port: true)
1614
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
1615
+ end
1616
+
1617
+ # closing_loc
1618
+ table.field("closing_loc", location_inspect(node.closing_loc))
1619
+
1620
+ digraph.nodes << <<~DOT
1621
+ #{id} [
1622
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1623
+ ];
1624
+ DOT
1625
+
1626
+ super
1627
+ end
1628
+
1629
+ # Visit a EmbeddedVariableNode node.
1630
+ def visit_embedded_variable_node(node)
1631
+ table = Table.new("EmbeddedVariableNode")
1632
+ id = node_id(node)
1633
+
1634
+ # operator_loc
1635
+ table.field("operator_loc", location_inspect(node.operator_loc))
1636
+
1637
+ # variable
1638
+ table.field("variable", port: true)
1639
+ digraph.edge("#{id}:variable -> #{node_id(node.variable)};")
1640
+
1641
+ digraph.nodes << <<~DOT
1642
+ #{id} [
1643
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1644
+ ];
1645
+ DOT
1646
+
1647
+ super
1648
+ end
1649
+
1650
+ # Visit a EnsureNode node.
1651
+ def visit_ensure_node(node)
1652
+ table = Table.new("EnsureNode")
1653
+ id = node_id(node)
1654
+
1655
+ # ensure_keyword_loc
1656
+ table.field("ensure_keyword_loc", location_inspect(node.ensure_keyword_loc))
1657
+
1658
+ # statements
1659
+ unless (statements = node.statements).nil?
1660
+ table.field("statements", port: true)
1661
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
1662
+ end
1663
+
1664
+ # end_keyword_loc
1665
+ table.field("end_keyword_loc", location_inspect(node.end_keyword_loc))
1666
+
1667
+ digraph.nodes << <<~DOT
1668
+ #{id} [
1669
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1670
+ ];
1671
+ DOT
1672
+
1673
+ super
1674
+ end
1675
+
1676
+ # Visit a FalseNode node.
1677
+ def visit_false_node(node)
1678
+ table = Table.new("FalseNode")
1679
+ id = node_id(node)
1680
+
1681
+ digraph.nodes << <<~DOT
1682
+ #{id} [
1683
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1684
+ ];
1685
+ DOT
1686
+
1687
+ super
1688
+ end
1689
+
1690
+ # Visit a FindPatternNode node.
1691
+ def visit_find_pattern_node(node)
1692
+ table = Table.new("FindPatternNode")
1693
+ id = node_id(node)
1694
+
1695
+ # constant
1696
+ unless (constant = node.constant).nil?
1697
+ table.field("constant", port: true)
1698
+ digraph.edge("#{id}:constant -> #{node_id(constant)};")
1699
+ end
1700
+
1701
+ # left
1702
+ table.field("left", port: true)
1703
+ digraph.edge("#{id}:left -> #{node_id(node.left)};")
1704
+
1705
+ # requireds
1706
+ if node.requireds.any?
1707
+ table.field("requireds", port: true)
1708
+
1709
+ waypoint = "#{id}_requireds"
1710
+ digraph.waypoint("#{waypoint};")
1711
+
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
1717
+
1718
+ # right
1719
+ table.field("right", port: true)
1720
+ digraph.edge("#{id}:right -> #{node_id(node.right)};")
1721
+
1722
+ # opening_loc
1723
+ unless (opening_loc = node.opening_loc).nil?
1724
+ table.field("opening_loc", location_inspect(opening_loc))
1725
+ end
1726
+
1727
+ # closing_loc
1728
+ unless (closing_loc = node.closing_loc).nil?
1729
+ table.field("closing_loc", location_inspect(closing_loc))
1730
+ end
1731
+
1732
+ digraph.nodes << <<~DOT
1733
+ #{id} [
1734
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1735
+ ];
1736
+ DOT
1737
+
1738
+ super
1739
+ end
1740
+
1741
+ # Visit a FlipFlopNode node.
1742
+ def visit_flip_flop_node(node)
1743
+ table = Table.new("FlipFlopNode")
1744
+ id = node_id(node)
1745
+
1746
+ # flags
1747
+ table.field("flags", range_flags_inspect(node))
1748
+
1749
+ # left
1750
+ unless (left = node.left).nil?
1751
+ table.field("left", port: true)
1752
+ digraph.edge("#{id}:left -> #{node_id(left)};")
1753
+ end
1754
+
1755
+ # right
1756
+ unless (right = node.right).nil?
1757
+ table.field("right", port: true)
1758
+ digraph.edge("#{id}:right -> #{node_id(right)};")
1759
+ end
1760
+
1761
+ # operator_loc
1762
+ table.field("operator_loc", location_inspect(node.operator_loc))
1763
+
1764
+ digraph.nodes << <<~DOT
1765
+ #{id} [
1766
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1767
+ ];
1768
+ DOT
1769
+
1770
+ super
1771
+ end
1772
+
1773
+ # Visit a FloatNode node.
1774
+ def visit_float_node(node)
1775
+ table = Table.new("FloatNode")
1776
+ id = node_id(node)
1777
+
1778
+ digraph.nodes << <<~DOT
1779
+ #{id} [
1780
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1781
+ ];
1782
+ DOT
1783
+
1784
+ super
1785
+ end
1786
+
1787
+ # Visit a ForNode node.
1788
+ def visit_for_node(node)
1789
+ table = Table.new("ForNode")
1790
+ id = node_id(node)
1791
+
1792
+ # index
1793
+ table.field("index", port: true)
1794
+ digraph.edge("#{id}:index -> #{node_id(node.index)};")
1795
+
1796
+ # collection
1797
+ table.field("collection", port: true)
1798
+ digraph.edge("#{id}:collection -> #{node_id(node.collection)};")
1799
+
1800
+ # statements
1801
+ unless (statements = node.statements).nil?
1802
+ table.field("statements", port: true)
1803
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
1804
+ end
1805
+
1806
+ # for_keyword_loc
1807
+ table.field("for_keyword_loc", location_inspect(node.for_keyword_loc))
1808
+
1809
+ # in_keyword_loc
1810
+ table.field("in_keyword_loc", location_inspect(node.in_keyword_loc))
1811
+
1812
+ # do_keyword_loc
1813
+ unless (do_keyword_loc = node.do_keyword_loc).nil?
1814
+ table.field("do_keyword_loc", location_inspect(do_keyword_loc))
1815
+ end
1816
+
1817
+ # end_keyword_loc
1818
+ table.field("end_keyword_loc", location_inspect(node.end_keyword_loc))
1819
+
1820
+ digraph.nodes << <<~DOT
1821
+ #{id} [
1822
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1823
+ ];
1824
+ DOT
1825
+
1826
+ super
1827
+ end
1828
+
1829
+ # Visit a ForwardingArgumentsNode node.
1830
+ def visit_forwarding_arguments_node(node)
1831
+ table = Table.new("ForwardingArgumentsNode")
1832
+ id = node_id(node)
1833
+
1834
+ digraph.nodes << <<~DOT
1835
+ #{id} [
1836
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1837
+ ];
1838
+ DOT
1839
+
1840
+ super
1841
+ end
1842
+
1843
+ # Visit a ForwardingParameterNode node.
1844
+ def visit_forwarding_parameter_node(node)
1845
+ table = Table.new("ForwardingParameterNode")
1846
+ id = node_id(node)
1847
+
1848
+ digraph.nodes << <<~DOT
1849
+ #{id} [
1850
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1851
+ ];
1852
+ DOT
1853
+
1854
+ super
1855
+ end
1856
+
1857
+ # Visit a ForwardingSuperNode node.
1858
+ def visit_forwarding_super_node(node)
1859
+ table = Table.new("ForwardingSuperNode")
1860
+ id = node_id(node)
1861
+
1862
+ # block
1863
+ unless (block = node.block).nil?
1864
+ table.field("block", port: true)
1865
+ digraph.edge("#{id}:block -> #{node_id(block)};")
1866
+ end
1867
+
1868
+ digraph.nodes << <<~DOT
1869
+ #{id} [
1870
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1871
+ ];
1872
+ DOT
1873
+
1874
+ super
1875
+ end
1876
+
1877
+ # Visit a GlobalVariableAndWriteNode node.
1878
+ def visit_global_variable_and_write_node(node)
1879
+ table = Table.new("GlobalVariableAndWriteNode")
1880
+ id = node_id(node)
1881
+
1882
+ # name
1883
+ table.field("name", node.name.inspect)
1884
+
1885
+ # name_loc
1886
+ table.field("name_loc", location_inspect(node.name_loc))
1887
+
1888
+ # operator_loc
1889
+ table.field("operator_loc", location_inspect(node.operator_loc))
1890
+
1891
+ # value
1892
+ table.field("value", port: true)
1893
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1894
+
1895
+ digraph.nodes << <<~DOT
1896
+ #{id} [
1897
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1898
+ ];
1899
+ DOT
1900
+
1901
+ super
1902
+ end
1903
+
1904
+ # Visit a GlobalVariableOperatorWriteNode node.
1905
+ def visit_global_variable_operator_write_node(node)
1906
+ table = Table.new("GlobalVariableOperatorWriteNode")
1907
+ id = node_id(node)
1908
+
1909
+ # name
1910
+ table.field("name", node.name.inspect)
1911
+
1912
+ # name_loc
1913
+ table.field("name_loc", location_inspect(node.name_loc))
1914
+
1915
+ # operator_loc
1916
+ table.field("operator_loc", location_inspect(node.operator_loc))
1917
+
1918
+ # value
1919
+ table.field("value", port: true)
1920
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1921
+
1922
+ # operator
1923
+ table.field("operator", node.operator.inspect)
1924
+
1925
+ digraph.nodes << <<~DOT
1926
+ #{id} [
1927
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1928
+ ];
1929
+ DOT
1930
+
1931
+ super
1932
+ end
1933
+
1934
+ # Visit a GlobalVariableOrWriteNode node.
1935
+ def visit_global_variable_or_write_node(node)
1936
+ table = Table.new("GlobalVariableOrWriteNode")
1937
+ id = node_id(node)
1938
+
1939
+ # name
1940
+ table.field("name", node.name.inspect)
1941
+
1942
+ # name_loc
1943
+ table.field("name_loc", location_inspect(node.name_loc))
1944
+
1945
+ # operator_loc
1946
+ table.field("operator_loc", location_inspect(node.operator_loc))
1947
+
1948
+ # value
1949
+ table.field("value", port: true)
1950
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
1951
+
1952
+ digraph.nodes << <<~DOT
1953
+ #{id} [
1954
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1955
+ ];
1956
+ DOT
1957
+
1958
+ super
1959
+ end
1960
+
1961
+ # Visit a GlobalVariableReadNode node.
1962
+ def visit_global_variable_read_node(node)
1963
+ table = Table.new("GlobalVariableReadNode")
1964
+ id = node_id(node)
1965
+
1966
+ # name
1967
+ table.field("name", node.name.inspect)
1968
+
1969
+ digraph.nodes << <<~DOT
1970
+ #{id} [
1971
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1972
+ ];
1973
+ DOT
1974
+
1975
+ super
1976
+ end
1977
+
1978
+ # Visit a GlobalVariableTargetNode node.
1979
+ def visit_global_variable_target_node(node)
1980
+ table = Table.new("GlobalVariableTargetNode")
1981
+ id = node_id(node)
1982
+
1983
+ # name
1984
+ table.field("name", node.name.inspect)
1985
+
1986
+ digraph.nodes << <<~DOT
1987
+ #{id} [
1988
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
1989
+ ];
1990
+ DOT
1991
+
1992
+ super
1993
+ end
1994
+
1995
+ # Visit a GlobalVariableWriteNode node.
1996
+ def visit_global_variable_write_node(node)
1997
+ table = Table.new("GlobalVariableWriteNode")
1998
+ id = node_id(node)
1999
+
2000
+ # name
2001
+ table.field("name", node.name.inspect)
2002
+
2003
+ # name_loc
2004
+ table.field("name_loc", location_inspect(node.name_loc))
2005
+
2006
+ # value
2007
+ table.field("value", port: true)
2008
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2009
+
2010
+ # operator_loc
2011
+ table.field("operator_loc", location_inspect(node.operator_loc))
2012
+
2013
+ digraph.nodes << <<~DOT
2014
+ #{id} [
2015
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2016
+ ];
2017
+ DOT
2018
+
2019
+ super
2020
+ end
2021
+
2022
+ # Visit a HashNode node.
2023
+ def visit_hash_node(node)
2024
+ table = Table.new("HashNode")
2025
+ id = node_id(node)
2026
+
2027
+ # opening_loc
2028
+ table.field("opening_loc", location_inspect(node.opening_loc))
2029
+
2030
+ # elements
2031
+ if node.elements.any?
2032
+ table.field("elements", port: true)
2033
+
2034
+ waypoint = "#{id}_elements"
2035
+ digraph.waypoint("#{waypoint};")
2036
+
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
2042
+
2043
+ # closing_loc
2044
+ table.field("closing_loc", location_inspect(node.closing_loc))
2045
+
2046
+ digraph.nodes << <<~DOT
2047
+ #{id} [
2048
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2049
+ ];
2050
+ DOT
2051
+
2052
+ super
2053
+ end
2054
+
2055
+ # Visit a HashPatternNode node.
2056
+ def visit_hash_pattern_node(node)
2057
+ table = Table.new("HashPatternNode")
2058
+ id = node_id(node)
2059
+
2060
+ # constant
2061
+ unless (constant = node.constant).nil?
2062
+ table.field("constant", port: true)
2063
+ digraph.edge("#{id}:constant -> #{node_id(constant)};")
2064
+ end
2065
+
2066
+ # elements
2067
+ if node.elements.any?
2068
+ table.field("elements", port: true)
2069
+
2070
+ waypoint = "#{id}_elements"
2071
+ digraph.waypoint("#{waypoint};")
2072
+
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
2078
+
2079
+ # rest
2080
+ unless (rest = node.rest).nil?
2081
+ table.field("rest", port: true)
2082
+ digraph.edge("#{id}:rest -> #{node_id(rest)};")
2083
+ end
2084
+
2085
+ # opening_loc
2086
+ unless (opening_loc = node.opening_loc).nil?
2087
+ table.field("opening_loc", location_inspect(opening_loc))
2088
+ end
2089
+
2090
+ # closing_loc
2091
+ unless (closing_loc = node.closing_loc).nil?
2092
+ table.field("closing_loc", location_inspect(closing_loc))
2093
+ end
2094
+
2095
+ digraph.nodes << <<~DOT
2096
+ #{id} [
2097
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2098
+ ];
2099
+ DOT
2100
+
2101
+ super
2102
+ end
2103
+
2104
+ # Visit a IfNode node.
2105
+ def visit_if_node(node)
2106
+ table = Table.new("IfNode")
2107
+ id = node_id(node)
2108
+
2109
+ # if_keyword_loc
2110
+ unless (if_keyword_loc = node.if_keyword_loc).nil?
2111
+ table.field("if_keyword_loc", location_inspect(if_keyword_loc))
2112
+ end
2113
+
2114
+ # predicate
2115
+ table.field("predicate", port: true)
2116
+ digraph.edge("#{id}:predicate -> #{node_id(node.predicate)};")
2117
+
2118
+ # then_keyword_loc
2119
+ unless (then_keyword_loc = node.then_keyword_loc).nil?
2120
+ table.field("then_keyword_loc", location_inspect(then_keyword_loc))
2121
+ end
2122
+
2123
+ # statements
2124
+ unless (statements = node.statements).nil?
2125
+ table.field("statements", port: true)
2126
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
2127
+ end
2128
+
2129
+ # consequent
2130
+ unless (consequent = node.consequent).nil?
2131
+ table.field("consequent", port: true)
2132
+ digraph.edge("#{id}:consequent -> #{node_id(consequent)};")
2133
+ end
2134
+
2135
+ # end_keyword_loc
2136
+ unless (end_keyword_loc = node.end_keyword_loc).nil?
2137
+ table.field("end_keyword_loc", location_inspect(end_keyword_loc))
2138
+ end
2139
+
2140
+ digraph.nodes << <<~DOT
2141
+ #{id} [
2142
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2143
+ ];
2144
+ DOT
2145
+
2146
+ super
2147
+ end
2148
+
2149
+ # Visit a ImaginaryNode node.
2150
+ def visit_imaginary_node(node)
2151
+ table = Table.new("ImaginaryNode")
2152
+ id = node_id(node)
2153
+
2154
+ # numeric
2155
+ table.field("numeric", port: true)
2156
+ digraph.edge("#{id}:numeric -> #{node_id(node.numeric)};")
2157
+
2158
+ digraph.nodes << <<~DOT
2159
+ #{id} [
2160
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2161
+ ];
2162
+ DOT
2163
+
2164
+ super
2165
+ end
2166
+
2167
+ # Visit a ImplicitNode node.
2168
+ def visit_implicit_node(node)
2169
+ table = Table.new("ImplicitNode")
2170
+ id = node_id(node)
2171
+
2172
+ # value
2173
+ table.field("value", port: true)
2174
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2175
+
2176
+ digraph.nodes << <<~DOT
2177
+ #{id} [
2178
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2179
+ ];
2180
+ DOT
2181
+
2182
+ super
2183
+ end
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
+
2199
+ # Visit a InNode node.
2200
+ def visit_in_node(node)
2201
+ table = Table.new("InNode")
2202
+ id = node_id(node)
2203
+
2204
+ # pattern
2205
+ table.field("pattern", port: true)
2206
+ digraph.edge("#{id}:pattern -> #{node_id(node.pattern)};")
2207
+
2208
+ # statements
2209
+ unless (statements = node.statements).nil?
2210
+ table.field("statements", port: true)
2211
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
2212
+ end
2213
+
2214
+ # in_loc
2215
+ table.field("in_loc", location_inspect(node.in_loc))
2216
+
2217
+ # then_loc
2218
+ unless (then_loc = node.then_loc).nil?
2219
+ table.field("then_loc", location_inspect(then_loc))
2220
+ end
2221
+
2222
+ digraph.nodes << <<~DOT
2223
+ #{id} [
2224
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2225
+ ];
2226
+ DOT
2227
+
2228
+ super
2229
+ end
2230
+
2231
+ # Visit a IndexAndWriteNode node.
2232
+ def visit_index_and_write_node(node)
2233
+ table = Table.new("IndexAndWriteNode")
2234
+ id = node_id(node)
2235
+
2236
+ # flags
2237
+ table.field("flags", call_node_flags_inspect(node))
2238
+
2239
+ # receiver
2240
+ unless (receiver = node.receiver).nil?
2241
+ table.field("receiver", port: true)
2242
+ digraph.edge("#{id}:receiver -> #{node_id(receiver)};")
2243
+ end
2244
+
2245
+ # call_operator_loc
2246
+ unless (call_operator_loc = node.call_operator_loc).nil?
2247
+ table.field("call_operator_loc", location_inspect(call_operator_loc))
2248
+ end
2249
+
2250
+ # opening_loc
2251
+ table.field("opening_loc", location_inspect(node.opening_loc))
2252
+
2253
+ # arguments
2254
+ unless (arguments = node.arguments).nil?
2255
+ table.field("arguments", port: true)
2256
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
2257
+ end
2258
+
2259
+ # closing_loc
2260
+ table.field("closing_loc", location_inspect(node.closing_loc))
2261
+
2262
+ # block
2263
+ unless (block = node.block).nil?
2264
+ table.field("block", port: true)
2265
+ digraph.edge("#{id}:block -> #{node_id(block)};")
2266
+ end
2267
+
2268
+ # operator_loc
2269
+ table.field("operator_loc", location_inspect(node.operator_loc))
2270
+
2271
+ # value
2272
+ table.field("value", port: true)
2273
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2274
+
2275
+ digraph.nodes << <<~DOT
2276
+ #{id} [
2277
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2278
+ ];
2279
+ DOT
2280
+
2281
+ super
2282
+ end
2283
+
2284
+ # Visit a IndexOperatorWriteNode node.
2285
+ def visit_index_operator_write_node(node)
2286
+ table = Table.new("IndexOperatorWriteNode")
2287
+ id = node_id(node)
2288
+
2289
+ # flags
2290
+ table.field("flags", call_node_flags_inspect(node))
2291
+
2292
+ # receiver
2293
+ unless (receiver = node.receiver).nil?
2294
+ table.field("receiver", port: true)
2295
+ digraph.edge("#{id}:receiver -> #{node_id(receiver)};")
2296
+ end
2297
+
2298
+ # call_operator_loc
2299
+ unless (call_operator_loc = node.call_operator_loc).nil?
2300
+ table.field("call_operator_loc", location_inspect(call_operator_loc))
2301
+ end
2302
+
2303
+ # opening_loc
2304
+ table.field("opening_loc", location_inspect(node.opening_loc))
2305
+
2306
+ # arguments
2307
+ unless (arguments = node.arguments).nil?
2308
+ table.field("arguments", port: true)
2309
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
2310
+ end
2311
+
2312
+ # closing_loc
2313
+ table.field("closing_loc", location_inspect(node.closing_loc))
2314
+
2315
+ # block
2316
+ unless (block = node.block).nil?
2317
+ table.field("block", port: true)
2318
+ digraph.edge("#{id}:block -> #{node_id(block)};")
2319
+ end
2320
+
2321
+ # operator
2322
+ table.field("operator", node.operator.inspect)
2323
+
2324
+ # operator_loc
2325
+ table.field("operator_loc", location_inspect(node.operator_loc))
2326
+
2327
+ # value
2328
+ table.field("value", port: true)
2329
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2330
+
2331
+ digraph.nodes << <<~DOT
2332
+ #{id} [
2333
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2334
+ ];
2335
+ DOT
2336
+
2337
+ super
2338
+ end
2339
+
2340
+ # Visit a IndexOrWriteNode node.
2341
+ def visit_index_or_write_node(node)
2342
+ table = Table.new("IndexOrWriteNode")
2343
+ id = node_id(node)
2344
+
2345
+ # flags
2346
+ table.field("flags", call_node_flags_inspect(node))
2347
+
2348
+ # receiver
2349
+ unless (receiver = node.receiver).nil?
2350
+ table.field("receiver", port: true)
2351
+ digraph.edge("#{id}:receiver -> #{node_id(receiver)};")
2352
+ end
2353
+
2354
+ # call_operator_loc
2355
+ unless (call_operator_loc = node.call_operator_loc).nil?
2356
+ table.field("call_operator_loc", location_inspect(call_operator_loc))
2357
+ end
2358
+
2359
+ # opening_loc
2360
+ table.field("opening_loc", location_inspect(node.opening_loc))
2361
+
2362
+ # arguments
2363
+ unless (arguments = node.arguments).nil?
2364
+ table.field("arguments", port: true)
2365
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
2366
+ end
2367
+
2368
+ # closing_loc
2369
+ table.field("closing_loc", location_inspect(node.closing_loc))
2370
+
2371
+ # block
2372
+ unless (block = node.block).nil?
2373
+ table.field("block", port: true)
2374
+ digraph.edge("#{id}:block -> #{node_id(block)};")
2375
+ end
2376
+
2377
+ # operator_loc
2378
+ table.field("operator_loc", location_inspect(node.operator_loc))
2379
+
2380
+ # value
2381
+ table.field("value", port: true)
2382
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2383
+
2384
+ digraph.nodes << <<~DOT
2385
+ #{id} [
2386
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2387
+ ];
2388
+ DOT
2389
+
2390
+ super
2391
+ end
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
+
2432
+ # Visit a InstanceVariableAndWriteNode node.
2433
+ def visit_instance_variable_and_write_node(node)
2434
+ table = Table.new("InstanceVariableAndWriteNode")
2435
+ id = node_id(node)
2436
+
2437
+ # name
2438
+ table.field("name", node.name.inspect)
2439
+
2440
+ # name_loc
2441
+ table.field("name_loc", location_inspect(node.name_loc))
2442
+
2443
+ # operator_loc
2444
+ table.field("operator_loc", location_inspect(node.operator_loc))
2445
+
2446
+ # value
2447
+ table.field("value", port: true)
2448
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2449
+
2450
+ digraph.nodes << <<~DOT
2451
+ #{id} [
2452
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2453
+ ];
2454
+ DOT
2455
+
2456
+ super
2457
+ end
2458
+
2459
+ # Visit a InstanceVariableOperatorWriteNode node.
2460
+ def visit_instance_variable_operator_write_node(node)
2461
+ table = Table.new("InstanceVariableOperatorWriteNode")
2462
+ id = node_id(node)
2463
+
2464
+ # name
2465
+ table.field("name", node.name.inspect)
2466
+
2467
+ # name_loc
2468
+ table.field("name_loc", location_inspect(node.name_loc))
2469
+
2470
+ # operator_loc
2471
+ table.field("operator_loc", location_inspect(node.operator_loc))
2472
+
2473
+ # value
2474
+ table.field("value", port: true)
2475
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2476
+
2477
+ # operator
2478
+ table.field("operator", node.operator.inspect)
2479
+
2480
+ digraph.nodes << <<~DOT
2481
+ #{id} [
2482
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2483
+ ];
2484
+ DOT
2485
+
2486
+ super
2487
+ end
2488
+
2489
+ # Visit a InstanceVariableOrWriteNode node.
2490
+ def visit_instance_variable_or_write_node(node)
2491
+ table = Table.new("InstanceVariableOrWriteNode")
2492
+ id = node_id(node)
2493
+
2494
+ # name
2495
+ table.field("name", node.name.inspect)
2496
+
2497
+ # name_loc
2498
+ table.field("name_loc", location_inspect(node.name_loc))
2499
+
2500
+ # operator_loc
2501
+ table.field("operator_loc", location_inspect(node.operator_loc))
2502
+
2503
+ # value
2504
+ table.field("value", port: true)
2505
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2506
+
2507
+ digraph.nodes << <<~DOT
2508
+ #{id} [
2509
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2510
+ ];
2511
+ DOT
2512
+
2513
+ super
2514
+ end
2515
+
2516
+ # Visit a InstanceVariableReadNode node.
2517
+ def visit_instance_variable_read_node(node)
2518
+ table = Table.new("InstanceVariableReadNode")
2519
+ id = node_id(node)
2520
+
2521
+ # name
2522
+ table.field("name", node.name.inspect)
2523
+
2524
+ digraph.nodes << <<~DOT
2525
+ #{id} [
2526
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2527
+ ];
2528
+ DOT
2529
+
2530
+ super
2531
+ end
2532
+
2533
+ # Visit a InstanceVariableTargetNode node.
2534
+ def visit_instance_variable_target_node(node)
2535
+ table = Table.new("InstanceVariableTargetNode")
2536
+ id = node_id(node)
2537
+
2538
+ # name
2539
+ table.field("name", node.name.inspect)
2540
+
2541
+ digraph.nodes << <<~DOT
2542
+ #{id} [
2543
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2544
+ ];
2545
+ DOT
2546
+
2547
+ super
2548
+ end
2549
+
2550
+ # Visit a InstanceVariableWriteNode node.
2551
+ def visit_instance_variable_write_node(node)
2552
+ table = Table.new("InstanceVariableWriteNode")
2553
+ id = node_id(node)
2554
+
2555
+ # name
2556
+ table.field("name", node.name.inspect)
2557
+
2558
+ # name_loc
2559
+ table.field("name_loc", location_inspect(node.name_loc))
2560
+
2561
+ # value
2562
+ table.field("value", port: true)
2563
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2564
+
2565
+ # operator_loc
2566
+ table.field("operator_loc", location_inspect(node.operator_loc))
2567
+
2568
+ digraph.nodes << <<~DOT
2569
+ #{id} [
2570
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2571
+ ];
2572
+ DOT
2573
+
2574
+ super
2575
+ end
2576
+
2577
+ # Visit a IntegerNode node.
2578
+ def visit_integer_node(node)
2579
+ table = Table.new("IntegerNode")
2580
+ id = node_id(node)
2581
+
2582
+ # flags
2583
+ table.field("flags", integer_base_flags_inspect(node))
2584
+
2585
+ digraph.nodes << <<~DOT
2586
+ #{id} [
2587
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2588
+ ];
2589
+ DOT
2590
+
2591
+ super
2592
+ end
2593
+
2594
+ # Visit a InterpolatedMatchLastLineNode node.
2595
+ def visit_interpolated_match_last_line_node(node)
2596
+ table = Table.new("InterpolatedMatchLastLineNode")
2597
+ id = node_id(node)
2598
+
2599
+ # flags
2600
+ table.field("flags", regular_expression_flags_inspect(node))
2601
+
2602
+ # opening_loc
2603
+ table.field("opening_loc", location_inspect(node.opening_loc))
2604
+
2605
+ # parts
2606
+ if node.parts.any?
2607
+ table.field("parts", port: true)
2608
+
2609
+ waypoint = "#{id}_parts"
2610
+ digraph.waypoint("#{waypoint};")
2611
+
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
2617
+
2618
+ # closing_loc
2619
+ table.field("closing_loc", location_inspect(node.closing_loc))
2620
+
2621
+ digraph.nodes << <<~DOT
2622
+ #{id} [
2623
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2624
+ ];
2625
+ DOT
2626
+
2627
+ super
2628
+ end
2629
+
2630
+ # Visit a InterpolatedRegularExpressionNode node.
2631
+ def visit_interpolated_regular_expression_node(node)
2632
+ table = Table.new("InterpolatedRegularExpressionNode")
2633
+ id = node_id(node)
2634
+
2635
+ # flags
2636
+ table.field("flags", regular_expression_flags_inspect(node))
2637
+
2638
+ # opening_loc
2639
+ table.field("opening_loc", location_inspect(node.opening_loc))
2640
+
2641
+ # parts
2642
+ if node.parts.any?
2643
+ table.field("parts", port: true)
2644
+
2645
+ waypoint = "#{id}_parts"
2646
+ digraph.waypoint("#{waypoint};")
2647
+
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
2653
+
2654
+ # closing_loc
2655
+ table.field("closing_loc", location_inspect(node.closing_loc))
2656
+
2657
+ digraph.nodes << <<~DOT
2658
+ #{id} [
2659
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2660
+ ];
2661
+ DOT
2662
+
2663
+ super
2664
+ end
2665
+
2666
+ # Visit a InterpolatedStringNode node.
2667
+ def visit_interpolated_string_node(node)
2668
+ table = Table.new("InterpolatedStringNode")
2669
+ id = node_id(node)
2670
+
2671
+ # opening_loc
2672
+ unless (opening_loc = node.opening_loc).nil?
2673
+ table.field("opening_loc", location_inspect(opening_loc))
2674
+ end
2675
+
2676
+ # parts
2677
+ if node.parts.any?
2678
+ table.field("parts", port: true)
2679
+
2680
+ waypoint = "#{id}_parts"
2681
+ digraph.waypoint("#{waypoint};")
2682
+
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
2688
+
2689
+ # closing_loc
2690
+ unless (closing_loc = node.closing_loc).nil?
2691
+ table.field("closing_loc", location_inspect(closing_loc))
2692
+ end
2693
+
2694
+ digraph.nodes << <<~DOT
2695
+ #{id} [
2696
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2697
+ ];
2698
+ DOT
2699
+
2700
+ super
2701
+ end
2702
+
2703
+ # Visit a InterpolatedSymbolNode node.
2704
+ def visit_interpolated_symbol_node(node)
2705
+ table = Table.new("InterpolatedSymbolNode")
2706
+ id = node_id(node)
2707
+
2708
+ # opening_loc
2709
+ unless (opening_loc = node.opening_loc).nil?
2710
+ table.field("opening_loc", location_inspect(opening_loc))
2711
+ end
2712
+
2713
+ # parts
2714
+ if node.parts.any?
2715
+ table.field("parts", port: true)
2716
+
2717
+ waypoint = "#{id}_parts"
2718
+ digraph.waypoint("#{waypoint};")
2719
+
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
2725
+
2726
+ # closing_loc
2727
+ unless (closing_loc = node.closing_loc).nil?
2728
+ table.field("closing_loc", location_inspect(closing_loc))
2729
+ end
2730
+
2731
+ digraph.nodes << <<~DOT
2732
+ #{id} [
2733
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2734
+ ];
2735
+ DOT
2736
+
2737
+ super
2738
+ end
2739
+
2740
+ # Visit a InterpolatedXStringNode node.
2741
+ def visit_interpolated_x_string_node(node)
2742
+ table = Table.new("InterpolatedXStringNode")
2743
+ id = node_id(node)
2744
+
2745
+ # opening_loc
2746
+ table.field("opening_loc", location_inspect(node.opening_loc))
2747
+
2748
+ # parts
2749
+ if node.parts.any?
2750
+ table.field("parts", port: true)
2751
+
2752
+ waypoint = "#{id}_parts"
2753
+ digraph.waypoint("#{waypoint};")
2754
+
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
2760
+
2761
+ # closing_loc
2762
+ table.field("closing_loc", location_inspect(node.closing_loc))
2763
+
2764
+ digraph.nodes << <<~DOT
2765
+ #{id} [
2766
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2767
+ ];
2768
+ DOT
2769
+
2770
+ super
2771
+ end
2772
+
2773
+ # Visit a KeywordHashNode node.
2774
+ def visit_keyword_hash_node(node)
2775
+ table = Table.new("KeywordHashNode")
2776
+ id = node_id(node)
2777
+
2778
+ # flags
2779
+ table.field("flags", keyword_hash_node_flags_inspect(node))
2780
+
2781
+ # elements
2782
+ if node.elements.any?
2783
+ table.field("elements", port: true)
2784
+
2785
+ waypoint = "#{id}_elements"
2786
+ digraph.waypoint("#{waypoint};")
2787
+
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
2793
+
2794
+ digraph.nodes << <<~DOT
2795
+ #{id} [
2796
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2797
+ ];
2798
+ DOT
2799
+
2800
+ super
2801
+ end
2802
+
2803
+ # Visit a KeywordRestParameterNode node.
2804
+ def visit_keyword_rest_parameter_node(node)
2805
+ table = Table.new("KeywordRestParameterNode")
2806
+ id = node_id(node)
2807
+
2808
+ # name
2809
+ table.field("name", node.name.inspect)
2810
+
2811
+ # name_loc
2812
+ unless (name_loc = node.name_loc).nil?
2813
+ table.field("name_loc", location_inspect(name_loc))
2814
+ end
2815
+
2816
+ # operator_loc
2817
+ table.field("operator_loc", location_inspect(node.operator_loc))
2818
+
2819
+ digraph.nodes << <<~DOT
2820
+ #{id} [
2821
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2822
+ ];
2823
+ DOT
2824
+
2825
+ super
2826
+ end
2827
+
2828
+ # Visit a LambdaNode node.
2829
+ def visit_lambda_node(node)
2830
+ table = Table.new("LambdaNode")
2831
+ id = node_id(node)
2832
+
2833
+ # locals
2834
+ table.field("locals", node.locals.inspect)
2835
+
2836
+ # locals_body_index
2837
+ table.field("locals_body_index", node.locals_body_index.inspect)
2838
+
2839
+ # operator_loc
2840
+ table.field("operator_loc", location_inspect(node.operator_loc))
2841
+
2842
+ # opening_loc
2843
+ table.field("opening_loc", location_inspect(node.opening_loc))
2844
+
2845
+ # closing_loc
2846
+ table.field("closing_loc", location_inspect(node.closing_loc))
2847
+
2848
+ # parameters
2849
+ unless (parameters = node.parameters).nil?
2850
+ table.field("parameters", port: true)
2851
+ digraph.edge("#{id}:parameters -> #{node_id(parameters)};")
2852
+ end
2853
+
2854
+ # body
2855
+ unless (body = node.body).nil?
2856
+ table.field("body", port: true)
2857
+ digraph.edge("#{id}:body -> #{node_id(body)};")
2858
+ end
2859
+
2860
+ digraph.nodes << <<~DOT
2861
+ #{id} [
2862
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2863
+ ];
2864
+ DOT
2865
+
2866
+ super
2867
+ end
2868
+
2869
+ # Visit a LocalVariableAndWriteNode node.
2870
+ def visit_local_variable_and_write_node(node)
2871
+ table = Table.new("LocalVariableAndWriteNode")
2872
+ id = node_id(node)
2873
+
2874
+ # name_loc
2875
+ table.field("name_loc", location_inspect(node.name_loc))
2876
+
2877
+ # operator_loc
2878
+ table.field("operator_loc", location_inspect(node.operator_loc))
2879
+
2880
+ # value
2881
+ table.field("value", port: true)
2882
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2883
+
2884
+ # name
2885
+ table.field("name", node.name.inspect)
2886
+
2887
+ # depth
2888
+ table.field("depth", node.depth.inspect)
2889
+
2890
+ digraph.nodes << <<~DOT
2891
+ #{id} [
2892
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2893
+ ];
2894
+ DOT
2895
+
2896
+ super
2897
+ end
2898
+
2899
+ # Visit a LocalVariableOperatorWriteNode node.
2900
+ def visit_local_variable_operator_write_node(node)
2901
+ table = Table.new("LocalVariableOperatorWriteNode")
2902
+ id = node_id(node)
2903
+
2904
+ # name_loc
2905
+ table.field("name_loc", location_inspect(node.name_loc))
2906
+
2907
+ # operator_loc
2908
+ table.field("operator_loc", location_inspect(node.operator_loc))
2909
+
2910
+ # value
2911
+ table.field("value", port: true)
2912
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2913
+
2914
+ # name
2915
+ table.field("name", node.name.inspect)
2916
+
2917
+ # operator
2918
+ table.field("operator", node.operator.inspect)
2919
+
2920
+ # depth
2921
+ table.field("depth", node.depth.inspect)
2922
+
2923
+ digraph.nodes << <<~DOT
2924
+ #{id} [
2925
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2926
+ ];
2927
+ DOT
2928
+
2929
+ super
2930
+ end
2931
+
2932
+ # Visit a LocalVariableOrWriteNode node.
2933
+ def visit_local_variable_or_write_node(node)
2934
+ table = Table.new("LocalVariableOrWriteNode")
2935
+ id = node_id(node)
2936
+
2937
+ # name_loc
2938
+ table.field("name_loc", location_inspect(node.name_loc))
2939
+
2940
+ # operator_loc
2941
+ table.field("operator_loc", location_inspect(node.operator_loc))
2942
+
2943
+ # value
2944
+ table.field("value", port: true)
2945
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
2946
+
2947
+ # name
2948
+ table.field("name", node.name.inspect)
2949
+
2950
+ # depth
2951
+ table.field("depth", node.depth.inspect)
2952
+
2953
+ digraph.nodes << <<~DOT
2954
+ #{id} [
2955
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2956
+ ];
2957
+ DOT
2958
+
2959
+ super
2960
+ end
2961
+
2962
+ # Visit a LocalVariableReadNode node.
2963
+ def visit_local_variable_read_node(node)
2964
+ table = Table.new("LocalVariableReadNode")
2965
+ id = node_id(node)
2966
+
2967
+ # name
2968
+ table.field("name", node.name.inspect)
2969
+
2970
+ # depth
2971
+ table.field("depth", node.depth.inspect)
2972
+
2973
+ digraph.nodes << <<~DOT
2974
+ #{id} [
2975
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2976
+ ];
2977
+ DOT
2978
+
2979
+ super
2980
+ end
2981
+
2982
+ # Visit a LocalVariableTargetNode node.
2983
+ def visit_local_variable_target_node(node)
2984
+ table = Table.new("LocalVariableTargetNode")
2985
+ id = node_id(node)
2986
+
2987
+ # name
2988
+ table.field("name", node.name.inspect)
2989
+
2990
+ # depth
2991
+ table.field("depth", node.depth.inspect)
2992
+
2993
+ digraph.nodes << <<~DOT
2994
+ #{id} [
2995
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
2996
+ ];
2997
+ DOT
2998
+
2999
+ super
3000
+ end
3001
+
3002
+ # Visit a LocalVariableWriteNode node.
3003
+ def visit_local_variable_write_node(node)
3004
+ table = Table.new("LocalVariableWriteNode")
3005
+ id = node_id(node)
3006
+
3007
+ # name
3008
+ table.field("name", node.name.inspect)
3009
+
3010
+ # depth
3011
+ table.field("depth", node.depth.inspect)
3012
+
3013
+ # name_loc
3014
+ table.field("name_loc", location_inspect(node.name_loc))
3015
+
3016
+ # value
3017
+ table.field("value", port: true)
3018
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
3019
+
3020
+ # operator_loc
3021
+ table.field("operator_loc", location_inspect(node.operator_loc))
3022
+
3023
+ digraph.nodes << <<~DOT
3024
+ #{id} [
3025
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3026
+ ];
3027
+ DOT
3028
+
3029
+ super
3030
+ end
3031
+
3032
+ # Visit a MatchLastLineNode node.
3033
+ def visit_match_last_line_node(node)
3034
+ table = Table.new("MatchLastLineNode")
3035
+ id = node_id(node)
3036
+
3037
+ # flags
3038
+ table.field("flags", regular_expression_flags_inspect(node))
3039
+
3040
+ # opening_loc
3041
+ table.field("opening_loc", location_inspect(node.opening_loc))
3042
+
3043
+ # content_loc
3044
+ table.field("content_loc", location_inspect(node.content_loc))
3045
+
3046
+ # closing_loc
3047
+ table.field("closing_loc", location_inspect(node.closing_loc))
3048
+
3049
+ # unescaped
3050
+ table.field("unescaped", node.unescaped.inspect)
3051
+
3052
+ digraph.nodes << <<~DOT
3053
+ #{id} [
3054
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3055
+ ];
3056
+ DOT
3057
+
3058
+ super
3059
+ end
3060
+
3061
+ # Visit a MatchPredicateNode node.
3062
+ def visit_match_predicate_node(node)
3063
+ table = Table.new("MatchPredicateNode")
3064
+ id = node_id(node)
3065
+
3066
+ # value
3067
+ table.field("value", port: true)
3068
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
3069
+
3070
+ # pattern
3071
+ table.field("pattern", port: true)
3072
+ digraph.edge("#{id}:pattern -> #{node_id(node.pattern)};")
3073
+
3074
+ # operator_loc
3075
+ table.field("operator_loc", location_inspect(node.operator_loc))
3076
+
3077
+ digraph.nodes << <<~DOT
3078
+ #{id} [
3079
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3080
+ ];
3081
+ DOT
3082
+
3083
+ super
3084
+ end
3085
+
3086
+ # Visit a MatchRequiredNode node.
3087
+ def visit_match_required_node(node)
3088
+ table = Table.new("MatchRequiredNode")
3089
+ id = node_id(node)
3090
+
3091
+ # value
3092
+ table.field("value", port: true)
3093
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
3094
+
3095
+ # pattern
3096
+ table.field("pattern", port: true)
3097
+ digraph.edge("#{id}:pattern -> #{node_id(node.pattern)};")
3098
+
3099
+ # operator_loc
3100
+ table.field("operator_loc", location_inspect(node.operator_loc))
3101
+
3102
+ digraph.nodes << <<~DOT
3103
+ #{id} [
3104
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3105
+ ];
3106
+ DOT
3107
+
3108
+ super
3109
+ end
3110
+
3111
+ # Visit a MatchWriteNode node.
3112
+ def visit_match_write_node(node)
3113
+ table = Table.new("MatchWriteNode")
3114
+ id = node_id(node)
3115
+
3116
+ # call
3117
+ table.field("call", port: true)
3118
+ digraph.edge("#{id}:call -> #{node_id(node.call)};")
3119
+
3120
+ # targets
3121
+ if node.targets.any?
3122
+ table.field("targets", port: true)
3123
+
3124
+ waypoint = "#{id}_targets"
3125
+ digraph.waypoint("#{waypoint};")
3126
+
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
3132
+
3133
+ digraph.nodes << <<~DOT
3134
+ #{id} [
3135
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3136
+ ];
3137
+ DOT
3138
+
3139
+ super
3140
+ end
3141
+
3142
+ # Visit a MissingNode node.
3143
+ def visit_missing_node(node)
3144
+ table = Table.new("MissingNode")
3145
+ id = node_id(node)
3146
+
3147
+ digraph.nodes << <<~DOT
3148
+ #{id} [
3149
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3150
+ ];
3151
+ DOT
3152
+
3153
+ super
3154
+ end
3155
+
3156
+ # Visit a ModuleNode node.
3157
+ def visit_module_node(node)
3158
+ table = Table.new("ModuleNode")
3159
+ id = node_id(node)
3160
+
3161
+ # locals
3162
+ table.field("locals", node.locals.inspect)
3163
+
3164
+ # module_keyword_loc
3165
+ table.field("module_keyword_loc", location_inspect(node.module_keyword_loc))
3166
+
3167
+ # constant_path
3168
+ table.field("constant_path", port: true)
3169
+ digraph.edge("#{id}:constant_path -> #{node_id(node.constant_path)};")
3170
+
3171
+ # body
3172
+ unless (body = node.body).nil?
3173
+ table.field("body", port: true)
3174
+ digraph.edge("#{id}:body -> #{node_id(body)};")
3175
+ end
3176
+
3177
+ # end_keyword_loc
3178
+ table.field("end_keyword_loc", location_inspect(node.end_keyword_loc))
3179
+
3180
+ # name
3181
+ table.field("name", node.name.inspect)
3182
+
3183
+ digraph.nodes << <<~DOT
3184
+ #{id} [
3185
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3186
+ ];
3187
+ DOT
3188
+
3189
+ super
3190
+ end
3191
+
3192
+ # Visit a MultiTargetNode node.
3193
+ def visit_multi_target_node(node)
3194
+ table = Table.new("MultiTargetNode")
3195
+ id = node_id(node)
3196
+
3197
+ # lefts
3198
+ if node.lefts.any?
3199
+ table.field("lefts", port: true)
3200
+
3201
+ waypoint = "#{id}_lefts"
3202
+ digraph.waypoint("#{waypoint};")
3203
+
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
3209
+
3210
+ # rest
3211
+ unless (rest = node.rest).nil?
3212
+ table.field("rest", port: true)
3213
+ digraph.edge("#{id}:rest -> #{node_id(rest)};")
3214
+ end
3215
+
3216
+ # rights
3217
+ if node.rights.any?
3218
+ table.field("rights", port: true)
3219
+
3220
+ waypoint = "#{id}_rights"
3221
+ digraph.waypoint("#{waypoint};")
3222
+
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
3228
+
3229
+ # lparen_loc
3230
+ unless (lparen_loc = node.lparen_loc).nil?
3231
+ table.field("lparen_loc", location_inspect(lparen_loc))
3232
+ end
3233
+
3234
+ # rparen_loc
3235
+ unless (rparen_loc = node.rparen_loc).nil?
3236
+ table.field("rparen_loc", location_inspect(rparen_loc))
3237
+ end
3238
+
3239
+ digraph.nodes << <<~DOT
3240
+ #{id} [
3241
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3242
+ ];
3243
+ DOT
3244
+
3245
+ super
3246
+ end
3247
+
3248
+ # Visit a MultiWriteNode node.
3249
+ def visit_multi_write_node(node)
3250
+ table = Table.new("MultiWriteNode")
3251
+ id = node_id(node)
3252
+
3253
+ # lefts
3254
+ if node.lefts.any?
3255
+ table.field("lefts", port: true)
3256
+
3257
+ waypoint = "#{id}_lefts"
3258
+ digraph.waypoint("#{waypoint};")
3259
+
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
3265
+
3266
+ # rest
3267
+ unless (rest = node.rest).nil?
3268
+ table.field("rest", port: true)
3269
+ digraph.edge("#{id}:rest -> #{node_id(rest)};")
3270
+ end
3271
+
3272
+ # rights
3273
+ if node.rights.any?
3274
+ table.field("rights", port: true)
3275
+
3276
+ waypoint = "#{id}_rights"
3277
+ digraph.waypoint("#{waypoint};")
3278
+
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
3284
+
3285
+ # lparen_loc
3286
+ unless (lparen_loc = node.lparen_loc).nil?
3287
+ table.field("lparen_loc", location_inspect(lparen_loc))
3288
+ end
3289
+
3290
+ # rparen_loc
3291
+ unless (rparen_loc = node.rparen_loc).nil?
3292
+ table.field("rparen_loc", location_inspect(rparen_loc))
3293
+ end
3294
+
3295
+ # operator_loc
3296
+ table.field("operator_loc", location_inspect(node.operator_loc))
3297
+
3298
+ # value
3299
+ table.field("value", port: true)
3300
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
3301
+
3302
+ digraph.nodes << <<~DOT
3303
+ #{id} [
3304
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3305
+ ];
3306
+ DOT
3307
+
3308
+ super
3309
+ end
3310
+
3311
+ # Visit a NextNode node.
3312
+ def visit_next_node(node)
3313
+ table = Table.new("NextNode")
3314
+ id = node_id(node)
3315
+
3316
+ # arguments
3317
+ unless (arguments = node.arguments).nil?
3318
+ table.field("arguments", port: true)
3319
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
3320
+ end
3321
+
3322
+ # keyword_loc
3323
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
3324
+
3325
+ digraph.nodes << <<~DOT
3326
+ #{id} [
3327
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3328
+ ];
3329
+ DOT
3330
+
3331
+ super
3332
+ end
3333
+
3334
+ # Visit a NilNode node.
3335
+ def visit_nil_node(node)
3336
+ table = Table.new("NilNode")
3337
+ id = node_id(node)
3338
+
3339
+ digraph.nodes << <<~DOT
3340
+ #{id} [
3341
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3342
+ ];
3343
+ DOT
3344
+
3345
+ super
3346
+ end
3347
+
3348
+ # Visit a NoKeywordsParameterNode node.
3349
+ def visit_no_keywords_parameter_node(node)
3350
+ table = Table.new("NoKeywordsParameterNode")
3351
+ id = node_id(node)
3352
+
3353
+ # operator_loc
3354
+ table.field("operator_loc", location_inspect(node.operator_loc))
3355
+
3356
+ # keyword_loc
3357
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
3358
+
3359
+ digraph.nodes << <<~DOT
3360
+ #{id} [
3361
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3362
+ ];
3363
+ DOT
3364
+
3365
+ super
3366
+ end
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
+
3385
+ # Visit a NumberedReferenceReadNode node.
3386
+ def visit_numbered_reference_read_node(node)
3387
+ table = Table.new("NumberedReferenceReadNode")
3388
+ id = node_id(node)
3389
+
3390
+ # number
3391
+ table.field("number", node.number.inspect)
3392
+
3393
+ digraph.nodes << <<~DOT
3394
+ #{id} [
3395
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3396
+ ];
3397
+ DOT
3398
+
3399
+ super
3400
+ end
3401
+
3402
+ # Visit a OptionalKeywordParameterNode node.
3403
+ def visit_optional_keyword_parameter_node(node)
3404
+ table = Table.new("OptionalKeywordParameterNode")
3405
+ id = node_id(node)
3406
+
3407
+ # name
3408
+ table.field("name", node.name.inspect)
3409
+
3410
+ # name_loc
3411
+ table.field("name_loc", location_inspect(node.name_loc))
3412
+
3413
+ # value
3414
+ table.field("value", port: true)
3415
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
3416
+
3417
+ digraph.nodes << <<~DOT
3418
+ #{id} [
3419
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3420
+ ];
3421
+ DOT
3422
+
3423
+ super
3424
+ end
3425
+
3426
+ # Visit a OptionalParameterNode node.
3427
+ def visit_optional_parameter_node(node)
3428
+ table = Table.new("OptionalParameterNode")
3429
+ id = node_id(node)
3430
+
3431
+ # name
3432
+ table.field("name", node.name.inspect)
3433
+
3434
+ # name_loc
3435
+ table.field("name_loc", location_inspect(node.name_loc))
3436
+
3437
+ # operator_loc
3438
+ table.field("operator_loc", location_inspect(node.operator_loc))
3439
+
3440
+ # value
3441
+ table.field("value", port: true)
3442
+ digraph.edge("#{id}:value -> #{node_id(node.value)};")
3443
+
3444
+ digraph.nodes << <<~DOT
3445
+ #{id} [
3446
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3447
+ ];
3448
+ DOT
3449
+
3450
+ super
3451
+ end
3452
+
3453
+ # Visit a OrNode node.
3454
+ def visit_or_node(node)
3455
+ table = Table.new("OrNode")
3456
+ id = node_id(node)
3457
+
3458
+ # left
3459
+ table.field("left", port: true)
3460
+ digraph.edge("#{id}:left -> #{node_id(node.left)};")
3461
+
3462
+ # right
3463
+ table.field("right", port: true)
3464
+ digraph.edge("#{id}:right -> #{node_id(node.right)};")
3465
+
3466
+ # operator_loc
3467
+ table.field("operator_loc", location_inspect(node.operator_loc))
3468
+
3469
+ digraph.nodes << <<~DOT
3470
+ #{id} [
3471
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3472
+ ];
3473
+ DOT
3474
+
3475
+ super
3476
+ end
3477
+
3478
+ # Visit a ParametersNode node.
3479
+ def visit_parameters_node(node)
3480
+ table = Table.new("ParametersNode")
3481
+ id = node_id(node)
3482
+
3483
+ # requireds
3484
+ if node.requireds.any?
3485
+ table.field("requireds", port: true)
3486
+
3487
+ waypoint = "#{id}_requireds"
3488
+ digraph.waypoint("#{waypoint};")
3489
+
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
3495
+
3496
+ # optionals
3497
+ if node.optionals.any?
3498
+ table.field("optionals", port: true)
3499
+
3500
+ waypoint = "#{id}_optionals"
3501
+ digraph.waypoint("#{waypoint};")
3502
+
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
3508
+
3509
+ # rest
3510
+ unless (rest = node.rest).nil?
3511
+ table.field("rest", port: true)
3512
+ digraph.edge("#{id}:rest -> #{node_id(rest)};")
3513
+ end
3514
+
3515
+ # posts
3516
+ if node.posts.any?
3517
+ table.field("posts", port: true)
3518
+
3519
+ waypoint = "#{id}_posts"
3520
+ digraph.waypoint("#{waypoint};")
3521
+
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
3527
+
3528
+ # keywords
3529
+ if node.keywords.any?
3530
+ table.field("keywords", port: true)
3531
+
3532
+ waypoint = "#{id}_keywords"
3533
+ digraph.waypoint("#{waypoint};")
3534
+
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
3540
+
3541
+ # keyword_rest
3542
+ unless (keyword_rest = node.keyword_rest).nil?
3543
+ table.field("keyword_rest", port: true)
3544
+ digraph.edge("#{id}:keyword_rest -> #{node_id(keyword_rest)};")
3545
+ end
3546
+
3547
+ # block
3548
+ unless (block = node.block).nil?
3549
+ table.field("block", port: true)
3550
+ digraph.edge("#{id}:block -> #{node_id(block)};")
3551
+ end
3552
+
3553
+ digraph.nodes << <<~DOT
3554
+ #{id} [
3555
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3556
+ ];
3557
+ DOT
3558
+
3559
+ super
3560
+ end
3561
+
3562
+ # Visit a ParenthesesNode node.
3563
+ def visit_parentheses_node(node)
3564
+ table = Table.new("ParenthesesNode")
3565
+ id = node_id(node)
3566
+
3567
+ # body
3568
+ unless (body = node.body).nil?
3569
+ table.field("body", port: true)
3570
+ digraph.edge("#{id}:body -> #{node_id(body)};")
3571
+ end
3572
+
3573
+ # opening_loc
3574
+ table.field("opening_loc", location_inspect(node.opening_loc))
3575
+
3576
+ # closing_loc
3577
+ table.field("closing_loc", location_inspect(node.closing_loc))
3578
+
3579
+ digraph.nodes << <<~DOT
3580
+ #{id} [
3581
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3582
+ ];
3583
+ DOT
3584
+
3585
+ super
3586
+ end
3587
+
3588
+ # Visit a PinnedExpressionNode node.
3589
+ def visit_pinned_expression_node(node)
3590
+ table = Table.new("PinnedExpressionNode")
3591
+ id = node_id(node)
3592
+
3593
+ # expression
3594
+ table.field("expression", port: true)
3595
+ digraph.edge("#{id}:expression -> #{node_id(node.expression)};")
3596
+
3597
+ # operator_loc
3598
+ table.field("operator_loc", location_inspect(node.operator_loc))
3599
+
3600
+ # lparen_loc
3601
+ table.field("lparen_loc", location_inspect(node.lparen_loc))
3602
+
3603
+ # rparen_loc
3604
+ table.field("rparen_loc", location_inspect(node.rparen_loc))
3605
+
3606
+ digraph.nodes << <<~DOT
3607
+ #{id} [
3608
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3609
+ ];
3610
+ DOT
3611
+
3612
+ super
3613
+ end
3614
+
3615
+ # Visit a PinnedVariableNode node.
3616
+ def visit_pinned_variable_node(node)
3617
+ table = Table.new("PinnedVariableNode")
3618
+ id = node_id(node)
3619
+
3620
+ # variable
3621
+ table.field("variable", port: true)
3622
+ digraph.edge("#{id}:variable -> #{node_id(node.variable)};")
3623
+
3624
+ # operator_loc
3625
+ table.field("operator_loc", location_inspect(node.operator_loc))
3626
+
3627
+ digraph.nodes << <<~DOT
3628
+ #{id} [
3629
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3630
+ ];
3631
+ DOT
3632
+
3633
+ super
3634
+ end
3635
+
3636
+ # Visit a PostExecutionNode node.
3637
+ def visit_post_execution_node(node)
3638
+ table = Table.new("PostExecutionNode")
3639
+ id = node_id(node)
3640
+
3641
+ # statements
3642
+ unless (statements = node.statements).nil?
3643
+ table.field("statements", port: true)
3644
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
3645
+ end
3646
+
3647
+ # keyword_loc
3648
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
3649
+
3650
+ # opening_loc
3651
+ table.field("opening_loc", location_inspect(node.opening_loc))
3652
+
3653
+ # closing_loc
3654
+ table.field("closing_loc", location_inspect(node.closing_loc))
3655
+
3656
+ digraph.nodes << <<~DOT
3657
+ #{id} [
3658
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3659
+ ];
3660
+ DOT
3661
+
3662
+ super
3663
+ end
3664
+
3665
+ # Visit a PreExecutionNode node.
3666
+ def visit_pre_execution_node(node)
3667
+ table = Table.new("PreExecutionNode")
3668
+ id = node_id(node)
3669
+
3670
+ # statements
3671
+ unless (statements = node.statements).nil?
3672
+ table.field("statements", port: true)
3673
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
3674
+ end
3675
+
3676
+ # keyword_loc
3677
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
3678
+
3679
+ # opening_loc
3680
+ table.field("opening_loc", location_inspect(node.opening_loc))
3681
+
3682
+ # closing_loc
3683
+ table.field("closing_loc", location_inspect(node.closing_loc))
3684
+
3685
+ digraph.nodes << <<~DOT
3686
+ #{id} [
3687
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3688
+ ];
3689
+ DOT
3690
+
3691
+ super
3692
+ end
3693
+
3694
+ # Visit a ProgramNode node.
3695
+ def visit_program_node(node)
3696
+ table = Table.new("ProgramNode")
3697
+ id = node_id(node)
3698
+
3699
+ # locals
3700
+ table.field("locals", node.locals.inspect)
3701
+
3702
+ # statements
3703
+ table.field("statements", port: true)
3704
+ digraph.edge("#{id}:statements -> #{node_id(node.statements)};")
3705
+
3706
+ digraph.nodes << <<~DOT
3707
+ #{id} [
3708
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3709
+ ];
3710
+ DOT
3711
+
3712
+ super
3713
+ end
3714
+
3715
+ # Visit a RangeNode node.
3716
+ def visit_range_node(node)
3717
+ table = Table.new("RangeNode")
3718
+ id = node_id(node)
3719
+
3720
+ # flags
3721
+ table.field("flags", range_flags_inspect(node))
3722
+
3723
+ # left
3724
+ unless (left = node.left).nil?
3725
+ table.field("left", port: true)
3726
+ digraph.edge("#{id}:left -> #{node_id(left)};")
3727
+ end
3728
+
3729
+ # right
3730
+ unless (right = node.right).nil?
3731
+ table.field("right", port: true)
3732
+ digraph.edge("#{id}:right -> #{node_id(right)};")
3733
+ end
3734
+
3735
+ # operator_loc
3736
+ table.field("operator_loc", location_inspect(node.operator_loc))
3737
+
3738
+ digraph.nodes << <<~DOT
3739
+ #{id} [
3740
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3741
+ ];
3742
+ DOT
3743
+
3744
+ super
3745
+ end
3746
+
3747
+ # Visit a RationalNode node.
3748
+ def visit_rational_node(node)
3749
+ table = Table.new("RationalNode")
3750
+ id = node_id(node)
3751
+
3752
+ # numeric
3753
+ table.field("numeric", port: true)
3754
+ digraph.edge("#{id}:numeric -> #{node_id(node.numeric)};")
3755
+
3756
+ digraph.nodes << <<~DOT
3757
+ #{id} [
3758
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3759
+ ];
3760
+ DOT
3761
+
3762
+ super
3763
+ end
3764
+
3765
+ # Visit a RedoNode node.
3766
+ def visit_redo_node(node)
3767
+ table = Table.new("RedoNode")
3768
+ id = node_id(node)
3769
+
3770
+ digraph.nodes << <<~DOT
3771
+ #{id} [
3772
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3773
+ ];
3774
+ DOT
3775
+
3776
+ super
3777
+ end
3778
+
3779
+ # Visit a RegularExpressionNode node.
3780
+ def visit_regular_expression_node(node)
3781
+ table = Table.new("RegularExpressionNode")
3782
+ id = node_id(node)
3783
+
3784
+ # flags
3785
+ table.field("flags", regular_expression_flags_inspect(node))
3786
+
3787
+ # opening_loc
3788
+ table.field("opening_loc", location_inspect(node.opening_loc))
3789
+
3790
+ # content_loc
3791
+ table.field("content_loc", location_inspect(node.content_loc))
3792
+
3793
+ # closing_loc
3794
+ table.field("closing_loc", location_inspect(node.closing_loc))
3795
+
3796
+ # unescaped
3797
+ table.field("unescaped", node.unescaped.inspect)
3798
+
3799
+ digraph.nodes << <<~DOT
3800
+ #{id} [
3801
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3802
+ ];
3803
+ DOT
3804
+
3805
+ super
3806
+ end
3807
+
3808
+ # Visit a RequiredKeywordParameterNode node.
3809
+ def visit_required_keyword_parameter_node(node)
3810
+ table = Table.new("RequiredKeywordParameterNode")
3811
+ id = node_id(node)
3812
+
3813
+ # name
3814
+ table.field("name", node.name.inspect)
3815
+
3816
+ # name_loc
3817
+ table.field("name_loc", location_inspect(node.name_loc))
3818
+
3819
+ digraph.nodes << <<~DOT
3820
+ #{id} [
3821
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3822
+ ];
3823
+ DOT
3824
+
3825
+ super
3826
+ end
3827
+
3828
+ # Visit a RequiredParameterNode node.
3829
+ def visit_required_parameter_node(node)
3830
+ table = Table.new("RequiredParameterNode")
3831
+ id = node_id(node)
3832
+
3833
+ # name
3834
+ table.field("name", node.name.inspect)
3835
+
3836
+ digraph.nodes << <<~DOT
3837
+ #{id} [
3838
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3839
+ ];
3840
+ DOT
3841
+
3842
+ super
3843
+ end
3844
+
3845
+ # Visit a RescueModifierNode node.
3846
+ def visit_rescue_modifier_node(node)
3847
+ table = Table.new("RescueModifierNode")
3848
+ id = node_id(node)
3849
+
3850
+ # expression
3851
+ table.field("expression", port: true)
3852
+ digraph.edge("#{id}:expression -> #{node_id(node.expression)};")
3853
+
3854
+ # keyword_loc
3855
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
3856
+
3857
+ # rescue_expression
3858
+ table.field("rescue_expression", port: true)
3859
+ digraph.edge("#{id}:rescue_expression -> #{node_id(node.rescue_expression)};")
3860
+
3861
+ digraph.nodes << <<~DOT
3862
+ #{id} [
3863
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3864
+ ];
3865
+ DOT
3866
+
3867
+ super
3868
+ end
3869
+
3870
+ # Visit a RescueNode node.
3871
+ def visit_rescue_node(node)
3872
+ table = Table.new("RescueNode")
3873
+ id = node_id(node)
3874
+
3875
+ # keyword_loc
3876
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
3877
+
3878
+ # exceptions
3879
+ if node.exceptions.any?
3880
+ table.field("exceptions", port: true)
3881
+
3882
+ waypoint = "#{id}_exceptions"
3883
+ digraph.waypoint("#{waypoint};")
3884
+
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
3890
+
3891
+ # operator_loc
3892
+ unless (operator_loc = node.operator_loc).nil?
3893
+ table.field("operator_loc", location_inspect(operator_loc))
3894
+ end
3895
+
3896
+ # reference
3897
+ unless (reference = node.reference).nil?
3898
+ table.field("reference", port: true)
3899
+ digraph.edge("#{id}:reference -> #{node_id(reference)};")
3900
+ end
3901
+
3902
+ # statements
3903
+ unless (statements = node.statements).nil?
3904
+ table.field("statements", port: true)
3905
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
3906
+ end
3907
+
3908
+ # consequent
3909
+ unless (consequent = node.consequent).nil?
3910
+ table.field("consequent", port: true)
3911
+ digraph.edge("#{id}:consequent -> #{node_id(consequent)};")
3912
+ end
3913
+
3914
+ digraph.nodes << <<~DOT
3915
+ #{id} [
3916
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3917
+ ];
3918
+ DOT
3919
+
3920
+ super
3921
+ end
3922
+
3923
+ # Visit a RestParameterNode node.
3924
+ def visit_rest_parameter_node(node)
3925
+ table = Table.new("RestParameterNode")
3926
+ id = node_id(node)
3927
+
3928
+ # name
3929
+ table.field("name", node.name.inspect)
3930
+
3931
+ # name_loc
3932
+ unless (name_loc = node.name_loc).nil?
3933
+ table.field("name_loc", location_inspect(name_loc))
3934
+ end
3935
+
3936
+ # operator_loc
3937
+ table.field("operator_loc", location_inspect(node.operator_loc))
3938
+
3939
+ digraph.nodes << <<~DOT
3940
+ #{id} [
3941
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3942
+ ];
3943
+ DOT
3944
+
3945
+ super
3946
+ end
3947
+
3948
+ # Visit a RetryNode node.
3949
+ def visit_retry_node(node)
3950
+ table = Table.new("RetryNode")
3951
+ id = node_id(node)
3952
+
3953
+ digraph.nodes << <<~DOT
3954
+ #{id} [
3955
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3956
+ ];
3957
+ DOT
3958
+
3959
+ super
3960
+ end
3961
+
3962
+ # Visit a ReturnNode node.
3963
+ def visit_return_node(node)
3964
+ table = Table.new("ReturnNode")
3965
+ id = node_id(node)
3966
+
3967
+ # keyword_loc
3968
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
3969
+
3970
+ # arguments
3971
+ unless (arguments = node.arguments).nil?
3972
+ table.field("arguments", port: true)
3973
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
3974
+ end
3975
+
3976
+ digraph.nodes << <<~DOT
3977
+ #{id} [
3978
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3979
+ ];
3980
+ DOT
3981
+
3982
+ super
3983
+ end
3984
+
3985
+ # Visit a SelfNode node.
3986
+ def visit_self_node(node)
3987
+ table = Table.new("SelfNode")
3988
+ id = node_id(node)
3989
+
3990
+ digraph.nodes << <<~DOT
3991
+ #{id} [
3992
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
3993
+ ];
3994
+ DOT
3995
+
3996
+ super
3997
+ end
3998
+
3999
+ # Visit a SingletonClassNode node.
4000
+ def visit_singleton_class_node(node)
4001
+ table = Table.new("SingletonClassNode")
4002
+ id = node_id(node)
4003
+
4004
+ # locals
4005
+ table.field("locals", node.locals.inspect)
4006
+
4007
+ # class_keyword_loc
4008
+ table.field("class_keyword_loc", location_inspect(node.class_keyword_loc))
4009
+
4010
+ # operator_loc
4011
+ table.field("operator_loc", location_inspect(node.operator_loc))
4012
+
4013
+ # expression
4014
+ table.field("expression", port: true)
4015
+ digraph.edge("#{id}:expression -> #{node_id(node.expression)};")
4016
+
4017
+ # body
4018
+ unless (body = node.body).nil?
4019
+ table.field("body", port: true)
4020
+ digraph.edge("#{id}:body -> #{node_id(body)};")
4021
+ end
4022
+
4023
+ # end_keyword_loc
4024
+ table.field("end_keyword_loc", location_inspect(node.end_keyword_loc))
4025
+
4026
+ digraph.nodes << <<~DOT
4027
+ #{id} [
4028
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4029
+ ];
4030
+ DOT
4031
+
4032
+ super
4033
+ end
4034
+
4035
+ # Visit a SourceEncodingNode node.
4036
+ def visit_source_encoding_node(node)
4037
+ table = Table.new("SourceEncodingNode")
4038
+ id = node_id(node)
4039
+
4040
+ digraph.nodes << <<~DOT
4041
+ #{id} [
4042
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4043
+ ];
4044
+ DOT
4045
+
4046
+ super
4047
+ end
4048
+
4049
+ # Visit a SourceFileNode node.
4050
+ def visit_source_file_node(node)
4051
+ table = Table.new("SourceFileNode")
4052
+ id = node_id(node)
4053
+
4054
+ # filepath
4055
+ table.field("filepath", node.filepath.inspect)
4056
+
4057
+ digraph.nodes << <<~DOT
4058
+ #{id} [
4059
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4060
+ ];
4061
+ DOT
4062
+
4063
+ super
4064
+ end
4065
+
4066
+ # Visit a SourceLineNode node.
4067
+ def visit_source_line_node(node)
4068
+ table = Table.new("SourceLineNode")
4069
+ id = node_id(node)
4070
+
4071
+ digraph.nodes << <<~DOT
4072
+ #{id} [
4073
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4074
+ ];
4075
+ DOT
4076
+
4077
+ super
4078
+ end
4079
+
4080
+ # Visit a SplatNode node.
4081
+ def visit_splat_node(node)
4082
+ table = Table.new("SplatNode")
4083
+ id = node_id(node)
4084
+
4085
+ # operator_loc
4086
+ table.field("operator_loc", location_inspect(node.operator_loc))
4087
+
4088
+ # expression
4089
+ unless (expression = node.expression).nil?
4090
+ table.field("expression", port: true)
4091
+ digraph.edge("#{id}:expression -> #{node_id(expression)};")
4092
+ end
4093
+
4094
+ digraph.nodes << <<~DOT
4095
+ #{id} [
4096
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4097
+ ];
4098
+ DOT
4099
+
4100
+ super
4101
+ end
4102
+
4103
+ # Visit a StatementsNode node.
4104
+ def visit_statements_node(node)
4105
+ table = Table.new("StatementsNode")
4106
+ id = node_id(node)
4107
+
4108
+ # body
4109
+ if node.body.any?
4110
+ table.field("body", port: true)
4111
+
4112
+ waypoint = "#{id}_body"
4113
+ digraph.waypoint("#{waypoint};")
4114
+
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
4120
+
4121
+ digraph.nodes << <<~DOT
4122
+ #{id} [
4123
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4124
+ ];
4125
+ DOT
4126
+
4127
+ super
4128
+ end
4129
+
4130
+ # Visit a StringNode node.
4131
+ def visit_string_node(node)
4132
+ table = Table.new("StringNode")
4133
+ id = node_id(node)
4134
+
4135
+ # flags
4136
+ table.field("flags", string_flags_inspect(node))
4137
+
4138
+ # opening_loc
4139
+ unless (opening_loc = node.opening_loc).nil?
4140
+ table.field("opening_loc", location_inspect(opening_loc))
4141
+ end
4142
+
4143
+ # content_loc
4144
+ table.field("content_loc", location_inspect(node.content_loc))
4145
+
4146
+ # closing_loc
4147
+ unless (closing_loc = node.closing_loc).nil?
4148
+ table.field("closing_loc", location_inspect(closing_loc))
4149
+ end
4150
+
4151
+ # unescaped
4152
+ table.field("unescaped", node.unescaped.inspect)
4153
+
4154
+ digraph.nodes << <<~DOT
4155
+ #{id} [
4156
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4157
+ ];
4158
+ DOT
4159
+
4160
+ super
4161
+ end
4162
+
4163
+ # Visit a SuperNode node.
4164
+ def visit_super_node(node)
4165
+ table = Table.new("SuperNode")
4166
+ id = node_id(node)
4167
+
4168
+ # keyword_loc
4169
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
4170
+
4171
+ # lparen_loc
4172
+ unless (lparen_loc = node.lparen_loc).nil?
4173
+ table.field("lparen_loc", location_inspect(lparen_loc))
4174
+ end
4175
+
4176
+ # arguments
4177
+ unless (arguments = node.arguments).nil?
4178
+ table.field("arguments", port: true)
4179
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
4180
+ end
4181
+
4182
+ # rparen_loc
4183
+ unless (rparen_loc = node.rparen_loc).nil?
4184
+ table.field("rparen_loc", location_inspect(rparen_loc))
4185
+ end
4186
+
4187
+ # block
4188
+ unless (block = node.block).nil?
4189
+ table.field("block", port: true)
4190
+ digraph.edge("#{id}:block -> #{node_id(block)};")
4191
+ end
4192
+
4193
+ digraph.nodes << <<~DOT
4194
+ #{id} [
4195
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4196
+ ];
4197
+ DOT
4198
+
4199
+ super
4200
+ end
4201
+
4202
+ # Visit a SymbolNode node.
4203
+ def visit_symbol_node(node)
4204
+ table = Table.new("SymbolNode")
4205
+ id = node_id(node)
4206
+
4207
+ # flags
4208
+ table.field("flags", symbol_flags_inspect(node))
4209
+
4210
+ # opening_loc
4211
+ unless (opening_loc = node.opening_loc).nil?
4212
+ table.field("opening_loc", location_inspect(opening_loc))
4213
+ end
4214
+
4215
+ # value_loc
4216
+ unless (value_loc = node.value_loc).nil?
4217
+ table.field("value_loc", location_inspect(value_loc))
4218
+ end
4219
+
4220
+ # closing_loc
4221
+ unless (closing_loc = node.closing_loc).nil?
4222
+ table.field("closing_loc", location_inspect(closing_loc))
4223
+ end
4224
+
4225
+ # unescaped
4226
+ table.field("unescaped", node.unescaped.inspect)
4227
+
4228
+ digraph.nodes << <<~DOT
4229
+ #{id} [
4230
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4231
+ ];
4232
+ DOT
4233
+
4234
+ super
4235
+ end
4236
+
4237
+ # Visit a TrueNode node.
4238
+ def visit_true_node(node)
4239
+ table = Table.new("TrueNode")
4240
+ id = node_id(node)
4241
+
4242
+ digraph.nodes << <<~DOT
4243
+ #{id} [
4244
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4245
+ ];
4246
+ DOT
4247
+
4248
+ super
4249
+ end
4250
+
4251
+ # Visit a UndefNode node.
4252
+ def visit_undef_node(node)
4253
+ table = Table.new("UndefNode")
4254
+ id = node_id(node)
4255
+
4256
+ # names
4257
+ if node.names.any?
4258
+ table.field("names", port: true)
4259
+
4260
+ waypoint = "#{id}_names"
4261
+ digraph.waypoint("#{waypoint};")
4262
+
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
4268
+
4269
+ # keyword_loc
4270
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
4271
+
4272
+ digraph.nodes << <<~DOT
4273
+ #{id} [
4274
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4275
+ ];
4276
+ DOT
4277
+
4278
+ super
4279
+ end
4280
+
4281
+ # Visit a UnlessNode node.
4282
+ def visit_unless_node(node)
4283
+ table = Table.new("UnlessNode")
4284
+ id = node_id(node)
4285
+
4286
+ # keyword_loc
4287
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
4288
+
4289
+ # predicate
4290
+ table.field("predicate", port: true)
4291
+ digraph.edge("#{id}:predicate -> #{node_id(node.predicate)};")
4292
+
4293
+ # then_keyword_loc
4294
+ unless (then_keyword_loc = node.then_keyword_loc).nil?
4295
+ table.field("then_keyword_loc", location_inspect(then_keyword_loc))
4296
+ end
4297
+
4298
+ # statements
4299
+ unless (statements = node.statements).nil?
4300
+ table.field("statements", port: true)
4301
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
4302
+ end
4303
+
4304
+ # consequent
4305
+ unless (consequent = node.consequent).nil?
4306
+ table.field("consequent", port: true)
4307
+ digraph.edge("#{id}:consequent -> #{node_id(consequent)};")
4308
+ end
4309
+
4310
+ # end_keyword_loc
4311
+ unless (end_keyword_loc = node.end_keyword_loc).nil?
4312
+ table.field("end_keyword_loc", location_inspect(end_keyword_loc))
4313
+ end
4314
+
4315
+ digraph.nodes << <<~DOT
4316
+ #{id} [
4317
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4318
+ ];
4319
+ DOT
4320
+
4321
+ super
4322
+ end
4323
+
4324
+ # Visit a UntilNode node.
4325
+ def visit_until_node(node)
4326
+ table = Table.new("UntilNode")
4327
+ id = node_id(node)
4328
+
4329
+ # flags
4330
+ table.field("flags", loop_flags_inspect(node))
4331
+
4332
+ # keyword_loc
4333
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
4334
+
4335
+ # closing_loc
4336
+ unless (closing_loc = node.closing_loc).nil?
4337
+ table.field("closing_loc", location_inspect(closing_loc))
4338
+ end
4339
+
4340
+ # predicate
4341
+ table.field("predicate", port: true)
4342
+ digraph.edge("#{id}:predicate -> #{node_id(node.predicate)};")
4343
+
4344
+ # statements
4345
+ unless (statements = node.statements).nil?
4346
+ table.field("statements", port: true)
4347
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
4348
+ end
4349
+
4350
+ digraph.nodes << <<~DOT
4351
+ #{id} [
4352
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4353
+ ];
4354
+ DOT
4355
+
4356
+ super
4357
+ end
4358
+
4359
+ # Visit a WhenNode node.
4360
+ def visit_when_node(node)
4361
+ table = Table.new("WhenNode")
4362
+ id = node_id(node)
4363
+
4364
+ # keyword_loc
4365
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
4366
+
4367
+ # conditions
4368
+ if node.conditions.any?
4369
+ table.field("conditions", port: true)
4370
+
4371
+ waypoint = "#{id}_conditions"
4372
+ digraph.waypoint("#{waypoint};")
4373
+
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
4379
+
4380
+ # statements
4381
+ unless (statements = node.statements).nil?
4382
+ table.field("statements", port: true)
4383
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
4384
+ end
4385
+
4386
+ digraph.nodes << <<~DOT
4387
+ #{id} [
4388
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4389
+ ];
4390
+ DOT
4391
+
4392
+ super
4393
+ end
4394
+
4395
+ # Visit a WhileNode node.
4396
+ def visit_while_node(node)
4397
+ table = Table.new("WhileNode")
4398
+ id = node_id(node)
4399
+
4400
+ # flags
4401
+ table.field("flags", loop_flags_inspect(node))
4402
+
4403
+ # keyword_loc
4404
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
4405
+
4406
+ # closing_loc
4407
+ unless (closing_loc = node.closing_loc).nil?
4408
+ table.field("closing_loc", location_inspect(closing_loc))
4409
+ end
4410
+
4411
+ # predicate
4412
+ table.field("predicate", port: true)
4413
+ digraph.edge("#{id}:predicate -> #{node_id(node.predicate)};")
4414
+
4415
+ # statements
4416
+ unless (statements = node.statements).nil?
4417
+ table.field("statements", port: true)
4418
+ digraph.edge("#{id}:statements -> #{node_id(statements)};")
4419
+ end
4420
+
4421
+ digraph.nodes << <<~DOT
4422
+ #{id} [
4423
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4424
+ ];
4425
+ DOT
4426
+
4427
+ super
4428
+ end
4429
+
4430
+ # Visit a XStringNode node.
4431
+ def visit_x_string_node(node)
4432
+ table = Table.new("XStringNode")
4433
+ id = node_id(node)
4434
+
4435
+ # flags
4436
+ table.field("flags", encoding_flags_inspect(node))
4437
+
4438
+ # opening_loc
4439
+ table.field("opening_loc", location_inspect(node.opening_loc))
4440
+
4441
+ # content_loc
4442
+ table.field("content_loc", location_inspect(node.content_loc))
4443
+
4444
+ # closing_loc
4445
+ table.field("closing_loc", location_inspect(node.closing_loc))
4446
+
4447
+ # unescaped
4448
+ table.field("unescaped", node.unescaped.inspect)
4449
+
4450
+ digraph.nodes << <<~DOT
4451
+ #{id} [
4452
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4453
+ ];
4454
+ DOT
4455
+
4456
+ super
4457
+ end
4458
+
4459
+ # Visit a YieldNode node.
4460
+ def visit_yield_node(node)
4461
+ table = Table.new("YieldNode")
4462
+ id = node_id(node)
4463
+
4464
+ # keyword_loc
4465
+ table.field("keyword_loc", location_inspect(node.keyword_loc))
4466
+
4467
+ # lparen_loc
4468
+ unless (lparen_loc = node.lparen_loc).nil?
4469
+ table.field("lparen_loc", location_inspect(lparen_loc))
4470
+ end
4471
+
4472
+ # arguments
4473
+ unless (arguments = node.arguments).nil?
4474
+ table.field("arguments", port: true)
4475
+ digraph.edge("#{id}:arguments -> #{node_id(arguments)};")
4476
+ end
4477
+
4478
+ # rparen_loc
4479
+ unless (rparen_loc = node.rparen_loc).nil?
4480
+ table.field("rparen_loc", location_inspect(rparen_loc))
4481
+ end
4482
+
4483
+ digraph.nodes << <<~DOT
4484
+ #{id} [
4485
+ label=<#{table.to_dot.gsub(/\n/, "\n ")}>
4486
+ ];
4487
+ DOT
4488
+
4489
+ super
4490
+ end
4491
+
4492
+ private
4493
+
4494
+ # Generate a unique node ID for a node throughout the digraph.
4495
+ def node_id(node)
4496
+ "Node_#{node.object_id}"
4497
+ end
4498
+
4499
+ # Inspect a location to display the start and end line and column numbers.
4500
+ def location_inspect(location)
4501
+ "(#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column})"
4502
+ end
4503
+
4504
+ # Inspect a node that has arguments_node_flags flags to display the flags as a
4505
+ # comma-separated list.
4506
+ def arguments_node_flags_inspect(node)
4507
+ flags = []
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?
4517
+ flags.join(", ")
4518
+ end
4519
+
4520
+ # Inspect a node that has call_node_flags flags to display the flags as a
4521
+ # comma-separated list.
4522
+ def call_node_flags_inspect(node)
4523
+ flags = []
4524
+ flags << "safe_navigation" if node.safe_navigation?
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?
4536
+ flags.join(", ")
4537
+ end
4538
+
4539
+ # Inspect a node that has integer_base_flags flags to display the flags as a
4540
+ # comma-separated list.
4541
+ def integer_base_flags_inspect(node)
4542
+ flags = []
4543
+ flags << "binary" if node.binary?
4544
+ flags << "decimal" if node.decimal?
4545
+ flags << "octal" if node.octal?
4546
+ flags << "hexadecimal" if node.hexadecimal?
4547
+ flags.join(", ")
4548
+ end
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
+
4558
+ # Inspect a node that has loop_flags flags to display the flags as a
4559
+ # comma-separated list.
4560
+ def loop_flags_inspect(node)
4561
+ flags = []
4562
+ flags << "begin_modifier" if node.begin_modifier?
4563
+ flags.join(", ")
4564
+ end
4565
+
4566
+ # Inspect a node that has range_flags flags to display the flags as a
4567
+ # comma-separated list.
4568
+ def range_flags_inspect(node)
4569
+ flags = []
4570
+ flags << "exclude_end" if node.exclude_end?
4571
+ flags.join(", ")
4572
+ end
4573
+
4574
+ # Inspect a node that has regular_expression_flags flags to display the flags as a
4575
+ # comma-separated list.
4576
+ def regular_expression_flags_inspect(node)
4577
+ flags = []
4578
+ flags << "ignore_case" if node.ignore_case?
4579
+ flags << "extended" if node.extended?
4580
+ flags << "multi_line" if node.multi_line?
4581
+ flags << "once" if node.once?
4582
+ flags << "euc_jp" if node.euc_jp?
4583
+ flags << "ascii_8bit" if node.ascii_8bit?
4584
+ flags << "windows_31j" if node.windows_31j?
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?
4589
+ flags.join(", ")
4590
+ end
4591
+
4592
+ # Inspect a node that has string_flags flags to display the flags as a
4593
+ # comma-separated list.
4594
+ def string_flags_inspect(node)
4595
+ flags = []
4596
+ flags << "forced_utf8_encoding" if node.forced_utf8_encoding?
4597
+ flags << "forced_binary_encoding" if node.forced_binary_encoding?
4598
+ flags << "frozen" if node.frozen?
4599
+ flags.join(", ")
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
4611
+ end
4612
+ end