Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
29445cf
Ignore test.rb
kddnewton Nov 29, 2021
a0ca55f
Support for embedding comments in the tree
kddnewton Nov 29, 2021
4a9cecc
Formatting checkpoint
kddnewton Nov 19, 2021
1f6b2be
Tests for formatting
kddnewton Nov 19, 2021
66c05d8
prettyprint
kddnewton Nov 29, 2021
d70f5f2
Print comments surrounding the node
kddnewton Nov 29, 2021
f50f236
Get comments printing
kddnewton Nov 29, 2021
4a7d506
Update with test cases for comments
kddnewton Nov 29, 2021
25eefba
VarAlias tests
kddnewton Nov 29, 2021
00717fa
A bunch of tests for formatting keywords without arguments
kddnewton Nov 29, 2021
fdd718a
Tests for xstring_literal and yield
kddnewton Nov 29, 2021
43aed5c
Tests for special array literals
kddnewton Nov 29, 2021
e791625
Until, UntilMod, While, WhileMod tests
kddnewton Nov 29, 2021
d2318b2
IfMod and UnlessMod formatting
kddnewton Nov 29, 2021
1fbe689
Tests for various leaf nodes
kddnewton Nov 29, 2021
547d16f
Tests for SClass and StringConcat
kddnewton Nov 29, 2021
14bb1e3
Tests for ConstPathField, ConstPathRef, KwRestParam, RestParam, TopCo…
kddnewton Nov 29, 2021
24b0ff9
Tests for Undef
kddnewton Nov 30, 2021
76fbec6
Tests for Unary
kddnewton Nov 30, 2021
c878170
Tests for VarRef
kddnewton Nov 30, 2021
40a3251
Tests for VarField
kddnewton Nov 30, 2021
e88a6e2
Tests for Not, SymbolLiteral, VCall
kddnewton Nov 30, 2021
4de0091
Tests for Int, Module, MRHS, OpAssign, Program, StringDVar, and some …
kddnewton Nov 30, 2021
b2ec4bd
Tests for ArrayLiteral, BraceBlock, DoBlock, Hash, and IfOp
kddnewton Nov 30, 2021
b3701eb
Tests for Case and When
kddnewton Nov 30, 2021
7446c58
More tests for When
kddnewton Nov 30, 2021
a87cd06
Tests for RAssign
kddnewton Nov 30, 2021
81a604e
Tests for RAssign
kddnewton Nov 30, 2021
98aeacf
Tests for Command, Const, ConstRef, Def
kddnewton Nov 30, 2021
b076fe4
Tests for Defined, Dot2, Dot3, and ExcessedComma
kddnewton Nov 30, 2021
c8bdb1c
Better heredocs, tests for Heredoc, Defs, and DefEndless
kddnewton Nov 30, 2021
e562cc7
Tests for Elsif, EmbDoc, Params
kddnewton Nov 30, 2021
ee1f4ed
Tests for MLHSParen
kddnewton Nov 30, 2021
0ff165f
Tests for MLHS
kddnewton Nov 30, 2021
8bddece
Tests for Lambda and MAssign
kddnewton Nov 30, 2021
374611b
Tests for In and When
kddnewton Nov 30, 2021
73c584f
Tests for Break, FCall, Kw, Label, MethodAddArg, MethodAddBlock, Next…
kddnewton Nov 30, 2021
517d576
Tests for AccessCtrl, CommandCall, Else, Ensure, Field, FndPtn, For, …
kddnewton Nov 30, 2021
b9c355b
Tests for RegexpLiteral
kddnewton Nov 30, 2021
a926d56
Visitors to remove lines
kddnewton Dec 1, 2021
fa6c741
StringLiteral and DynaSymbol
kddnewton Dec 1, 2021
c139cb4
Add a better CLI that will format files
kddnewton Dec 1, 2021
257c5a5
Add a write mode for the CLI
kddnewton Dec 1, 2021
9f6d1f8
Format with stree
kddnewton Dec 1, 2021
ed2167b
Attach comments to statements as inline nodes directly
kddnewton Dec 1, 2021
41365d6
Fix up comment formatting
kddnewton Dec 1, 2021
30e9394
Format yourself
kddnewton Dec 1, 2021
f4682a1
Format the test suite
kddnewton Dec 1, 2021
7ab01a1
A bunch of these nodes do not need to go on the token list
kddnewton Dec 1, 2021
46d949a
Speed up
kddnewton Dec 1, 2021
29af9b7
Remove need for visitor
kddnewton Dec 1, 2021
410e7e3
Format everything
kddnewton Dec 1, 2021
613396e
Group stuff with nest
kddnewton Dec 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove need for visitor
  • Loading branch information
kddnewton committed Dec 1, 2021
commit 29af9b763d658d3306723407dc7b3494205bb042
3 changes: 3 additions & 0 deletions bin/profile
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ StackProf.run(mode: :cpu, out: "tmp/profile.dump", raw: true) do
end

GC.enable

`bundle exec stackprof --d3-flamegraph tmp/profile.dump > tmp/flamegraph.html`
puts "open tmp/flamegraph.html"
71 changes: 40 additions & 31 deletions lib/syntax_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2303,39 +2303,48 @@ def on_binary(left, operator, right)
)
end

# This is a visitor that can be passed to PrettyPrint.visit that will
# propagate BreakParent nodes all of the way up the tree. When a BreakParent
# is encountered, it will break the surrounding group, and then that group
# will break its parent, and so on.
class RemoveBreaksVisitor
def on_enter(doc)
case doc
when PrettyPrint::Indent, PrettyPrint::Align, PrettyPrint::Group
doc.contents.map! { |child| remove_breaks(child) }
when PrettyPrint::IfBreak
doc.flat_contents.map! { |child| remove_breaks(child) }
when PrettyPrint::LineSuffix
return false
end
# This module will remove any breakables from the list of contents so that no
# newlines are present in the output.
module RemoveBreaks
class << self
def call(doc)
marker = Object.new
stack = [doc]

while stack.any?
doc = stack.pop

if doc == marker
stack.pop
next
end

true
end
stack += [doc, marker]

def on_exit(doc)
end
case doc
when PrettyPrint::Align, PrettyPrint::Indent, PrettyPrint::Group
doc.contents.map! { |child| remove_breaks(child) }
stack += doc.contents.reverse
when PrettyPrint::IfBreak
doc.flat_contents.map! { |child| remove_breaks(child) }
stack += doc.flat_contents.reverse
end
end
end

private
private

def remove_breaks(doc)
case doc
when PrettyPrint::Breakable
text = PrettyPrint::Text.new
text.add(object: doc.force? ? "; " : doc.separator, width: doc.width)
text
when PrettyPrint::IfBreak
PrettyPrint::Align.new(indent: 0, contents: doc.flat_contents)
else
doc
def remove_breaks(doc)
case doc
when PrettyPrint::Breakable
text = PrettyPrint::Text.new
text.add(object: doc.force? ? "; " : doc.separator, width: doc.width)
text
when PrettyPrint::IfBreak
PrettyPrint::Align.new(indent: 0, contents: doc.flat_contents)
else
doc
end
end
end
end
Expand Down Expand Up @@ -2374,7 +2383,7 @@ def child_nodes
def format(q)
q.group(0, "|", "|") do
doc = q.format(params)
PrettyPrint.visit(doc, RemoveBreaksVisitor.new)
RemoveBreaks.call(doc)

if locals.any?
q.text("; ")
Expand Down Expand Up @@ -10647,7 +10656,7 @@ def format(q)
# assume that's the way the developer wanted this expression
# represented.
doc = q.group(0, '#{', "}") { q.format(statements) }
PrettyPrint.visit(doc, RemoveBreaksVisitor.new)
RemoveBreaks.call(doc)
else
q.group do
q.text('#{')
Expand Down
71 changes: 6 additions & 65 deletions lib/syntax_tree/prettyprint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -590,37 +590,6 @@ def self.singleline_format(output = ''.dup, maxwidth = nil, newline = nil, gensp
output
end

# This method provides a way to walk through the print tree with a specified
# +visitor+ object. +visitor+ should respond to both #on_enter(doc) and
# #on_exit(doc).
def self.visit(doc, visitor)
marker = Object.new
stack = [doc]

while stack.any?
doc = stack.pop

if doc == marker
visitor.on_exit(stack.pop)
next
end

stack += [doc, marker]

if visitor.on_enter(doc)
case doc
when Array
doc.reverse_each { |part| stack << part }
when IfBreak
stack << doc.break_contents if doc.break_contents
stack << doc.flat_contents if doc.flat_contents
when Align, Indent, Group, LineSuffix
stack << doc.contents
end
end
end
end

# The output object. It represents the final destination of the contents of
# the print tree. It should respond to <<.
#
Expand Down Expand Up @@ -717,10 +686,8 @@ def current_group
# Flushes all of the generated print tree onto the output buffer, then clears
# the generated tree from memory.
def flush
# First, ensure that we've propagated all of the necessary break-parent
# nodes throughout the tree.
# First, get the root group, since we placed one at the top to begin with.
doc = groups.first
propagate_breaks(doc)

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

groups.reverse_each do |group|
break if group.break?
group.break
end

doc
end

Expand Down Expand Up @@ -1101,37 +1073,6 @@ def fits?(next_command, rest_commands, remaining)
false
end

# This will walk the doc tree and propagate BreakParent nodes all of the way
# up the tree. When a BreakParent is encountered, it will break the
# surrounding group, and then that group will break its parent, and so on.
def propagate_breaks(doc)
marker = Object.new
stack = [doc]
groups = []

while doc = stack.pop
if doc == marker
groups.last&.break if stack.pop.is_a?(Group) && groups.pop.break?
else
stack += [doc, marker]
enter = false

case doc
when BreakParent
groups.last&.break
when Group
groups << doc
stack += doc.contents.reverse
when IfBreak
stack += doc.break_contents.reverse
stack += doc.flat_contents.reverse
when Align, Indent, LineSuffix
stack += doc.contents.reverse
end
end
end
end

# Resets the group stack and target array so that this pretty printer object
# can continue to be used before calling flush again if desired.
def reset
Expand Down