Skip to content

Commit 29af9b7

Browse files
committed
Remove need for visitor
1 parent 46d949a commit 29af9b7

File tree

3 files changed

+49
-96
lines changed

3 files changed

+49
-96
lines changed

bin/profile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ StackProf.run(mode: :cpu, out: "tmp/profile.dump", raw: true) do
1414
end
1515

1616
GC.enable
17+
18+
`bundle exec stackprof --d3-flamegraph tmp/profile.dump > tmp/flamegraph.html`
19+
puts "open tmp/flamegraph.html"

lib/syntax_tree.rb

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,39 +2303,48 @@ def on_binary(left, operator, right)
23032303
)
23042304
end
23052305

2306-
# This is a visitor that can be passed to PrettyPrint.visit that will
2307-
# propagate BreakParent nodes all of the way up the tree. When a BreakParent
2308-
# is encountered, it will break the surrounding group, and then that group
2309-
# will break its parent, and so on.
2310-
class RemoveBreaksVisitor
2311-
def on_enter(doc)
2312-
case doc
2313-
when PrettyPrint::Indent, PrettyPrint::Align, PrettyPrint::Group
2314-
doc.contents.map! { |child| remove_breaks(child) }
2315-
when PrettyPrint::IfBreak
2316-
doc.flat_contents.map! { |child| remove_breaks(child) }
2317-
when PrettyPrint::LineSuffix
2318-
return false
2319-
end
2306+
# This module will remove any breakables from the list of contents so that no
2307+
# newlines are present in the output.
2308+
module RemoveBreaks
2309+
class << self
2310+
def call(doc)
2311+
marker = Object.new
2312+
stack = [doc]
2313+
2314+
while stack.any?
2315+
doc = stack.pop
2316+
2317+
if doc == marker
2318+
stack.pop
2319+
next
2320+
end
23202321

2321-
true
2322-
end
2322+
stack += [doc, marker]
23232323

2324-
def on_exit(doc)
2325-
end
2324+
case doc
2325+
when PrettyPrint::Align, PrettyPrint::Indent, PrettyPrint::Group
2326+
doc.contents.map! { |child| remove_breaks(child) }
2327+
stack += doc.contents.reverse
2328+
when PrettyPrint::IfBreak
2329+
doc.flat_contents.map! { |child| remove_breaks(child) }
2330+
stack += doc.flat_contents.reverse
2331+
end
2332+
end
2333+
end
23262334

2327-
private
2335+
private
23282336

2329-
def remove_breaks(doc)
2330-
case doc
2331-
when PrettyPrint::Breakable
2332-
text = PrettyPrint::Text.new
2333-
text.add(object: doc.force? ? "; " : doc.separator, width: doc.width)
2334-
text
2335-
when PrettyPrint::IfBreak
2336-
PrettyPrint::Align.new(indent: 0, contents: doc.flat_contents)
2337-
else
2338-
doc
2337+
def remove_breaks(doc)
2338+
case doc
2339+
when PrettyPrint::Breakable
2340+
text = PrettyPrint::Text.new
2341+
text.add(object: doc.force? ? "; " : doc.separator, width: doc.width)
2342+
text
2343+
when PrettyPrint::IfBreak
2344+
PrettyPrint::Align.new(indent: 0, contents: doc.flat_contents)
2345+
else
2346+
doc
2347+
end
23392348
end
23402349
end
23412350
end
@@ -2374,7 +2383,7 @@ def child_nodes
23742383
def format(q)
23752384
q.group(0, "|", "|") do
23762385
doc = q.format(params)
2377-
PrettyPrint.visit(doc, RemoveBreaksVisitor.new)
2386+
RemoveBreaks.call(doc)
23782387

23792388
if locals.any?
23802389
q.text("; ")
@@ -10647,7 +10656,7 @@ def format(q)
1064710656
# assume that's the way the developer wanted this expression
1064810657
# represented.
1064910658
doc = q.group(0, '#{', "}") { q.format(statements) }
10650-
PrettyPrint.visit(doc, RemoveBreaksVisitor.new)
10659+
RemoveBreaks.call(doc)
1065110660
else
1065210661
q.group do
1065310662
q.text('#{')

lib/syntax_tree/prettyprint.rb

Lines changed: 6 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -590,37 +590,6 @@ def self.singleline_format(output = ''.dup, maxwidth = nil, newline = nil, gensp
590590
output
591591
end
592592

593-
# This method provides a way to walk through the print tree with a specified
594-
# +visitor+ object. +visitor+ should respond to both #on_enter(doc) and
595-
# #on_exit(doc).
596-
def self.visit(doc, visitor)
597-
marker = Object.new
598-
stack = [doc]
599-
600-
while stack.any?
601-
doc = stack.pop
602-
603-
if doc == marker
604-
visitor.on_exit(stack.pop)
605-
next
606-
end
607-
608-
stack += [doc, marker]
609-
610-
if visitor.on_enter(doc)
611-
case doc
612-
when Array
613-
doc.reverse_each { |part| stack << part }
614-
when IfBreak
615-
stack << doc.break_contents if doc.break_contents
616-
stack << doc.flat_contents if doc.flat_contents
617-
when Align, Indent, Group, LineSuffix
618-
stack << doc.contents
619-
end
620-
end
621-
end
622-
end
623-
624593
# The output object. It represents the final destination of the contents of
625594
# the print tree. It should respond to <<.
626595
#
@@ -717,10 +686,8 @@ def current_group
717686
# Flushes all of the generated print tree onto the output buffer, then clears
718687
# the generated tree from memory.
719688
def flush
720-
# First, ensure that we've propagated all of the necessary break-parent
721-
# nodes throughout the tree.
689+
# First, get the root group, since we placed one at the top to begin with.
722690
doc = groups.first
723-
propagate_breaks(doc)
724691

725692
# This represents how far along the current line we are. It gets reset
726693
# back to 0 when we encounter a newline.
@@ -879,6 +846,11 @@ def break_parent
879846
doc = BreakParent.new
880847
target << doc
881848

849+
groups.reverse_each do |group|
850+
break if group.break?
851+
group.break
852+
end
853+
882854
doc
883855
end
884856

@@ -1101,37 +1073,6 @@ def fits?(next_command, rest_commands, remaining)
11011073
false
11021074
end
11031075

1104-
# This will walk the doc tree and propagate BreakParent nodes all of the way
1105-
# up the tree. When a BreakParent is encountered, it will break the
1106-
# surrounding group, and then that group will break its parent, and so on.
1107-
def propagate_breaks(doc)
1108-
marker = Object.new
1109-
stack = [doc]
1110-
groups = []
1111-
1112-
while doc = stack.pop
1113-
if doc == marker
1114-
groups.last&.break if stack.pop.is_a?(Group) && groups.pop.break?
1115-
else
1116-
stack += [doc, marker]
1117-
enter = false
1118-
1119-
case doc
1120-
when BreakParent
1121-
groups.last&.break
1122-
when Group
1123-
groups << doc
1124-
stack += doc.contents.reverse
1125-
when IfBreak
1126-
stack += doc.break_contents.reverse
1127-
stack += doc.flat_contents.reverse
1128-
when Align, Indent, LineSuffix
1129-
stack += doc.contents.reverse
1130-
end
1131-
end
1132-
end
1133-
end
1134-
11351076
# Resets the group stack and target array so that this pretty printer object
11361077
# can continue to be used before calling flush again if desired.
11371078
def reset

0 commit comments

Comments
 (0)