rufo 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/asterite/rufo.svg)](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
|