seafoam 0.13 → 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,7 +143,7 @@ module Seafoam
141
143
  name = parser.graph_name(graph_header)
142
144
  graph = parser.read_graph
143
145
 
144
- writer.write name, graph
146
+ writer.write(name, graph)
145
147
  end
146
148
  end
147
149
  end
@@ -152,8 +154,8 @@ module Seafoam
152
154
  # seafoam file.bgv info
153
155
  def info(name, formatter_module, *args)
154
156
  file, *rest = parse_name(name)
155
- raise ArgumentError, 'info only works with a file' unless rest == [nil, nil, nil]
156
- 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?
157
159
 
158
160
  parser = BGV::BGVParser.new(file)
159
161
  major, minor = parser.read_file_header(version_check: false)
@@ -165,8 +167,8 @@ module Seafoam
165
167
  # seafoam file.bgv list
166
168
  def list(name, formatter_module, *args)
167
169
  file, *rest = parse_name(name)
168
- raise ArgumentError, 'list only works with a file' unless rest == [nil, nil, nil]
169
- 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?
170
172
 
171
173
  parser = BGV::BGVParser.new(file)
172
174
  parser.read_file_header
@@ -188,7 +190,7 @@ module Seafoam
188
190
  # seafoam file.bgv:n... search term...
189
191
  def search(name, *terms)
190
192
  file, graph_index, node_id, = parse_name(name)
191
- 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
192
194
 
193
195
  parser = BGV::BGVParser.new(file)
194
196
  parser.read_file_header
@@ -199,13 +201,13 @@ module Seafoam
199
201
 
200
202
  if !graph_index || index == graph_index
201
203
  header = parser.read_graph_header
202
- search_object "#{file}:#{index}", header, terms
204
+ search_object("#{file}:#{index}", header, terms)
203
205
  graph = parser.read_graph
204
206
  graph.nodes.each_value do |node|
205
- search_object "#{file}:#{index}:#{node.id}", node.props, terms
207
+ search_object("#{file}:#{index}:#{node.id}", node.props, terms)
206
208
  end
207
209
  graph.edges.each do |edge|
208
- 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)
209
211
  end
210
212
  else
211
213
  parser.skip_graph_header
@@ -231,8 +233,8 @@ module Seafoam
231
233
  highlight_on = "\033[1m"
232
234
  highlight_off = "\033[0m"
233
235
  else
234
- highlight_on = ''
235
- highlight_off = ''
236
+ highlight_on = ""
237
+ highlight_off = ""
236
238
  end
237
239
  @out.puts "#{tag} ...#{before}#{highlight_on}#{match}#{highlight_off}#{after}..."
238
240
  start = index + t.size
@@ -243,8 +245,8 @@ module Seafoam
243
245
  # seafoam file.bgv:n... edges
244
246
  def edges(name, formatter_module, *args)
245
247
  file, graph_index, node_id, edge_id = parse_name(name)
246
- raise ArgumentError, 'edges needs at least a graph' unless graph_index
247
- 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?
248
250
 
249
251
  entry = nil
250
252
 
@@ -252,16 +254,16 @@ module Seafoam
252
254
  parser.read_graph_header
253
255
  graph = parser.read_graph
254
256
  if node_id
255
- Passes.apply graph
257
+ Passes.apply(graph)
256
258
  node = graph.nodes[node_id]
257
- raise ArgumentError, 'node not found' unless node
259
+ raise ArgumentError, "node not found" unless node
258
260
 
259
261
  if edge_id
260
262
  to = graph.nodes[edge_id]
261
- raise ArgumentError, 'edge node not found' unless to
263
+ raise ArgumentError, "edge node not found" unless to
262
264
 
263
265
  edges = node.outputs.select { |edge| edge.to == to }
264
- raise ArgumentError, 'edge not found' if edges.empty?
266
+ raise ArgumentError, "edge not found" if edges.empty?
265
267
 
266
268
  entry = formatter_module::EdgesFormatter::EdgesEntry.new(edges)
267
269
  else
@@ -279,8 +281,10 @@ module Seafoam
279
281
 
280
282
  # seafoam file.bgv... props
281
283
  def props(name, *args)
284
+ # rubocop:disable Metrics/BlockNesting
285
+
282
286
  file, graph_index, node_id, edge_id = parse_name(name)
283
- raise ArgumentError, 'props does not take arguments' unless args.empty?
287
+ raise ArgumentError, "props does not take arguments" unless args.empty?
284
288
 
285
289
  if graph_index
286
290
  with_graph(file, graph_index) do |parser|
@@ -288,29 +292,29 @@ module Seafoam
288
292
  if node_id
289
293
  graph = parser.read_graph
290
294
  node = graph.nodes[node_id]
291
- raise ArgumentError, 'node not found' unless node
295
+ raise ArgumentError, "node not found" unless node
292
296
 
293
297
  if edge_id
294
298
  to = graph.nodes[edge_id]
295
- raise ArgumentError, 'edge node not found' unless to
299
+ raise ArgumentError, "edge node not found" unless to
296
300
 
297
301
  edges = node.outputs.select { |edge| edge.to == to }
298
- raise ArgumentError, 'edge not found' if edges.empty?
302
+ raise ArgumentError, "edge not found" if edges.empty?
299
303
 
300
304
  if edges.size > 1
301
305
  edges.each do |edge|
302
- pretty_print edge.props
306
+ pretty_print(edge.props)
303
307
  @out.puts
304
308
  end
305
309
  else
306
- pretty_print edges.first.props
310
+ pretty_print(edges.first.props)
307
311
  end
308
312
  else
309
- pretty_print node.props
313
+ pretty_print(node.props)
310
314
  end
311
315
  break
312
316
  else
313
- pretty_print graph_header
317
+ pretty_print(graph_header)
314
318
  parser.skip_graph
315
319
  end
316
320
  end
@@ -318,24 +322,26 @@ module Seafoam
318
322
  parser = BGV::BGVParser.new(file)
319
323
  parser.read_file_header
320
324
  document_props = parser.read_document_props
321
- pretty_print document_props || {}
325
+ pretty_print(document_props || {})
322
326
  end
327
+
328
+ # rubocop:enable Metrics/BlockNesting
323
329
  end
324
330
 
325
331
  # seafoam file.bgv:n:n source
326
332
  def source(name, formatter_module, *args)
327
333
  file, graph_index, node_id, edge_id = parse_name(name)
328
- raise ArgumentError, 'source needs a node' unless node_id
329
- raise ArgumentError, 'source only works with a node' if edge_id
330
- 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?
331
337
 
332
338
  with_graph(file, graph_index) do |parser|
333
339
  parser.read_graph_header
334
340
  graph = parser.read_graph
335
341
  node = graph.nodes[node_id]
336
- raise ArgumentError, 'node not found' unless node
342
+ raise ArgumentError, "node not found" unless node
337
343
 
338
- formatter = formatter_module::SourceFormatter.new(node.props['nodeSourcePosition'])
344
+ formatter = formatter_module::SourceFormatter.new(node.props["nodeSourcePosition"])
339
345
  @out.puts formatter.format
340
346
  end
341
347
  end
@@ -345,9 +351,9 @@ module Seafoam
345
351
  file, graph_index, *rest = parse_name(name)
346
352
 
347
353
  if graph_index.nil? || !rest.all?(&:nil?)
348
- raise ArgumentError, 'describe only works with a graph'
354
+ raise ArgumentError, "describe only works with a graph"
349
355
  end
350
- raise ArgumentError, 'describe does not take arguments' unless args.empty?
356
+ raise ArgumentError, "describe does not take arguments" unless args.empty?
351
357
 
352
358
  parser = BGV::BGVParser.new(file)
353
359
  parser.read_file_header
@@ -368,19 +374,23 @@ module Seafoam
368
374
  description = Seafoam::Graal::GraphDescription.new
369
375
 
370
376
  graph.nodes.each_value do |node|
371
- 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
+
372
382
  case node_class
373
- when 'org.graalvm.compiler.nodes.IfNode'
383
+ when "org.graalvm.compiler.nodes.IfNode"
374
384
  description.branches = true
375
- when 'org.graalvm.compiler.nodes.LoopBeginNode'
385
+ when "org.graalvm.compiler.nodes.LoopBeginNode"
376
386
  description.loops = true
377
- when 'org.graalvm.compiler.nodes.InvokeNode', 'org.graalvm.compiler.nodes.InvokeWithExceptionNode'
387
+ when "org.graalvm.compiler.nodes.InvokeNode", "org.graalvm.compiler.nodes.InvokeWithExceptionNode"
378
388
  description.calls = true
379
389
  end
380
390
  end
381
391
 
382
392
  description.deopts = graph.nodes[0].outputs.map(&:to)
383
- .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" }
384
394
 
385
395
  formatter = formatter_module::DescribeFormatter.new(graph, description)
386
396
  @out.puts formatter.format
@@ -392,15 +402,18 @@ module Seafoam
392
402
  # seafoam file.bgv:n render options...
393
403
  def render(name, *args)
394
404
  file, graph_index, *rest = parse_name(name)
395
- raise ArgumentError, 'render needs at least a graph' unless graph_index
396
- 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]
397
407
 
398
408
  pass_options = {
399
409
  simplify_truffle_args: true,
400
410
  hide_frame_state: true,
401
411
  hide_pi: true,
412
+ hide_begin_end: true,
402
413
  hide_floating: false,
403
- reduce_edges: true
414
+ reduce_edges: true,
415
+ simplify_alloc: true,
416
+ hide_null_fields: true,
404
417
  }
405
418
  spotlight_nodes = nil
406
419
  args = args.dup
@@ -410,75 +423,81 @@ module Seafoam
410
423
  until args.empty?
411
424
  arg = args.shift
412
425
  case arg
413
- when '--out'
426
+ when "--out"
414
427
  out_file = args.shift
415
428
  explicit_out_file = true
416
- raise ArgumentError, 'no file for --out' unless out_file
429
+ raise ArgumentError, "no file for --out" unless out_file
417
430
 
418
431
  out_ext = File.extname(out_file).downcase
419
432
  case out_ext
420
- when '.pdf'
433
+ when ".pdf"
421
434
  out_format = :pdf
422
- when '.svg'
435
+ when ".svg"
423
436
  out_format = :svg
424
- when '.png'
437
+ when ".png"
425
438
  out_format = :png
426
- when '.dot'
439
+ when ".dot"
427
440
  out_format = :dot
428
- when '.mmd'
441
+ when ".mmd"
429
442
  out_format = :mmd
430
- when '.md'
443
+ when ".md"
431
444
  out_format = :md
432
445
  else
433
446
  raise ArgumentError, "unknown render format #{out_ext}"
434
447
  end
435
- when '--md'
448
+ when "--md"
436
449
  out_file = @out
437
450
  out_format = :md
438
451
  explicit_out_file = true
439
- when '--spotlight'
452
+ when "--spotlight"
440
453
  spotlight_arg = args.shift
441
- raise ArgumentError, 'no list for --spotlight' unless spotlight_arg
454
+ raise ArgumentError, "no list for --spotlight" unless spotlight_arg
442
455
 
443
- spotlight_nodes = spotlight_arg.split(',').map { |n| Integer(n) }
444
- when '--full-truffle-args'
456
+ spotlight_nodes = spotlight_arg.split(",").map { |n| Integer(n) }
457
+ when "--full-truffle-args"
445
458
  pass_options[:simplify_truffle_args] = false
446
- 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"
447
464
  pass_options[:hide_frame_state] = false
448
- when '--show-pi'
465
+ when "--show-pi"
449
466
  pass_options[:hide_pi] = false
450
- when '--hide-floating'
467
+ when "--show-begin-end"
468
+ pass_options[:hide_begin_end] = false
469
+ when "--hide-floating"
451
470
  pass_options[:hide_floating] = true
452
- when '--no-reduce-edges'
471
+ when "--no-reduce-edges"
453
472
  pass_options[:reduce_edges] = false
454
- when '--draw-blocks'
473
+ when "--draw-blocks"
455
474
  draw_blocks = true
456
- when '--option'
475
+ when "--option"
457
476
  key = args.shift
458
- raise ArgumentError, 'no key for --option' unless key
477
+ raise ArgumentError, "no key for --option" unless key
459
478
 
460
479
  value = args.shift
461
480
  raise ArgumentError, "no value for --option #{key}" unless out_file
462
481
 
463
- value = { 'true' => true, 'false' => 'false' }.fetch(key, value)
482
+ value = { "true" => true, "false" => "false" }.fetch(key, value)
464
483
  pass_options[key.to_sym] = value
465
484
  else
466
485
  raise ArgumentError, "unexpected option #{arg}"
467
486
  end
468
487
  end
469
- out_file ||= 'graph.pdf'
488
+ out_file ||= "graph.pdf"
470
489
  out_format ||= :pdf
471
490
  with_graph(file, graph_index) do |parser|
472
491
  parser.skip_graph_header
473
492
  graph = parser.read_graph
474
- Passes.apply graph, pass_options
493
+ Passes.apply(graph, pass_options)
475
494
  if spotlight_nodes
476
495
  spotlight = Spotlight.new(graph)
477
496
  spotlight_nodes.each do |node_id|
478
497
  node = graph.nodes[node_id]
479
- raise ArgumentError, 'node not found' unless node
498
+ raise ArgumentError, "node not found" unless node
480
499
 
481
- spotlight.light node
500
+ spotlight.light(node)
482
501
  end
483
502
  spotlight.shade
484
503
  end
@@ -488,35 +507,35 @@ module Seafoam
488
507
  case out_format
489
508
  when :dot
490
509
  writer = GraphvizWriter.new(stream)
491
- writer.write_graph graph, false, draw_blocks
510
+ writer.write_graph(graph, false, draw_blocks)
492
511
  when :mmd
493
512
  writer = MermaidWriter.new(stream)
494
- writer.write_graph graph
513
+ writer.write_graph(graph, false, draw_blocks)
495
514
  when :md
496
515
  writer = MarkdownWriter.new(stream)
497
- writer.write_graph graph
516
+ writer.write_graph(graph)
498
517
  else
499
518
  raise
500
519
  end
501
520
  end
502
521
  if out_file.is_a?(String)
503
- File.open(out_file, 'w') do |stream|
504
- action.call stream
522
+ File.open(out_file, "w") do |stream|
523
+ action.call(stream)
505
524
  end
506
525
  else
507
- action.call out_file
526
+ action.call(out_file)
508
527
  end
509
528
  else
510
529
  begin
511
- 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|
512
531
  writer = GraphvizWriter.new(stream)
513
532
  hidpi = out_format == :png
514
- writer.write_graph graph, hidpi, draw_blocks
533
+ writer.write_graph(graph, hidpi, draw_blocks)
515
534
  end
516
535
  rescue Errno::ENOENT
517
- raise 'Could not run Graphviz - is it installed?'
536
+ raise "Could not run Graphviz - is it installed?"
518
537
  end
519
- autoopen out_file unless explicit_out_file
538
+ autoopen(out_file) unless explicit_out_file
520
539
  end
521
540
  end
522
541
  end
@@ -524,12 +543,12 @@ module Seafoam
524
543
  # seafoam file.bgv debug options...
525
544
  def debug(name, *args)
526
545
  file, *rest = parse_name(name)
527
- 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]
528
547
 
529
548
  skip = false
530
549
  args.each do |arg|
531
550
  case arg
532
- when '--skip'
551
+ when "--skip"
533
552
  skip = true
534
553
  else
535
554
  raise ArgumentError, "unexpected option #{arg}"
@@ -539,10 +558,10 @@ module Seafoam
539
558
  File.open(file) do |stream|
540
559
  parser = BGVDebugParser.new(@out, stream)
541
560
  begin
542
- pretty_print parser.read_file_header
561
+ pretty_print(parser.read_file_header)
543
562
  document_props = parser.read_document_props
544
563
  if document_props
545
- pretty_print document_props
564
+ pretty_print(document_props)
546
565
  end
547
566
  loop do
548
567
  index, id = parser.read_graph_preheader
@@ -553,8 +572,8 @@ module Seafoam
553
572
  parser.skip_graph_header
554
573
  parser.skip_graph
555
574
  else
556
- pretty_print parser.read_graph_header
557
- pretty_print parser.read_graph
575
+ pretty_print(parser.read_graph_header)
576
+ pretty_print(parser.read_graph)
558
577
  end
559
578
  end
560
579
  rescue StandardError => e
@@ -597,53 +616,58 @@ module Seafoam
597
616
  parser.skip_graph
598
617
  end
599
618
  end
600
- raise ArgumentError, 'graph not found' unless graph_found
619
+ raise ArgumentError, "graph not found" unless graph_found
601
620
  end
602
621
 
603
622
  # Prints help.
604
623
  def help(*_args)
605
- @out.puts 'seafoam file.bgv info'
606
- @out.puts ' file.bgv list'
607
- @out.puts ' file.bgv[:graph][:node[-edge]] search term...'
608
- @out.puts ' file.bgv[:graph][:node[-edge]] edges'
609
- @out.puts ' file.bgv[:graph][:node[-edge]] props'
610
- @out.puts ' file.bgv:graph:node source'
611
- @out.puts ' file.bgv:graph describe'
612
- @out.puts ' file.bgv:graph render'
613
- @out.puts ' --spotlight n,n,n...'
614
- @out.puts ' --out graph.pdf'
615
- @out.puts ' graph.svg'
616
- @out.puts ' graph.png'
617
- @out.puts ' graph.dot'
618
- @out.puts ' --full-truffle-args'
619
- @out.puts ' --show-frame-state'
620
- @out.puts ' --show-pi'
621
- @out.puts ' --hide-floating'
622
- @out.puts ' --no-reduce-edges'
623
- @out.puts ' --draw-blocks'
624
- @out.puts ' --option key value'
625
- @out.puts ' --help'
626
- @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"
627
651
  end
628
652
 
629
653
  # Prints the version.
630
654
  def version(*args)
631
- raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
655
+ raise ArgumentError, "unexpected arguments #{args.join(" ")}" unless args.empty?
632
656
 
633
657
  @out.puts "seafoam #{VERSION}"
634
658
  end
635
659
 
636
660
  # Parse a name like file.bgv:g:n-e to [file.bgv, g, n, e].
637
661
  def parse_name(name)
638
- *pre, post = name.split('.')
662
+ *pre, post = name.split(".")
639
663
 
640
- file_ext, graph, node, *rest = post.split(':')
664
+ file_ext, graph, node, *rest = post.split(":")
641
665
  raise ArgumentError, "too many parts to .ext:g:n-e in #{name}" unless rest.empty?
642
666
 
643
- file = [*pre, file_ext].join('.')
667
+ file = [*pre, file_ext].join(".")
644
668
 
645
669
  if node
646
- node, edge, *rest = node.split('-')
670
+ node, edge, *rest = node.split("-")
647
671
  raise ArgumentError, "too many parts to edge name in #{name}" unless rest.empty?
648
672
  else
649
673
  node = nil
@@ -663,9 +687,9 @@ module Seafoam
663
687
 
664
688
  case RUBY_PLATFORM
665
689
  when /darwin/
666
- system 'open', file
690
+ system("open", file)
667
691
  when /linux/
668
- system 'xdg-open', file
692
+ system("xdg-open", file)
669
693
  end
670
694
  # Don't worry if it fails.
671
695
  end