seafoam 0.11 → 0.14

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