seafoam 0.13 → 0.15

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
@@ -344,10 +350,20 @@ module Seafoam
344
350
  def describe(name, formatter_module, *args)
345
351
  file, graph_index, *rest = parse_name(name)
346
352
 
353
+ pass_options = DEFAULT_PASS_OPTIONS.dup
354
+ until args.empty?
355
+ arg = args.shift
356
+ case arg
357
+ when "--no-simplify"
358
+ pass_options.merge!(NO_SIMPLIFY_PASS_OPTIONS)
359
+ else
360
+ raise ArgumentError, "unexpected option #{arg}"
361
+ end
362
+ end
363
+
347
364
  if graph_index.nil? || !rest.all?(&:nil?)
348
- raise ArgumentError, 'describe only works with a graph'
365
+ raise ArgumentError, "describe only works with a graph"
349
366
  end
350
- raise ArgumentError, 'describe does not take arguments' unless args.empty?
351
367
 
352
368
  parser = BGV::BGVParser.new(file)
353
369
  parser.read_file_header
@@ -365,22 +381,33 @@ module Seafoam
365
381
  end
366
382
 
367
383
  graph = parser.read_graph
384
+ Passes.apply(graph, pass_options)
385
+
368
386
  description = Seafoam::Graal::GraphDescription.new
369
387
 
370
388
  graph.nodes.each_value do |node|
371
- node_class = node.props.dig(:node_class, :node_class)
372
- case node_class
373
- when 'org.graalvm.compiler.nodes.IfNode'
374
- description.branches = true
375
- when 'org.graalvm.compiler.nodes.LoopBeginNode'
376
- description.loops = true
377
- when 'org.graalvm.compiler.nodes.InvokeNode', 'org.graalvm.compiler.nodes.InvokeWithExceptionNode'
378
- description.calls = true
389
+ next if node.props[:hidden]
390
+
391
+ node_class = node.node_class
392
+ if node_class
393
+ simple_node_class = node_class[/([^.]+)$/, 1]
394
+ description.node_counts[simple_node_class] += 1
395
+
396
+ case node_class
397
+ when "org.graalvm.compiler.nodes.IfNode"
398
+ description.branches = true
399
+ when "org.graalvm.compiler.nodes.LoopBeginNode"
400
+ description.loops = true
401
+ when "org.graalvm.compiler.nodes.InvokeNode", "org.graalvm.compiler.nodes.InvokeWithExceptionNode"
402
+ description.calls = true
403
+ end
404
+ elsif node.props[:synthetic_class]
405
+ description.node_counts["*" + node.props[:synthetic_class]] += 1
379
406
  end
380
- end
381
407
 
382
- description.deopts = graph.nodes[0].outputs.map(&:to)
383
- .all? { |t| t.props.dig(:node_class, :node_class) == 'org.graalvm.compiler.nodes.DeoptimizeNode' }
408
+ description.deopts = graph.nodes[0].outputs.map(&:to)
409
+ .all? { |t| t.node_class == "org.graalvm.compiler.nodes.DeoptimizeNode" }
410
+ end
384
411
 
385
412
  formatter = formatter_module::DescribeFormatter.new(graph, description)
386
413
  @out.puts formatter.format
@@ -392,16 +419,10 @@ module Seafoam
392
419
  # seafoam file.bgv:n render options...
393
420
  def render(name, *args)
394
421
  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]
397
-
398
- pass_options = {
399
- simplify_truffle_args: true,
400
- hide_frame_state: true,
401
- hide_pi: true,
402
- hide_floating: false,
403
- reduce_edges: true
404
- }
422
+ raise ArgumentError, "render needs at least a graph" unless graph_index
423
+ raise ArgumentError, "render only works with a graph" unless rest == [nil, nil]
424
+
425
+ pass_options = DEFAULT_PASS_OPTIONS.dup
405
426
  spotlight_nodes = nil
406
427
  args = args.dup
407
428
  out_file = nil
@@ -410,75 +431,85 @@ module Seafoam
410
431
  until args.empty?
411
432
  arg = args.shift
412
433
  case arg
413
- when '--out'
434
+ when "--out"
414
435
  out_file = args.shift
415
436
  explicit_out_file = true
416
- raise ArgumentError, 'no file for --out' unless out_file
437
+ raise ArgumentError, "no file for --out" unless out_file
417
438
 
418
439
  out_ext = File.extname(out_file).downcase
419
440
  case out_ext
420
- when '.pdf'
441
+ when ".pdf"
421
442
  out_format = :pdf
422
- when '.svg'
443
+ when ".svg"
423
444
  out_format = :svg
424
- when '.png'
445
+ when ".png"
425
446
  out_format = :png
426
- when '.dot'
447
+ when ".dot"
427
448
  out_format = :dot
428
- when '.mmd'
449
+ when ".mmd"
429
450
  out_format = :mmd
430
- when '.md'
451
+ when ".md"
431
452
  out_format = :md
432
453
  else
433
454
  raise ArgumentError, "unknown render format #{out_ext}"
434
455
  end
435
- when '--md'
456
+ when "--md"
436
457
  out_file = @out
437
458
  out_format = :md
438
459
  explicit_out_file = true
439
- when '--spotlight'
460
+ when "--spotlight"
440
461
  spotlight_arg = args.shift
441
- raise ArgumentError, 'no list for --spotlight' unless spotlight_arg
462
+ raise ArgumentError, "no list for --spotlight" unless spotlight_arg
442
463
 
443
- spotlight_nodes = spotlight_arg.split(',').map { |n| Integer(n) }
444
- when '--full-truffle-args'
464
+ spotlight_nodes = spotlight_arg.split(",").map { |n| Integer(n) }
465
+ when "--full-truffle-args"
445
466
  pass_options[:simplify_truffle_args] = false
446
- when '--show-frame-state'
467
+ when "--show-reachability-fences"
468
+ pass_options[:hide_reachability_fences] = false
469
+ when "--no-simplify-alloc"
470
+ pass_options[:simplify_alloc] = false
471
+ when "--show-null-fields"
472
+ pass_options[:hide_null_fields] = false
473
+ when "--show-frame-state"
447
474
  pass_options[:hide_frame_state] = false
448
- when '--show-pi'
475
+ when "--show-pi"
449
476
  pass_options[:hide_pi] = false
450
- when '--hide-floating'
477
+ when "--show-begin-end"
478
+ pass_options[:hide_begin_end] = false
479
+ when "--hide-floating"
451
480
  pass_options[:hide_floating] = true
452
- when '--no-reduce-edges'
481
+ when "--no-reduce-edges"
453
482
  pass_options[:reduce_edges] = false
454
- when '--draw-blocks'
483
+ when "--no-simplify"
484
+ pass_options.merge!(NO_SIMPLIFY_PASS_OPTIONS)
485
+ when "--draw-blocks"
455
486
  draw_blocks = true
456
- when '--option'
487
+ when "--option"
457
488
  key = args.shift
458
- raise ArgumentError, 'no key for --option' unless key
489
+ raise ArgumentError, "no key for --option" unless key
459
490
 
460
491
  value = args.shift
461
- raise ArgumentError, "no value for --option #{key}" unless out_file
492
+ raise ArgumentError, "no value for --option #{key}" unless value
462
493
 
463
- value = { 'true' => true, 'false' => 'false' }.fetch(key, value)
494
+ value = { "true" => true, "false" => "false" }.fetch(key, value)
464
495
  pass_options[key.to_sym] = value
465
496
  else
466
497
  raise ArgumentError, "unexpected option #{arg}"
467
498
  end
468
499
  end
469
- out_file ||= 'graph.pdf'
500
+ out_file ||= "graph.pdf"
470
501
  out_format ||= :pdf
471
502
  with_graph(file, graph_index) do |parser|
472
503
  parser.skip_graph_header
473
504
  graph = parser.read_graph
474
- Passes.apply graph, pass_options
505
+ Passes.apply(graph, pass_options)
475
506
  if spotlight_nodes
476
507
  spotlight = Spotlight.new(graph)
477
508
  spotlight_nodes.each do |node_id|
478
509
  node = graph.nodes[node_id]
479
- raise ArgumentError, 'node not found' unless node
510
+ raise ArgumentError, "node not found" unless node
480
511
 
481
- spotlight.light node
512
+ spotlight.light(node)
482
513
  end
483
514
  spotlight.shade
484
515
  end
@@ -488,35 +519,35 @@ module Seafoam
488
519
  case out_format
489
520
  when :dot
490
521
  writer = GraphvizWriter.new(stream)
491
- writer.write_graph graph, false, draw_blocks
522
+ writer.write_graph(graph, false, draw_blocks)
492
523
  when :mmd
493
524
  writer = MermaidWriter.new(stream)
494
- writer.write_graph graph
525
+ writer.write_graph(graph, false, draw_blocks)
495
526
  when :md
496
527
  writer = MarkdownWriter.new(stream)
497
- writer.write_graph graph
528
+ writer.write_graph(graph)
498
529
  else
499
530
  raise
500
531
  end
501
532
  end
502
533
  if out_file.is_a?(String)
503
- File.open(out_file, 'w') do |stream|
504
- action.call stream
534
+ File.open(out_file, "w") do |stream|
535
+ action.call(stream)
505
536
  end
506
537
  else
507
- action.call out_file
538
+ action.call(out_file)
508
539
  end
509
540
  else
510
541
  begin
511
- IO.popen(['dot', "-T#{out_format}", '-o', out_file], 'w') do |stream|
542
+ IO.popen(["dot", "-T#{out_format}", "-o", out_file], "w") do |stream|
512
543
  writer = GraphvizWriter.new(stream)
513
544
  hidpi = out_format == :png
514
- writer.write_graph graph, hidpi, draw_blocks
545
+ writer.write_graph(graph, hidpi, draw_blocks)
515
546
  end
516
547
  rescue Errno::ENOENT
517
- raise 'Could not run Graphviz - is it installed?'
548
+ raise "Could not run Graphviz - is it installed?"
518
549
  end
519
- autoopen out_file unless explicit_out_file
550
+ autoopen(out_file) unless explicit_out_file
520
551
  end
521
552
  end
522
553
  end
@@ -524,12 +555,12 @@ module Seafoam
524
555
  # seafoam file.bgv debug options...
525
556
  def debug(name, *args)
526
557
  file, *rest = parse_name(name)
527
- raise ArgumentError, 'debug only works with a file' unless rest == [nil, nil, nil]
558
+ raise ArgumentError, "debug only works with a file" unless rest == [nil, nil, nil]
528
559
 
529
560
  skip = false
530
561
  args.each do |arg|
531
562
  case arg
532
- when '--skip'
563
+ when "--skip"
533
564
  skip = true
534
565
  else
535
566
  raise ArgumentError, "unexpected option #{arg}"
@@ -539,10 +570,10 @@ module Seafoam
539
570
  File.open(file) do |stream|
540
571
  parser = BGVDebugParser.new(@out, stream)
541
572
  begin
542
- pretty_print parser.read_file_header
573
+ pretty_print(parser.read_file_header)
543
574
  document_props = parser.read_document_props
544
575
  if document_props
545
- pretty_print document_props
576
+ pretty_print(document_props)
546
577
  end
547
578
  loop do
548
579
  index, id = parser.read_graph_preheader
@@ -553,8 +584,8 @@ module Seafoam
553
584
  parser.skip_graph_header
554
585
  parser.skip_graph
555
586
  else
556
- pretty_print parser.read_graph_header
557
- pretty_print parser.read_graph
587
+ pretty_print(parser.read_graph_header)
588
+ pretty_print(parser.read_graph)
558
589
  end
559
590
  end
560
591
  rescue StandardError => e
@@ -597,53 +628,59 @@ module Seafoam
597
628
  parser.skip_graph
598
629
  end
599
630
  end
600
- raise ArgumentError, 'graph not found' unless graph_found
631
+ raise ArgumentError, "graph not found" unless graph_found
601
632
  end
602
633
 
603
634
  # Prints help.
604
635
  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'
636
+ @out.puts "seafoam file.bgv info"
637
+ @out.puts " file.bgv list"
638
+ @out.puts " file.bgv[:graph][:node[-edge]] search term..."
639
+ @out.puts " file.bgv[:graph][:node[-edge]] edges"
640
+ @out.puts " file.bgv[:graph][:node[-edge]] props"
641
+ @out.puts " file.bgv:graph:node source"
642
+ @out.puts " file.bgv:graph describe"
643
+ @out.puts " file.bgv:graph render"
644
+ @out.puts " --spotlight n,n,n..."
645
+ @out.puts " --out graph.pdf"
646
+ @out.puts " graph.svg"
647
+ @out.puts " graph.png"
648
+ @out.puts " graph.dot (Graphviz)"
649
+ @out.puts " graph.mmd (Mermaid)"
650
+ @out.puts " graph.md (Markdown)"
651
+ @out.puts " --full-truffle-args"
652
+ @out.puts " --show-frame-state"
653
+ @out.puts " --no-simplify-alloc"
654
+ @out.puts " --show-null-fields"
655
+ @out.puts " --show-pi"
656
+ @out.puts " --show-begin-end"
657
+ @out.puts " --hide-floating"
658
+ @out.puts " --no-reduce-edges"
659
+ @out.puts " --no-simplify"
660
+ @out.puts " --draw-blocks"
661
+ @out.puts " --option key value"
662
+ @out.puts " --help"
663
+ @out.puts " --version"
627
664
  end
628
665
 
629
666
  # Prints the version.
630
667
  def version(*args)
631
- raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
668
+ raise ArgumentError, "unexpected arguments #{args.join(" ")}" unless args.empty?
632
669
 
633
670
  @out.puts "seafoam #{VERSION}"
634
671
  end
635
672
 
636
673
  # Parse a name like file.bgv:g:n-e to [file.bgv, g, n, e].
637
674
  def parse_name(name)
638
- *pre, post = name.split('.')
675
+ *pre, post = name.split(".")
639
676
 
640
- file_ext, graph, node, *rest = post.split(':')
677
+ file_ext, graph, node, *rest = post.split(":")
641
678
  raise ArgumentError, "too many parts to .ext:g:n-e in #{name}" unless rest.empty?
642
679
 
643
- file = [*pre, file_ext].join('.')
680
+ file = [*pre, file_ext].join(".")
644
681
 
645
682
  if node
646
- node, edge, *rest = node.split('-')
683
+ node, edge, *rest = node.split("-")
647
684
  raise ArgumentError, "too many parts to edge name in #{name}" unless rest.empty?
648
685
  else
649
686
  node = nil
@@ -663,11 +700,33 @@ module Seafoam
663
700
 
664
701
  case RUBY_PLATFORM
665
702
  when /darwin/
666
- system 'open', file
703
+ system("open", file)
667
704
  when /linux/
668
- system 'xdg-open', file
705
+ system("xdg-open", file)
669
706
  end
670
707
  # Don't worry if it fails.
671
708
  end
709
+
710
+ DEFAULT_PASS_OPTIONS = {
711
+ simplify_truffle_args: true,
712
+ hide_reachability_fences: true,
713
+ hide_frame_state: true,
714
+ hide_pi: true,
715
+ hide_begin_end: true,
716
+ hide_floating: false,
717
+ reduce_edges: true,
718
+ simplify_alloc: true,
719
+ hide_null_fields: true,
720
+ }
721
+
722
+ NO_SIMPLIFY_PASS_OPTIONS = {
723
+ simplify_truffle_args: false,
724
+ hide_reachability_fences: false,
725
+ simplify_alloc: false,
726
+ hide_null_fields: false,
727
+ hide_pi: false,
728
+ hide_begin_end: false,
729
+ reduce_edges: false,
730
+ }
672
731
  end
673
732
  end