seafoam 0.11 → 0.14

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.
@@ -1,5 +1,7 @@
1
- require 'json'
2
- require 'set'
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "set"
3
5
 
4
6
  module Seafoam
5
7
  # Implementations of the command-line commands that you can run in Seafoam.
@@ -12,7 +14,7 @@ module Seafoam
12
14
  def seafoam(*args)
13
15
  first, *args = args
14
16
 
15
- if first == '--json'
17
+ if first == "--json"
16
18
  formatter_module = Seafoam::Formatters::Json
17
19
  first, *args = args
18
20
  else
@@ -20,11 +22,11 @@ module Seafoam
20
22
  end
21
23
 
22
24
  case first
23
- when nil, 'help', '-h', '--help', '-help'
24
- raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
25
+ when nil, "help", "-h", "--help", "-help"
26
+ raise ArgumentError, "unexpected arguments #{args.join(" ")}" unless args.empty?
25
27
 
26
28
  help(*args)
27
- when 'version', '-v', '-version', '--version'
29
+ when "version", "-v", "-version", "--version"
28
30
  version(*args)
29
31
  else
30
32
  name = first
@@ -32,24 +34,24 @@ module Seafoam
32
34
  case command
33
35
  when nil
34
36
  help(*args)
35
- when 'info'
36
- info name, formatter_module, *args
37
- when 'list'
38
- list name, formatter_module, *args
39
- when 'search'
40
- search name, *args
41
- when 'edges'
42
- edges name, formatter_module, *args
43
- when 'props'
44
- props name, *args
45
- when 'source'
46
- source name, formatter_module, *args
47
- when 'render'
48
- render name, *args
49
- when 'debug'
50
- debug name, *args
51
- when 'describe'
52
- describe name, formatter_module, *args
37
+ when "info"
38
+ info(name, formatter_module, *args)
39
+ when "list"
40
+ list(name, formatter_module, *args)
41
+ when "search"
42
+ search(name, *args)
43
+ when "edges"
44
+ edges(name, formatter_module, *args)
45
+ when "props"
46
+ props(name, *args)
47
+ when "source"
48
+ source(name, formatter_module, *args)
49
+ when "render"
50
+ render(name, *args)
51
+ when "debug"
52
+ debug(name, *args)
53
+ when "describe"
54
+ describe(name, formatter_module, *args)
53
55
  else
54
56
  raise ArgumentError, "unknown command #{command}"
55
57
  end
@@ -59,14 +61,14 @@ module Seafoam
59
61
  # Run the bgv2isabelle command.
60
62
  def bgv2isabelle(*args)
61
63
  case args.first
62
- when nil, 'help', '-h', '--help', '-help'
64
+ when nil, "help", "-h", "--help", "-help"
63
65
  args = args.drop(1)
64
- raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
66
+ raise ArgumentError, "unexpected arguments #{args.join(" ")}" unless args.empty?
65
67
 
66
- @out.puts 'bgv2isabelle file.bgv...'
67
- @out.puts ' --help'
68
- @out.puts ' --version'
69
- when 'version', '-v', '-version', '--version'
68
+ @out.puts "bgv2isabelle file.bgv..."
69
+ @out.puts " --help"
70
+ @out.puts " --version"
71
+ when "version", "-v", "-version", "--version"
70
72
  args = args.drop(1)
71
73
  version(*args)
72
74
  else
@@ -74,10 +76,10 @@ module Seafoam
74
76
 
75
77
  until args.empty?
76
78
  arg = args.shift
77
- if arg.start_with?('-')
79
+ if arg.start_with?("-")
78
80
  raise ArgumentError, "unknown option #{arg}"
79
81
  else
80
- files.push arg
82
+ files.push(arg)
81
83
  end
82
84
  end
83
85
 
@@ -96,7 +98,7 @@ module Seafoam
96
98
  name = parser.graph_name(graph_header)
97
99
  graph = parser.read_graph
98
100
 
99
- writer.write index, name, graph
101
+ writer.write(index, name, graph)
100
102
  end
101
103
  end
102
104
  end
@@ -104,14 +106,14 @@ module Seafoam
104
106
 
105
107
  def bgv2json(*args)
106
108
  case args.first
107
- when nil, 'help', '-h', '--help', '-help'
109
+ when nil, "help", "-h", "--help", "-help"
108
110
  args = args.drop(1)
109
- raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
111
+ raise ArgumentError, "unexpected arguments #{args.join(" ")}" unless args.empty?
110
112
 
111
- @out.puts 'bgv2json file.bgv...'
112
- @out.puts ' --help'
113
- @out.puts ' --version'
114
- when 'version', '-v', '-version', '--version'
113
+ @out.puts "bgv2json file.bgv..."
114
+ @out.puts " --help"
115
+ @out.puts " --version"
116
+ when "version", "-v", "-version", "--version"
115
117
  args = args.drop(1)
116
118
  version(*args)
117
119
  else
@@ -119,10 +121,10 @@ module Seafoam
119
121
 
120
122
  until args.empty?
121
123
  arg = args.shift
122
- if arg.start_with?('-')
124
+ if arg.start_with?("-")
123
125
  raise ArgumentError, "unknown option #{arg}"
124
126
  else
125
- files.push arg
127
+ files.push(arg)
126
128
  end
127
129
  end
128
130
 
@@ -141,53 +143,9 @@ module Seafoam
141
143
  name = parser.graph_name(graph_header)
142
144
  graph = parser.read_graph
143
145
 
144
- writer.write name, graph
145
- end
146
- end
147
- end
148
- end
149
-
150
- def cfg2asm(*args)
151
- case args.first
152
- when nil, 'help', '-h', '--help', '-help'
153
- args = args.drop(1)
154
- raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
155
-
156
- @out.puts 'cfg2asm file.bgv...'
157
- @out.puts ' --no-comments'
158
- @out.puts ' --help'
159
- @out.puts ' --version'
160
- when 'version', '-v', '-version', '--version'
161
- args = args.drop(1)
162
- version(*args)
163
- else
164
- comments = true
165
- files = []
166
-
167
- until args.empty?
168
- arg = args.shift
169
- if arg.start_with?('-')
170
- case arg
171
- when '--no-comments'
172
- comments = false
173
- else
174
- raise ArgumentError, "unknown option #{arg}"
175
- end
176
- else
177
- files.push arg
146
+ writer.write(name, graph)
178
147
  end
179
148
  end
180
-
181
- files.each_with_index do |file, n|
182
- parser = Seafoam::CFG::CFGParser.new(@out, file)
183
- parser.skip_over_cfg 'After code installation'
184
- nmethod = parser.read_nmethod
185
-
186
- disassembler = Seafoam::CFG::Disassembler.new(@out)
187
- @out.puts if n.positive?
188
- @out.puts "[#{file}]"
189
- disassembler.disassemble(nmethod, comments)
190
- end
191
149
  end
192
150
  end
193
151
 
@@ -196,8 +154,8 @@ module Seafoam
196
154
  # seafoam file.bgv info
197
155
  def info(name, formatter_module, *args)
198
156
  file, *rest = parse_name(name)
199
- raise ArgumentError, 'info only works with a file' unless rest == [nil, nil, nil]
200
- raise ArgumentError, 'info does not take arguments' unless args.empty?
157
+ raise ArgumentError, "info only works with a file" unless rest == [nil, nil, nil]
158
+ raise ArgumentError, "info does not take arguments" unless args.empty?
201
159
 
202
160
  parser = BGV::BGVParser.new(file)
203
161
  major, minor = parser.read_file_header(version_check: false)
@@ -209,8 +167,8 @@ module Seafoam
209
167
  # seafoam file.bgv list
210
168
  def list(name, formatter_module, *args)
211
169
  file, *rest = parse_name(name)
212
- raise ArgumentError, 'list only works with a file' unless rest == [nil, nil, nil]
213
- raise ArgumentError, 'list does not take arguments' unless args.empty?
170
+ raise ArgumentError, "list only works with a file" unless rest == [nil, nil, nil]
171
+ raise ArgumentError, "list does not take arguments" unless args.empty?
214
172
 
215
173
  parser = BGV::BGVParser.new(file)
216
174
  parser.read_file_header
@@ -232,7 +190,7 @@ module Seafoam
232
190
  # seafoam file.bgv:n... search term...
233
191
  def search(name, *terms)
234
192
  file, graph_index, node_id, = parse_name(name)
235
- raise ArgumentError, 'search only works with a file or graph' if node_id
193
+ raise ArgumentError, "search only works with a file or graph" if node_id
236
194
 
237
195
  parser = BGV::BGVParser.new(file)
238
196
  parser.read_file_header
@@ -243,13 +201,13 @@ module Seafoam
243
201
 
244
202
  if !graph_index || index == graph_index
245
203
  header = parser.read_graph_header
246
- search_object "#{file}:#{index}", header, terms
204
+ search_object("#{file}:#{index}", header, terms)
247
205
  graph = parser.read_graph
248
206
  graph.nodes.each_value do |node|
249
- search_object "#{file}:#{index}:#{node.id}", node.props, terms
207
+ search_object("#{file}:#{index}:#{node.id}", node.props, terms)
250
208
  end
251
209
  graph.edges.each do |edge|
252
- search_object "#{file}:#{index}:#{edge.from.id}-#{edge.to.id}", edge.props, terms
210
+ search_object("#{file}:#{index}:#{edge.from.id}-#{edge.to.id}", edge.props, terms)
253
211
  end
254
212
  else
255
213
  parser.skip_graph_header
@@ -275,8 +233,8 @@ module Seafoam
275
233
  highlight_on = "\033[1m"
276
234
  highlight_off = "\033[0m"
277
235
  else
278
- highlight_on = ''
279
- highlight_off = ''
236
+ highlight_on = ""
237
+ highlight_off = ""
280
238
  end
281
239
  @out.puts "#{tag} ...#{before}#{highlight_on}#{match}#{highlight_off}#{after}..."
282
240
  start = index + t.size
@@ -287,8 +245,8 @@ module Seafoam
287
245
  # seafoam file.bgv:n... edges
288
246
  def edges(name, formatter_module, *args)
289
247
  file, graph_index, node_id, edge_id = parse_name(name)
290
- raise ArgumentError, 'edges needs at least a graph' unless graph_index
291
- raise ArgumentError, 'edges does not take arguments' unless args.empty?
248
+ raise ArgumentError, "edges needs at least a graph" unless graph_index
249
+ raise ArgumentError, "edges does not take arguments" unless args.empty?
292
250
 
293
251
  entry = nil
294
252
 
@@ -296,16 +254,16 @@ module Seafoam
296
254
  parser.read_graph_header
297
255
  graph = parser.read_graph
298
256
  if node_id
299
- Passes.apply graph
257
+ Passes.apply(graph)
300
258
  node = graph.nodes[node_id]
301
- raise ArgumentError, 'node not found' unless node
259
+ raise ArgumentError, "node not found" unless node
302
260
 
303
261
  if edge_id
304
262
  to = graph.nodes[edge_id]
305
- raise ArgumentError, 'edge node not found' unless to
263
+ raise ArgumentError, "edge node not found" unless to
306
264
 
307
265
  edges = node.outputs.select { |edge| edge.to == to }
308
- raise ArgumentError, 'edge not found' if edges.empty?
266
+ raise ArgumentError, "edge not found" if edges.empty?
309
267
 
310
268
  entry = formatter_module::EdgesFormatter::EdgesEntry.new(edges)
311
269
  else
@@ -323,8 +281,10 @@ module Seafoam
323
281
 
324
282
  # seafoam file.bgv... props
325
283
  def props(name, *args)
284
+ # rubocop:disable Metrics/BlockNesting
285
+
326
286
  file, graph_index, node_id, edge_id = parse_name(name)
327
- raise ArgumentError, 'props does not take arguments' unless args.empty?
287
+ raise ArgumentError, "props does not take arguments" unless args.empty?
328
288
 
329
289
  if graph_index
330
290
  with_graph(file, graph_index) do |parser|
@@ -332,29 +292,29 @@ module Seafoam
332
292
  if node_id
333
293
  graph = parser.read_graph
334
294
  node = graph.nodes[node_id]
335
- raise ArgumentError, 'node not found' unless node
295
+ raise ArgumentError, "node not found" unless node
336
296
 
337
297
  if edge_id
338
298
  to = graph.nodes[edge_id]
339
- raise ArgumentError, 'edge node not found' unless to
299
+ raise ArgumentError, "edge node not found" unless to
340
300
 
341
301
  edges = node.outputs.select { |edge| edge.to == to }
342
- raise ArgumentError, 'edge not found' if edges.empty?
302
+ raise ArgumentError, "edge not found" if edges.empty?
343
303
 
344
304
  if edges.size > 1
345
305
  edges.each do |edge|
346
- pretty_print edge.props
306
+ pretty_print(edge.props)
347
307
  @out.puts
348
308
  end
349
309
  else
350
- pretty_print edges.first.props
310
+ pretty_print(edges.first.props)
351
311
  end
352
312
  else
353
- pretty_print node.props
313
+ pretty_print(node.props)
354
314
  end
355
315
  break
356
316
  else
357
- pretty_print graph_header
317
+ pretty_print(graph_header)
358
318
  parser.skip_graph
359
319
  end
360
320
  end
@@ -362,24 +322,26 @@ module Seafoam
362
322
  parser = BGV::BGVParser.new(file)
363
323
  parser.read_file_header
364
324
  document_props = parser.read_document_props
365
- pretty_print document_props || {}
325
+ pretty_print(document_props || {})
366
326
  end
327
+
328
+ # rubocop:enable Metrics/BlockNesting
367
329
  end
368
330
 
369
331
  # seafoam file.bgv:n:n source
370
332
  def source(name, formatter_module, *args)
371
333
  file, graph_index, node_id, edge_id = parse_name(name)
372
- raise ArgumentError, 'source needs a node' unless node_id
373
- raise ArgumentError, 'source only works with a node' if edge_id
374
- raise ArgumentError, 'source does not take arguments' unless args.empty?
334
+ raise ArgumentError, "source needs a node" unless node_id
335
+ raise ArgumentError, "source only works with a node" if edge_id
336
+ raise ArgumentError, "source does not take arguments" unless args.empty?
375
337
 
376
338
  with_graph(file, graph_index) do |parser|
377
339
  parser.read_graph_header
378
340
  graph = parser.read_graph
379
341
  node = graph.nodes[node_id]
380
- raise ArgumentError, 'node not found' unless node
342
+ raise ArgumentError, "node not found" unless node
381
343
 
382
- formatter = formatter_module::SourceFormatter.new(node.props['nodeSourcePosition'])
344
+ formatter = formatter_module::SourceFormatter.new(node.props["nodeSourcePosition"])
383
345
  @out.puts formatter.format
384
346
  end
385
347
  end
@@ -389,9 +351,9 @@ module Seafoam
389
351
  file, graph_index, *rest = parse_name(name)
390
352
 
391
353
  if graph_index.nil? || !rest.all?(&:nil?)
392
- raise ArgumentError, 'describe only works with a graph'
354
+ raise ArgumentError, "describe only works with a graph"
393
355
  end
394
- raise ArgumentError, 'describe does not take arguments' unless args.empty?
356
+ raise ArgumentError, "describe does not take arguments" unless args.empty?
395
357
 
396
358
  parser = BGV::BGVParser.new(file)
397
359
  parser.read_file_header
@@ -412,19 +374,23 @@ module Seafoam
412
374
  description = Seafoam::Graal::GraphDescription.new
413
375
 
414
376
  graph.nodes.each_value do |node|
415
- node_class = node.props.dig(:node_class, :node_class)
377
+ node_class = node.node_class
378
+
379
+ simple_node_class = node_class[/([^.]+)$/, 1]
380
+ description.node_counts[simple_node_class] += 1
381
+
416
382
  case node_class
417
- when 'org.graalvm.compiler.nodes.IfNode'
383
+ when "org.graalvm.compiler.nodes.IfNode"
418
384
  description.branches = true
419
- when 'org.graalvm.compiler.nodes.LoopBeginNode'
385
+ when "org.graalvm.compiler.nodes.LoopBeginNode"
420
386
  description.loops = true
421
- when 'org.graalvm.compiler.nodes.InvokeNode', 'org.graalvm.compiler.nodes.InvokeWithExceptionNode'
387
+ when "org.graalvm.compiler.nodes.InvokeNode", "org.graalvm.compiler.nodes.InvokeWithExceptionNode"
422
388
  description.calls = true
423
389
  end
424
390
  end
425
391
 
426
392
  description.deopts = graph.nodes[0].outputs.map(&:to)
427
- .all? { |t| t.props.dig(:node_class, :node_class) == 'org.graalvm.compiler.nodes.DeoptimizeNode' }
393
+ .all? { |t| t.node_class == "org.graalvm.compiler.nodes.DeoptimizeNode" }
428
394
 
429
395
  formatter = formatter_module::DescribeFormatter.new(graph, description)
430
396
  @out.puts formatter.format
@@ -436,15 +402,18 @@ module Seafoam
436
402
  # seafoam file.bgv:n render options...
437
403
  def render(name, *args)
438
404
  file, graph_index, *rest = parse_name(name)
439
- raise ArgumentError, 'render needs at least a graph' unless graph_index
440
- raise ArgumentError, 'render only works with a graph' unless rest == [nil, nil]
405
+ raise ArgumentError, "render needs at least a graph" unless graph_index
406
+ raise ArgumentError, "render only works with a graph" unless rest == [nil, nil]
441
407
 
442
408
  pass_options = {
443
409
  simplify_truffle_args: true,
444
410
  hide_frame_state: true,
445
411
  hide_pi: true,
412
+ hide_begin_end: true,
446
413
  hide_floating: false,
447
- reduce_edges: true
414
+ reduce_edges: true,
415
+ simplify_alloc: true,
416
+ hide_null_fields: true,
448
417
  }
449
418
  spotlight_nodes = nil
450
419
  args = args.dup
@@ -454,85 +423,119 @@ module Seafoam
454
423
  until args.empty?
455
424
  arg = args.shift
456
425
  case arg
457
- when '--out'
426
+ when "--out"
458
427
  out_file = args.shift
459
428
  explicit_out_file = true
460
- raise ArgumentError, 'no file for --out' unless out_file
461
- when '--spotlight'
429
+ raise ArgumentError, "no file for --out" unless out_file
430
+
431
+ out_ext = File.extname(out_file).downcase
432
+ case out_ext
433
+ when ".pdf"
434
+ out_format = :pdf
435
+ when ".svg"
436
+ out_format = :svg
437
+ when ".png"
438
+ out_format = :png
439
+ when ".dot"
440
+ out_format = :dot
441
+ when ".mmd"
442
+ out_format = :mmd
443
+ when ".md"
444
+ out_format = :md
445
+ else
446
+ raise ArgumentError, "unknown render format #{out_ext}"
447
+ end
448
+ when "--md"
449
+ out_file = @out
450
+ out_format = :md
451
+ explicit_out_file = true
452
+ when "--spotlight"
462
453
  spotlight_arg = args.shift
463
- raise ArgumentError, 'no list for --spotlight' unless spotlight_arg
454
+ raise ArgumentError, "no list for --spotlight" unless spotlight_arg
464
455
 
465
- spotlight_nodes = spotlight_arg.split(',').map { |n| Integer(n) }
466
- when '--full-truffle-args'
456
+ spotlight_nodes = spotlight_arg.split(",").map { |n| Integer(n) }
457
+ when "--full-truffle-args"
467
458
  pass_options[:simplify_truffle_args] = false
468
- when '--show-frame-state'
459
+ when "--no-simplify-alloc"
460
+ pass_options[:simplify_alloc] = false
461
+ when "--show-null-fields"
462
+ pass_options[:hide_null_fields] = false
463
+ when "--show-frame-state"
469
464
  pass_options[:hide_frame_state] = false
470
- when '--show-pi'
465
+ when "--show-pi"
471
466
  pass_options[:hide_pi] = false
472
- when '--hide-floating'
467
+ when "--show-begin-end"
468
+ pass_options[:hide_begin_end] = false
469
+ when "--hide-floating"
473
470
  pass_options[:hide_floating] = true
474
- when '--no-reduce-edges'
471
+ when "--no-reduce-edges"
475
472
  pass_options[:reduce_edges] = false
476
- when '--draw-blocks'
473
+ when "--draw-blocks"
477
474
  draw_blocks = true
478
- when '--option'
475
+ when "--option"
479
476
  key = args.shift
480
- raise ArgumentError, 'no key for --option' unless key
477
+ raise ArgumentError, "no key for --option" unless key
481
478
 
482
479
  value = args.shift
483
480
  raise ArgumentError, "no value for --option #{key}" unless out_file
484
481
 
485
- value = { 'true' => true, 'false' => 'false' }.fetch(key, value)
482
+ value = { "true" => true, "false" => "false" }.fetch(key, value)
486
483
  pass_options[key.to_sym] = value
487
484
  else
488
485
  raise ArgumentError, "unexpected option #{arg}"
489
486
  end
490
487
  end
491
- out_file ||= 'graph.pdf'
492
- out_ext = File.extname(out_file).downcase
493
- case out_ext
494
- when '.pdf'
495
- out_format = :pdf
496
- when '.svg'
497
- out_format = :svg
498
- when '.png'
499
- out_format = :png
500
- when '.dot'
501
- out_format = :dot
502
- else
503
- raise ArgumentError, "unknown render format #{out_ext}"
504
- end
505
-
488
+ out_file ||= "graph.pdf"
489
+ out_format ||= :pdf
506
490
  with_graph(file, graph_index) do |parser|
507
491
  parser.skip_graph_header
508
492
  graph = parser.read_graph
509
- Passes.apply graph, pass_options
493
+ Passes.apply(graph, pass_options)
510
494
  if spotlight_nodes
511
495
  spotlight = Spotlight.new(graph)
512
496
  spotlight_nodes.each do |node_id|
513
497
  node = graph.nodes[node_id]
514
- raise ArgumentError, 'node not found' unless node
498
+ raise ArgumentError, "node not found" unless node
515
499
 
516
- spotlight.light node
500
+ spotlight.light(node)
517
501
  end
518
502
  spotlight.shade
519
503
  end
520
- if out_format == :dot
521
- File.open(out_file, 'w') do |stream|
522
- writer = GraphvizWriter.new(stream)
523
- writer.write_graph graph, false, draw_blocks
504
+ case out_format
505
+ when :dot, :mmd, :md
506
+ action = lambda do |stream|
507
+ case out_format
508
+ when :dot
509
+ writer = GraphvizWriter.new(stream)
510
+ writer.write_graph(graph, false, draw_blocks)
511
+ when :mmd
512
+ writer = MermaidWriter.new(stream)
513
+ writer.write_graph(graph, false, draw_blocks)
514
+ when :md
515
+ writer = MarkdownWriter.new(stream)
516
+ writer.write_graph(graph)
517
+ else
518
+ raise
519
+ end
520
+ end
521
+ if out_file.is_a?(String)
522
+ File.open(out_file, "w") do |stream|
523
+ action.call(stream)
524
+ end
525
+ else
526
+ action.call(out_file)
524
527
  end
525
528
  else
526
529
  begin
527
- IO.popen(['dot', "-T#{out_format}", '-o', out_file], 'w') do |stream|
530
+ IO.popen(["dot", "-T#{out_format}", "-o", out_file], "w") do |stream|
528
531
  writer = GraphvizWriter.new(stream)
529
532
  hidpi = out_format == :png
530
- writer.write_graph graph, hidpi, draw_blocks
533
+ writer.write_graph(graph, hidpi, draw_blocks)
531
534
  end
532
535
  rescue Errno::ENOENT
533
- raise 'Could not run Graphviz - is it installed?'
536
+ raise "Could not run Graphviz - is it installed?"
534
537
  end
535
- autoopen out_file unless explicit_out_file
538
+ autoopen(out_file) unless explicit_out_file
536
539
  end
537
540
  end
538
541
  end
@@ -540,12 +543,12 @@ module Seafoam
540
543
  # seafoam file.bgv debug options...
541
544
  def debug(name, *args)
542
545
  file, *rest = parse_name(name)
543
- raise ArgumentError, 'debug only works with a file' unless rest == [nil, nil, nil]
546
+ raise ArgumentError, "debug only works with a file" unless rest == [nil, nil, nil]
544
547
 
545
548
  skip = false
546
549
  args.each do |arg|
547
550
  case arg
548
- when '--skip'
551
+ when "--skip"
549
552
  skip = true
550
553
  else
551
554
  raise ArgumentError, "unexpected option #{arg}"
@@ -555,10 +558,10 @@ module Seafoam
555
558
  File.open(file) do |stream|
556
559
  parser = BGVDebugParser.new(@out, stream)
557
560
  begin
558
- pretty_print parser.read_file_header
561
+ pretty_print(parser.read_file_header)
559
562
  document_props = parser.read_document_props
560
563
  if document_props
561
- pretty_print document_props
564
+ pretty_print(document_props)
562
565
  end
563
566
  loop do
564
567
  index, id = parser.read_graph_preheader
@@ -569,8 +572,8 @@ module Seafoam
569
572
  parser.skip_graph_header
570
573
  parser.skip_graph
571
574
  else
572
- pretty_print parser.read_graph_header
573
- pretty_print parser.read_graph
575
+ pretty_print(parser.read_graph_header)
576
+ pretty_print(parser.read_graph)
574
577
  end
575
578
  end
576
579
  rescue StandardError => e
@@ -613,53 +616,58 @@ module Seafoam
613
616
  parser.skip_graph
614
617
  end
615
618
  end
616
- raise ArgumentError, 'graph not found' unless graph_found
619
+ raise ArgumentError, "graph not found" unless graph_found
617
620
  end
618
621
 
619
622
  # Prints help.
620
623
  def help(*_args)
621
- @out.puts 'seafoam file.bgv info'
622
- @out.puts ' file.bgv list'
623
- @out.puts ' file.bgv[:graph][:node[-edge]] search term...'
624
- @out.puts ' file.bgv[:graph][:node[-edge]] edges'
625
- @out.puts ' file.bgv[:graph][:node[-edge]] props'
626
- @out.puts ' file.bgv:graph:node source'
627
- @out.puts ' file.bgv:graph describe'
628
- @out.puts ' file.bgv:graph render'
629
- @out.puts ' --spotlight n,n,n...'
630
- @out.puts ' --out graph.pdf'
631
- @out.puts ' graph.svg'
632
- @out.puts ' graph.png'
633
- @out.puts ' graph.dot'
634
- @out.puts ' --full-truffle-args'
635
- @out.puts ' --show-frame-state'
636
- @out.puts ' --show-pi'
637
- @out.puts ' --hide-floating'
638
- @out.puts ' --no-reduce-edges'
639
- @out.puts ' --draw-blocks'
640
- @out.puts ' --option key value'
641
- @out.puts ' --help'
642
- @out.puts ' --version'
624
+ @out.puts "seafoam file.bgv info"
625
+ @out.puts " file.bgv list"
626
+ @out.puts " file.bgv[:graph][:node[-edge]] search term..."
627
+ @out.puts " file.bgv[:graph][:node[-edge]] edges"
628
+ @out.puts " file.bgv[:graph][:node[-edge]] props"
629
+ @out.puts " file.bgv:graph:node source"
630
+ @out.puts " file.bgv:graph describe"
631
+ @out.puts " file.bgv:graph render"
632
+ @out.puts " --spotlight n,n,n..."
633
+ @out.puts " --out graph.pdf"
634
+ @out.puts " graph.svg"
635
+ @out.puts " graph.png"
636
+ @out.puts " graph.dot (Graphviz)"
637
+ @out.puts " graph.mmd (Mermaid)"
638
+ @out.puts " graph.md (Markdown)"
639
+ @out.puts " --full-truffle-args"
640
+ @out.puts " --show-frame-state"
641
+ @out.puts " --no-simplify-alloc"
642
+ @out.puts " --show-null-fields"
643
+ @out.puts " --show-pi"
644
+ @out.puts " --show-begin-end"
645
+ @out.puts " --hide-floating"
646
+ @out.puts " --no-reduce-edges"
647
+ @out.puts " --draw-blocks"
648
+ @out.puts " --option key value"
649
+ @out.puts " --help"
650
+ @out.puts " --version"
643
651
  end
644
652
 
645
653
  # Prints the version.
646
654
  def version(*args)
647
- raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
655
+ raise ArgumentError, "unexpected arguments #{args.join(" ")}" unless args.empty?
648
656
 
649
657
  @out.puts "seafoam #{VERSION}"
650
658
  end
651
659
 
652
660
  # Parse a name like file.bgv:g:n-e to [file.bgv, g, n, e].
653
661
  def parse_name(name)
654
- *pre, post = name.split('.')
662
+ *pre, post = name.split(".")
655
663
 
656
- file_ext, graph, node, *rest = post.split(':')
664
+ file_ext, graph, node, *rest = post.split(":")
657
665
  raise ArgumentError, "too many parts to .ext:g:n-e in #{name}" unless rest.empty?
658
666
 
659
- file = [*pre, file_ext].join('.')
667
+ file = [*pre, file_ext].join(".")
660
668
 
661
669
  if node
662
- node, edge, *rest = node.split('-')
670
+ node, edge, *rest = node.split("-")
663
671
  raise ArgumentError, "too many parts to edge name in #{name}" unless rest.empty?
664
672
  else
665
673
  node = nil
@@ -679,9 +687,9 @@ module Seafoam
679
687
 
680
688
  case RUBY_PLATFORM
681
689
  when /darwin/
682
- system 'open', file
690
+ system("open", file)
683
691
  when /linux/
684
- system 'xdg-open', file
692
+ system("xdg-open", file)
685
693
  end
686
694
  # Don't worry if it fails.
687
695
  end