unparser 0.1.15 → 0.1.16
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/Changelog.md +6 -0
- data/circle.yml +1 -1
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/reek.yml +1 -0
- data/lib/unparser/ast.rb +1 -1
- data/lib/unparser/ast/local_variable_scope.rb +1 -1
- data/lib/unparser/cli/differ.rb +1 -1
- data/lib/unparser/cli/source.rb +2 -0
- data/lib/unparser/constants.rb +0 -11
- data/lib/unparser/dsl.rb +1 -1
- data/lib/unparser/emitter.rb +41 -13
- data/lib/unparser/emitter/argument.rb +22 -34
- data/lib/unparser/emitter/assignment.rb +29 -6
- data/lib/unparser/emitter/begin.rb +10 -8
- data/lib/unparser/emitter/binary.rb +3 -12
- data/lib/unparser/emitter/block.rb +1 -0
- data/lib/unparser/emitter/case.rb +4 -2
- data/lib/unparser/emitter/cbase.rb +1 -0
- data/lib/unparser/emitter/class.rb +2 -1
- data/lib/unparser/emitter/def.rb +1 -1
- data/lib/unparser/emitter/defined.rb +2 -1
- data/lib/unparser/emitter/flipflop.rb +3 -2
- data/lib/unparser/emitter/flow_modifier.rb +22 -5
- data/lib/unparser/emitter/for.rb +2 -1
- data/lib/unparser/emitter/if.rb +10 -3
- data/lib/unparser/emitter/literal.rb +1 -0
- data/lib/unparser/emitter/literal/dynamic_body.rb +1 -1
- data/lib/unparser/emitter/literal/hash.rb +1 -1
- data/lib/unparser/emitter/literal/primitive.rb +83 -1
- data/lib/unparser/emitter/literal/range.rb +3 -2
- data/lib/unparser/emitter/match.rb +1 -0
- data/lib/unparser/emitter/module.rb +1 -1
- data/lib/unparser/emitter/op_assign.rb +3 -1
- data/lib/unparser/emitter/redo.rb +1 -0
- data/lib/unparser/emitter/repetition.rb +5 -3
- data/lib/unparser/emitter/resbody.rb +2 -2
- data/lib/unparser/emitter/rescue.rb +2 -1
- data/lib/unparser/emitter/retry.rb +1 -0
- data/lib/unparser/emitter/send.rb +13 -14
- data/lib/unparser/emitter/send/arguments.rb +1 -2
- data/lib/unparser/emitter/send/attribute_assignment.rb +3 -2
- data/lib/unparser/emitter/send/binary.rb +3 -2
- data/lib/unparser/emitter/send/index.rb +16 -2
- data/lib/unparser/emitter/send/regular.rb +2 -1
- data/lib/unparser/emitter/send/unary.rb +2 -1
- data/lib/unparser/emitter/splat.rb +2 -0
- data/lib/unparser/emitter/super.rb +2 -0
- data/lib/unparser/emitter/undef.rb +1 -0
- data/lib/unparser/emitter/variable.rb +4 -0
- data/lib/unparser/emitter/yield.rb +1 -0
- data/lib/unparser/preprocessor.rb +19 -12
- data/spec/integration/unparser/corpus_spec.rb +3 -2
- data/spec/integrations.yml +11 -1
- data/spec/unit/unparser_spec.rb +190 -183
- data/unparser.gemspec +2 -2
- metadata +5 -4
@@ -5,6 +5,7 @@ module Unparser
|
|
5
5
|
|
6
6
|
# Emitter for postconditions
|
7
7
|
class Post < self
|
8
|
+
include Unterminated
|
8
9
|
|
9
10
|
handle :while_post, :until_post
|
10
11
|
|
@@ -32,6 +33,7 @@ module Unparser
|
|
32
33
|
|
33
34
|
# Base class for while and until emitters
|
34
35
|
class Repetition < self
|
36
|
+
include Terminated
|
35
37
|
|
36
38
|
MAP = {
|
37
39
|
while: K_WHILE,
|
@@ -87,7 +89,7 @@ module Unparser
|
|
87
89
|
#
|
88
90
|
def emit_normal
|
89
91
|
emit_keyword
|
90
|
-
|
92
|
+
visit(condition)
|
91
93
|
emit_body
|
92
94
|
k_end
|
93
95
|
end
|
@@ -99,10 +101,10 @@ module Unparser
|
|
99
101
|
# @api private
|
100
102
|
#
|
101
103
|
def emit_postcontrol
|
102
|
-
|
104
|
+
visit_plain(body)
|
103
105
|
ws
|
104
106
|
emit_keyword
|
105
|
-
|
107
|
+
visit_plain(condition)
|
106
108
|
end
|
107
109
|
|
108
110
|
end # Repetition
|
@@ -4,6 +4,7 @@ module Unparser
|
|
4
4
|
class Emitter
|
5
5
|
# Emitter for rescue nodes
|
6
6
|
class Rescue < self
|
7
|
+
include Unterminated
|
7
8
|
|
8
9
|
handle :rescue
|
9
10
|
|
@@ -56,7 +57,7 @@ module Unparser
|
|
56
57
|
# @api private
|
57
58
|
#
|
58
59
|
def emit_standalone
|
59
|
-
|
60
|
+
visit_plain(body)
|
60
61
|
ws
|
61
62
|
run(Resbody::Standalone, rescue_body)
|
62
63
|
end
|
@@ -16,17 +16,8 @@ module Unparser
|
|
16
16
|
|
17
17
|
children :receiver, :selector
|
18
18
|
|
19
|
-
# Test for terminated expression
|
20
|
-
#
|
21
|
-
# @return [Boolean]
|
22
|
-
#
|
23
|
-
# @api private
|
24
|
-
#
|
25
19
|
def terminated?
|
26
|
-
|
27
|
-
Index::Reference,
|
28
|
-
Regular
|
29
|
-
].include?(effective_emitter)
|
20
|
+
effective_emitter.terminated?
|
30
21
|
end
|
31
22
|
|
32
23
|
private
|
@@ -38,16 +29,26 @@ module Unparser
|
|
38
29
|
# @api private
|
39
30
|
#
|
40
31
|
def dispatch
|
41
|
-
effective_emitter.
|
32
|
+
effective_emitter.write_to_buffer
|
42
33
|
end
|
43
34
|
|
44
35
|
# Return effective emitter
|
45
36
|
#
|
46
|
-
# @return [
|
37
|
+
# @return [Emitter]
|
47
38
|
#
|
48
39
|
# @api private
|
49
40
|
#
|
50
41
|
def effective_emitter
|
42
|
+
effective_emitter_class.new(node, parent)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return effective emitter
|
46
|
+
#
|
47
|
+
# @return [Class:Emitter]
|
48
|
+
#
|
49
|
+
# @api private
|
50
|
+
#
|
51
|
+
def effective_emitter_class
|
51
52
|
case selector
|
52
53
|
when INDEX_REFERENCE
|
53
54
|
Index::Reference
|
@@ -57,7 +58,6 @@ module Unparser
|
|
57
58
|
non_index_emitter
|
58
59
|
end
|
59
60
|
end
|
60
|
-
memoize :effective_emitter
|
61
61
|
|
62
62
|
# Return non index emitter
|
63
63
|
#
|
@@ -86,7 +86,6 @@ module Unparser
|
|
86
86
|
def string_selector
|
87
87
|
selector.to_s
|
88
88
|
end
|
89
|
-
memoize :string_selector
|
90
89
|
|
91
90
|
# Test for unary operator implemented as method
|
92
91
|
#
|
@@ -3,7 +3,6 @@
|
|
3
3
|
module Unparser
|
4
4
|
class Emitter
|
5
5
|
class Send
|
6
|
-
|
7
6
|
# Emitter for arguments of send nodes
|
8
7
|
class Arguments < Emitter
|
9
8
|
|
@@ -19,7 +18,7 @@ module Unparser
|
|
19
18
|
return if children.empty?
|
20
19
|
|
21
20
|
parentheses do
|
22
|
-
|
21
|
+
delimited_plain(effective_arguments)
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
@@ -5,6 +5,7 @@ module Unparser
|
|
5
5
|
class Send
|
6
6
|
# Emitter for send as attribute assignment
|
7
7
|
class AttributeAssignment < self
|
8
|
+
include Unterminated
|
8
9
|
|
9
10
|
# Perform regular dispatch
|
10
11
|
#
|
@@ -16,7 +17,7 @@ module Unparser
|
|
16
17
|
emit_receiver
|
17
18
|
emit_attribute
|
18
19
|
emit_operator
|
19
|
-
|
20
|
+
visit(arguments.first)
|
20
21
|
end
|
21
22
|
|
22
23
|
private
|
@@ -28,7 +29,7 @@ module Unparser
|
|
28
29
|
# @api private
|
29
30
|
#
|
30
31
|
def emit_receiver
|
31
|
-
|
32
|
+
visit(receiver)
|
32
33
|
write(T_DOT)
|
33
34
|
end
|
34
35
|
|
@@ -5,6 +5,7 @@ module Unparser
|
|
5
5
|
class Send
|
6
6
|
# Emitter for binary sends
|
7
7
|
class Binary < self
|
8
|
+
include Unterminated
|
8
9
|
|
9
10
|
private
|
10
11
|
|
@@ -15,7 +16,7 @@ module Unparser
|
|
15
16
|
# @api private
|
16
17
|
#
|
17
18
|
def dispatch
|
18
|
-
|
19
|
+
visit(receiver)
|
19
20
|
emit_operator
|
20
21
|
emit_right
|
21
22
|
end
|
@@ -47,7 +48,7 @@ module Unparser
|
|
47
48
|
# @api private
|
48
49
|
#
|
49
50
|
def emit_right
|
50
|
-
|
51
|
+
visit(right_node)
|
51
52
|
end
|
52
53
|
|
53
54
|
end # Binary
|
@@ -26,11 +26,12 @@ module Unparser
|
|
26
26
|
# @api private
|
27
27
|
#
|
28
28
|
def emit_receiver
|
29
|
-
|
29
|
+
visit(first_child)
|
30
30
|
end
|
31
31
|
|
32
32
|
# Emitter for index reference nodes
|
33
33
|
class Reference < self
|
34
|
+
include Terminated
|
34
35
|
|
35
36
|
private
|
36
37
|
|
@@ -42,13 +43,26 @@ module Unparser
|
|
42
43
|
#
|
43
44
|
def emit_operation
|
44
45
|
parentheses(*INDEX_PARENS) do
|
45
|
-
|
46
|
+
delimited_plain(arguments)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end # Reference
|
49
50
|
|
50
51
|
# Emitter for assign to index nodes
|
51
52
|
class Assign < self
|
53
|
+
include Unterminated
|
54
|
+
|
55
|
+
# Test if assign will be emitted terminated
|
56
|
+
#
|
57
|
+
# @return [Boolean]
|
58
|
+
#
|
59
|
+
# @api private
|
60
|
+
#
|
61
|
+
def terminated?
|
62
|
+
mlhs?
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
52
66
|
|
53
67
|
define_group(:indices, 2..-2)
|
54
68
|
define_child(:value, -1)
|
@@ -5,6 +5,7 @@ module Unparser
|
|
5
5
|
class Send
|
6
6
|
# Emitter for "regular" receiver.selector(arguments...) case
|
7
7
|
class Regular < self
|
8
|
+
include Terminated
|
8
9
|
|
9
10
|
private
|
10
11
|
|
@@ -28,7 +29,7 @@ module Unparser
|
|
28
29
|
#
|
29
30
|
def emit_receiver
|
30
31
|
return unless first_child
|
31
|
-
|
32
|
+
visit(receiver)
|
32
33
|
write(T_DOT)
|
33
34
|
end
|
34
35
|
|
@@ -5,6 +5,7 @@ module Unparser
|
|
5
5
|
class Send
|
6
6
|
# Emitter for unary sends
|
7
7
|
class Unary < self
|
8
|
+
include Unterminated
|
8
9
|
|
9
10
|
private
|
10
11
|
|
@@ -26,7 +27,7 @@ module Unparser
|
|
26
27
|
write('+')
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
+
visit(receiver)
|
30
31
|
end
|
31
32
|
|
32
33
|
end # Unary
|
@@ -5,6 +5,7 @@ module Unparser
|
|
5
5
|
|
6
6
|
# Emitter for various variable accesses
|
7
7
|
class Variable < self
|
8
|
+
include Terminated
|
8
9
|
|
9
10
|
handle :ivar, :lvar, :cvar, :gvar, :back_ref
|
10
11
|
|
@@ -26,6 +27,7 @@ module Unparser
|
|
26
27
|
|
27
28
|
# Emitter for constant access
|
28
29
|
class Const < self
|
30
|
+
include Terminated
|
29
31
|
|
30
32
|
handle :const
|
31
33
|
|
@@ -59,6 +61,8 @@ module Unparser
|
|
59
61
|
|
60
62
|
# Emitter for nth_ref nodes (regexp captures)
|
61
63
|
class NthRef < self
|
64
|
+
include Terminated
|
65
|
+
|
62
66
|
PREFIX = '$'.freeze
|
63
67
|
handle :nth_ref
|
64
68
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Unparser
|
4
4
|
# Preprocessor to normalize AST generated by parser
|
5
5
|
class Preprocessor
|
6
|
-
include Adamantium::Flat, NodeHelpers, AbstractType, Concord.new(:node), Procto.call(:result)
|
6
|
+
include Adamantium::Flat, NodeHelpers, AbstractType, Concord.new(:node, :parent_type), Procto.call(:result)
|
7
7
|
|
8
8
|
# Return preprocessor result
|
9
9
|
#
|
@@ -23,10 +23,10 @@ module Unparser
|
|
23
23
|
#
|
24
24
|
# @api private
|
25
25
|
#
|
26
|
-
def self.run(node)
|
26
|
+
def self.run(node, parent_type = nil)
|
27
27
|
return EMPTY if node.nil?
|
28
28
|
REGISTRY.fetch(node.type, [Noop]).reduce(node) do |current, processor|
|
29
|
-
processor.call(current)
|
29
|
+
processor.call(current, parent_type)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -49,14 +49,14 @@ module Unparser
|
|
49
49
|
|
50
50
|
# Visit node
|
51
51
|
#
|
52
|
-
# @param [Parser::AST::Node]
|
52
|
+
# @param [Parser::AST::Node] child
|
53
53
|
#
|
54
54
|
# @return [undefined]
|
55
55
|
#
|
56
56
|
# @api private
|
57
57
|
#
|
58
|
-
def visit(
|
59
|
-
self.class.run(node)
|
58
|
+
def visit(child)
|
59
|
+
self.class.run(child, node.type)
|
60
60
|
end
|
61
61
|
|
62
62
|
# Return children
|
@@ -77,7 +77,7 @@ module Unparser
|
|
77
77
|
#
|
78
78
|
def visited_children
|
79
79
|
children.map do |node|
|
80
|
-
if node.
|
80
|
+
if node.is_a?(Parser::AST::Node)
|
81
81
|
visit(node)
|
82
82
|
else
|
83
83
|
node
|
@@ -155,6 +155,12 @@ module Unparser
|
|
155
155
|
class CompactDSTR < self
|
156
156
|
|
157
157
|
register :dstr
|
158
|
+
register :dsym
|
159
|
+
|
160
|
+
MAP = IceNine.deep_freeze(
|
161
|
+
dstr: :str,
|
162
|
+
dsym: :sym
|
163
|
+
)
|
158
164
|
|
159
165
|
# Return preprocessor result
|
160
166
|
#
|
@@ -163,8 +169,8 @@ module Unparser
|
|
163
169
|
# @api private
|
164
170
|
#
|
165
171
|
def result
|
166
|
-
if children.all? { |child| child.type.equal?(:str) }
|
167
|
-
node.updated(
|
172
|
+
if children.any? && children.all? { |child| child.type.equal?(:str) }
|
173
|
+
node.updated(MAP.fetch(node.type), [children.map { |child| child.children.first }.join])
|
168
174
|
else
|
169
175
|
node
|
170
176
|
end
|
@@ -201,7 +207,8 @@ module Unparser
|
|
201
207
|
|
202
208
|
# Preprocessor for begin nodes. Removes begin nodes with one child.
|
203
209
|
#
|
204
|
-
#
|
210
|
+
# This reduces the amount of complex logic needed inside unparser to emit "nice" syntax with minimal
|
211
|
+
# tokens.
|
205
212
|
#
|
206
213
|
class Begin < self
|
207
214
|
|
@@ -214,10 +221,10 @@ module Unparser
|
|
214
221
|
# @api private
|
215
222
|
#
|
216
223
|
def result
|
217
|
-
if children.one?
|
224
|
+
if children.one? && !parent_type.equal?(:regexp)
|
218
225
|
visit(children.first)
|
219
226
|
else
|
220
|
-
Noop.call(node)
|
227
|
+
Noop.call(node, parent_type)
|
221
228
|
end
|
222
229
|
end
|
223
230
|
|