Skip to content

[WIP] Support Prism #347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ gemspec
gem "bundler", ">= 1.15"
gem "debug", ">= 1.0.0"
gem "guard-rspec", "~> 4.0"
gem "prism", "~> 1.2"
gem "rake", "~> 13.0"
gem "rspec", "~> 3.0"
gem "rspec_junit_formatter", "~> 0.6.0"
Expand Down
9 changes: 8 additions & 1 deletion lib/rufo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ def initialize(message, lineno)
end

def self.format(code, **options)
Formatter.format(code, **options)
engine = options.delete(:engine)
case engine
when :prism
PrismFormatter.format(code, **options)
else
Formatter.format(code, **options)
end
end
end

Expand All @@ -25,6 +31,7 @@ def self.format(code, **options)
require_relative "rufo/parser"
require_relative "rufo/formatter"
require_relative "rufo/erb_formatter"
require_relative "rufo/prism_formatter"
require_relative "rufo/version"
require_relative "rufo/file_list"
require_relative "rufo/file_finder"
182 changes: 182 additions & 0 deletions lib/rufo/prism_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# frozen_string_literal: true

require "prism"

class Rufo::PrismFormatter
include Rufo::Settings

DEBUG = true

def self.format(code, **options)
formatter = new(code, **options)
formatter.format
formatter.result
end

def initialize(code, **options)
@code = code
@parse_result = Prism.parse(code)
unless @parse_result.errors.empty?
error = @parse_result.errors.first
raise Rufo::SyntaxError.new(error.message, error.location.start_line)
end

init_settings(options)
end

def format
debug_log @parse_result
visitor = FormatVisitor.new(@code)
@parse_result.value.accept(visitor)
@output = visitor.output

@output.chomp! if @output.end_with?("\n\n")
@output.lstrip!
@output << "\n" unless @output.end_with?("\n")
end

def result
@output
end

def debug_log(object)
if DEBUG
p [:debug, object]
end
end

class FormatVisitor < Prism::Visitor
attr_reader :output

def initialize(code)
super()
@code = code
@output = +""
end

def visit_nil_node(_node)
write("nil")
end

def visit_true_node(_node)
write("true")
end

def visit_false_node(_node)
write("false")
end

def visit_integer_node(node)
write_code_at(node.location)
end

def visit_float_node(node)
write_code_at(node.location)
end

def visit_rational_node(node)
write_code_at(node.location)
end

def visit_imaginary_node(node)
write_code_at(node.location)
end

def visit_symbol_node(node)
write_code_at(node.location)
end

def visit_interpolated_symbol_node(node)
write_code_at(node.location)
end

def visit_string_node(node)
write_code_at(node.location)
end

def visit_class_variable_read_node(node)
write_code_at(node.location)
end

def visit_global_variable_read_node(node)
write_code_at(node.location)
end

def visit_numbered_reference_read_node(node)
write_code_at(node.location)
end

def visit_local_variable_read_node(node)
write_code_at(node.location)
end

def visit_local_variable_write_node(node)
write(node.name.to_s)
write(" = ")
node.value.accept(self)
end

def visit_hash_node(node)
write_code_at(node.location)
end

def visit_instance_variable_read_node(node)
write(node.name.to_s)
end

def visit_undef_node(node)
write("undef ")
node.names.each_with_index do |name, i|
if i > 0
write ", "
end
name.accept(self)
end
end

def visit_parentheses_node(node)
write_code_at(node.opening_loc)
node.body.accept(self)
write_code_at(node.closing_loc)
end

def visit_call_node(node)
write(node.message)
if node.receiver
node.receiver.accept(self)
end
end

def visit_statements_node(node)
previous = nil
node.body.each do |child|
if previous&.newline?
write "\n"
end

child.accept(self)
previous = child
end
end

private

def write(value)
@output << value
end

def write_code_at(location)
write(code_at(location))
end

def code_at(location)
@code[location.start_offset...location.end_offset]
end

def debug_log(object)
if Rufo::PrismFormatter::DEBUG
p [:debug, object]
end
end
end
end
13 changes: 13 additions & 0 deletions spec/lib/rufo/prism_formatter_source_specs/booleans.rb.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#~# ORIGINAL false

false

#~# EXPECTED
false

#~# ORIGINAL true

true

#~# EXPECTED
true
6 changes: 6 additions & 0 deletions spec/lib/rufo/prism_formatter_source_specs/chars.rb.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#~# ORIGINAL char

?a

#~# EXPECTED
?a
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#~# ORIGINAL

@@foo

#~# EXPECTED
@@foo
13 changes: 13 additions & 0 deletions spec/lib/rufo/prism_formatter_source_specs/floats.rb.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#~# ORIGINAL

12.34

#~# EXPECTED
12.34

#~# ORIGINAL

12.34e-10

#~# EXPECTED
12.34e-10
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#~# ORIGINAL

3.141592i

#~# EXPECTED
3.141592i
6 changes: 6 additions & 0 deletions spec/lib/rufo/prism_formatter_source_specs/integers.rb.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#~# ORIGINAL 123

123

#~# EXPECTED
123
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#~# ORIGINAL




a = 1

#~# EXPECTED
a = 1
6 changes: 6 additions & 0 deletions spec/lib/rufo/prism_formatter_source_specs/nil.rb.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#~# ORIGINAL nil

nil

#~# EXPECTED
nil
6 changes: 6 additions & 0 deletions spec/lib/rufo/prism_formatter_source_specs/rationals.rb.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#~# ORIGINAL

3.141592r

#~# EXPECTED
3.141592r
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#~# ORIGINAL

{ 1 => 2 }

#~# EXPECTED
{ 1 => 2 }

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#~# ORIGINAL

$~

#~# EXPECTED
$~

#~# ORIGINAL

$1

#~# EXPECTED
$1

#~# ORIGINAL

$!

#~# EXPECTED
$!

#~# ORIGINAL

$@

#~# EXPECTED
$@
27 changes: 27 additions & 0 deletions spec/lib/rufo/prism_formatter_source_specs/symbol_literals.rb.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#~# ORIGINAL

:foo

#~# EXPECTED
:foo

#~# ORIGINAL

:"foo"

#~# EXPECTED
:"foo"

#~# ORIGINAL

:"foo#{1}"

#~# EXPECTED
:"foo#{1}"

#~# ORIGINAL

:*

#~# EXPECTED
:*
34 changes: 34 additions & 0 deletions spec/lib/rufo/prism_formatter_source_specs/unary_operators.rb.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#~# ORIGINAL

- x

#~# EXPECTED
-x

#~# ORIGINAL

+ x

#~# EXPECTED
+x

#~# ORIGINAL

+x

#~# EXPECTED
+x

#~# ORIGINAL

+(x)

#~# EXPECTED
+(x)

#~# ORIGINAL

+ (x)

#~# EXPECTED
+(x)
Loading