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
Add a better CLI that will format files
  • Loading branch information
kddnewton committed Dec 1, 2021
commit c139cb482066070860d56db46f4049c778ae8021
75 changes: 70 additions & 5 deletions exe/stree
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,74 @@

require_relative File.expand_path('../lib/syntax_tree', __dir__)

source = ARGF.read
program = SyntaxTree.new(source).parse
help = <<~EOF
stree MDOE FILE

pp program
puts
puts program.format
MODE: one of "a", "ast", "d", "doc", "f", or "format"
FILE: one or more paths to files to parse
EOF

if ARGV.length < 2
warn(help)
exit(1)
end

module SyntaxTree::CLI
class AST
def run(source)
pp SyntaxTree.parse(source)
end
end

class Doc
def run(source)
formatter = SyntaxTree::Formatter.new([])
SyntaxTree.parse(source).format(formatter)
pp formatter.groups.first
end
end

class Format
def run(source)
puts SyntaxTree.format(source)
end
end
end

mode =
case ARGV.shift
when 'a', 'ast'
SyntaxTree::CLI::AST.new
when 'd', 'doc'
SyntaxTree::CLI::Doc.new
when 'f', 'format'
SyntaxTree::CLI::Format.new
else
warn(help)
exit(1)
end

queue = Queue.new
ARGV.each { |pattern| Dir[pattern].each { |filepath| queue << filepath } }

if queue.size <= 1
filepath = queue.shift
mode.run(File.read(filepath)) if File.file?(filepath)
return
end

count = [8, queue.size].min
threads =
count.times.map do
Thread.new do
loop do
filepath = queue.shift
break if filepath == :exit

mode.run(File.read(filepath)) if File.file?(filepath)
end
end
end

count.times { queue << :exit }
threads.each(&:join)
19 changes: 11 additions & 8 deletions lib/syntax_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ class Formatter < PP

def initialize(*)
super

@stack = []
@quote = '"'
end
Expand Down Expand Up @@ -258,6 +257,16 @@ def self.parse(source)
response unless parser.error?
end

def self.format(source)
output = []

formatter = Formatter.new(output)
parse(source).format(formatter)

formatter.flush
output.join
end

private

# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -8718,15 +8727,9 @@ def child_nodes
[statements]
end

def format
out = []
q = Formatter.new(out)

def format(q)
q.format(statements)
q.breakable(force: true)
q.flush

out.join
end

def pretty_print(q)
Expand Down
42 changes: 24 additions & 18 deletions lib/syntax_tree/prettyprint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ def self.for(output)
# output. If an IfBreak node is used, only the flat contents are printed.
# LineSuffix nodes are printed at the end of the buffer when #flush is called.
class SingleLine
# The output object. It stores rendered text and shoudl respond to <<.
# The output object. It stores rendered text and should respond to <<.
attr_reader :output

# The current array of contents that the print tree builder methods should
Expand Down Expand Up @@ -653,12 +653,17 @@ def self.visit(doc, visitor)
end

# The output object. It represents the final destination of the contents of
# the print tree. Its type is one of the classes in the Buffer module. Those
# classes all wrap an object that should respond to <<.
# the print tree. It should respond to <<.
#
# This defaults to Buffer::StringBuffer.new('')
# This defaults to "".dup
attr_reader :output

# This is an output buffer that wraps the output object and provides
# additional functionality depending on its type.
#
# This defaults to Buffer::StringBuffer.new("".dup)
attr_reader :buffer

# The maximum width of a line, before it is separated in to a newline
#
# This defaults to 80, and should be an Integer
Expand Down Expand Up @@ -699,7 +704,8 @@ def self.visit(doc, visitor)
# The block is used to generate spaces. ->(n) { ' ' * n } is used if it is not
# given.
def initialize(output = ''.dup, maxwidth = 80, newline = DEFAULT_NEWLINE, &genspace)
@output = Buffer.for(output)
@output = output
@buffer = Buffer.for(output)
@maxwidth = maxwidth
@newline = newline
@genspace = genspace || DEFAULT_GENSPACE
Expand Down Expand Up @@ -772,7 +778,7 @@ def flush

case doc
when Text
doc.objects.each { |object| output << object }
doc.objects.each { |object| buffer << object }
position += doc.width
when Array
doc.reverse_each { |part| commands << [indent, mode, part] }
Expand All @@ -781,7 +787,7 @@ def flush
when Align
commands << [indent.align(doc.indent), mode, doc.contents]
when Trim
position -= output.trim!
position -= buffer.trim!
when Group
if mode == MODE_FLAT && !should_remeasure
commands << [indent, doc.break? ? MODE_BREAK : MODE_FLAT, doc.contents]
Expand Down Expand Up @@ -813,7 +819,7 @@ def flush
# groups).
should_remeasure = true
else
output << doc.separator
buffer << doc.separator
position += doc.width
next
end
Expand All @@ -829,18 +835,18 @@ def flush
end

if !doc.indent?
output << newline
buffer << newline

if indent.root
output << indent.root.value
buffer << indent.root.value
position = indent.root.length
else
position = 0
end
else
position -= output.trim!
output << newline
output << indent.value
position -= buffer.trim!
buffer << newline
buffer << indent.value
position = indent.length
end
when BreakParent
Expand All @@ -853,7 +859,7 @@ def flush
#
# This is useful behavior for putting marker nodes into the list so that
# you can know how things are getting mapped before they get printed.
output << doc
buffer << doc
end

if commands.empty? && line_suffixes.any?
Expand Down Expand Up @@ -1079,7 +1085,7 @@ def fits?(next_command, rest_commands, remaining)
# This is our output buffer, really only necessary to keep track of
# because we could encounter a Trim doc node that would actually add
# remaining space.
buffer = output.class.new
fit_buffer = buffer.class.new

while remaining >= 0
if commands.empty?
Expand All @@ -1094,7 +1100,7 @@ def fits?(next_command, rest_commands, remaining)

case doc
when Text
doc.objects.each { |object| buffer << object }
doc.objects.each { |object| fit_buffer << object }
remaining -= doc.width
when Array
doc.reverse_each { |part| commands << [indent, mode, part] }
Expand All @@ -1103,7 +1109,7 @@ def fits?(next_command, rest_commands, remaining)
when Align
commands << [indent.align(doc.indent), mode, doc.contents]
when Trim
remaining += buffer.trim!
remaining += fit_buffer.trim!
when Group
commands << [indent, doc.break? ? MODE_BREAK : mode, doc.contents]
when IfBreak
Expand All @@ -1114,7 +1120,7 @@ def fits?(next_command, rest_commands, remaining)
end
when Breakable
if mode == MODE_FLAT && !doc.force?
buffer << doc.separator
fit_buffer << doc.separator
remaining -= doc.width
next
end
Expand Down
5 changes: 1 addition & 4 deletions test/syntax_tree_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1024,10 +1024,7 @@ def test_zsuper
.each_with_index do |source, index|
define_method(:"test_formatting_#{basename}_#{index}") do
original, expected = source.split("-\n")
expected ||= original

actual = SyntaxTree.new(original).parse.format
assert_equal(expected, actual)
assert_equal(expected || original, SyntaxTree.format(original))
end
end
end
Expand Down