prism 0.17.1 → 0.19.0

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