prism 0.27.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/config.yml +39 -27
  4. data/docs/configuration.md +1 -0
  5. data/ext/prism/api_node.c +814 -807
  6. data/ext/prism/extension.c +5 -3
  7. data/ext/prism/extension.h +1 -1
  8. data/include/prism/ast.h +38 -16
  9. data/include/prism/diagnostic.h +12 -5
  10. data/include/prism/options.h +2 -2
  11. data/include/prism/parser.h +10 -0
  12. data/include/prism/static_literals.h +8 -6
  13. data/include/prism/version.h +2 -2
  14. data/lib/prism/dot_visitor.rb +22 -6
  15. data/lib/prism/dsl.rb +8 -8
  16. data/lib/prism/ffi.rb +3 -3
  17. data/lib/prism/inspect_visitor.rb +2156 -0
  18. data/lib/prism/lex_compat.rb +1 -1
  19. data/lib/prism/mutation_compiler.rb +2 -2
  20. data/lib/prism/node.rb +589 -1715
  21. data/lib/prism/node_ext.rb +34 -5
  22. data/lib/prism/parse_result.rb +78 -0
  23. data/lib/prism/pattern.rb +12 -6
  24. data/lib/prism/polyfill/byteindex.rb +13 -0
  25. data/lib/prism/polyfill/unpack1.rb +14 -0
  26. data/lib/prism/reflection.rb +13 -13
  27. data/lib/prism/serialize.rb +21 -14
  28. data/lib/prism/translation/parser/compiler.rb +2 -2
  29. data/lib/prism/translation/parser.rb +6 -6
  30. data/lib/prism/translation/ripper.rb +13 -9
  31. data/lib/prism/translation/ruby_parser.rb +4 -4
  32. data/lib/prism.rb +2 -1
  33. data/prism.gemspec +36 -38
  34. data/rbi/prism/compiler.rbi +3 -5
  35. data/rbi/prism/inspect_visitor.rbi +12 -0
  36. data/rbi/prism/node.rbi +354 -319
  37. data/rbi/prism/parse_result.rbi +23 -0
  38. data/rbi/prism/translation/ripper.rbi +1 -11
  39. data/sig/prism/dsl.rbs +3 -3
  40. data/sig/prism/inspect_visitor.rbs +22 -0
  41. data/sig/prism/node.rbs +64 -47
  42. data/sig/prism/parse_result.rbs +12 -0
  43. data/src/diagnostic.c +38 -24
  44. data/src/node.c +41 -16
  45. data/src/options.c +2 -2
  46. data/src/prettyprint.c +61 -18
  47. data/src/prism.c +607 -185
  48. data/src/serialize.c +5 -2
  49. data/src/static_literals.c +120 -34
  50. data/src/token_type.c +4 -4
  51. metadata +7 -9
  52. data/lib/prism/node_inspector.rb +0 -68
  53. data/lib/prism/polyfill/string.rb +0 -12
  54. data/rbi/prism/desugar_compiler.rbi +0 -5
  55. data/rbi/prism/mutation_compiler.rbi +0 -5
  56. data/rbi/prism/translation/parser/compiler.rbi +0 -13
  57. data/rbi/prism/translation/ripper/ripper_compiler.rbi +0 -5
  58. data/rbi/prism/translation/ruby_parser.rbi +0 -11
@@ -0,0 +1,2156 @@
1
+ # frozen_string_literal: true
2
+
3
+ =begin
4
+ This file is generated by the templates/template.rb script and should not be
5
+ modified manually. See templates/lib/prism/inspect_visitor.rb.erb
6
+ if you are looking to modify the template
7
+ =end
8
+
9
+ module Prism
10
+ # This visitor is responsible for composing the strings that get returned by
11
+ # the various #inspect methods defined on each of the nodes.
12
+ class InspectVisitor < Visitor
13
+ # Most of the time, we can simply pass down the indent to the next node.
14
+ # However, when we are inside a list we want some extra special formatting
15
+ # when we hit an element in that list. In this case, we have a special
16
+ # command that replaces the subsequent indent with the given value.
17
+ class Replace # :nodoc:
18
+ attr_reader :value
19
+
20
+ def initialize(value)
21
+ @value = value
22
+ end
23
+ end
24
+
25
+ private_constant :Replace
26
+
27
+ # The current prefix string.
28
+ attr_reader :indent
29
+
30
+ # The list of commands that we need to execute in order to compose the
31
+ # final string.
32
+ attr_reader :commands
33
+
34
+ # Initializes a new instance of the InspectVisitor.
35
+ def initialize(indent = +"")
36
+ @indent = indent
37
+ @commands = []
38
+ end
39
+
40
+ # Compose an inspect string for the given node.
41
+ def self.compose(node)
42
+ visitor = new
43
+ node.accept(visitor)
44
+ visitor.compose
45
+ end
46
+
47
+ # Compose the final string.
48
+ def compose
49
+ buffer = +""
50
+ replace = nil
51
+
52
+ until commands.empty?
53
+ # @type var command: String | node | Replace
54
+ # @type var indent: String
55
+ command, indent = *commands.shift
56
+
57
+ case command
58
+ when String
59
+ buffer << (replace || indent)
60
+ buffer << command
61
+ replace = nil
62
+ when Node
63
+ visitor = InspectVisitor.new(indent)
64
+ command.accept(visitor)
65
+ @commands = [*visitor.commands, *@commands]
66
+ when Replace
67
+ replace = command.value
68
+ else
69
+ raise "Unknown command: #{command.inspect}"
70
+ end
71
+ end
72
+
73
+ buffer
74
+ end
75
+
76
+ # Inspect a AliasGlobalVariableNode node.
77
+ def visit_alias_global_variable_node(node)
78
+ commands << [inspect_node("AliasGlobalVariableNode", node), indent]
79
+ commands << ["├── new_name:\n", indent]
80
+ commands << [node.new_name, "#{indent}│ "]
81
+ commands << ["├── old_name:\n", indent]
82
+ commands << [node.old_name, "#{indent}│ "]
83
+ commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
84
+ end
85
+
86
+ # Inspect a AliasMethodNode node.
87
+ def visit_alias_method_node(node)
88
+ commands << [inspect_node("AliasMethodNode", node), indent]
89
+ commands << ["├── new_name:\n", indent]
90
+ commands << [node.new_name, "#{indent}│ "]
91
+ commands << ["├── old_name:\n", indent]
92
+ commands << [node.old_name, "#{indent}│ "]
93
+ commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
94
+ end
95
+
96
+ # Inspect a AlternationPatternNode node.
97
+ def visit_alternation_pattern_node(node)
98
+ commands << [inspect_node("AlternationPatternNode", node), indent]
99
+ commands << ["├── left:\n", indent]
100
+ commands << [node.left, "#{indent}│ "]
101
+ commands << ["├── right:\n", indent]
102
+ commands << [node.right, "#{indent}│ "]
103
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
104
+ end
105
+
106
+ # Inspect a AndNode node.
107
+ def visit_and_node(node)
108
+ commands << [inspect_node("AndNode", node), indent]
109
+ commands << ["├── left:\n", indent]
110
+ commands << [node.left, "#{indent}│ "]
111
+ commands << ["├── right:\n", indent]
112
+ commands << [node.right, "#{indent}│ "]
113
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
114
+ end
115
+
116
+ # Inspect a ArgumentsNode node.
117
+ def visit_arguments_node(node)
118
+ commands << [inspect_node("ArgumentsNode", node), indent]
119
+ flags = [("contains_keywords" if node.contains_keywords?), ("contains_keyword_splat" if node.contains_keyword_splat?)].compact
120
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
121
+ commands << ["└── arguments: (length: #{(arguments = node.arguments).length})\n", indent]
122
+ if arguments.any?
123
+ arguments[0...-1].each do |child|
124
+ commands << [Replace.new("#{indent} ├── "), indent]
125
+ commands << [child, "#{indent} │ "]
126
+ end
127
+ commands << [Replace.new("#{indent} └── "), indent]
128
+ commands << [arguments[-1], "#{indent} "]
129
+ end
130
+ end
131
+
132
+ # Inspect a ArrayNode node.
133
+ def visit_array_node(node)
134
+ commands << [inspect_node("ArrayNode", node), indent]
135
+ flags = [("contains_splat" if node.contains_splat?)].compact
136
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
137
+ commands << ["├── elements: (length: #{(elements = node.elements).length})\n", indent]
138
+ if elements.any?
139
+ elements[0...-1].each do |child|
140
+ commands << [Replace.new("#{indent}│ ├── "), indent]
141
+ commands << [child, "#{indent}│ │ "]
142
+ end
143
+ commands << [Replace.new("#{indent}│ └── "), indent]
144
+ commands << [elements[-1], "#{indent}│ "]
145
+ end
146
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
147
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
148
+ end
149
+
150
+ # Inspect a ArrayPatternNode node.
151
+ def visit_array_pattern_node(node)
152
+ commands << [inspect_node("ArrayPatternNode", node), indent]
153
+ if (constant = node.constant).nil?
154
+ commands << ["├── constant: ∅\n", indent]
155
+ else
156
+ commands << ["├── constant:\n", indent]
157
+ commands << [constant, "#{indent}│ "]
158
+ end
159
+ commands << ["├── requireds: (length: #{(requireds = node.requireds).length})\n", indent]
160
+ if requireds.any?
161
+ requireds[0...-1].each do |child|
162
+ commands << [Replace.new("#{indent}│ ├── "), indent]
163
+ commands << [child, "#{indent}│ │ "]
164
+ end
165
+ commands << [Replace.new("#{indent}│ └── "), indent]
166
+ commands << [requireds[-1], "#{indent}│ "]
167
+ end
168
+ if (rest = node.rest).nil?
169
+ commands << ["├── rest: ∅\n", indent]
170
+ else
171
+ commands << ["├── rest:\n", indent]
172
+ commands << [rest, "#{indent}│ "]
173
+ end
174
+ commands << ["├── posts: (length: #{(posts = node.posts).length})\n", indent]
175
+ if posts.any?
176
+ posts[0...-1].each do |child|
177
+ commands << [Replace.new("#{indent}│ ├── "), indent]
178
+ commands << [child, "#{indent}│ │ "]
179
+ end
180
+ commands << [Replace.new("#{indent}│ └── "), indent]
181
+ commands << [posts[-1], "#{indent}│ "]
182
+ end
183
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
184
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
185
+ end
186
+
187
+ # Inspect a AssocNode node.
188
+ def visit_assoc_node(node)
189
+ commands << [inspect_node("AssocNode", node), indent]
190
+ commands << ["├── key:\n", indent]
191
+ commands << [node.key, "#{indent}│ "]
192
+ commands << ["├── value:\n", indent]
193
+ commands << [node.value, "#{indent}│ "]
194
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
195
+ end
196
+
197
+ # Inspect a AssocSplatNode node.
198
+ def visit_assoc_splat_node(node)
199
+ commands << [inspect_node("AssocSplatNode", node), indent]
200
+ if (value = node.value).nil?
201
+ commands << ["├── value: ∅\n", indent]
202
+ else
203
+ commands << ["├── value:\n", indent]
204
+ commands << [value, "#{indent}│ "]
205
+ end
206
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
207
+ end
208
+
209
+ # Inspect a BackReferenceReadNode node.
210
+ def visit_back_reference_read_node(node)
211
+ commands << [inspect_node("BackReferenceReadNode", node), indent]
212
+ commands << ["└── name: #{node.name.inspect}\n", indent]
213
+ end
214
+
215
+ # Inspect a BeginNode node.
216
+ def visit_begin_node(node)
217
+ commands << [inspect_node("BeginNode", node), indent]
218
+ commands << ["├── begin_keyword_loc: #{inspect_location(node.begin_keyword_loc)}\n", indent]
219
+ if (statements = node.statements).nil?
220
+ commands << ["├── statements: ∅\n", indent]
221
+ else
222
+ commands << ["├── statements:\n", indent]
223
+ commands << [statements, "#{indent}│ "]
224
+ end
225
+ if (rescue_clause = node.rescue_clause).nil?
226
+ commands << ["├── rescue_clause: ∅\n", indent]
227
+ else
228
+ commands << ["├── rescue_clause:\n", indent]
229
+ commands << [rescue_clause, "#{indent}│ "]
230
+ end
231
+ if (else_clause = node.else_clause).nil?
232
+ commands << ["├── else_clause: ∅\n", indent]
233
+ else
234
+ commands << ["├── else_clause:\n", indent]
235
+ commands << [else_clause, "#{indent}│ "]
236
+ end
237
+ if (ensure_clause = node.ensure_clause).nil?
238
+ commands << ["├── ensure_clause: ∅\n", indent]
239
+ else
240
+ commands << ["├── ensure_clause:\n", indent]
241
+ commands << [ensure_clause, "#{indent}│ "]
242
+ end
243
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
244
+ end
245
+
246
+ # Inspect a BlockArgumentNode node.
247
+ def visit_block_argument_node(node)
248
+ commands << [inspect_node("BlockArgumentNode", node), indent]
249
+ if (expression = node.expression).nil?
250
+ commands << ["├── expression: ∅\n", indent]
251
+ else
252
+ commands << ["├── expression:\n", indent]
253
+ commands << [expression, "#{indent}│ "]
254
+ end
255
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
256
+ end
257
+
258
+ # Inspect a BlockLocalVariableNode node.
259
+ def visit_block_local_variable_node(node)
260
+ commands << [inspect_node("BlockLocalVariableNode", node), indent]
261
+ flags = [("repeated_parameter" if node.repeated_parameter?)].compact
262
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
263
+ commands << ["└── name: #{node.name.inspect}\n", indent]
264
+ end
265
+
266
+ # Inspect a BlockNode node.
267
+ def visit_block_node(node)
268
+ commands << [inspect_node("BlockNode", node), indent]
269
+ commands << ["├── locals: #{node.locals.inspect}\n", indent]
270
+ if (parameters = node.parameters).nil?
271
+ commands << ["├── parameters: ∅\n", indent]
272
+ else
273
+ commands << ["├── parameters:\n", indent]
274
+ commands << [parameters, "#{indent}│ "]
275
+ end
276
+ if (body = node.body).nil?
277
+ commands << ["├── body: ∅\n", indent]
278
+ else
279
+ commands << ["├── body:\n", indent]
280
+ commands << [body, "#{indent}│ "]
281
+ end
282
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
283
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
284
+ end
285
+
286
+ # Inspect a BlockParameterNode node.
287
+ def visit_block_parameter_node(node)
288
+ commands << [inspect_node("BlockParameterNode", node), indent]
289
+ flags = [("repeated_parameter" if node.repeated_parameter?)].compact
290
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
291
+ if (name = node.name).nil?
292
+ commands << ["├── name: ∅\n", indent]
293
+ else
294
+ commands << ["├── name: #{name.inspect}\n", indent]
295
+ end
296
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
297
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
298
+ end
299
+
300
+ # Inspect a BlockParametersNode node.
301
+ def visit_block_parameters_node(node)
302
+ commands << [inspect_node("BlockParametersNode", node), indent]
303
+ if (parameters = node.parameters).nil?
304
+ commands << ["├── parameters: ∅\n", indent]
305
+ else
306
+ commands << ["├── parameters:\n", indent]
307
+ commands << [parameters, "#{indent}│ "]
308
+ end
309
+ commands << ["├── locals: (length: #{(locals = node.locals).length})\n", indent]
310
+ if locals.any?
311
+ locals[0...-1].each do |child|
312
+ commands << [Replace.new("#{indent}│ ├── "), indent]
313
+ commands << [child, "#{indent}│ │ "]
314
+ end
315
+ commands << [Replace.new("#{indent}│ └── "), indent]
316
+ commands << [locals[-1], "#{indent}│ "]
317
+ end
318
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
319
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
320
+ end
321
+
322
+ # Inspect a BreakNode node.
323
+ def visit_break_node(node)
324
+ commands << [inspect_node("BreakNode", node), indent]
325
+ if (arguments = node.arguments).nil?
326
+ commands << ["├── arguments: ∅\n", indent]
327
+ else
328
+ commands << ["├── arguments:\n", indent]
329
+ commands << [arguments, "#{indent}│ "]
330
+ end
331
+ commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
332
+ end
333
+
334
+ # Inspect a CallAndWriteNode node.
335
+ def visit_call_and_write_node(node)
336
+ commands << [inspect_node("CallAndWriteNode", node), indent]
337
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
338
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
339
+ if (receiver = node.receiver).nil?
340
+ commands << ["├── receiver: ∅\n", indent]
341
+ else
342
+ commands << ["├── receiver:\n", indent]
343
+ commands << [receiver, "#{indent}│ "]
344
+ end
345
+ commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent]
346
+ commands << ["├── message_loc: #{inspect_location(node.message_loc)}\n", indent]
347
+ commands << ["├── read_name: #{node.read_name.inspect}\n", indent]
348
+ commands << ["├── write_name: #{node.write_name.inspect}\n", indent]
349
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
350
+ commands << ["└── value:\n", indent]
351
+ commands << [node.value, "#{indent} "]
352
+ end
353
+
354
+ # Inspect a CallNode node.
355
+ def visit_call_node(node)
356
+ commands << [inspect_node("CallNode", node), indent]
357
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
358
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
359
+ if (receiver = node.receiver).nil?
360
+ commands << ["├── receiver: ∅\n", indent]
361
+ else
362
+ commands << ["├── receiver:\n", indent]
363
+ commands << [receiver, "#{indent}│ "]
364
+ end
365
+ commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent]
366
+ commands << ["├── name: #{node.name.inspect}\n", indent]
367
+ commands << ["├── message_loc: #{inspect_location(node.message_loc)}\n", indent]
368
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
369
+ if (arguments = node.arguments).nil?
370
+ commands << ["├── arguments: ∅\n", indent]
371
+ else
372
+ commands << ["├── arguments:\n", indent]
373
+ commands << [arguments, "#{indent}│ "]
374
+ end
375
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
376
+ if (block = node.block).nil?
377
+ commands << ["└── block: ∅\n", indent]
378
+ else
379
+ commands << ["└── block:\n", indent]
380
+ commands << [block, "#{indent} "]
381
+ end
382
+ end
383
+
384
+ # Inspect a CallOperatorWriteNode node.
385
+ def visit_call_operator_write_node(node)
386
+ commands << [inspect_node("CallOperatorWriteNode", node), indent]
387
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
388
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
389
+ if (receiver = node.receiver).nil?
390
+ commands << ["├── receiver: ∅\n", indent]
391
+ else
392
+ commands << ["├── receiver:\n", indent]
393
+ commands << [receiver, "#{indent}│ "]
394
+ end
395
+ commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent]
396
+ commands << ["├── message_loc: #{inspect_location(node.message_loc)}\n", indent]
397
+ commands << ["├── read_name: #{node.read_name.inspect}\n", indent]
398
+ commands << ["├── write_name: #{node.write_name.inspect}\n", indent]
399
+ commands << ["├── operator: #{node.operator.inspect}\n", indent]
400
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
401
+ commands << ["└── value:\n", indent]
402
+ commands << [node.value, "#{indent} "]
403
+ end
404
+
405
+ # Inspect a CallOrWriteNode node.
406
+ def visit_call_or_write_node(node)
407
+ commands << [inspect_node("CallOrWriteNode", node), indent]
408
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
409
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
410
+ if (receiver = node.receiver).nil?
411
+ commands << ["├── receiver: ∅\n", indent]
412
+ else
413
+ commands << ["├── receiver:\n", indent]
414
+ commands << [receiver, "#{indent}│ "]
415
+ end
416
+ commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent]
417
+ commands << ["├── message_loc: #{inspect_location(node.message_loc)}\n", indent]
418
+ commands << ["├── read_name: #{node.read_name.inspect}\n", indent]
419
+ commands << ["├── write_name: #{node.write_name.inspect}\n", indent]
420
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
421
+ commands << ["└── value:\n", indent]
422
+ commands << [node.value, "#{indent} "]
423
+ end
424
+
425
+ # Inspect a CallTargetNode node.
426
+ def visit_call_target_node(node)
427
+ commands << [inspect_node("CallTargetNode", node), indent]
428
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
429
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
430
+ commands << ["├── receiver:\n", indent]
431
+ commands << [node.receiver, "#{indent}│ "]
432
+ commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent]
433
+ commands << ["├── name: #{node.name.inspect}\n", indent]
434
+ commands << ["└── message_loc: #{inspect_location(node.message_loc)}\n", indent]
435
+ end
436
+
437
+ # Inspect a CapturePatternNode node.
438
+ def visit_capture_pattern_node(node)
439
+ commands << [inspect_node("CapturePatternNode", node), indent]
440
+ commands << ["├── value:\n", indent]
441
+ commands << [node.value, "#{indent}│ "]
442
+ commands << ["├── target:\n", indent]
443
+ commands << [node.target, "#{indent}│ "]
444
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
445
+ end
446
+
447
+ # Inspect a CaseMatchNode node.
448
+ def visit_case_match_node(node)
449
+ commands << [inspect_node("CaseMatchNode", node), indent]
450
+ if (predicate = node.predicate).nil?
451
+ commands << ["├── predicate: ∅\n", indent]
452
+ else
453
+ commands << ["├── predicate:\n", indent]
454
+ commands << [predicate, "#{indent}│ "]
455
+ end
456
+ commands << ["├── conditions: (length: #{(conditions = node.conditions).length})\n", indent]
457
+ if conditions.any?
458
+ conditions[0...-1].each do |child|
459
+ commands << [Replace.new("#{indent}│ ├── "), indent]
460
+ commands << [child, "#{indent}│ │ "]
461
+ end
462
+ commands << [Replace.new("#{indent}│ └── "), indent]
463
+ commands << [conditions[-1], "#{indent}│ "]
464
+ end
465
+ if (consequent = node.consequent).nil?
466
+ commands << ["├── consequent: ∅\n", indent]
467
+ else
468
+ commands << ["├── consequent:\n", indent]
469
+ commands << [consequent, "#{indent}│ "]
470
+ end
471
+ commands << ["├── case_keyword_loc: #{inspect_location(node.case_keyword_loc)}\n", indent]
472
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
473
+ end
474
+
475
+ # Inspect a CaseNode node.
476
+ def visit_case_node(node)
477
+ commands << [inspect_node("CaseNode", node), indent]
478
+ if (predicate = node.predicate).nil?
479
+ commands << ["├── predicate: ∅\n", indent]
480
+ else
481
+ commands << ["├── predicate:\n", indent]
482
+ commands << [predicate, "#{indent}│ "]
483
+ end
484
+ commands << ["├── conditions: (length: #{(conditions = node.conditions).length})\n", indent]
485
+ if conditions.any?
486
+ conditions[0...-1].each do |child|
487
+ commands << [Replace.new("#{indent}│ ├── "), indent]
488
+ commands << [child, "#{indent}│ │ "]
489
+ end
490
+ commands << [Replace.new("#{indent}│ └── "), indent]
491
+ commands << [conditions[-1], "#{indent}│ "]
492
+ end
493
+ if (consequent = node.consequent).nil?
494
+ commands << ["├── consequent: ∅\n", indent]
495
+ else
496
+ commands << ["├── consequent:\n", indent]
497
+ commands << [consequent, "#{indent}│ "]
498
+ end
499
+ commands << ["├── case_keyword_loc: #{inspect_location(node.case_keyword_loc)}\n", indent]
500
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
501
+ end
502
+
503
+ # Inspect a ClassNode node.
504
+ def visit_class_node(node)
505
+ commands << [inspect_node("ClassNode", node), indent]
506
+ commands << ["├── locals: #{node.locals.inspect}\n", indent]
507
+ commands << ["├── class_keyword_loc: #{inspect_location(node.class_keyword_loc)}\n", indent]
508
+ commands << ["├── constant_path:\n", indent]
509
+ commands << [node.constant_path, "#{indent}│ "]
510
+ commands << ["├── inheritance_operator_loc: #{inspect_location(node.inheritance_operator_loc)}\n", indent]
511
+ if (superclass = node.superclass).nil?
512
+ commands << ["├── superclass: ∅\n", indent]
513
+ else
514
+ commands << ["├── superclass:\n", indent]
515
+ commands << [superclass, "#{indent}│ "]
516
+ end
517
+ if (body = node.body).nil?
518
+ commands << ["├── body: ∅\n", indent]
519
+ else
520
+ commands << ["├── body:\n", indent]
521
+ commands << [body, "#{indent}│ "]
522
+ end
523
+ commands << ["├── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
524
+ commands << ["└── name: #{node.name.inspect}\n", indent]
525
+ end
526
+
527
+ # Inspect a ClassVariableAndWriteNode node.
528
+ def visit_class_variable_and_write_node(node)
529
+ commands << [inspect_node("ClassVariableAndWriteNode", node), indent]
530
+ commands << ["├── name: #{node.name.inspect}\n", indent]
531
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
532
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
533
+ commands << ["└── value:\n", indent]
534
+ commands << [node.value, "#{indent} "]
535
+ end
536
+
537
+ # Inspect a ClassVariableOperatorWriteNode node.
538
+ def visit_class_variable_operator_write_node(node)
539
+ commands << [inspect_node("ClassVariableOperatorWriteNode", node), indent]
540
+ commands << ["├── name: #{node.name.inspect}\n", indent]
541
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
542
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
543
+ commands << ["├── value:\n", indent]
544
+ commands << [node.value, "#{indent}│ "]
545
+ commands << ["└── operator: #{node.operator.inspect}\n", indent]
546
+ end
547
+
548
+ # Inspect a ClassVariableOrWriteNode node.
549
+ def visit_class_variable_or_write_node(node)
550
+ commands << [inspect_node("ClassVariableOrWriteNode", node), indent]
551
+ commands << ["├── name: #{node.name.inspect}\n", indent]
552
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
553
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
554
+ commands << ["└── value:\n", indent]
555
+ commands << [node.value, "#{indent} "]
556
+ end
557
+
558
+ # Inspect a ClassVariableReadNode node.
559
+ def visit_class_variable_read_node(node)
560
+ commands << [inspect_node("ClassVariableReadNode", node), indent]
561
+ commands << ["└── name: #{node.name.inspect}\n", indent]
562
+ end
563
+
564
+ # Inspect a ClassVariableTargetNode node.
565
+ def visit_class_variable_target_node(node)
566
+ commands << [inspect_node("ClassVariableTargetNode", node), indent]
567
+ commands << ["└── name: #{node.name.inspect}\n", indent]
568
+ end
569
+
570
+ # Inspect a ClassVariableWriteNode node.
571
+ def visit_class_variable_write_node(node)
572
+ commands << [inspect_node("ClassVariableWriteNode", node), indent]
573
+ commands << ["├── name: #{node.name.inspect}\n", indent]
574
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
575
+ commands << ["├── value:\n", indent]
576
+ commands << [node.value, "#{indent}│ "]
577
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
578
+ end
579
+
580
+ # Inspect a ConstantAndWriteNode node.
581
+ def visit_constant_and_write_node(node)
582
+ commands << [inspect_node("ConstantAndWriteNode", node), indent]
583
+ commands << ["├── name: #{node.name.inspect}\n", indent]
584
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
585
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
586
+ commands << ["└── value:\n", indent]
587
+ commands << [node.value, "#{indent} "]
588
+ end
589
+
590
+ # Inspect a ConstantOperatorWriteNode node.
591
+ def visit_constant_operator_write_node(node)
592
+ commands << [inspect_node("ConstantOperatorWriteNode", node), indent]
593
+ commands << ["├── name: #{node.name.inspect}\n", indent]
594
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
595
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
596
+ commands << ["├── value:\n", indent]
597
+ commands << [node.value, "#{indent}│ "]
598
+ commands << ["└── operator: #{node.operator.inspect}\n", indent]
599
+ end
600
+
601
+ # Inspect a ConstantOrWriteNode node.
602
+ def visit_constant_or_write_node(node)
603
+ commands << [inspect_node("ConstantOrWriteNode", node), indent]
604
+ commands << ["├── name: #{node.name.inspect}\n", indent]
605
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
606
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
607
+ commands << ["└── value:\n", indent]
608
+ commands << [node.value, "#{indent} "]
609
+ end
610
+
611
+ # Inspect a ConstantPathAndWriteNode node.
612
+ def visit_constant_path_and_write_node(node)
613
+ commands << [inspect_node("ConstantPathAndWriteNode", node), indent]
614
+ commands << ["├── target:\n", indent]
615
+ commands << [node.target, "#{indent}│ "]
616
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
617
+ commands << ["└── value:\n", indent]
618
+ commands << [node.value, "#{indent} "]
619
+ end
620
+
621
+ # Inspect a ConstantPathNode node.
622
+ def visit_constant_path_node(node)
623
+ commands << [inspect_node("ConstantPathNode", node), indent]
624
+ if (parent = node.parent).nil?
625
+ commands << ["├── parent: ∅\n", indent]
626
+ else
627
+ commands << ["├── parent:\n", indent]
628
+ commands << [parent, "#{indent}│ "]
629
+ end
630
+ if (name = node.name).nil?
631
+ commands << ["├── name: ∅\n", indent]
632
+ else
633
+ commands << ["├── name: #{name.inspect}\n", indent]
634
+ end
635
+ commands << ["├── delimiter_loc: #{inspect_location(node.delimiter_loc)}\n", indent]
636
+ commands << ["└── name_loc: #{inspect_location(node.name_loc)}\n", indent]
637
+ end
638
+
639
+ # Inspect a ConstantPathOperatorWriteNode node.
640
+ def visit_constant_path_operator_write_node(node)
641
+ commands << [inspect_node("ConstantPathOperatorWriteNode", node), indent]
642
+ commands << ["├── target:\n", indent]
643
+ commands << [node.target, "#{indent}│ "]
644
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
645
+ commands << ["├── value:\n", indent]
646
+ commands << [node.value, "#{indent}│ "]
647
+ commands << ["└── operator: #{node.operator.inspect}\n", indent]
648
+ end
649
+
650
+ # Inspect a ConstantPathOrWriteNode node.
651
+ def visit_constant_path_or_write_node(node)
652
+ commands << [inspect_node("ConstantPathOrWriteNode", node), indent]
653
+ commands << ["├── target:\n", indent]
654
+ commands << [node.target, "#{indent}│ "]
655
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
656
+ commands << ["└── value:\n", indent]
657
+ commands << [node.value, "#{indent} "]
658
+ end
659
+
660
+ # Inspect a ConstantPathTargetNode node.
661
+ def visit_constant_path_target_node(node)
662
+ commands << [inspect_node("ConstantPathTargetNode", node), indent]
663
+ if (parent = node.parent).nil?
664
+ commands << ["├── parent: ∅\n", indent]
665
+ else
666
+ commands << ["├── parent:\n", indent]
667
+ commands << [parent, "#{indent}│ "]
668
+ end
669
+ if (name = node.name).nil?
670
+ commands << ["├── name: ∅\n", indent]
671
+ else
672
+ commands << ["├── name: #{name.inspect}\n", indent]
673
+ end
674
+ commands << ["├── delimiter_loc: #{inspect_location(node.delimiter_loc)}\n", indent]
675
+ commands << ["└── name_loc: #{inspect_location(node.name_loc)}\n", indent]
676
+ end
677
+
678
+ # Inspect a ConstantPathWriteNode node.
679
+ def visit_constant_path_write_node(node)
680
+ commands << [inspect_node("ConstantPathWriteNode", node), indent]
681
+ commands << ["├── target:\n", indent]
682
+ commands << [node.target, "#{indent}│ "]
683
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
684
+ commands << ["└── value:\n", indent]
685
+ commands << [node.value, "#{indent} "]
686
+ end
687
+
688
+ # Inspect a ConstantReadNode node.
689
+ def visit_constant_read_node(node)
690
+ commands << [inspect_node("ConstantReadNode", node), indent]
691
+ commands << ["└── name: #{node.name.inspect}\n", indent]
692
+ end
693
+
694
+ # Inspect a ConstantTargetNode node.
695
+ def visit_constant_target_node(node)
696
+ commands << [inspect_node("ConstantTargetNode", node), indent]
697
+ commands << ["└── name: #{node.name.inspect}\n", indent]
698
+ end
699
+
700
+ # Inspect a ConstantWriteNode node.
701
+ def visit_constant_write_node(node)
702
+ commands << [inspect_node("ConstantWriteNode", node), indent]
703
+ commands << ["├── name: #{node.name.inspect}\n", indent]
704
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
705
+ commands << ["├── value:\n", indent]
706
+ commands << [node.value, "#{indent}│ "]
707
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
708
+ end
709
+
710
+ # Inspect a DefNode node.
711
+ def visit_def_node(node)
712
+ commands << [inspect_node("DefNode", node), indent]
713
+ commands << ["├── name: #{node.name.inspect}\n", indent]
714
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
715
+ if (receiver = node.receiver).nil?
716
+ commands << ["├── receiver: ∅\n", indent]
717
+ else
718
+ commands << ["├── receiver:\n", indent]
719
+ commands << [receiver, "#{indent}│ "]
720
+ end
721
+ if (parameters = node.parameters).nil?
722
+ commands << ["├── parameters: ∅\n", indent]
723
+ else
724
+ commands << ["├── parameters:\n", indent]
725
+ commands << [parameters, "#{indent}│ "]
726
+ end
727
+ if (body = node.body).nil?
728
+ commands << ["├── body: ∅\n", indent]
729
+ else
730
+ commands << ["├── body:\n", indent]
731
+ commands << [body, "#{indent}│ "]
732
+ end
733
+ commands << ["├── locals: #{node.locals.inspect}\n", indent]
734
+ commands << ["├── def_keyword_loc: #{inspect_location(node.def_keyword_loc)}\n", indent]
735
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
736
+ commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent]
737
+ commands << ["├── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent]
738
+ commands << ["├── equal_loc: #{inspect_location(node.equal_loc)}\n", indent]
739
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
740
+ end
741
+
742
+ # Inspect a DefinedNode node.
743
+ def visit_defined_node(node)
744
+ commands << [inspect_node("DefinedNode", node), indent]
745
+ commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent]
746
+ commands << ["├── value:\n", indent]
747
+ commands << [node.value, "#{indent}│ "]
748
+ commands << ["├── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent]
749
+ commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
750
+ end
751
+
752
+ # Inspect a ElseNode node.
753
+ def visit_else_node(node)
754
+ commands << [inspect_node("ElseNode", node), indent]
755
+ commands << ["├── else_keyword_loc: #{inspect_location(node.else_keyword_loc)}\n", indent]
756
+ if (statements = node.statements).nil?
757
+ commands << ["├── statements: ∅\n", indent]
758
+ else
759
+ commands << ["├── statements:\n", indent]
760
+ commands << [statements, "#{indent}│ "]
761
+ end
762
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
763
+ end
764
+
765
+ # Inspect a EmbeddedStatementsNode node.
766
+ def visit_embedded_statements_node(node)
767
+ commands << [inspect_node("EmbeddedStatementsNode", node), indent]
768
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
769
+ if (statements = node.statements).nil?
770
+ commands << ["├── statements: ∅\n", indent]
771
+ else
772
+ commands << ["├── statements:\n", indent]
773
+ commands << [statements, "#{indent}│ "]
774
+ end
775
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
776
+ end
777
+
778
+ # Inspect a EmbeddedVariableNode node.
779
+ def visit_embedded_variable_node(node)
780
+ commands << [inspect_node("EmbeddedVariableNode", node), indent]
781
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
782
+ commands << ["└── variable:\n", indent]
783
+ commands << [node.variable, "#{indent} "]
784
+ end
785
+
786
+ # Inspect a EnsureNode node.
787
+ def visit_ensure_node(node)
788
+ commands << [inspect_node("EnsureNode", node), indent]
789
+ commands << ["├── ensure_keyword_loc: #{inspect_location(node.ensure_keyword_loc)}\n", indent]
790
+ if (statements = node.statements).nil?
791
+ commands << ["├── statements: ∅\n", indent]
792
+ else
793
+ commands << ["├── statements:\n", indent]
794
+ commands << [statements, "#{indent}│ "]
795
+ end
796
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
797
+ end
798
+
799
+ # Inspect a FalseNode node.
800
+ def visit_false_node(node)
801
+ commands << [inspect_node("FalseNode", node), indent]
802
+ end
803
+
804
+ # Inspect a FindPatternNode node.
805
+ def visit_find_pattern_node(node)
806
+ commands << [inspect_node("FindPatternNode", node), indent]
807
+ if (constant = node.constant).nil?
808
+ commands << ["├── constant: ∅\n", indent]
809
+ else
810
+ commands << ["├── constant:\n", indent]
811
+ commands << [constant, "#{indent}│ "]
812
+ end
813
+ commands << ["├── left:\n", indent]
814
+ commands << [node.left, "#{indent}│ "]
815
+ commands << ["├── requireds: (length: #{(requireds = node.requireds).length})\n", indent]
816
+ if requireds.any?
817
+ requireds[0...-1].each do |child|
818
+ commands << [Replace.new("#{indent}│ ├── "), indent]
819
+ commands << [child, "#{indent}│ │ "]
820
+ end
821
+ commands << [Replace.new("#{indent}│ └── "), indent]
822
+ commands << [requireds[-1], "#{indent}│ "]
823
+ end
824
+ commands << ["├── right:\n", indent]
825
+ commands << [node.right, "#{indent}│ "]
826
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
827
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
828
+ end
829
+
830
+ # Inspect a FlipFlopNode node.
831
+ def visit_flip_flop_node(node)
832
+ commands << [inspect_node("FlipFlopNode", node), indent]
833
+ flags = [("exclude_end" if node.exclude_end?)].compact
834
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
835
+ if (left = node.left).nil?
836
+ commands << ["├── left: ∅\n", indent]
837
+ else
838
+ commands << ["├── left:\n", indent]
839
+ commands << [left, "#{indent}│ "]
840
+ end
841
+ if (right = node.right).nil?
842
+ commands << ["├── right: ∅\n", indent]
843
+ else
844
+ commands << ["├── right:\n", indent]
845
+ commands << [right, "#{indent}│ "]
846
+ end
847
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
848
+ end
849
+
850
+ # Inspect a FloatNode node.
851
+ def visit_float_node(node)
852
+ commands << [inspect_node("FloatNode", node), indent]
853
+ commands << ["└── value: #{node.value.inspect}\n", indent]
854
+ end
855
+
856
+ # Inspect a ForNode node.
857
+ def visit_for_node(node)
858
+ commands << [inspect_node("ForNode", node), indent]
859
+ commands << ["├── index:\n", indent]
860
+ commands << [node.index, "#{indent}│ "]
861
+ commands << ["├── collection:\n", indent]
862
+ commands << [node.collection, "#{indent}│ "]
863
+ if (statements = node.statements).nil?
864
+ commands << ["├── statements: ∅\n", indent]
865
+ else
866
+ commands << ["├── statements:\n", indent]
867
+ commands << [statements, "#{indent}│ "]
868
+ end
869
+ commands << ["├── for_keyword_loc: #{inspect_location(node.for_keyword_loc)}\n", indent]
870
+ commands << ["├── in_keyword_loc: #{inspect_location(node.in_keyword_loc)}\n", indent]
871
+ commands << ["├── do_keyword_loc: #{inspect_location(node.do_keyword_loc)}\n", indent]
872
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
873
+ end
874
+
875
+ # Inspect a ForwardingArgumentsNode node.
876
+ def visit_forwarding_arguments_node(node)
877
+ commands << [inspect_node("ForwardingArgumentsNode", node), indent]
878
+ end
879
+
880
+ # Inspect a ForwardingParameterNode node.
881
+ def visit_forwarding_parameter_node(node)
882
+ commands << [inspect_node("ForwardingParameterNode", node), indent]
883
+ end
884
+
885
+ # Inspect a ForwardingSuperNode node.
886
+ def visit_forwarding_super_node(node)
887
+ commands << [inspect_node("ForwardingSuperNode", node), indent]
888
+ if (block = node.block).nil?
889
+ commands << ["└── block: ∅\n", indent]
890
+ else
891
+ commands << ["└── block:\n", indent]
892
+ commands << [block, "#{indent} "]
893
+ end
894
+ end
895
+
896
+ # Inspect a GlobalVariableAndWriteNode node.
897
+ def visit_global_variable_and_write_node(node)
898
+ commands << [inspect_node("GlobalVariableAndWriteNode", node), indent]
899
+ commands << ["├── name: #{node.name.inspect}\n", indent]
900
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
901
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
902
+ commands << ["└── value:\n", indent]
903
+ commands << [node.value, "#{indent} "]
904
+ end
905
+
906
+ # Inspect a GlobalVariableOperatorWriteNode node.
907
+ def visit_global_variable_operator_write_node(node)
908
+ commands << [inspect_node("GlobalVariableOperatorWriteNode", node), indent]
909
+ commands << ["├── name: #{node.name.inspect}\n", indent]
910
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
911
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
912
+ commands << ["├── value:\n", indent]
913
+ commands << [node.value, "#{indent}│ "]
914
+ commands << ["└── operator: #{node.operator.inspect}\n", indent]
915
+ end
916
+
917
+ # Inspect a GlobalVariableOrWriteNode node.
918
+ def visit_global_variable_or_write_node(node)
919
+ commands << [inspect_node("GlobalVariableOrWriteNode", node), indent]
920
+ commands << ["├── name: #{node.name.inspect}\n", indent]
921
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
922
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
923
+ commands << ["└── value:\n", indent]
924
+ commands << [node.value, "#{indent} "]
925
+ end
926
+
927
+ # Inspect a GlobalVariableReadNode node.
928
+ def visit_global_variable_read_node(node)
929
+ commands << [inspect_node("GlobalVariableReadNode", node), indent]
930
+ commands << ["└── name: #{node.name.inspect}\n", indent]
931
+ end
932
+
933
+ # Inspect a GlobalVariableTargetNode node.
934
+ def visit_global_variable_target_node(node)
935
+ commands << [inspect_node("GlobalVariableTargetNode", node), indent]
936
+ commands << ["└── name: #{node.name.inspect}\n", indent]
937
+ end
938
+
939
+ # Inspect a GlobalVariableWriteNode node.
940
+ def visit_global_variable_write_node(node)
941
+ commands << [inspect_node("GlobalVariableWriteNode", node), indent]
942
+ commands << ["├── name: #{node.name.inspect}\n", indent]
943
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
944
+ commands << ["├── value:\n", indent]
945
+ commands << [node.value, "#{indent}│ "]
946
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
947
+ end
948
+
949
+ # Inspect a HashNode node.
950
+ def visit_hash_node(node)
951
+ commands << [inspect_node("HashNode", node), indent]
952
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
953
+ commands << ["├── elements: (length: #{(elements = node.elements).length})\n", indent]
954
+ if elements.any?
955
+ elements[0...-1].each do |child|
956
+ commands << [Replace.new("#{indent}│ ├── "), indent]
957
+ commands << [child, "#{indent}│ │ "]
958
+ end
959
+ commands << [Replace.new("#{indent}│ └── "), indent]
960
+ commands << [elements[-1], "#{indent}│ "]
961
+ end
962
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
963
+ end
964
+
965
+ # Inspect a HashPatternNode node.
966
+ def visit_hash_pattern_node(node)
967
+ commands << [inspect_node("HashPatternNode", node), indent]
968
+ if (constant = node.constant).nil?
969
+ commands << ["├── constant: ∅\n", indent]
970
+ else
971
+ commands << ["├── constant:\n", indent]
972
+ commands << [constant, "#{indent}│ "]
973
+ end
974
+ commands << ["├── elements: (length: #{(elements = node.elements).length})\n", indent]
975
+ if elements.any?
976
+ elements[0...-1].each do |child|
977
+ commands << [Replace.new("#{indent}│ ├── "), indent]
978
+ commands << [child, "#{indent}│ │ "]
979
+ end
980
+ commands << [Replace.new("#{indent}│ └── "), indent]
981
+ commands << [elements[-1], "#{indent}│ "]
982
+ end
983
+ if (rest = node.rest).nil?
984
+ commands << ["├── rest: ∅\n", indent]
985
+ else
986
+ commands << ["├── rest:\n", indent]
987
+ commands << [rest, "#{indent}│ "]
988
+ end
989
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
990
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
991
+ end
992
+
993
+ # Inspect a IfNode node.
994
+ def visit_if_node(node)
995
+ commands << [inspect_node("IfNode", node), indent]
996
+ commands << ["├── if_keyword_loc: #{inspect_location(node.if_keyword_loc)}\n", indent]
997
+ commands << ["├── predicate:\n", indent]
998
+ commands << [node.predicate, "#{indent}│ "]
999
+ commands << ["├── then_keyword_loc: #{inspect_location(node.then_keyword_loc)}\n", indent]
1000
+ if (statements = node.statements).nil?
1001
+ commands << ["├── statements: ∅\n", indent]
1002
+ else
1003
+ commands << ["├── statements:\n", indent]
1004
+ commands << [statements, "#{indent}│ "]
1005
+ end
1006
+ if (consequent = node.consequent).nil?
1007
+ commands << ["├── consequent: ∅\n", indent]
1008
+ else
1009
+ commands << ["├── consequent:\n", indent]
1010
+ commands << [consequent, "#{indent}│ "]
1011
+ end
1012
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
1013
+ end
1014
+
1015
+ # Inspect a ImaginaryNode node.
1016
+ def visit_imaginary_node(node)
1017
+ commands << [inspect_node("ImaginaryNode", node), indent]
1018
+ commands << ["└── numeric:\n", indent]
1019
+ commands << [node.numeric, "#{indent} "]
1020
+ end
1021
+
1022
+ # Inspect a ImplicitNode node.
1023
+ def visit_implicit_node(node)
1024
+ commands << [inspect_node("ImplicitNode", node), indent]
1025
+ commands << ["└── value:\n", indent]
1026
+ commands << [node.value, "#{indent} "]
1027
+ end
1028
+
1029
+ # Inspect a ImplicitRestNode node.
1030
+ def visit_implicit_rest_node(node)
1031
+ commands << [inspect_node("ImplicitRestNode", node), indent]
1032
+ end
1033
+
1034
+ # Inspect a InNode node.
1035
+ def visit_in_node(node)
1036
+ commands << [inspect_node("InNode", node), indent]
1037
+ commands << ["├── pattern:\n", indent]
1038
+ commands << [node.pattern, "#{indent}│ "]
1039
+ if (statements = node.statements).nil?
1040
+ commands << ["├── statements: ∅\n", indent]
1041
+ else
1042
+ commands << ["├── statements:\n", indent]
1043
+ commands << [statements, "#{indent}│ "]
1044
+ end
1045
+ commands << ["├── in_loc: #{inspect_location(node.in_loc)}\n", indent]
1046
+ commands << ["└── then_loc: #{inspect_location(node.then_loc)}\n", indent]
1047
+ end
1048
+
1049
+ # Inspect a IndexAndWriteNode node.
1050
+ def visit_index_and_write_node(node)
1051
+ commands << [inspect_node("IndexAndWriteNode", node), indent]
1052
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
1053
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1054
+ if (receiver = node.receiver).nil?
1055
+ commands << ["├── receiver: ∅\n", indent]
1056
+ else
1057
+ commands << ["├── receiver:\n", indent]
1058
+ commands << [receiver, "#{indent}│ "]
1059
+ end
1060
+ commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent]
1061
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1062
+ if (arguments = node.arguments).nil?
1063
+ commands << ["├── arguments: ∅\n", indent]
1064
+ else
1065
+ commands << ["├── arguments:\n", indent]
1066
+ commands << [arguments, "#{indent}│ "]
1067
+ end
1068
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1069
+ if (block = node.block).nil?
1070
+ commands << ["├── block: ∅\n", indent]
1071
+ else
1072
+ commands << ["├── block:\n", indent]
1073
+ commands << [block, "#{indent}│ "]
1074
+ end
1075
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1076
+ commands << ["└── value:\n", indent]
1077
+ commands << [node.value, "#{indent} "]
1078
+ end
1079
+
1080
+ # Inspect a IndexOperatorWriteNode node.
1081
+ def visit_index_operator_write_node(node)
1082
+ commands << [inspect_node("IndexOperatorWriteNode", node), indent]
1083
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
1084
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1085
+ if (receiver = node.receiver).nil?
1086
+ commands << ["├── receiver: ∅\n", indent]
1087
+ else
1088
+ commands << ["├── receiver:\n", indent]
1089
+ commands << [receiver, "#{indent}│ "]
1090
+ end
1091
+ commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent]
1092
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1093
+ if (arguments = node.arguments).nil?
1094
+ commands << ["├── arguments: ∅\n", indent]
1095
+ else
1096
+ commands << ["├── arguments:\n", indent]
1097
+ commands << [arguments, "#{indent}│ "]
1098
+ end
1099
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1100
+ if (block = node.block).nil?
1101
+ commands << ["├── block: ∅\n", indent]
1102
+ else
1103
+ commands << ["├── block:\n", indent]
1104
+ commands << [block, "#{indent}│ "]
1105
+ end
1106
+ commands << ["├── operator: #{node.operator.inspect}\n", indent]
1107
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1108
+ commands << ["└── value:\n", indent]
1109
+ commands << [node.value, "#{indent} "]
1110
+ end
1111
+
1112
+ # Inspect a IndexOrWriteNode node.
1113
+ def visit_index_or_write_node(node)
1114
+ commands << [inspect_node("IndexOrWriteNode", node), indent]
1115
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
1116
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1117
+ if (receiver = node.receiver).nil?
1118
+ commands << ["├── receiver: ∅\n", indent]
1119
+ else
1120
+ commands << ["├── receiver:\n", indent]
1121
+ commands << [receiver, "#{indent}│ "]
1122
+ end
1123
+ commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent]
1124
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1125
+ if (arguments = node.arguments).nil?
1126
+ commands << ["├── arguments: ∅\n", indent]
1127
+ else
1128
+ commands << ["├── arguments:\n", indent]
1129
+ commands << [arguments, "#{indent}│ "]
1130
+ end
1131
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1132
+ if (block = node.block).nil?
1133
+ commands << ["├── block: ∅\n", indent]
1134
+ else
1135
+ commands << ["├── block:\n", indent]
1136
+ commands << [block, "#{indent}│ "]
1137
+ end
1138
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1139
+ commands << ["└── value:\n", indent]
1140
+ commands << [node.value, "#{indent} "]
1141
+ end
1142
+
1143
+ # Inspect a IndexTargetNode node.
1144
+ def visit_index_target_node(node)
1145
+ commands << [inspect_node("IndexTargetNode", node), indent]
1146
+ flags = [("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact
1147
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1148
+ commands << ["├── receiver:\n", indent]
1149
+ commands << [node.receiver, "#{indent}│ "]
1150
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1151
+ if (arguments = node.arguments).nil?
1152
+ commands << ["├── arguments: ∅\n", indent]
1153
+ else
1154
+ commands << ["├── arguments:\n", indent]
1155
+ commands << [arguments, "#{indent}│ "]
1156
+ end
1157
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1158
+ if (block = node.block).nil?
1159
+ commands << ["└── block: ∅\n", indent]
1160
+ else
1161
+ commands << ["└── block:\n", indent]
1162
+ commands << [block, "#{indent} "]
1163
+ end
1164
+ end
1165
+
1166
+ # Inspect a InstanceVariableAndWriteNode node.
1167
+ def visit_instance_variable_and_write_node(node)
1168
+ commands << [inspect_node("InstanceVariableAndWriteNode", node), indent]
1169
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1170
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1171
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1172
+ commands << ["└── value:\n", indent]
1173
+ commands << [node.value, "#{indent} "]
1174
+ end
1175
+
1176
+ # Inspect a InstanceVariableOperatorWriteNode node.
1177
+ def visit_instance_variable_operator_write_node(node)
1178
+ commands << [inspect_node("InstanceVariableOperatorWriteNode", node), indent]
1179
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1180
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1181
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1182
+ commands << ["├── value:\n", indent]
1183
+ commands << [node.value, "#{indent}│ "]
1184
+ commands << ["└── operator: #{node.operator.inspect}\n", indent]
1185
+ end
1186
+
1187
+ # Inspect a InstanceVariableOrWriteNode node.
1188
+ def visit_instance_variable_or_write_node(node)
1189
+ commands << [inspect_node("InstanceVariableOrWriteNode", node), indent]
1190
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1191
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1192
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1193
+ commands << ["└── value:\n", indent]
1194
+ commands << [node.value, "#{indent} "]
1195
+ end
1196
+
1197
+ # Inspect a InstanceVariableReadNode node.
1198
+ def visit_instance_variable_read_node(node)
1199
+ commands << [inspect_node("InstanceVariableReadNode", node), indent]
1200
+ commands << ["└── name: #{node.name.inspect}\n", indent]
1201
+ end
1202
+
1203
+ # Inspect a InstanceVariableTargetNode node.
1204
+ def visit_instance_variable_target_node(node)
1205
+ commands << [inspect_node("InstanceVariableTargetNode", node), indent]
1206
+ commands << ["└── name: #{node.name.inspect}\n", indent]
1207
+ end
1208
+
1209
+ # Inspect a InstanceVariableWriteNode node.
1210
+ def visit_instance_variable_write_node(node)
1211
+ commands << [inspect_node("InstanceVariableWriteNode", node), indent]
1212
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1213
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1214
+ commands << ["├── value:\n", indent]
1215
+ commands << [node.value, "#{indent}│ "]
1216
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1217
+ end
1218
+
1219
+ # Inspect a IntegerNode node.
1220
+ def visit_integer_node(node)
1221
+ commands << [inspect_node("IntegerNode", node), indent]
1222
+ flags = [("binary" if node.binary?), ("decimal" if node.decimal?), ("octal" if node.octal?), ("hexadecimal" if node.hexadecimal?)].compact
1223
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1224
+ commands << ["└── value: #{node.value.inspect}\n", indent]
1225
+ end
1226
+
1227
+ # Inspect a InterpolatedMatchLastLineNode node.
1228
+ def visit_interpolated_match_last_line_node(node)
1229
+ commands << [inspect_node("InterpolatedMatchLastLineNode", node), indent]
1230
+ flags = [("ignore_case" if node.ignore_case?), ("extended" if node.extended?), ("multi_line" if node.multi_line?), ("once" if node.once?), ("euc_jp" if node.euc_jp?), ("ascii_8bit" if node.ascii_8bit?), ("windows_31j" if node.windows_31j?), ("utf_8" if node.utf_8?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact
1231
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1232
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1233
+ commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent]
1234
+ if parts.any?
1235
+ parts[0...-1].each do |child|
1236
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1237
+ commands << [child, "#{indent}│ │ "]
1238
+ end
1239
+ commands << [Replace.new("#{indent}│ └── "), indent]
1240
+ commands << [parts[-1], "#{indent}│ "]
1241
+ end
1242
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1243
+ end
1244
+
1245
+ # Inspect a InterpolatedRegularExpressionNode node.
1246
+ def visit_interpolated_regular_expression_node(node)
1247
+ commands << [inspect_node("InterpolatedRegularExpressionNode", node), indent]
1248
+ flags = [("ignore_case" if node.ignore_case?), ("extended" if node.extended?), ("multi_line" if node.multi_line?), ("once" if node.once?), ("euc_jp" if node.euc_jp?), ("ascii_8bit" if node.ascii_8bit?), ("windows_31j" if node.windows_31j?), ("utf_8" if node.utf_8?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact
1249
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1250
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1251
+ commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent]
1252
+ if parts.any?
1253
+ parts[0...-1].each do |child|
1254
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1255
+ commands << [child, "#{indent}│ │ "]
1256
+ end
1257
+ commands << [Replace.new("#{indent}│ └── "), indent]
1258
+ commands << [parts[-1], "#{indent}│ "]
1259
+ end
1260
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1261
+ end
1262
+
1263
+ # Inspect a InterpolatedStringNode node.
1264
+ def visit_interpolated_string_node(node)
1265
+ commands << [inspect_node("InterpolatedStringNode", node), indent]
1266
+ flags = [("frozen" if node.frozen?), ("mutable" if node.mutable?)].compact
1267
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1268
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1269
+ commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent]
1270
+ if parts.any?
1271
+ parts[0...-1].each do |child|
1272
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1273
+ commands << [child, "#{indent}│ │ "]
1274
+ end
1275
+ commands << [Replace.new("#{indent}│ └── "), indent]
1276
+ commands << [parts[-1], "#{indent}│ "]
1277
+ end
1278
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1279
+ end
1280
+
1281
+ # Inspect a InterpolatedSymbolNode node.
1282
+ def visit_interpolated_symbol_node(node)
1283
+ commands << [inspect_node("InterpolatedSymbolNode", node), indent]
1284
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1285
+ commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent]
1286
+ if parts.any?
1287
+ parts[0...-1].each do |child|
1288
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1289
+ commands << [child, "#{indent}│ │ "]
1290
+ end
1291
+ commands << [Replace.new("#{indent}│ └── "), indent]
1292
+ commands << [parts[-1], "#{indent}│ "]
1293
+ end
1294
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1295
+ end
1296
+
1297
+ # Inspect a InterpolatedXStringNode node.
1298
+ def visit_interpolated_x_string_node(node)
1299
+ commands << [inspect_node("InterpolatedXStringNode", node), indent]
1300
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1301
+ commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent]
1302
+ if parts.any?
1303
+ parts[0...-1].each do |child|
1304
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1305
+ commands << [child, "#{indent}│ │ "]
1306
+ end
1307
+ commands << [Replace.new("#{indent}│ └── "), indent]
1308
+ commands << [parts[-1], "#{indent}│ "]
1309
+ end
1310
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1311
+ end
1312
+
1313
+ # Inspect a ItParametersNode node.
1314
+ def visit_it_parameters_node(node)
1315
+ commands << [inspect_node("ItParametersNode", node), indent]
1316
+ end
1317
+
1318
+ # Inspect a KeywordHashNode node.
1319
+ def visit_keyword_hash_node(node)
1320
+ commands << [inspect_node("KeywordHashNode", node), indent]
1321
+ flags = [("symbol_keys" if node.symbol_keys?)].compact
1322
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1323
+ commands << ["└── elements: (length: #{(elements = node.elements).length})\n", indent]
1324
+ if elements.any?
1325
+ elements[0...-1].each do |child|
1326
+ commands << [Replace.new("#{indent} ├── "), indent]
1327
+ commands << [child, "#{indent} │ "]
1328
+ end
1329
+ commands << [Replace.new("#{indent} └── "), indent]
1330
+ commands << [elements[-1], "#{indent} "]
1331
+ end
1332
+ end
1333
+
1334
+ # Inspect a KeywordRestParameterNode node.
1335
+ def visit_keyword_rest_parameter_node(node)
1336
+ commands << [inspect_node("KeywordRestParameterNode", node), indent]
1337
+ flags = [("repeated_parameter" if node.repeated_parameter?)].compact
1338
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1339
+ if (name = node.name).nil?
1340
+ commands << ["├── name: ∅\n", indent]
1341
+ else
1342
+ commands << ["├── name: #{name.inspect}\n", indent]
1343
+ end
1344
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1345
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1346
+ end
1347
+
1348
+ # Inspect a LambdaNode node.
1349
+ def visit_lambda_node(node)
1350
+ commands << [inspect_node("LambdaNode", node), indent]
1351
+ commands << ["├── locals: #{node.locals.inspect}\n", indent]
1352
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1353
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1354
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1355
+ if (parameters = node.parameters).nil?
1356
+ commands << ["├── parameters: ∅\n", indent]
1357
+ else
1358
+ commands << ["├── parameters:\n", indent]
1359
+ commands << [parameters, "#{indent}│ "]
1360
+ end
1361
+ if (body = node.body).nil?
1362
+ commands << ["└── body: ∅\n", indent]
1363
+ else
1364
+ commands << ["└── body:\n", indent]
1365
+ commands << [body, "#{indent} "]
1366
+ end
1367
+ end
1368
+
1369
+ # Inspect a LocalVariableAndWriteNode node.
1370
+ def visit_local_variable_and_write_node(node)
1371
+ commands << [inspect_node("LocalVariableAndWriteNode", node), indent]
1372
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1373
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1374
+ commands << ["├── value:\n", indent]
1375
+ commands << [node.value, "#{indent}│ "]
1376
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1377
+ commands << ["└── depth: #{node.depth.inspect}\n", indent]
1378
+ end
1379
+
1380
+ # Inspect a LocalVariableOperatorWriteNode node.
1381
+ def visit_local_variable_operator_write_node(node)
1382
+ commands << [inspect_node("LocalVariableOperatorWriteNode", node), indent]
1383
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1384
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1385
+ commands << ["├── value:\n", indent]
1386
+ commands << [node.value, "#{indent}│ "]
1387
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1388
+ commands << ["├── operator: #{node.operator.inspect}\n", indent]
1389
+ commands << ["└── depth: #{node.depth.inspect}\n", indent]
1390
+ end
1391
+
1392
+ # Inspect a LocalVariableOrWriteNode node.
1393
+ def visit_local_variable_or_write_node(node)
1394
+ commands << [inspect_node("LocalVariableOrWriteNode", node), indent]
1395
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1396
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1397
+ commands << ["├── value:\n", indent]
1398
+ commands << [node.value, "#{indent}│ "]
1399
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1400
+ commands << ["└── depth: #{node.depth.inspect}\n", indent]
1401
+ end
1402
+
1403
+ # Inspect a LocalVariableReadNode node.
1404
+ def visit_local_variable_read_node(node)
1405
+ commands << [inspect_node("LocalVariableReadNode", node), indent]
1406
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1407
+ commands << ["└── depth: #{node.depth.inspect}\n", indent]
1408
+ end
1409
+
1410
+ # Inspect a LocalVariableTargetNode node.
1411
+ def visit_local_variable_target_node(node)
1412
+ commands << [inspect_node("LocalVariableTargetNode", node), indent]
1413
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1414
+ commands << ["└── depth: #{node.depth.inspect}\n", indent]
1415
+ end
1416
+
1417
+ # Inspect a LocalVariableWriteNode node.
1418
+ def visit_local_variable_write_node(node)
1419
+ commands << [inspect_node("LocalVariableWriteNode", node), indent]
1420
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1421
+ commands << ["├── depth: #{node.depth.inspect}\n", indent]
1422
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1423
+ commands << ["├── value:\n", indent]
1424
+ commands << [node.value, "#{indent}│ "]
1425
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1426
+ end
1427
+
1428
+ # Inspect a MatchLastLineNode node.
1429
+ def visit_match_last_line_node(node)
1430
+ commands << [inspect_node("MatchLastLineNode", node), indent]
1431
+ flags = [("ignore_case" if node.ignore_case?), ("extended" if node.extended?), ("multi_line" if node.multi_line?), ("once" if node.once?), ("euc_jp" if node.euc_jp?), ("ascii_8bit" if node.ascii_8bit?), ("windows_31j" if node.windows_31j?), ("utf_8" if node.utf_8?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact
1432
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1433
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1434
+ commands << ["├── content_loc: #{inspect_location(node.content_loc)}\n", indent]
1435
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1436
+ commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent]
1437
+ end
1438
+
1439
+ # Inspect a MatchPredicateNode node.
1440
+ def visit_match_predicate_node(node)
1441
+ commands << [inspect_node("MatchPredicateNode", node), indent]
1442
+ commands << ["├── value:\n", indent]
1443
+ commands << [node.value, "#{indent}│ "]
1444
+ commands << ["├── pattern:\n", indent]
1445
+ commands << [node.pattern, "#{indent}│ "]
1446
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1447
+ end
1448
+
1449
+ # Inspect a MatchRequiredNode node.
1450
+ def visit_match_required_node(node)
1451
+ commands << [inspect_node("MatchRequiredNode", node), indent]
1452
+ commands << ["├── value:\n", indent]
1453
+ commands << [node.value, "#{indent}│ "]
1454
+ commands << ["├── pattern:\n", indent]
1455
+ commands << [node.pattern, "#{indent}│ "]
1456
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1457
+ end
1458
+
1459
+ # Inspect a MatchWriteNode node.
1460
+ def visit_match_write_node(node)
1461
+ commands << [inspect_node("MatchWriteNode", node), indent]
1462
+ commands << ["├── call:\n", indent]
1463
+ commands << [node.call, "#{indent}│ "]
1464
+ commands << ["└── targets: (length: #{(targets = node.targets).length})\n", indent]
1465
+ if targets.any?
1466
+ targets[0...-1].each do |child|
1467
+ commands << [Replace.new("#{indent} ├── "), indent]
1468
+ commands << [child, "#{indent} │ "]
1469
+ end
1470
+ commands << [Replace.new("#{indent} └── "), indent]
1471
+ commands << [targets[-1], "#{indent} "]
1472
+ end
1473
+ end
1474
+
1475
+ # Inspect a MissingNode node.
1476
+ def visit_missing_node(node)
1477
+ commands << [inspect_node("MissingNode", node), indent]
1478
+ end
1479
+
1480
+ # Inspect a ModuleNode node.
1481
+ def visit_module_node(node)
1482
+ commands << [inspect_node("ModuleNode", node), indent]
1483
+ commands << ["├── locals: #{node.locals.inspect}\n", indent]
1484
+ commands << ["├── module_keyword_loc: #{inspect_location(node.module_keyword_loc)}\n", indent]
1485
+ commands << ["├── constant_path:\n", indent]
1486
+ commands << [node.constant_path, "#{indent}│ "]
1487
+ if (body = node.body).nil?
1488
+ commands << ["├── body: ∅\n", indent]
1489
+ else
1490
+ commands << ["├── body:\n", indent]
1491
+ commands << [body, "#{indent}│ "]
1492
+ end
1493
+ commands << ["├── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
1494
+ commands << ["└── name: #{node.name.inspect}\n", indent]
1495
+ end
1496
+
1497
+ # Inspect a MultiTargetNode node.
1498
+ def visit_multi_target_node(node)
1499
+ commands << [inspect_node("MultiTargetNode", node), indent]
1500
+ commands << ["├── lefts: (length: #{(lefts = node.lefts).length})\n", indent]
1501
+ if lefts.any?
1502
+ lefts[0...-1].each do |child|
1503
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1504
+ commands << [child, "#{indent}│ │ "]
1505
+ end
1506
+ commands << [Replace.new("#{indent}│ └── "), indent]
1507
+ commands << [lefts[-1], "#{indent}│ "]
1508
+ end
1509
+ if (rest = node.rest).nil?
1510
+ commands << ["├── rest: ∅\n", indent]
1511
+ else
1512
+ commands << ["├── rest:\n", indent]
1513
+ commands << [rest, "#{indent}│ "]
1514
+ end
1515
+ commands << ["├── rights: (length: #{(rights = node.rights).length})\n", indent]
1516
+ if rights.any?
1517
+ rights[0...-1].each do |child|
1518
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1519
+ commands << [child, "#{indent}│ │ "]
1520
+ end
1521
+ commands << [Replace.new("#{indent}│ └── "), indent]
1522
+ commands << [rights[-1], "#{indent}│ "]
1523
+ end
1524
+ commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent]
1525
+ commands << ["└── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent]
1526
+ end
1527
+
1528
+ # Inspect a MultiWriteNode node.
1529
+ def visit_multi_write_node(node)
1530
+ commands << [inspect_node("MultiWriteNode", node), indent]
1531
+ commands << ["├── lefts: (length: #{(lefts = node.lefts).length})\n", indent]
1532
+ if lefts.any?
1533
+ lefts[0...-1].each do |child|
1534
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1535
+ commands << [child, "#{indent}│ │ "]
1536
+ end
1537
+ commands << [Replace.new("#{indent}│ └── "), indent]
1538
+ commands << [lefts[-1], "#{indent}│ "]
1539
+ end
1540
+ if (rest = node.rest).nil?
1541
+ commands << ["├── rest: ∅\n", indent]
1542
+ else
1543
+ commands << ["├── rest:\n", indent]
1544
+ commands << [rest, "#{indent}│ "]
1545
+ end
1546
+ commands << ["├── rights: (length: #{(rights = node.rights).length})\n", indent]
1547
+ if rights.any?
1548
+ rights[0...-1].each do |child|
1549
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1550
+ commands << [child, "#{indent}│ │ "]
1551
+ end
1552
+ commands << [Replace.new("#{indent}│ └── "), indent]
1553
+ commands << [rights[-1], "#{indent}│ "]
1554
+ end
1555
+ commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent]
1556
+ commands << ["├── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent]
1557
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1558
+ commands << ["└── value:\n", indent]
1559
+ commands << [node.value, "#{indent} "]
1560
+ end
1561
+
1562
+ # Inspect a NextNode node.
1563
+ def visit_next_node(node)
1564
+ commands << [inspect_node("NextNode", node), indent]
1565
+ if (arguments = node.arguments).nil?
1566
+ commands << ["├── arguments: ∅\n", indent]
1567
+ else
1568
+ commands << ["├── arguments:\n", indent]
1569
+ commands << [arguments, "#{indent}│ "]
1570
+ end
1571
+ commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
1572
+ end
1573
+
1574
+ # Inspect a NilNode node.
1575
+ def visit_nil_node(node)
1576
+ commands << [inspect_node("NilNode", node), indent]
1577
+ end
1578
+
1579
+ # Inspect a NoKeywordsParameterNode node.
1580
+ def visit_no_keywords_parameter_node(node)
1581
+ commands << [inspect_node("NoKeywordsParameterNode", node), indent]
1582
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1583
+ commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
1584
+ end
1585
+
1586
+ # Inspect a NumberedParametersNode node.
1587
+ def visit_numbered_parameters_node(node)
1588
+ commands << [inspect_node("NumberedParametersNode", node), indent]
1589
+ commands << ["└── maximum: #{node.maximum.inspect}\n", indent]
1590
+ end
1591
+
1592
+ # Inspect a NumberedReferenceReadNode node.
1593
+ def visit_numbered_reference_read_node(node)
1594
+ commands << [inspect_node("NumberedReferenceReadNode", node), indent]
1595
+ commands << ["└── number: #{node.number.inspect}\n", indent]
1596
+ end
1597
+
1598
+ # Inspect a OptionalKeywordParameterNode node.
1599
+ def visit_optional_keyword_parameter_node(node)
1600
+ commands << [inspect_node("OptionalKeywordParameterNode", node), indent]
1601
+ flags = [("repeated_parameter" if node.repeated_parameter?)].compact
1602
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1603
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1604
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1605
+ commands << ["└── value:\n", indent]
1606
+ commands << [node.value, "#{indent} "]
1607
+ end
1608
+
1609
+ # Inspect a OptionalParameterNode node.
1610
+ def visit_optional_parameter_node(node)
1611
+ commands << [inspect_node("OptionalParameterNode", node), indent]
1612
+ flags = [("repeated_parameter" if node.repeated_parameter?)].compact
1613
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1614
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1615
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1616
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1617
+ commands << ["└── value:\n", indent]
1618
+ commands << [node.value, "#{indent} "]
1619
+ end
1620
+
1621
+ # Inspect a OrNode node.
1622
+ def visit_or_node(node)
1623
+ commands << [inspect_node("OrNode", node), indent]
1624
+ commands << ["├── left:\n", indent]
1625
+ commands << [node.left, "#{indent}│ "]
1626
+ commands << ["├── right:\n", indent]
1627
+ commands << [node.right, "#{indent}│ "]
1628
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1629
+ end
1630
+
1631
+ # Inspect a ParametersNode node.
1632
+ def visit_parameters_node(node)
1633
+ commands << [inspect_node("ParametersNode", node), indent]
1634
+ commands << ["├── requireds: (length: #{(requireds = node.requireds).length})\n", indent]
1635
+ if requireds.any?
1636
+ requireds[0...-1].each do |child|
1637
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1638
+ commands << [child, "#{indent}│ │ "]
1639
+ end
1640
+ commands << [Replace.new("#{indent}│ └── "), indent]
1641
+ commands << [requireds[-1], "#{indent}│ "]
1642
+ end
1643
+ commands << ["├── optionals: (length: #{(optionals = node.optionals).length})\n", indent]
1644
+ if optionals.any?
1645
+ optionals[0...-1].each do |child|
1646
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1647
+ commands << [child, "#{indent}│ │ "]
1648
+ end
1649
+ commands << [Replace.new("#{indent}│ └── "), indent]
1650
+ commands << [optionals[-1], "#{indent}│ "]
1651
+ end
1652
+ if (rest = node.rest).nil?
1653
+ commands << ["├── rest: ∅\n", indent]
1654
+ else
1655
+ commands << ["├── rest:\n", indent]
1656
+ commands << [rest, "#{indent}│ "]
1657
+ end
1658
+ commands << ["├── posts: (length: #{(posts = node.posts).length})\n", indent]
1659
+ if posts.any?
1660
+ posts[0...-1].each do |child|
1661
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1662
+ commands << [child, "#{indent}│ │ "]
1663
+ end
1664
+ commands << [Replace.new("#{indent}│ └── "), indent]
1665
+ commands << [posts[-1], "#{indent}│ "]
1666
+ end
1667
+ commands << ["├── keywords: (length: #{(keywords = node.keywords).length})\n", indent]
1668
+ if keywords.any?
1669
+ keywords[0...-1].each do |child|
1670
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1671
+ commands << [child, "#{indent}│ │ "]
1672
+ end
1673
+ commands << [Replace.new("#{indent}│ └── "), indent]
1674
+ commands << [keywords[-1], "#{indent}│ "]
1675
+ end
1676
+ if (keyword_rest = node.keyword_rest).nil?
1677
+ commands << ["├── keyword_rest: ∅\n", indent]
1678
+ else
1679
+ commands << ["├── keyword_rest:\n", indent]
1680
+ commands << [keyword_rest, "#{indent}│ "]
1681
+ end
1682
+ if (block = node.block).nil?
1683
+ commands << ["└── block: ∅\n", indent]
1684
+ else
1685
+ commands << ["└── block:\n", indent]
1686
+ commands << [block, "#{indent} "]
1687
+ end
1688
+ end
1689
+
1690
+ # Inspect a ParenthesesNode node.
1691
+ def visit_parentheses_node(node)
1692
+ commands << [inspect_node("ParenthesesNode", node), indent]
1693
+ if (body = node.body).nil?
1694
+ commands << ["├── body: ∅\n", indent]
1695
+ else
1696
+ commands << ["├── body:\n", indent]
1697
+ commands << [body, "#{indent}│ "]
1698
+ end
1699
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1700
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1701
+ end
1702
+
1703
+ # Inspect a PinnedExpressionNode node.
1704
+ def visit_pinned_expression_node(node)
1705
+ commands << [inspect_node("PinnedExpressionNode", node), indent]
1706
+ commands << ["├── expression:\n", indent]
1707
+ commands << [node.expression, "#{indent}│ "]
1708
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1709
+ commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent]
1710
+ commands << ["└── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent]
1711
+ end
1712
+
1713
+ # Inspect a PinnedVariableNode node.
1714
+ def visit_pinned_variable_node(node)
1715
+ commands << [inspect_node("PinnedVariableNode", node), indent]
1716
+ commands << ["├── variable:\n", indent]
1717
+ commands << [node.variable, "#{indent}│ "]
1718
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1719
+ end
1720
+
1721
+ # Inspect a PostExecutionNode node.
1722
+ def visit_post_execution_node(node)
1723
+ commands << [inspect_node("PostExecutionNode", node), indent]
1724
+ if (statements = node.statements).nil?
1725
+ commands << ["├── statements: ∅\n", indent]
1726
+ else
1727
+ commands << ["├── statements:\n", indent]
1728
+ commands << [statements, "#{indent}│ "]
1729
+ end
1730
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
1731
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1732
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1733
+ end
1734
+
1735
+ # Inspect a PreExecutionNode node.
1736
+ def visit_pre_execution_node(node)
1737
+ commands << [inspect_node("PreExecutionNode", node), indent]
1738
+ if (statements = node.statements).nil?
1739
+ commands << ["├── statements: ∅\n", indent]
1740
+ else
1741
+ commands << ["├── statements:\n", indent]
1742
+ commands << [statements, "#{indent}│ "]
1743
+ end
1744
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
1745
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1746
+ commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1747
+ end
1748
+
1749
+ # Inspect a ProgramNode node.
1750
+ def visit_program_node(node)
1751
+ commands << [inspect_node("ProgramNode", node), indent]
1752
+ commands << ["├── locals: #{node.locals.inspect}\n", indent]
1753
+ commands << ["└── statements:\n", indent]
1754
+ commands << [node.statements, "#{indent} "]
1755
+ end
1756
+
1757
+ # Inspect a RangeNode node.
1758
+ def visit_range_node(node)
1759
+ commands << [inspect_node("RangeNode", node), indent]
1760
+ flags = [("exclude_end" if node.exclude_end?)].compact
1761
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1762
+ if (left = node.left).nil?
1763
+ commands << ["├── left: ∅\n", indent]
1764
+ else
1765
+ commands << ["├── left:\n", indent]
1766
+ commands << [left, "#{indent}│ "]
1767
+ end
1768
+ if (right = node.right).nil?
1769
+ commands << ["├── right: ∅\n", indent]
1770
+ else
1771
+ commands << ["├── right:\n", indent]
1772
+ commands << [right, "#{indent}│ "]
1773
+ end
1774
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1775
+ end
1776
+
1777
+ # Inspect a RationalNode node.
1778
+ def visit_rational_node(node)
1779
+ commands << [inspect_node("RationalNode", node), indent]
1780
+ commands << ["└── numeric:\n", indent]
1781
+ commands << [node.numeric, "#{indent} "]
1782
+ end
1783
+
1784
+ # Inspect a RedoNode node.
1785
+ def visit_redo_node(node)
1786
+ commands << [inspect_node("RedoNode", node), indent]
1787
+ end
1788
+
1789
+ # Inspect a RegularExpressionNode node.
1790
+ def visit_regular_expression_node(node)
1791
+ commands << [inspect_node("RegularExpressionNode", node), indent]
1792
+ flags = [("ignore_case" if node.ignore_case?), ("extended" if node.extended?), ("multi_line" if node.multi_line?), ("once" if node.once?), ("euc_jp" if node.euc_jp?), ("ascii_8bit" if node.ascii_8bit?), ("windows_31j" if node.windows_31j?), ("utf_8" if node.utf_8?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact
1793
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1794
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1795
+ commands << ["├── content_loc: #{inspect_location(node.content_loc)}\n", indent]
1796
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1797
+ commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent]
1798
+ end
1799
+
1800
+ # Inspect a RequiredKeywordParameterNode node.
1801
+ def visit_required_keyword_parameter_node(node)
1802
+ commands << [inspect_node("RequiredKeywordParameterNode", node), indent]
1803
+ flags = [("repeated_parameter" if node.repeated_parameter?)].compact
1804
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1805
+ commands << ["├── name: #{node.name.inspect}\n", indent]
1806
+ commands << ["└── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1807
+ end
1808
+
1809
+ # Inspect a RequiredParameterNode node.
1810
+ def visit_required_parameter_node(node)
1811
+ commands << [inspect_node("RequiredParameterNode", node), indent]
1812
+ flags = [("repeated_parameter" if node.repeated_parameter?)].compact
1813
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1814
+ commands << ["└── name: #{node.name.inspect}\n", indent]
1815
+ end
1816
+
1817
+ # Inspect a RescueModifierNode node.
1818
+ def visit_rescue_modifier_node(node)
1819
+ commands << [inspect_node("RescueModifierNode", node), indent]
1820
+ commands << ["├── expression:\n", indent]
1821
+ commands << [node.expression, "#{indent}│ "]
1822
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
1823
+ commands << ["└── rescue_expression:\n", indent]
1824
+ commands << [node.rescue_expression, "#{indent} "]
1825
+ end
1826
+
1827
+ # Inspect a RescueNode node.
1828
+ def visit_rescue_node(node)
1829
+ commands << [inspect_node("RescueNode", node), indent]
1830
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
1831
+ commands << ["├── exceptions: (length: #{(exceptions = node.exceptions).length})\n", indent]
1832
+ if exceptions.any?
1833
+ exceptions[0...-1].each do |child|
1834
+ commands << [Replace.new("#{indent}│ ├── "), indent]
1835
+ commands << [child, "#{indent}│ │ "]
1836
+ end
1837
+ commands << [Replace.new("#{indent}│ └── "), indent]
1838
+ commands << [exceptions[-1], "#{indent}│ "]
1839
+ end
1840
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1841
+ if (reference = node.reference).nil?
1842
+ commands << ["├── reference: ∅\n", indent]
1843
+ else
1844
+ commands << ["├── reference:\n", indent]
1845
+ commands << [reference, "#{indent}│ "]
1846
+ end
1847
+ if (statements = node.statements).nil?
1848
+ commands << ["├── statements: ∅\n", indent]
1849
+ else
1850
+ commands << ["├── statements:\n", indent]
1851
+ commands << [statements, "#{indent}│ "]
1852
+ end
1853
+ if (consequent = node.consequent).nil?
1854
+ commands << ["└── consequent: ∅\n", indent]
1855
+ else
1856
+ commands << ["└── consequent:\n", indent]
1857
+ commands << [consequent, "#{indent} "]
1858
+ end
1859
+ end
1860
+
1861
+ # Inspect a RestParameterNode node.
1862
+ def visit_rest_parameter_node(node)
1863
+ commands << [inspect_node("RestParameterNode", node), indent]
1864
+ flags = [("repeated_parameter" if node.repeated_parameter?)].compact
1865
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1866
+ if (name = node.name).nil?
1867
+ commands << ["├── name: ∅\n", indent]
1868
+ else
1869
+ commands << ["├── name: #{name.inspect}\n", indent]
1870
+ end
1871
+ commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent]
1872
+ commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1873
+ end
1874
+
1875
+ # Inspect a RetryNode node.
1876
+ def visit_retry_node(node)
1877
+ commands << [inspect_node("RetryNode", node), indent]
1878
+ end
1879
+
1880
+ # Inspect a ReturnNode node.
1881
+ def visit_return_node(node)
1882
+ commands << [inspect_node("ReturnNode", node), indent]
1883
+ flags = [("redundant" if node.redundant?)].compact
1884
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1885
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
1886
+ if (arguments = node.arguments).nil?
1887
+ commands << ["└── arguments: ∅\n", indent]
1888
+ else
1889
+ commands << ["└── arguments:\n", indent]
1890
+ commands << [arguments, "#{indent} "]
1891
+ end
1892
+ end
1893
+
1894
+ # Inspect a SelfNode node.
1895
+ def visit_self_node(node)
1896
+ commands << [inspect_node("SelfNode", node), indent]
1897
+ end
1898
+
1899
+ # Inspect a ShareableConstantNode node.
1900
+ def visit_shareable_constant_node(node)
1901
+ commands << [inspect_node("ShareableConstantNode", node), indent]
1902
+ flags = [("literal" if node.literal?), ("experimental_everything" if node.experimental_everything?), ("experimental_copy" if node.experimental_copy?)].compact
1903
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1904
+ commands << ["└── write:\n", indent]
1905
+ commands << [node.write, "#{indent} "]
1906
+ end
1907
+
1908
+ # Inspect a SingletonClassNode node.
1909
+ def visit_singleton_class_node(node)
1910
+ commands << [inspect_node("SingletonClassNode", node), indent]
1911
+ commands << ["├── locals: #{node.locals.inspect}\n", indent]
1912
+ commands << ["├── class_keyword_loc: #{inspect_location(node.class_keyword_loc)}\n", indent]
1913
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1914
+ commands << ["├── expression:\n", indent]
1915
+ commands << [node.expression, "#{indent}│ "]
1916
+ if (body = node.body).nil?
1917
+ commands << ["├── body: ∅\n", indent]
1918
+ else
1919
+ commands << ["├── body:\n", indent]
1920
+ commands << [body, "#{indent}│ "]
1921
+ end
1922
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
1923
+ end
1924
+
1925
+ # Inspect a SourceEncodingNode node.
1926
+ def visit_source_encoding_node(node)
1927
+ commands << [inspect_node("SourceEncodingNode", node), indent]
1928
+ end
1929
+
1930
+ # Inspect a SourceFileNode node.
1931
+ def visit_source_file_node(node)
1932
+ commands << [inspect_node("SourceFileNode", node), indent]
1933
+ flags = [("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("frozen" if node.frozen?), ("mutable" if node.mutable?)].compact
1934
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1935
+ commands << ["└── filepath: #{node.filepath.inspect}\n", indent]
1936
+ end
1937
+
1938
+ # Inspect a SourceLineNode node.
1939
+ def visit_source_line_node(node)
1940
+ commands << [inspect_node("SourceLineNode", node), indent]
1941
+ end
1942
+
1943
+ # Inspect a SplatNode node.
1944
+ def visit_splat_node(node)
1945
+ commands << [inspect_node("SplatNode", node), indent]
1946
+ commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent]
1947
+ if (expression = node.expression).nil?
1948
+ commands << ["└── expression: ∅\n", indent]
1949
+ else
1950
+ commands << ["└── expression:\n", indent]
1951
+ commands << [expression, "#{indent} "]
1952
+ end
1953
+ end
1954
+
1955
+ # Inspect a StatementsNode node.
1956
+ def visit_statements_node(node)
1957
+ commands << [inspect_node("StatementsNode", node), indent]
1958
+ commands << ["└── body: (length: #{(body = node.body).length})\n", indent]
1959
+ if body.any?
1960
+ body[0...-1].each do |child|
1961
+ commands << [Replace.new("#{indent} ├── "), indent]
1962
+ commands << [child, "#{indent} │ "]
1963
+ end
1964
+ commands << [Replace.new("#{indent} └── "), indent]
1965
+ commands << [body[-1], "#{indent} "]
1966
+ end
1967
+ end
1968
+
1969
+ # Inspect a StringNode node.
1970
+ def visit_string_node(node)
1971
+ commands << [inspect_node("StringNode", node), indent]
1972
+ flags = [("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("frozen" if node.frozen?), ("mutable" if node.mutable?)].compact
1973
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
1974
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
1975
+ commands << ["├── content_loc: #{inspect_location(node.content_loc)}\n", indent]
1976
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
1977
+ commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent]
1978
+ end
1979
+
1980
+ # Inspect a SuperNode node.
1981
+ def visit_super_node(node)
1982
+ commands << [inspect_node("SuperNode", node), indent]
1983
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
1984
+ commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent]
1985
+ if (arguments = node.arguments).nil?
1986
+ commands << ["├── arguments: ∅\n", indent]
1987
+ else
1988
+ commands << ["├── arguments:\n", indent]
1989
+ commands << [arguments, "#{indent}│ "]
1990
+ end
1991
+ commands << ["├── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent]
1992
+ if (block = node.block).nil?
1993
+ commands << ["└── block: ∅\n", indent]
1994
+ else
1995
+ commands << ["└── block:\n", indent]
1996
+ commands << [block, "#{indent} "]
1997
+ end
1998
+ end
1999
+
2000
+ # Inspect a SymbolNode node.
2001
+ def visit_symbol_node(node)
2002
+ commands << [inspect_node("SymbolNode", node), indent]
2003
+ flags = [("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact
2004
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
2005
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
2006
+ commands << ["├── value_loc: #{inspect_location(node.value_loc)}\n", indent]
2007
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
2008
+ commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent]
2009
+ end
2010
+
2011
+ # Inspect a TrueNode node.
2012
+ def visit_true_node(node)
2013
+ commands << [inspect_node("TrueNode", node), indent]
2014
+ end
2015
+
2016
+ # Inspect a UndefNode node.
2017
+ def visit_undef_node(node)
2018
+ commands << [inspect_node("UndefNode", node), indent]
2019
+ commands << ["├── names: (length: #{(names = node.names).length})\n", indent]
2020
+ if names.any?
2021
+ names[0...-1].each do |child|
2022
+ commands << [Replace.new("#{indent}│ ├── "), indent]
2023
+ commands << [child, "#{indent}│ │ "]
2024
+ end
2025
+ commands << [Replace.new("#{indent}│ └── "), indent]
2026
+ commands << [names[-1], "#{indent}│ "]
2027
+ end
2028
+ commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
2029
+ end
2030
+
2031
+ # Inspect a UnlessNode node.
2032
+ def visit_unless_node(node)
2033
+ commands << [inspect_node("UnlessNode", node), indent]
2034
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
2035
+ commands << ["├── predicate:\n", indent]
2036
+ commands << [node.predicate, "#{indent}│ "]
2037
+ commands << ["├── then_keyword_loc: #{inspect_location(node.then_keyword_loc)}\n", indent]
2038
+ if (statements = node.statements).nil?
2039
+ commands << ["├── statements: ∅\n", indent]
2040
+ else
2041
+ commands << ["├── statements:\n", indent]
2042
+ commands << [statements, "#{indent}│ "]
2043
+ end
2044
+ if (consequent = node.consequent).nil?
2045
+ commands << ["├── consequent: ∅\n", indent]
2046
+ else
2047
+ commands << ["├── consequent:\n", indent]
2048
+ commands << [consequent, "#{indent}│ "]
2049
+ end
2050
+ commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent]
2051
+ end
2052
+
2053
+ # Inspect a UntilNode node.
2054
+ def visit_until_node(node)
2055
+ commands << [inspect_node("UntilNode", node), indent]
2056
+ flags = [("begin_modifier" if node.begin_modifier?)].compact
2057
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
2058
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
2059
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
2060
+ commands << ["├── predicate:\n", indent]
2061
+ commands << [node.predicate, "#{indent}│ "]
2062
+ if (statements = node.statements).nil?
2063
+ commands << ["└── statements: ∅\n", indent]
2064
+ else
2065
+ commands << ["└── statements:\n", indent]
2066
+ commands << [statements, "#{indent} "]
2067
+ end
2068
+ end
2069
+
2070
+ # Inspect a WhenNode node.
2071
+ def visit_when_node(node)
2072
+ commands << [inspect_node("WhenNode", node), indent]
2073
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
2074
+ commands << ["├── conditions: (length: #{(conditions = node.conditions).length})\n", indent]
2075
+ if conditions.any?
2076
+ conditions[0...-1].each do |child|
2077
+ commands << [Replace.new("#{indent}│ ├── "), indent]
2078
+ commands << [child, "#{indent}│ │ "]
2079
+ end
2080
+ commands << [Replace.new("#{indent}│ └── "), indent]
2081
+ commands << [conditions[-1], "#{indent}│ "]
2082
+ end
2083
+ commands << ["├── then_keyword_loc: #{inspect_location(node.then_keyword_loc)}\n", indent]
2084
+ if (statements = node.statements).nil?
2085
+ commands << ["└── statements: ∅\n", indent]
2086
+ else
2087
+ commands << ["└── statements:\n", indent]
2088
+ commands << [statements, "#{indent} "]
2089
+ end
2090
+ end
2091
+
2092
+ # Inspect a WhileNode node.
2093
+ def visit_while_node(node)
2094
+ commands << [inspect_node("WhileNode", node), indent]
2095
+ flags = [("begin_modifier" if node.begin_modifier?)].compact
2096
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
2097
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
2098
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
2099
+ commands << ["├── predicate:\n", indent]
2100
+ commands << [node.predicate, "#{indent}│ "]
2101
+ if (statements = node.statements).nil?
2102
+ commands << ["└── statements: ∅\n", indent]
2103
+ else
2104
+ commands << ["└── statements:\n", indent]
2105
+ commands << [statements, "#{indent} "]
2106
+ end
2107
+ end
2108
+
2109
+ # Inspect a XStringNode node.
2110
+ def visit_x_string_node(node)
2111
+ commands << [inspect_node("XStringNode", node), indent]
2112
+ flags = [("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?)].compact
2113
+ commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
2114
+ commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent]
2115
+ commands << ["├── content_loc: #{inspect_location(node.content_loc)}\n", indent]
2116
+ commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent]
2117
+ commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent]
2118
+ end
2119
+
2120
+ # Inspect a YieldNode node.
2121
+ def visit_yield_node(node)
2122
+ commands << [inspect_node("YieldNode", node), indent]
2123
+ commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent]
2124
+ commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent]
2125
+ if (arguments = node.arguments).nil?
2126
+ commands << ["├── arguments: ∅\n", indent]
2127
+ else
2128
+ commands << ["├── arguments:\n", indent]
2129
+ commands << [arguments, "#{indent}│ "]
2130
+ end
2131
+ commands << ["└── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent]
2132
+ end
2133
+
2134
+ private
2135
+
2136
+ # Compose a header for the given node.
2137
+ def inspect_node(name, node)
2138
+ result = +"@ #{name} ("
2139
+
2140
+ location = node.location
2141
+ result << "location: (#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column})"
2142
+ result << ", newline: true" if node.newline?
2143
+
2144
+ result << ")\n"
2145
+ end
2146
+
2147
+ # Compose a string representing the given inner location field.
2148
+ def inspect_location(location)
2149
+ if location
2150
+ "(#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column}) = #{location.slice.inspect}"
2151
+ else
2152
+ "∅"
2153
+ end
2154
+ end
2155
+ end
2156
+ end