unparser 0.1.5 → 0.1.6
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/.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
@@ -0,0 +1,136 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Unparser
|
4
|
+
class Emitter
|
5
|
+
class Literal
|
6
|
+
|
7
|
+
# Abstract namespace class for hash pair emitters
|
8
|
+
class HashPair < self
|
9
|
+
|
10
|
+
# Pair emitter that emits hash-rocket separated key values
|
11
|
+
class Rocket < self
|
12
|
+
HASHROCKET = ' => '.freeze
|
13
|
+
|
14
|
+
handle :pair_rocket, :pair
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Perform dispatch
|
19
|
+
#
|
20
|
+
# @return [undefined]
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
#
|
24
|
+
def dispatch
|
25
|
+
delimited(children, HASHROCKET)
|
26
|
+
end
|
27
|
+
|
28
|
+
end # Rocket
|
29
|
+
|
30
|
+
# Pair emitter that emits colon separated key values
|
31
|
+
class Colon < self
|
32
|
+
COLON = ': '.freeze
|
33
|
+
|
34
|
+
handle :pair_colon
|
35
|
+
|
36
|
+
children :key, :value
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Perform dispatch
|
41
|
+
#
|
42
|
+
# @return [undefined]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
#
|
46
|
+
def dispatch
|
47
|
+
write(key.children.first.to_s, COLON)
|
48
|
+
visit(value)
|
49
|
+
end
|
50
|
+
|
51
|
+
end # Colon
|
52
|
+
|
53
|
+
end # HashPair
|
54
|
+
|
55
|
+
# Emitter for hash bodies
|
56
|
+
class HashBody < self
|
57
|
+
|
58
|
+
DELIMITER = ', '.freeze
|
59
|
+
BAREWORD = /\A[A-Za-z_][A-Za-z_0-9]*[?!]?\z/.freeze
|
60
|
+
|
61
|
+
handle :hash_body
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# Perform dispatch
|
66
|
+
#
|
67
|
+
# @return [undefined]
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
#
|
71
|
+
def dispatch
|
72
|
+
delimited(effective_body, DELIMITER)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Return effective body
|
76
|
+
#
|
77
|
+
# @return [Enumerable<Parser::AST::Node>]
|
78
|
+
#
|
79
|
+
# @api private
|
80
|
+
#
|
81
|
+
def effective_body
|
82
|
+
children.map do |pair|
|
83
|
+
key, _value = *pair
|
84
|
+
if key.type == :sym && key.children.first.to_s =~ BAREWORD
|
85
|
+
s(:pair_colon, pair.children)
|
86
|
+
else
|
87
|
+
s(:pair_rocket, pair.children)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end # HashBody
|
93
|
+
|
94
|
+
# Emitter for Hash literals
|
95
|
+
class Hash < self
|
96
|
+
|
97
|
+
DELIMITER = ', '.freeze
|
98
|
+
OPEN = '{'.freeze
|
99
|
+
CLOSE = '}'.freeze
|
100
|
+
|
101
|
+
handle :hash
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
# Perform dispatch
|
106
|
+
#
|
107
|
+
# @return [undefined]
|
108
|
+
#
|
109
|
+
# @api private
|
110
|
+
#
|
111
|
+
def dispatch
|
112
|
+
if children.empty?
|
113
|
+
write(OPEN, CLOSE)
|
114
|
+
else
|
115
|
+
emit_hash_body
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Emit hash body
|
120
|
+
#
|
121
|
+
# @return [undefined]
|
122
|
+
#
|
123
|
+
# @api private
|
124
|
+
#
|
125
|
+
def emit_hash_body
|
126
|
+
parentheses(OPEN, CLOSE) do
|
127
|
+
write(WS)
|
128
|
+
run(HashBody)
|
129
|
+
write(WS)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end # Hash
|
134
|
+
end # Literal
|
135
|
+
end # Emitter
|
136
|
+
end # Unparser
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
class Literal
|
@@ -12,7 +14,7 @@ module Unparser
|
|
12
14
|
# Emitter for primitives based on Object#inspect
|
13
15
|
class Inspect < self
|
14
16
|
|
15
|
-
handle :float, :
|
17
|
+
handle :float, :int, :sym
|
16
18
|
|
17
19
|
private
|
18
20
|
|
@@ -23,7 +25,7 @@ module Unparser
|
|
23
25
|
# @api private
|
24
26
|
#
|
25
27
|
def dispatch
|
26
|
-
|
28
|
+
write(value.inspect)
|
27
29
|
end
|
28
30
|
|
29
31
|
end # Inspect
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
class Literal
|
@@ -46,7 +48,7 @@ module Unparser
|
|
46
48
|
def write_body(node)
|
47
49
|
case node.type
|
48
50
|
when :str
|
49
|
-
|
51
|
+
buffer.append_without_prefix(escape(node).children.first)
|
50
52
|
else
|
51
53
|
visit(s(:interpolated, [node]))
|
52
54
|
end
|
@@ -95,7 +97,7 @@ module Unparser
|
|
95
97
|
def delimiter
|
96
98
|
location = node.location
|
97
99
|
return DELIMITER unless location
|
98
|
-
location.
|
100
|
+
location.end.source[-1]
|
99
101
|
end
|
100
102
|
memoize :delimiter
|
101
103
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
# Emitter for return nodes
|
@@ -5,8 +7,6 @@ module Unparser
|
|
5
7
|
|
6
8
|
handle :return
|
7
9
|
|
8
|
-
children :argument
|
9
|
-
|
10
10
|
private
|
11
11
|
|
12
12
|
# Perform dispatch
|
@@ -17,8 +17,23 @@ module Unparser
|
|
17
17
|
#
|
18
18
|
def dispatch
|
19
19
|
write(K_RETURN)
|
20
|
-
|
21
|
-
|
20
|
+
emit_break_return_arguments
|
21
|
+
end
|
22
|
+
|
23
|
+
# Emit break or return arguments
|
24
|
+
#
|
25
|
+
# @return [undefined]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
#
|
29
|
+
def emit_break_return_arguments
|
30
|
+
return if children.empty?
|
31
|
+
head, *tail = children
|
32
|
+
parentheses { visit(head) }
|
33
|
+
tail.each do |node|
|
34
|
+
write(DEFAULT_DELIMITER)
|
35
|
+
parentheses { visit(node) }
|
36
|
+
end
|
22
37
|
end
|
23
38
|
|
24
39
|
end # Return
|
@@ -1,8 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
# Root emitter a special case
|
4
6
|
class Root < self
|
5
7
|
include Concord::Public.new(:buffer, :comments)
|
8
|
+
|
9
|
+
# Return root node type
|
10
|
+
#
|
11
|
+
# @return [nil]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
#
|
15
|
+
def node_type
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
6
19
|
end # Root
|
7
20
|
end # Emitter
|
8
21
|
end # Unparser
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
# Emitter for send
|
@@ -71,10 +73,12 @@ module Unparser
|
|
71
73
|
# @api private
|
72
74
|
#
|
73
75
|
def non_index_emitter
|
74
|
-
if
|
76
|
+
if binary_operator?
|
75
77
|
Binary
|
76
|
-
elsif
|
78
|
+
elsif unary_operator?
|
77
79
|
Unary
|
80
|
+
elsif attribute_assignment?
|
81
|
+
AttributeAssignment
|
78
82
|
else
|
79
83
|
Regular
|
80
84
|
end
|
@@ -91,18 +95,6 @@ module Unparser
|
|
91
95
|
end
|
92
96
|
memoize :string_selector
|
93
97
|
|
94
|
-
# Delegate to emitter
|
95
|
-
#
|
96
|
-
# @param [Class:Emitter] emitter
|
97
|
-
#
|
98
|
-
# @return [undefined]
|
99
|
-
#
|
100
|
-
# @api private
|
101
|
-
#
|
102
|
-
def run(emitter)
|
103
|
-
emitter.new(node, self).write_to_buffer
|
104
|
-
end
|
105
|
-
|
106
98
|
# Test for unary operator implemented as method
|
107
99
|
#
|
108
100
|
# @return [true]
|
@@ -113,7 +105,7 @@ module Unparser
|
|
113
105
|
#
|
114
106
|
# @api private
|
115
107
|
#
|
116
|
-
def
|
108
|
+
def unary_operator?
|
117
109
|
UNARY_OPERATORS.include?(selector)
|
118
110
|
end
|
119
111
|
|
@@ -127,8 +119,8 @@ module Unparser
|
|
127
119
|
#
|
128
120
|
# @api private
|
129
121
|
#
|
130
|
-
def
|
131
|
-
BINARY_OPERATORS.include?(selector) && arguments.
|
122
|
+
def binary_operator?
|
123
|
+
BINARY_OPERATORS.include?(selector) && arguments.one? && arguments.first.type != :splat
|
132
124
|
end
|
133
125
|
|
134
126
|
# Emit selector
|
@@ -161,6 +153,8 @@ module Unparser
|
|
161
153
|
|
162
154
|
# Test for assignment
|
163
155
|
#
|
156
|
+
# FIXME: This also returns true for <= operator!
|
157
|
+
#
|
164
158
|
# @return [true]
|
165
159
|
# if node represents attribute / element assignment
|
166
160
|
#
|
@@ -173,6 +167,19 @@ module Unparser
|
|
173
167
|
string_selector[-1] == ASSIGN_SUFFIX
|
174
168
|
end
|
175
169
|
|
170
|
+
# Test for attribute assignment
|
171
|
+
#
|
172
|
+
# @return [true]
|
173
|
+
# if node represetns and attribute assignment
|
174
|
+
#
|
175
|
+
# @return [false]
|
176
|
+
#
|
177
|
+
# @api private
|
178
|
+
#
|
179
|
+
def attribute_assignment?
|
180
|
+
!BINARY_OPERATORS.include?(selector) && !UNARY_OPERATORS.include?(selector) && assignment? && !mlhs?
|
181
|
+
end
|
182
|
+
|
176
183
|
# Test for empty arguments
|
177
184
|
#
|
178
185
|
# @return [true]
|
@@ -196,6 +203,7 @@ module Unparser
|
|
196
203
|
def arguments
|
197
204
|
children[2..-1]
|
198
205
|
end
|
206
|
+
memoize :arguments
|
199
207
|
|
200
208
|
# Emit arguments
|
201
209
|
#
|
@@ -204,11 +212,7 @@ module Unparser
|
|
204
212
|
# @api private
|
205
213
|
#
|
206
214
|
def emit_arguments
|
207
|
-
|
208
|
-
return if args.empty?
|
209
|
-
parentheses do
|
210
|
-
delimited(args)
|
211
|
-
end
|
215
|
+
run(Arguments, s(:arguments, arguments))
|
212
216
|
end
|
213
217
|
|
214
218
|
end # Send
|