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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f651b0e7deb5c6d36cbe7632aa761954e7d49939
4
- data.tar.gz: 20b7c26c352e682cf72547fdeebf25d31b467aa4
3
+ metadata.gz: 447a4661f121c8ffd43ba8fc6e5e7267ab5dc3d5
4
+ data.tar.gz: a69acf6a569e48b611a51d6105bc3081b47742fe
5
5
  SHA512:
6
- metadata.gz: b9f40a5d0fd5ad07143ccc49fafddce8bd72cad15ada182f8cdf03b239a956f5a4072fe0df639d53a3c88d928a12058a360158b1a3b61462e073b2d9973cdfb1
7
- data.tar.gz: 122c69242308b0999954d684ae4cfb4a0020d5ec9b68de7f76ce449a47076d659d8062f8c69fe9da80057031e07caddcc19f8a0fb653cd1e7ee0be3619d990c9
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.
@@ -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}"
@@ -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
- consume_op "::"
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
- if rescue_body
946
- # [:rescue, type, name, body, nil]
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
- write ")"
1467
- return
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
- visit node[1]
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
- if semicolon? && void_exps?(body)
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
- write "; end"
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
- indent_body body
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
@@ -1,3 +1,3 @@
1
1
  module Rufo
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
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.3
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-22 00:00:00.000000000 Z
11
+ date: 2017-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler