rufo 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +25 -0
- data/lib/rufo/command.rb +6 -3
- data/lib/rufo/formatter.rb +110 -12
- data/lib/rufo/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 447a4661f121c8ffd43ba8fc6e5e7267ab5dc3d5
|
|
4
|
+
data.tar.gz: a69acf6a569e48b611a51d6105bc3081b47742fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9e0df262618cf4ff4e6b6b4ddd9b241b734e52a2fe35c170ee70c4dbabc7d48df15e39c9432574982886dc19631a7263fb0d53f00e7deb45e50d7173fbe75275
|
|
7
|
+
data.tar.gz: 1aaf628a9c1ee5d2405b518048d1ae1524d5f673798c511751675cfe38680041619286f0e5056e59c81cc4deabb5e39f54775b87af31f041a8c65119b79befb4
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Rufo
|
|
2
2
|
|
|
3
|
+
[](https://travis-ci.org/asterite/rufo)
|
|
4
|
+
|
|
3
5
|
**Ru**by **fo**rmatter
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
@@ -75,6 +77,29 @@ indent_size 2
|
|
|
75
77
|
As time passes there might be more configurations available. Please open an
|
|
76
78
|
issue if you need something else to be configurable.
|
|
77
79
|
|
|
80
|
+
## Status
|
|
81
|
+
|
|
82
|
+
The current version is 0.0.3. The formatter was tested on some big files with many Ruby
|
|
83
|
+
syntax and idioms, but since it's so new there might be some missing stuff. Don't hesitate
|
|
84
|
+
to open an issue if you find something is not working well. In any case, if the formatter
|
|
85
|
+
chokes on some valid input you will get an error prompting you to submit a bug report here :-)
|
|
86
|
+
|
|
87
|
+
## How it works
|
|
88
|
+
|
|
89
|
+
Rufo is a **real** formatter, not a simple find and replace one. It works by employing
|
|
90
|
+
a Ruby parser and a Ruby lexer. The parser is used for the shape of the program. The program
|
|
91
|
+
is traversed and the lexer is used to sync this structure to tokens. This is why comments
|
|
92
|
+
can be handled well, because they are provided by the lexer (comments are not returned by
|
|
93
|
+
a parser).
|
|
94
|
+
|
|
95
|
+
To parse and lex, [Ripper](https://ruby-doc.org/stdlib-2.4.0/libdoc/ripper/rdoc/Ripper.html) is used.
|
|
96
|
+
|
|
97
|
+
As a reference, this was implemented in a similar fashion to [Crystal](https://github.com/crystal-lang/crystal)'s formatter.
|
|
98
|
+
|
|
99
|
+
And as a side note, rufo has **no dependencies**. It only depends on `rspec` for tests, but that's it.
|
|
100
|
+
That means it loads very fast (no need to read many Ruby files), and because `Ripper` is mostly written
|
|
101
|
+
in C (uses Ruby's lexer and parser) it formats files pretty fast too.
|
|
102
|
+
|
|
78
103
|
## Development
|
|
79
104
|
|
|
80
105
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/rufo/command.rb
CHANGED
|
@@ -9,9 +9,6 @@ module Rufo::Command
|
|
|
9
9
|
else
|
|
10
10
|
format_args ARGV, want_check
|
|
11
11
|
end
|
|
12
|
-
rescue Rufo::SyntaxError
|
|
13
|
-
STDERR.puts "Error: the given text is not a valid ruby program (it has syntax errors)"
|
|
14
|
-
exit 1
|
|
15
12
|
end
|
|
16
13
|
|
|
17
14
|
def self.format_stdin(want_check)
|
|
@@ -23,6 +20,9 @@ module Rufo::Command
|
|
|
23
20
|
else
|
|
24
21
|
print result
|
|
25
22
|
end
|
|
23
|
+
rescue Rufo::SyntaxError
|
|
24
|
+
STDERR.puts "Error: the given text is not a valid ruby program (it has syntax errors)"
|
|
25
|
+
exit 1
|
|
26
26
|
rescue Rufo::Bug => ex
|
|
27
27
|
STDERR.puts "You've found a bug!"
|
|
28
28
|
STDERR.puts "Please report it to https://github.com/asterite/rufo/issues with code that triggers it"
|
|
@@ -68,6 +68,9 @@ module Rufo::Command
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
false
|
|
71
|
+
rescue Rufo::SyntaxError
|
|
72
|
+
STDERR.puts "Error: the given text in #{filename} is not a valid ruby program (it has syntax errors)"
|
|
73
|
+
exit 1
|
|
71
74
|
rescue Rufo::Bug => ex
|
|
72
75
|
STDERR.puts "You've found a bug!"
|
|
73
76
|
STDERR.puts "It happened while trying to format the file #{filename}"
|
data/lib/rufo/formatter.rb
CHANGED
|
@@ -110,8 +110,18 @@ class Rufo::Formatter
|
|
|
110
110
|
#
|
|
111
111
|
# [:@int, "123", [1, 0]]
|
|
112
112
|
consume_token :on_int
|
|
113
|
+
when :@gvar
|
|
114
|
+
# [:@gvar, "$abc", [1, 0]]
|
|
115
|
+
write node[1]
|
|
116
|
+
next_token
|
|
117
|
+
when :@backref
|
|
118
|
+
# [:@backref, "$1", [1, 0]]
|
|
119
|
+
write node[1]
|
|
120
|
+
next_token
|
|
113
121
|
when :string_literal
|
|
114
122
|
visit_string_literal node
|
|
123
|
+
when :string_concat
|
|
124
|
+
visit_string_concat node
|
|
115
125
|
when :@tstring_content
|
|
116
126
|
# [:@tstring_content, "hello ", [1, 1]]
|
|
117
127
|
heredoc, tilde = @current_heredoc
|
|
@@ -294,6 +304,8 @@ class Rufo::Formatter
|
|
|
294
304
|
consume_keyword "super"
|
|
295
305
|
when :super
|
|
296
306
|
visit_super(node)
|
|
307
|
+
when :defined
|
|
308
|
+
visit_defined(node)
|
|
297
309
|
else
|
|
298
310
|
bug "Unhandled node: #{node.first}"
|
|
299
311
|
end
|
|
@@ -397,6 +409,16 @@ class Rufo::Formatter
|
|
|
397
409
|
end
|
|
398
410
|
end
|
|
399
411
|
|
|
412
|
+
def visit_string_concat(node)
|
|
413
|
+
# string1 string2
|
|
414
|
+
# [:string_concat, string1, string2]
|
|
415
|
+
_, string1, string2 = node
|
|
416
|
+
|
|
417
|
+
visit string1
|
|
418
|
+
consume_space
|
|
419
|
+
visit string2
|
|
420
|
+
end
|
|
421
|
+
|
|
400
422
|
def visit_string_interpolation(node)
|
|
401
423
|
# [:string_embexpr, exps]
|
|
402
424
|
consume_token :on_embexpr_beg
|
|
@@ -610,7 +632,7 @@ class Rufo::Formatter
|
|
|
610
632
|
|
|
611
633
|
def consume_call_dot
|
|
612
634
|
if current_token_kind == :on_op
|
|
613
|
-
|
|
635
|
+
consume_token :on_op
|
|
614
636
|
else
|
|
615
637
|
check :on_period
|
|
616
638
|
next_token
|
|
@@ -942,9 +964,9 @@ class Rufo::Formatter
|
|
|
942
964
|
_, body, rescue_body, else_body, ensure_body = node
|
|
943
965
|
indent_body body
|
|
944
966
|
|
|
945
|
-
|
|
946
|
-
# [:rescue, type, name, body,
|
|
947
|
-
_, type, name, body = rescue_body
|
|
967
|
+
while rescue_body
|
|
968
|
+
# [:rescue, type, name, body, more_rescue]
|
|
969
|
+
_, type, name, body, more_rescue = rescue_body
|
|
948
970
|
write_indent
|
|
949
971
|
consume_keyword "rescue"
|
|
950
972
|
if type
|
|
@@ -965,6 +987,7 @@ class Rufo::Formatter
|
|
|
965
987
|
end
|
|
966
988
|
|
|
967
989
|
indent_body body
|
|
990
|
+
rescue_body = more_rescue
|
|
968
991
|
end
|
|
969
992
|
|
|
970
993
|
if else_body
|
|
@@ -1452,9 +1475,15 @@ class Rufo::Formatter
|
|
|
1452
1475
|
end
|
|
1453
1476
|
|
|
1454
1477
|
has_newline = false
|
|
1478
|
+
last_token = nil
|
|
1455
1479
|
|
|
1456
1480
|
while current_token_kind == :on_words_sep
|
|
1457
1481
|
has_newline ||= current_token_value.include?("\n")
|
|
1482
|
+
|
|
1483
|
+
unless current_token[2].strip.empty?
|
|
1484
|
+
last_token = current_token
|
|
1485
|
+
end
|
|
1486
|
+
|
|
1458
1487
|
next_token
|
|
1459
1488
|
end
|
|
1460
1489
|
|
|
@@ -1463,8 +1492,12 @@ class Rufo::Formatter
|
|
|
1463
1492
|
write_indent(next_indent)
|
|
1464
1493
|
end
|
|
1465
1494
|
|
|
1466
|
-
|
|
1467
|
-
|
|
1495
|
+
if last_token
|
|
1496
|
+
write last_token[2].strip
|
|
1497
|
+
else
|
|
1498
|
+
write current_token_value.strip
|
|
1499
|
+
next_token
|
|
1500
|
+
end
|
|
1468
1501
|
end
|
|
1469
1502
|
|
|
1470
1503
|
def visit_hash(node)
|
|
@@ -1683,7 +1716,12 @@ class Rufo::Formatter
|
|
|
1683
1716
|
consume_space if space?
|
|
1684
1717
|
|
|
1685
1718
|
indent(@column) do
|
|
1686
|
-
|
|
1719
|
+
# For `return a b` there comes many nodes, not just one... (see #8)
|
|
1720
|
+
if node[1][0].is_a?(Symbol)
|
|
1721
|
+
visit node[1]
|
|
1722
|
+
else
|
|
1723
|
+
visit_exps node[1], false, false
|
|
1724
|
+
end
|
|
1687
1725
|
end
|
|
1688
1726
|
end
|
|
1689
1727
|
end
|
|
@@ -1764,6 +1802,39 @@ class Rufo::Formatter
|
|
|
1764
1802
|
end
|
|
1765
1803
|
end
|
|
1766
1804
|
|
|
1805
|
+
def visit_defined(node)
|
|
1806
|
+
# [:defined, exp]
|
|
1807
|
+
_, exp = node
|
|
1808
|
+
|
|
1809
|
+
consume_keyword "defined?"
|
|
1810
|
+
skip_space_or_newline
|
|
1811
|
+
|
|
1812
|
+
has_paren = current_token_kind == :on_lparen
|
|
1813
|
+
|
|
1814
|
+
if has_paren
|
|
1815
|
+
write "("
|
|
1816
|
+
next_token
|
|
1817
|
+
skip_space_or_newline
|
|
1818
|
+
else
|
|
1819
|
+
consume_space
|
|
1820
|
+
end
|
|
1821
|
+
|
|
1822
|
+
# exp can be [:paren, exp] if there's a parentheses,
|
|
1823
|
+
# though not always (only if there's a space after `defined?`)
|
|
1824
|
+
if exp[0] == :paren
|
|
1825
|
+
exp = exp[1]
|
|
1826
|
+
end
|
|
1827
|
+
|
|
1828
|
+
visit exp
|
|
1829
|
+
|
|
1830
|
+
if has_paren
|
|
1831
|
+
skip_space_or_newline
|
|
1832
|
+
check :on_rparen
|
|
1833
|
+
write ")"
|
|
1834
|
+
next_token
|
|
1835
|
+
end
|
|
1836
|
+
end
|
|
1837
|
+
|
|
1767
1838
|
def visit_literal_elements(elements)
|
|
1768
1839
|
base_column = @column
|
|
1769
1840
|
|
|
@@ -1891,20 +1962,47 @@ class Rufo::Formatter
|
|
|
1891
1962
|
skip_space
|
|
1892
1963
|
|
|
1893
1964
|
# Keep `while cond; end` as is
|
|
1894
|
-
|
|
1965
|
+
semicolon = semicolon?
|
|
1966
|
+
is_do = keyword?("do")
|
|
1967
|
+
|
|
1968
|
+
if (semicolon || is_do) && void_exps?(body)
|
|
1895
1969
|
next_token
|
|
1896
1970
|
skip_space
|
|
1897
1971
|
|
|
1898
1972
|
if keyword?("end")
|
|
1899
|
-
|
|
1973
|
+
if is_do
|
|
1974
|
+
write " do end"
|
|
1975
|
+
else
|
|
1976
|
+
write "; end"
|
|
1977
|
+
end
|
|
1900
1978
|
next_token
|
|
1901
1979
|
return
|
|
1902
1980
|
end
|
|
1903
1981
|
end
|
|
1904
1982
|
|
|
1905
|
-
|
|
1983
|
+
if semicolon || is_do
|
|
1984
|
+
next_token
|
|
1985
|
+
skip_space
|
|
1986
|
+
skip_semicolons
|
|
1987
|
+
|
|
1988
|
+
if newline? || comment?
|
|
1989
|
+
indent_body body
|
|
1990
|
+
write_indent
|
|
1991
|
+
else
|
|
1992
|
+
skip_space_or_newline
|
|
1993
|
+
if semicolon
|
|
1994
|
+
write "; "
|
|
1995
|
+
else
|
|
1996
|
+
write " do "
|
|
1997
|
+
end
|
|
1998
|
+
visit_exps body, false, false
|
|
1999
|
+
consume_space
|
|
2000
|
+
end
|
|
2001
|
+
else
|
|
2002
|
+
indent_body body
|
|
2003
|
+
write_indent
|
|
2004
|
+
end
|
|
1906
2005
|
|
|
1907
|
-
write_indent
|
|
1908
2006
|
consume_keyword "end"
|
|
1909
2007
|
end
|
|
1910
2008
|
|
|
@@ -1991,7 +2089,7 @@ class Rufo::Formatter
|
|
|
1991
2089
|
|
|
1992
2090
|
def consume_space
|
|
1993
2091
|
skip_space_or_newline
|
|
1994
|
-
write_space " "
|
|
2092
|
+
write_space " " unless @output[-1] == " "
|
|
1995
2093
|
end
|
|
1996
2094
|
|
|
1997
2095
|
def skip_space
|
data/lib/rufo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rufo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ary Borenszweig
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-06-
|
|
11
|
+
date: 2017-06-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|