unparser 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +38 -2
- data/.travis.yml +3 -6
- data/Changelog.md +7 -0
- data/Gemfile +1 -0
- data/Gemfile.devtools +22 -17
- data/README.md +3 -4
- data/TODO +3 -2
- data/bin/unparser +10 -0
- data/circle.yml +2 -0
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/reek.yml +10 -0
- data/config/rubocop.yml +9 -17
- data/lib/unparser.rb +8 -1
- data/lib/unparser/buffer.rb +2 -0
- data/lib/unparser/cli.rb +113 -0
- data/lib/unparser/cli/differ.rb +30 -0
- data/lib/unparser/cli/preprocessor.rb +196 -0
- data/lib/unparser/cli/source.rb +118 -0
- data/lib/unparser/comments.rb +64 -23
- data/lib/unparser/constants.rb +19 -7
- data/lib/unparser/emitter.rb +23 -25
- data/lib/unparser/emitter/alias.rb +2 -0
- data/lib/unparser/emitter/argument.rb +2 -0
- data/lib/unparser/emitter/assignment.rb +3 -1
- data/lib/unparser/emitter/begin.rb +3 -6
- data/lib/unparser/emitter/binary.rb +2 -0
- data/lib/unparser/emitter/block.rb +2 -0
- data/lib/unparser/emitter/break.rb +4 -5
- data/lib/unparser/emitter/case.rb +2 -0
- data/lib/unparser/emitter/cbase.rb +2 -0
- data/lib/unparser/emitter/class.rb +4 -3
- data/lib/unparser/emitter/def.rb +2 -0
- data/lib/unparser/emitter/defined.rb +2 -0
- data/lib/unparser/emitter/empty.rb +2 -0
- data/lib/unparser/emitter/ensure.rb +2 -0
- data/lib/unparser/emitter/flipflop.rb +2 -0
- data/lib/unparser/emitter/for.rb +2 -0
- data/lib/unparser/emitter/hookexe.rb +2 -0
- data/lib/unparser/emitter/if.rb +2 -0
- data/lib/unparser/emitter/literal.rb +2 -0
- data/lib/unparser/emitter/literal/array.rb +33 -0
- data/lib/unparser/emitter/literal/dynamic.rb +21 -1
- data/lib/unparser/emitter/literal/dynamic_body.rb +9 -5
- data/lib/unparser/emitter/literal/execute_string.rb +2 -0
- data/lib/unparser/emitter/literal/hash.rb +136 -0
- data/lib/unparser/emitter/literal/primitive.rb +4 -2
- data/lib/unparser/emitter/literal/range.rb +2 -0
- data/lib/unparser/emitter/literal/regexp.rb +4 -2
- data/lib/unparser/emitter/literal/singleton.rb +2 -0
- data/lib/unparser/emitter/match.rb +2 -0
- data/lib/unparser/emitter/module.rb +2 -3
- data/lib/unparser/emitter/next.rb +2 -0
- data/lib/unparser/emitter/op_assign.rb +3 -1
- data/lib/unparser/emitter/redo.rb +2 -0
- data/lib/unparser/emitter/repetition.rb +2 -0
- data/lib/unparser/emitter/resbody.rb +2 -0
- data/lib/unparser/emitter/rescue.rb +2 -0
- data/lib/unparser/emitter/retry.rb +2 -0
- data/lib/unparser/emitter/return.rb +19 -4
- data/lib/unparser/emitter/root.rb +13 -0
- data/lib/unparser/emitter/send.rb +26 -22
- data/lib/unparser/emitter/send/arguments.rb +46 -0
- data/lib/unparser/emitter/send/attribute_assignment.rb +35 -0
- data/lib/unparser/emitter/send/binary.rb +2 -0
- data/lib/unparser/emitter/send/index.rb +2 -0
- data/lib/unparser/emitter/send/regular.rb +4 -2
- data/lib/unparser/emitter/send/unary.rb +3 -1
- data/lib/unparser/emitter/splat.rb +2 -0
- data/lib/unparser/emitter/super.rb +2 -0
- data/lib/unparser/emitter/undef.rb +2 -0
- data/lib/unparser/emitter/variable.rb +2 -0
- data/lib/unparser/emitter/yield.rb +2 -0
- data/lib/unparser/finalize.rb +2 -0
- data/lib/unparser/node_helpers.rb +19 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/unit/unparser/buffer/append_spec.rb +2 -0
- data/spec/unit/unparser/buffer/append_without_prefix_spec.rb +2 -0
- data/spec/unit/unparser/buffer/capture_content_spec.rb +2 -0
- data/spec/unit/unparser/buffer/content_spec.rb +3 -1
- data/spec/unit/unparser/buffer/fresh_line_spec.rb +2 -0
- data/spec/unit/unparser/buffer/indent_spec.rb +3 -1
- data/spec/unit/unparser/buffer/nl_spec.rb +2 -0
- data/spec/unit/unparser/buffer/unindent_spec.rb +2 -0
- data/spec/unit/unparser/comments/consume_spec.rb +2 -1
- data/spec/unit/unparser/comments/take_all_spec.rb +2 -1
- data/spec/unit/unparser/comments/take_before_spec.rb +6 -5
- data/spec/unit/unparser/comments/take_eol_comments_spec.rb +2 -1
- data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +2 -0
- data/spec/unit/unparser_spec.rb +110 -57
- data/unparser.gemspec +5 -4
- metadata +32 -12
- data/bin/test-unparser +0 -26
- data/lib/unparser/emitter/literal/composed.rb +0 -64
- data/spec/unit/unparser/comments/skip_eol_comment_spec.rb +0 -29
data/lib/unparser/constants.rb
CHANGED
@@ -1,18 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
# All unparser constants maybe included in other libraries.
|
3
5
|
module Constants
|
4
6
|
|
7
|
+
# All unary operators of the ruby language
|
5
8
|
UNARY_OPERATORS = %w(
|
6
9
|
! ~ -@ +@
|
7
10
|
).map(&:to_sym).to_set
|
8
11
|
|
12
|
+
# All binary operators of the ruby language
|
9
13
|
BINARY_OPERATORS = %w(
|
10
14
|
+ - * / & | && || << >> ==
|
11
15
|
=== != <= < <=> > >= =~ !~ ^
|
12
16
|
** %
|
13
17
|
).map(&:to_sym).to_set
|
14
18
|
|
15
|
-
COMMENT = '#'
|
19
|
+
COMMENT = '#'
|
16
20
|
|
17
21
|
WS = ' '
|
18
22
|
NL = "\n"
|
@@ -34,6 +38,10 @@ module Unparser
|
|
34
38
|
M_PO = '('
|
35
39
|
M_PC = ')'
|
36
40
|
|
41
|
+
SNGL_QUOTE = "'"
|
42
|
+
DBL_QUOTE = '"'
|
43
|
+
|
44
|
+
# Keywords
|
37
45
|
K_DO = 'do'
|
38
46
|
K_DEF = 'def'
|
39
47
|
K_END = 'end'
|
@@ -77,12 +85,16 @@ module Unparser
|
|
77
85
|
K_FILE = '__FILE__'
|
78
86
|
K_THEN = 'then'
|
79
87
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
88
|
+
# Nodes that can be emitted in tokens that terminate their expression.
|
89
|
+
#
|
90
|
+
# These nodes dont require parentheses to be exactly reproduced in context of a more complex expression.
|
91
|
+
#
|
92
|
+
TERMINATED = %w(
|
93
|
+
int float self kwbegin const regexp args lvar
|
94
|
+
ivar gvar cvar if case module class sclass super
|
95
|
+
yield zsuper break next defined? str block while loop until
|
96
|
+
def defs true false nil array hash sym return
|
97
|
+
).map(&:to_sym).to_set
|
86
98
|
|
87
99
|
KEYWORDS = constants.each_with_object([]) do |name, keywords|
|
88
100
|
value = const_get(name).freeze
|
data/lib/unparser/emitter.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
|
3
5
|
# Emitter base class
|
4
6
|
class Emitter
|
5
|
-
include Adamantium::Flat, AbstractType, Constants
|
7
|
+
include Adamantium::Flat, AbstractType, Constants, NodeHelpers
|
6
8
|
include Concord.new(:node, :parent)
|
7
9
|
|
8
10
|
# Registry for node emitters
|
@@ -14,6 +16,16 @@ module Unparser
|
|
14
16
|
|
15
17
|
CURLY_BRACKETS = IceNine.deep_freeze(%w({ }))
|
16
18
|
|
19
|
+
# Return node type
|
20
|
+
#
|
21
|
+
# @return [Symbol]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
#
|
25
|
+
def node_type
|
26
|
+
node.type
|
27
|
+
end
|
28
|
+
|
17
29
|
# Define remaining children
|
18
30
|
#
|
19
31
|
# @param [Enumerable<Symbol>] names
|
@@ -201,7 +213,6 @@ module Unparser
|
|
201
213
|
conditional_parentheses(!emitter.terminated?) do
|
202
214
|
emitter.write_to_buffer
|
203
215
|
end
|
204
|
-
emitter.write_to_buffer
|
205
216
|
end
|
206
217
|
|
207
218
|
# Visit within parentheses
|
@@ -256,10 +267,12 @@ module Unparser
|
|
256
267
|
# @api private
|
257
268
|
#
|
258
269
|
def delimited(nodes, delimiter = DEFAULT_DELIMITER)
|
259
|
-
|
260
|
-
|
270
|
+
return if nodes.empty?
|
271
|
+
head, *tail = nodes
|
272
|
+
visit(head)
|
273
|
+
tail.each do |node|
|
274
|
+
write(delimiter)
|
261
275
|
visit(node)
|
262
|
-
write(delimiter) if index < max
|
263
276
|
end
|
264
277
|
end
|
265
278
|
|
@@ -456,34 +469,19 @@ module Unparser
|
|
456
469
|
# @api private
|
457
470
|
#
|
458
471
|
def parent_type
|
459
|
-
parent
|
472
|
+
parent.node_type
|
460
473
|
end
|
461
474
|
|
462
|
-
#
|
475
|
+
# Delegate to emitter
|
463
476
|
#
|
464
|
-
# @param [
|
465
|
-
#
|
466
|
-
# @return [Parser::AST::Node]
|
467
|
-
#
|
468
|
-
# @api private
|
469
|
-
#
|
470
|
-
def s(type, *children)
|
471
|
-
Parser::AST::Node.new(type, *children)
|
472
|
-
end
|
473
|
-
|
474
|
-
# Helper to introduce an end-of-line comment
|
477
|
+
# @param [Class:Emitter] emitter
|
475
478
|
#
|
476
479
|
# @return [undefined]
|
477
480
|
#
|
478
481
|
# @api private
|
479
482
|
#
|
480
|
-
def
|
481
|
-
|
482
|
-
comment = buffer.capture_content do
|
483
|
-
write(COMMENT, WS)
|
484
|
-
yield
|
485
|
-
end
|
486
|
-
comments.skip_eol_comment(comment)
|
483
|
+
def run(emitter, node = node)
|
484
|
+
emitter.new(node, self).write_to_buffer
|
487
485
|
end
|
488
486
|
|
489
487
|
end # Emitter
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
|
@@ -15,12 +17,7 @@ module Unparser
|
|
15
17
|
# @api private
|
16
18
|
#
|
17
19
|
def emit_inner
|
18
|
-
|
19
|
-
max = childs.length - 1
|
20
|
-
childs.each_with_index do |child, index|
|
21
|
-
visit(child)
|
22
|
-
nl if index < max
|
23
|
-
end
|
20
|
+
delimited(children, NL)
|
24
21
|
end
|
25
22
|
|
26
23
|
# Emitter for implicit begins
|
@@ -1,12 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
# Emitter for break nodes
|
4
|
-
class Break <
|
6
|
+
class Break < Return
|
5
7
|
|
6
8
|
handle :break
|
7
9
|
|
8
|
-
children :arguments
|
9
|
-
|
10
10
|
private
|
11
11
|
|
12
12
|
# Perform dispatch
|
@@ -18,8 +18,7 @@ module Unparser
|
|
18
18
|
def dispatch
|
19
19
|
conditional_parentheses(parent_type == :or || parent_type == :and) do
|
20
20
|
write(K_BREAK)
|
21
|
-
|
22
|
-
visit_parentheses(arguments)
|
21
|
+
emit_break_return_arguments
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
# Emitter for class nodes
|
@@ -21,9 +23,6 @@ module Unparser
|
|
21
23
|
emit_superclass
|
22
24
|
emit_body
|
23
25
|
k_end
|
24
|
-
unless parent_type == :send
|
25
|
-
eol_comment { visit(name) }
|
26
|
-
end
|
27
26
|
end
|
28
27
|
|
29
28
|
# Emit superclass
|
@@ -47,6 +46,8 @@ module Unparser
|
|
47
46
|
|
48
47
|
children :object, :body
|
49
48
|
|
49
|
+
private
|
50
|
+
|
50
51
|
# Perform dispatch
|
51
52
|
#
|
52
53
|
# @return [undefined]
|
data/lib/unparser/emitter/def.rb
CHANGED
data/lib/unparser/emitter/for.rb
CHANGED
data/lib/unparser/emitter/if.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Unparser
|
4
|
+
class Emitter
|
5
|
+
class Literal
|
6
|
+
|
7
|
+
# Array literal emitter
|
8
|
+
class Array < self
|
9
|
+
OPEN = '['.freeze
|
10
|
+
CLOSE = ']'.freeze
|
11
|
+
DELIMITER = ', '.freeze
|
12
|
+
|
13
|
+
handle :array
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# Perform dispatch
|
18
|
+
#
|
19
|
+
# @return [undefined]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
#
|
23
|
+
def dispatch
|
24
|
+
parentheses(OPEN, CLOSE) do
|
25
|
+
delimited(children, DELIMITER)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end # Array
|
30
|
+
|
31
|
+
end # Literal
|
32
|
+
end # Emitter
|
33
|
+
end # Unparser
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
class Literal
|
@@ -15,7 +17,25 @@ module Unparser
|
|
15
17
|
#
|
16
18
|
def dispatch
|
17
19
|
util = self.class
|
18
|
-
|
20
|
+
if interpolation?
|
21
|
+
visit_parentheses(dynamic_body, util::OPEN, util::CLOSE)
|
22
|
+
else
|
23
|
+
delimited(children, WS)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Test for interpolation
|
28
|
+
#
|
29
|
+
# @return [true]
|
30
|
+
# if dynamic component was interpolated
|
31
|
+
#
|
32
|
+
# @return [false]
|
33
|
+
# otherwise
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
#
|
37
|
+
def interpolation?
|
38
|
+
children.any? { |child| child.type != :str }
|
19
39
|
end
|
20
40
|
|
21
41
|
# Return dynamic body
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
class Literal
|
@@ -61,9 +63,11 @@ module Unparser
|
|
61
63
|
emit_interpolated_segment(node)
|
62
64
|
end
|
63
65
|
|
64
|
-
|
65
|
-
"
|
66
|
-
|
66
|
+
pairs = Parser::Lexer::ESCAPES.invert.map do |key, value|
|
67
|
+
[key, "\\#{value}"] unless key == WS
|
68
|
+
end.compact
|
69
|
+
|
70
|
+
ESCAPES = ::Hash[pairs]
|
67
71
|
|
68
72
|
REPLACEMENTS = ::Regexp.union(ESCAPES.keys)
|
69
73
|
|
@@ -79,8 +83,8 @@ module Unparser
|
|
79
83
|
util = self.class
|
80
84
|
string = node.children.first
|
81
85
|
segment = string
|
82
|
-
.gsub(util::DELIMITER, util::REPLACEMENT)
|
83
86
|
.gsub(REPLACEMENTS, ESCAPES)
|
87
|
+
.gsub(util::DELIMITER, util::REPLACEMENT)
|
84
88
|
write(segment)
|
85
89
|
end
|
86
90
|
|
@@ -112,7 +116,7 @@ module Unparser
|
|
112
116
|
handle :dyn_regexp_body
|
113
117
|
|
114
118
|
DELIMITER = '/'.freeze
|
115
|
-
REPLACEMENT = '
|
119
|
+
REPLACEMENT = '\/'.freeze
|
116
120
|
|
117
121
|
end # Regexp
|
118
122
|
|