unparser 0.4.7 → 0.6.7
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/README.md +40 -9
- data/bin/unparser +2 -2
- data/lib/unparser/abstract_type.rb +121 -0
- data/lib/unparser/adamantium/method_builder.rb +111 -0
- data/lib/unparser/adamantium.rb +150 -0
- data/lib/unparser/anima/attribute.rb +59 -0
- data/lib/unparser/anima/error.rb +23 -0
- data/lib/unparser/anima.rb +184 -0
- data/lib/unparser/ast/local_variable_scope.rb +6 -76
- data/lib/unparser/ast.rb +1 -3
- data/lib/unparser/buffer.rb +14 -25
- data/lib/unparser/cli.rb +85 -77
- data/lib/unparser/{cli/color.rb → color.rb} +4 -14
- data/lib/unparser/comments.rb +0 -26
- data/lib/unparser/concord.rb +114 -0
- data/lib/unparser/constants.rb +4 -53
- data/lib/unparser/diff.rb +98 -0
- data/lib/unparser/dsl.rb +0 -32
- data/lib/unparser/either.rb +153 -0
- data/lib/unparser/emitter/alias.rb +2 -8
- data/lib/unparser/emitter/args.rb +45 -0
- data/lib/unparser/emitter/argument.rb +13 -169
- data/lib/unparser/emitter/array.rb +27 -0
- data/lib/unparser/emitter/array_pattern.rb +29 -0
- data/lib/unparser/emitter/assignment.rb +36 -127
- data/lib/unparser/emitter/begin.rb +9 -84
- data/lib/unparser/emitter/binary.rb +7 -20
- data/lib/unparser/emitter/block.rb +57 -41
- data/lib/unparser/emitter/case.rb +6 -48
- data/lib/unparser/emitter/case_guard.rb +27 -0
- data/lib/unparser/emitter/case_match.rb +40 -0
- data/lib/unparser/emitter/cbase.rb +1 -3
- data/lib/unparser/emitter/class.rb +6 -26
- data/lib/unparser/emitter/const_pattern.rb +24 -0
- data/lib/unparser/emitter/def.rb +7 -51
- data/lib/unparser/emitter/defined.rb +2 -12
- data/lib/unparser/emitter/dstr.rb +22 -0
- data/lib/unparser/emitter/dsym.rb +41 -0
- data/lib/unparser/emitter/find_pattern.rb +18 -0
- data/lib/unparser/emitter/flipflop.rb +11 -10
- data/lib/unparser/emitter/float.rb +29 -0
- data/lib/unparser/emitter/flow_modifier.rb +15 -53
- data/lib/unparser/emitter/for.rb +5 -19
- data/lib/unparser/emitter/hash.rb +36 -0
- data/lib/unparser/emitter/hash_pattern.rb +67 -0
- data/lib/unparser/emitter/hookexe.rb +5 -11
- data/lib/unparser/emitter/if.rb +15 -71
- data/lib/unparser/emitter/in_match.rb +21 -0
- data/lib/unparser/emitter/in_pattern.rb +36 -0
- data/lib/unparser/emitter/index.rb +22 -89
- data/lib/unparser/emitter/kwargs.rb +13 -0
- data/lib/unparser/emitter/kwbegin.rb +31 -0
- data/lib/unparser/emitter/lambda.rb +0 -8
- data/lib/unparser/emitter/masgn.rb +20 -0
- data/lib/unparser/emitter/match.rb +3 -17
- data/lib/unparser/emitter/match_alt.rb +23 -0
- data/lib/unparser/emitter/match_as.rb +21 -0
- data/lib/unparser/emitter/match_pattern.rb +30 -0
- data/lib/unparser/emitter/match_pattern_p.rb +20 -0
- data/lib/unparser/emitter/match_rest.rb +33 -0
- data/lib/unparser/emitter/match_var.rb +19 -0
- data/lib/unparser/emitter/mlhs.rb +40 -0
- data/lib/unparser/emitter/module.rb +3 -9
- data/lib/unparser/emitter/op_assign.rb +14 -29
- data/lib/unparser/emitter/pair.rb +33 -0
- data/lib/unparser/emitter/pin.rb +19 -0
- data/lib/unparser/emitter/primitive.rb +93 -0
- data/lib/unparser/emitter/range.rb +35 -0
- data/lib/unparser/emitter/regexp.rb +35 -0
- data/lib/unparser/emitter/repetition.rb +17 -57
- data/lib/unparser/emitter/rescue.rb +1 -97
- data/lib/unparser/emitter/root.rb +17 -1
- data/lib/unparser/emitter/send.rb +10 -219
- data/lib/unparser/emitter/simple.rb +33 -0
- data/lib/unparser/emitter/splat.rb +13 -19
- data/lib/unparser/emitter/super.rb +1 -29
- data/lib/unparser/emitter/undef.rb +1 -9
- data/lib/unparser/emitter/variable.rb +1 -31
- data/lib/unparser/emitter/xstr.rb +72 -0
- data/lib/unparser/emitter/yield.rb +1 -9
- data/lib/unparser/emitter.rb +24 -425
- data/lib/unparser/equalizer.rb +98 -0
- data/lib/unparser/generation.rb +252 -0
- data/lib/unparser/node_details/send.rb +65 -0
- data/lib/unparser/node_details.rb +21 -0
- data/lib/unparser/node_helpers.rb +48 -6
- data/lib/unparser/validation.rb +172 -0
- data/lib/unparser/writer/binary.rb +99 -0
- data/lib/unparser/writer/dynamic_string.rb +211 -0
- data/lib/unparser/writer/resbody.rb +40 -0
- data/lib/unparser/writer/rescue.rb +43 -0
- data/lib/unparser/{emitter → writer}/send/attribute_assignment.rb +11 -26
- data/lib/unparser/writer/send/binary.rb +27 -0
- data/lib/unparser/writer/send/conditional.rb +25 -0
- data/lib/unparser/writer/send/regular.rb +33 -0
- data/lib/unparser/{emitter → writer}/send/unary.rb +10 -17
- data/lib/unparser/writer/send.rb +115 -0
- data/lib/unparser/writer.rb +15 -0
- data/lib/unparser.rb +161 -77
- metadata +100 -157
- data/.circleci/config.yml +0 -49
- data/.gitignore +0 -37
- data/.rspec +0 -4
- data/.rubocop.yml +0 -9
- data/Changelog.md +0 -156
- data/Gemfile +0 -9
- data/Gemfile.lock +0 -181
- data/LICENSE +0 -20
- data/Rakefile +0 -22
- data/config/devtools.yml +0 -2
- data/config/flay.yml +0 -3
- data/config/flog.yml +0 -2
- data/config/mutant.yml +0 -6
- data/config/reek.yml +0 -98
- data/config/rubocop.yml +0 -122
- data/config/yardstick.yml +0 -2
- data/lib/unparser/cli/differ.rb +0 -152
- data/lib/unparser/cli/source.rb +0 -267
- data/lib/unparser/emitter/empty.rb +0 -23
- data/lib/unparser/emitter/ensure.rb +0 -37
- data/lib/unparser/emitter/literal/array.rb +0 -29
- data/lib/unparser/emitter/literal/dynamic.rb +0 -53
- data/lib/unparser/emitter/literal/dynamic_body.rb +0 -132
- data/lib/unparser/emitter/literal/execute_string.rb +0 -38
- data/lib/unparser/emitter/literal/hash.rb +0 -156
- data/lib/unparser/emitter/literal/primitive.rb +0 -145
- data/lib/unparser/emitter/literal/range.rb +0 -36
- data/lib/unparser/emitter/literal/regexp.rb +0 -114
- data/lib/unparser/emitter/literal/singleton.rb +0 -26
- data/lib/unparser/emitter/literal.rb +0 -10
- data/lib/unparser/emitter/meta.rb +0 -16
- data/lib/unparser/emitter/redo.rb +0 -25
- data/lib/unparser/emitter/resbody.rb +0 -76
- data/lib/unparser/emitter/retry.rb +0 -25
- data/lib/unparser/emitter/send/binary.rb +0 -57
- data/lib/unparser/emitter/send/conditional.rb +0 -40
- data/lib/unparser/emitter/send/regular.rb +0 -40
- data/lib/unparser/preprocessor.rb +0 -159
- data/spec/integration/unparser/corpus_spec.rb +0 -111
- data/spec/integrations.yml +0 -92
- data/spec/spec_helper.rb +0 -20
- data/spec/unit/unparser/buffer/append_spec.rb +0 -24
- data/spec/unit/unparser/buffer/append_without_prefix_spec.rb +0 -23
- data/spec/unit/unparser/buffer/capture_content_spec.rb +0 -17
- data/spec/unit/unparser/buffer/content_spec.rb +0 -38
- data/spec/unit/unparser/buffer/fresh_line_spec.rb +0 -20
- data/spec/unit/unparser/buffer/indent_spec.rb +0 -20
- data/spec/unit/unparser/buffer/nl_spec.rb +0 -16
- data/spec/unit/unparser/buffer/unindent_spec.rb +0 -20
- data/spec/unit/unparser/comments/consume_spec.rb +0 -22
- data/spec/unit/unparser/comments/take_all_spec.rb +0 -19
- data/spec/unit/unparser/comments/take_before_spec.rb +0 -46
- data/spec/unit/unparser/comments/take_eol_comments_spec.rb +0 -32
- data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +0 -17
- data/spec/unit/unparser_spec.rb +0 -1849
- data/unparser.gemspec +0 -32
|
@@ -4,109 +4,13 @@ module Unparser
|
|
|
4
4
|
class Emitter
|
|
5
5
|
# Emitter for rescue nodes
|
|
6
6
|
class Rescue < self
|
|
7
|
-
include Unterminated
|
|
8
|
-
|
|
9
7
|
handle :rescue
|
|
10
8
|
|
|
11
|
-
children :body, :rescue_body
|
|
12
|
-
|
|
13
|
-
define_group :rescue_bodies, 1..-2
|
|
14
|
-
|
|
15
|
-
EMBEDDED_TYPES = %i[block def defs kwbegin ensure].to_set.freeze
|
|
16
|
-
|
|
17
|
-
NOINDENT_STANDALONE_RESCUE = %i[root begin pair_rocket pair_colon lvasgn ivasgn].to_set.freeze
|
|
18
|
-
|
|
19
9
|
private
|
|
20
10
|
|
|
21
|
-
# Perform dispatch
|
|
22
|
-
#
|
|
23
|
-
# @return [undefined]
|
|
24
|
-
#
|
|
25
|
-
# @api private
|
|
26
|
-
#
|
|
27
11
|
def dispatch
|
|
28
|
-
|
|
29
|
-
if NOINDENT_STANDALONE_RESCUE.include?(parent_type)
|
|
30
|
-
emit_standalone
|
|
31
|
-
else
|
|
32
|
-
indented { emit_standalone }
|
|
33
|
-
end
|
|
34
|
-
else
|
|
35
|
-
emit_embedded
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Test if rescue node ist standalone
|
|
40
|
-
#
|
|
41
|
-
# @return [Boolean]
|
|
42
|
-
#
|
|
43
|
-
# @api private
|
|
44
|
-
#
|
|
45
|
-
def standalone?
|
|
46
|
-
if parent_type.equal?(:ensure)
|
|
47
|
-
!parent.node.children.first.equal?(node)
|
|
48
|
-
else
|
|
49
|
-
!EMBEDDED_TYPES.include?(parent_type)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Emit standalone form
|
|
54
|
-
#
|
|
55
|
-
# @return [undefined]
|
|
56
|
-
#
|
|
57
|
-
# @api private
|
|
58
|
-
#
|
|
59
|
-
def emit_standalone
|
|
60
|
-
visit_plain(body)
|
|
61
|
-
ws
|
|
62
|
-
run(Resbody::Standalone, rescue_body)
|
|
12
|
+
emit_rescue_postcontrol(node)
|
|
63
13
|
end
|
|
64
|
-
|
|
65
|
-
# Emit embedded form
|
|
66
|
-
#
|
|
67
|
-
# @return [undefined]
|
|
68
|
-
#
|
|
69
|
-
# @api private
|
|
70
|
-
#
|
|
71
|
-
def emit_embedded
|
|
72
|
-
if body
|
|
73
|
-
visit_indented(body)
|
|
74
|
-
else
|
|
75
|
-
nl
|
|
76
|
-
end
|
|
77
|
-
rescue_bodies.each do |child|
|
|
78
|
-
run(Resbody::Embedded, child)
|
|
79
|
-
end
|
|
80
|
-
emit_else
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Emit else
|
|
84
|
-
#
|
|
85
|
-
# @return [undefined]
|
|
86
|
-
#
|
|
87
|
-
# @api private
|
|
88
|
-
#
|
|
89
|
-
def emit_else
|
|
90
|
-
return unless else_branch
|
|
91
|
-
|
|
92
|
-
write(K_ELSE)
|
|
93
|
-
visit_indented(else_branch)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Return else body
|
|
97
|
-
#
|
|
98
|
-
# @return [Parser::AST::Node]
|
|
99
|
-
# if else body is present
|
|
100
|
-
#
|
|
101
|
-
# @return [nil]
|
|
102
|
-
# otherwise
|
|
103
|
-
#
|
|
104
|
-
# @api private
|
|
105
|
-
#
|
|
106
|
-
def else_branch
|
|
107
|
-
children.last
|
|
108
|
-
end
|
|
109
|
-
|
|
110
14
|
end # Rescue
|
|
111
15
|
end # Emitter
|
|
112
16
|
end # Unparser
|
|
@@ -4,8 +4,24 @@ module Unparser
|
|
|
4
4
|
class Emitter
|
|
5
5
|
# Root emitter a special case
|
|
6
6
|
class Root < self
|
|
7
|
-
include Concord::Public.new(:
|
|
7
|
+
include Concord::Public.new(:buffer, :node, :comments)
|
|
8
8
|
include LocalVariableRoot
|
|
9
|
+
|
|
10
|
+
END_NL = %i[class sclass module begin].freeze
|
|
11
|
+
|
|
12
|
+
private_constant(*constants(false))
|
|
13
|
+
|
|
14
|
+
def dispatch
|
|
15
|
+
if children.any?
|
|
16
|
+
emit_body(node, indent: false)
|
|
17
|
+
else
|
|
18
|
+
visit_deep(node)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
emit_eof_comments
|
|
22
|
+
|
|
23
|
+
nl if END_NL.include?(node.type) && !buffer.fresh_line?
|
|
24
|
+
end
|
|
9
25
|
end # Root
|
|
10
26
|
end # Emitter
|
|
11
27
|
end # Unparser
|
|
@@ -3,236 +3,27 @@
|
|
|
3
3
|
module Unparser
|
|
4
4
|
class Emitter
|
|
5
5
|
# Emitter for send
|
|
6
|
-
# ignore :reek:TooManyMethods
|
|
7
6
|
class Send < self
|
|
7
|
+
handle :csend, :send
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
INDEX_ASSIGN = :'[]='
|
|
13
|
-
INDEX_REFERENCE = :'[]'
|
|
14
|
-
NON_ASSIGN_RANGE = (0..-2).freeze
|
|
15
|
-
|
|
16
|
-
children :receiver, :selector
|
|
9
|
+
def emit_mlhs
|
|
10
|
+
writer.emit_mlhs
|
|
11
|
+
end
|
|
17
12
|
|
|
18
|
-
def
|
|
19
|
-
|
|
13
|
+
def emit_heredoc_reminders
|
|
14
|
+
writer.emit_heredoc_reminders
|
|
20
15
|
end
|
|
21
16
|
|
|
22
17
|
private
|
|
23
18
|
|
|
24
|
-
# Perform dispatch
|
|
25
|
-
#
|
|
26
|
-
# @return [undefined]
|
|
27
|
-
#
|
|
28
|
-
# @api private
|
|
29
|
-
#
|
|
30
19
|
def dispatch
|
|
31
|
-
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Return effective emitter
|
|
35
|
-
#
|
|
36
|
-
# @return [Emitter]
|
|
37
|
-
#
|
|
38
|
-
# @api private
|
|
39
|
-
#
|
|
40
|
-
def effective_emitter
|
|
41
|
-
effective_emitter_class.new(node, parent)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Return effective emitter
|
|
45
|
-
#
|
|
46
|
-
# @return [Class:Emitter]
|
|
47
|
-
#
|
|
48
|
-
# @api private
|
|
49
|
-
#
|
|
50
|
-
def effective_emitter_class
|
|
51
|
-
if binary_operator?
|
|
52
|
-
Binary
|
|
53
|
-
elsif unary_operator?
|
|
54
|
-
Unary
|
|
55
|
-
elsif attribute_assignment?
|
|
56
|
-
AttributeAssignment
|
|
57
|
-
else
|
|
58
|
-
Regular
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Return string selector
|
|
63
|
-
#
|
|
64
|
-
# @return [String]
|
|
65
|
-
#
|
|
66
|
-
# @api private
|
|
67
|
-
#
|
|
68
|
-
def string_selector
|
|
69
|
-
selector.to_s
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Test for unary operator implemented as method
|
|
73
|
-
#
|
|
74
|
-
# @return [Boolean]
|
|
75
|
-
#
|
|
76
|
-
# @api private
|
|
77
|
-
#
|
|
78
|
-
def unary_operator?
|
|
79
|
-
UNARY_OPERATORS.include?(selector)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Test for binary operator implemented as method
|
|
83
|
-
#
|
|
84
|
-
# @return [Boolean]
|
|
85
|
-
#
|
|
86
|
-
# @api private
|
|
87
|
-
#
|
|
88
|
-
def binary_operator?
|
|
89
|
-
BINARY_OPERATORS.include?(selector) && arguments.one? && !arguments.first.type.equal?(:splat)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Emit selector
|
|
93
|
-
#
|
|
94
|
-
# @return [undefined]
|
|
95
|
-
#
|
|
96
|
-
# @api private
|
|
97
|
-
#
|
|
98
|
-
def emit_selector
|
|
99
|
-
write(mlhs? ? non_assignment_selector : string_selector)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# Test for mlhs
|
|
103
|
-
#
|
|
104
|
-
# @return [Boolean]
|
|
105
|
-
#
|
|
106
|
-
# @api private
|
|
107
|
-
#
|
|
108
|
-
def mlhs?
|
|
109
|
-
parent_type.equal?(:mlhs)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
# Test for assignment
|
|
113
|
-
#
|
|
114
|
-
# FIXME: This also returns true for <= operator!
|
|
115
|
-
#
|
|
116
|
-
# @return [Boolean]
|
|
117
|
-
#
|
|
118
|
-
# @api private
|
|
119
|
-
#
|
|
120
|
-
def assignment?
|
|
121
|
-
string_selector[-1].eql?(ASSIGN_SUFFIX)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Test for attribute assignment
|
|
125
|
-
#
|
|
126
|
-
# @return [Boolean]
|
|
127
|
-
#
|
|
128
|
-
# @api private
|
|
129
|
-
#
|
|
130
|
-
def attribute_assignment?
|
|
131
|
-
!BINARY_OPERATORS.include?(selector) && !UNARY_OPERATORS.include?(selector) && assignment? && !mlhs?
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
# Test for empty arguments
|
|
135
|
-
#
|
|
136
|
-
# @return [Boolean]
|
|
137
|
-
#
|
|
138
|
-
# @api private
|
|
139
|
-
#
|
|
140
|
-
def arguments?
|
|
141
|
-
arguments.any?
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
# Return argument nodes
|
|
145
|
-
#
|
|
146
|
-
# @return [Array<Parser::AST::Node>]
|
|
147
|
-
#
|
|
148
|
-
# @api private
|
|
149
|
-
#
|
|
150
|
-
def arguments
|
|
151
|
-
children[2..-1]
|
|
152
|
-
end
|
|
153
|
-
memoize :arguments
|
|
154
|
-
|
|
155
|
-
# Emit arguments
|
|
156
|
-
#
|
|
157
|
-
# @return [undefined]
|
|
158
|
-
#
|
|
159
|
-
# @api private
|
|
160
|
-
#
|
|
161
|
-
def emit_arguments
|
|
162
|
-
if arguments.empty?
|
|
163
|
-
write('()') if receiver.nil? && avoid_clash?
|
|
164
|
-
else
|
|
165
|
-
normal_arguments
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
# Emit normal arguments
|
|
170
|
-
#
|
|
171
|
-
# @return [undefined]
|
|
172
|
-
#
|
|
173
|
-
# @api private
|
|
174
|
-
#
|
|
175
|
-
def normal_arguments
|
|
176
|
-
parentheses do
|
|
177
|
-
delimited_plain(effective_arguments)
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
# The effective arguments
|
|
182
|
-
#
|
|
183
|
-
# @return [Parser::AST::Node]
|
|
184
|
-
#
|
|
185
|
-
# @api private
|
|
186
|
-
#
|
|
187
|
-
def effective_arguments
|
|
188
|
-
last = arguments.length - 1
|
|
189
|
-
arguments.each_with_index.map do |argument, index|
|
|
190
|
-
if last.equal?(index) && argument.type.equal?(:hash) && argument.children.any?
|
|
191
|
-
argument.updated(:hash_body)
|
|
192
|
-
else
|
|
193
|
-
argument
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
# Test if clash with local variable or constant needs to be avoided
|
|
199
|
-
#
|
|
200
|
-
# @return [Boolean]
|
|
201
|
-
#
|
|
202
|
-
# @api private
|
|
203
|
-
#
|
|
204
|
-
def avoid_clash?
|
|
205
|
-
local_variable_clash? || parses_as_constant?
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
# Test for local variable clash
|
|
209
|
-
#
|
|
210
|
-
# @return [Boolean]
|
|
211
|
-
#
|
|
212
|
-
# @api private
|
|
213
|
-
#
|
|
214
|
-
def local_variable_clash?
|
|
215
|
-
local_variable_scope.local_variable_defined_for_node?(node, selector)
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# The non assignment selector
|
|
219
|
-
#
|
|
220
|
-
# @return [String]
|
|
221
|
-
#
|
|
222
|
-
# @api private
|
|
223
|
-
def non_assignment_selector
|
|
224
|
-
string_selector[NON_ASSIGN_RANGE]
|
|
20
|
+
writer.dispatch
|
|
225
21
|
end
|
|
226
22
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
# @return [Boolean]
|
|
230
|
-
#
|
|
231
|
-
# @api private
|
|
232
|
-
#
|
|
233
|
-
def parses_as_constant?
|
|
234
|
-
Unparser.parse(selector.to_s).type.equal?(:const)
|
|
23
|
+
def writer
|
|
24
|
+
writer_with(Writer::Send, node)
|
|
235
25
|
end
|
|
26
|
+
memoize :writer
|
|
236
27
|
end # Send
|
|
237
28
|
end # Emitter
|
|
238
29
|
end # Unparser
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unparser
|
|
4
|
+
class Emitter
|
|
5
|
+
# Emitter for simple nodes that generate a single token
|
|
6
|
+
class Simple < self
|
|
7
|
+
MAP = {
|
|
8
|
+
__ENCODING__: '__ENCODING__',
|
|
9
|
+
__FILE__: '__FILE__',
|
|
10
|
+
__LINE__: '__LINE__',
|
|
11
|
+
false: 'false',
|
|
12
|
+
forward_arg: '...',
|
|
13
|
+
forwarded_args: '...',
|
|
14
|
+
kwnilarg: '**nil',
|
|
15
|
+
match_nil_pattern: '**nil',
|
|
16
|
+
nil: 'nil',
|
|
17
|
+
redo: 'redo',
|
|
18
|
+
retry: 'retry',
|
|
19
|
+
self: 'self',
|
|
20
|
+
true: 'true',
|
|
21
|
+
zsuper: 'super'
|
|
22
|
+
}.freeze
|
|
23
|
+
|
|
24
|
+
handle(*MAP.keys)
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def dispatch
|
|
29
|
+
write(MAP.fetch(node_type))
|
|
30
|
+
end
|
|
31
|
+
end # Simple
|
|
32
|
+
end # Emitter
|
|
33
|
+
end # Unparser
|
|
@@ -4,46 +4,40 @@ module Unparser
|
|
|
4
4
|
class Emitter
|
|
5
5
|
# Emitter for splats
|
|
6
6
|
class KwSplat < self
|
|
7
|
-
include Terminated
|
|
8
|
-
|
|
9
7
|
handle :kwsplat
|
|
10
8
|
|
|
11
9
|
children :subject
|
|
12
10
|
|
|
13
11
|
private
|
|
14
12
|
|
|
15
|
-
# Perform dispatch
|
|
16
|
-
#
|
|
17
|
-
# @return [undefined]
|
|
18
|
-
#
|
|
19
|
-
# @api private
|
|
20
|
-
#
|
|
21
13
|
def dispatch
|
|
22
|
-
write(
|
|
14
|
+
write('**')
|
|
23
15
|
visit(subject)
|
|
24
16
|
end
|
|
25
17
|
end
|
|
26
18
|
|
|
27
19
|
# Emitter for splats
|
|
28
20
|
class Splat < self
|
|
29
|
-
include Terminated
|
|
30
|
-
|
|
31
21
|
handle :splat
|
|
32
22
|
|
|
33
23
|
children :subject
|
|
34
24
|
|
|
25
|
+
def emit_mlhs
|
|
26
|
+
write('*')
|
|
27
|
+
subject_emitter.emit_mlhs if subject
|
|
28
|
+
end
|
|
29
|
+
|
|
35
30
|
private
|
|
36
31
|
|
|
37
|
-
# Perform dispatch
|
|
38
|
-
#
|
|
39
|
-
# @return [undefined]
|
|
40
|
-
#
|
|
41
|
-
# @api private
|
|
42
|
-
#
|
|
43
32
|
def dispatch
|
|
44
|
-
write(
|
|
45
|
-
|
|
33
|
+
write('*')
|
|
34
|
+
subject_emitter.write_to_buffer
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def subject_emitter
|
|
38
|
+
emitter(subject)
|
|
46
39
|
end
|
|
40
|
+
memoize :subject_emitter
|
|
47
41
|
end
|
|
48
42
|
end
|
|
49
43
|
end # Unparser
|
|
@@ -3,42 +3,14 @@
|
|
|
3
3
|
module Unparser
|
|
4
4
|
class Emitter
|
|
5
5
|
|
|
6
|
-
# Emitter for zsuper nodes
|
|
7
|
-
class ZSuper < self
|
|
8
|
-
include Terminated
|
|
9
|
-
|
|
10
|
-
handle :zsuper
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
# Perform dispatch
|
|
15
|
-
#
|
|
16
|
-
# @return [undefined]
|
|
17
|
-
#
|
|
18
|
-
# @api private
|
|
19
|
-
#
|
|
20
|
-
def dispatch
|
|
21
|
-
write(K_SUPER)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
end # ZSuper
|
|
25
|
-
|
|
26
6
|
# Emitter for super nodes
|
|
27
7
|
class Super < self
|
|
28
|
-
include Terminated
|
|
29
|
-
|
|
30
8
|
handle :super
|
|
31
9
|
|
|
32
10
|
private
|
|
33
11
|
|
|
34
|
-
# Perform dispatch
|
|
35
|
-
#
|
|
36
|
-
# @return [undefined]
|
|
37
|
-
#
|
|
38
|
-
# @api private
|
|
39
|
-
#
|
|
40
12
|
def dispatch
|
|
41
|
-
write(
|
|
13
|
+
write('super')
|
|
42
14
|
parentheses do
|
|
43
15
|
delimited(children)
|
|
44
16
|
end
|
|
@@ -4,20 +4,12 @@ module Unparser
|
|
|
4
4
|
class Emitter
|
|
5
5
|
# Emitter for undef nodes
|
|
6
6
|
class Undef < self
|
|
7
|
-
include Unterminated
|
|
8
|
-
|
|
9
7
|
handle :undef
|
|
10
8
|
|
|
11
9
|
private
|
|
12
10
|
|
|
13
|
-
# Perform dispatch
|
|
14
|
-
#
|
|
15
|
-
# @return [undefined]
|
|
16
|
-
#
|
|
17
|
-
# @api private
|
|
18
|
-
#
|
|
19
11
|
def dispatch
|
|
20
|
-
write(
|
|
12
|
+
write('undef ')
|
|
21
13
|
delimited(children)
|
|
22
14
|
end
|
|
23
15
|
|
|
@@ -5,20 +5,12 @@ module Unparser
|
|
|
5
5
|
|
|
6
6
|
# Emitter for various variable accesses
|
|
7
7
|
class Variable < self
|
|
8
|
-
include Terminated
|
|
9
|
-
|
|
10
8
|
handle :ivar, :lvar, :cvar, :gvar, :back_ref
|
|
11
9
|
|
|
12
10
|
children :name
|
|
13
11
|
|
|
14
12
|
private
|
|
15
13
|
|
|
16
|
-
# Perform dispatch
|
|
17
|
-
#
|
|
18
|
-
# @return [undefined]
|
|
19
|
-
#
|
|
20
|
-
# @api private
|
|
21
|
-
#
|
|
22
14
|
def dispatch
|
|
23
15
|
write(name.to_s)
|
|
24
16
|
end
|
|
@@ -27,43 +19,27 @@ module Unparser
|
|
|
27
19
|
|
|
28
20
|
# Emitter for constant access
|
|
29
21
|
class Const < self
|
|
30
|
-
include Terminated
|
|
31
|
-
|
|
32
22
|
handle :const
|
|
33
23
|
|
|
34
24
|
children :scope, :name
|
|
35
25
|
|
|
36
26
|
private
|
|
37
27
|
|
|
38
|
-
# Perform dispatch
|
|
39
|
-
#
|
|
40
|
-
# @return [undefined]
|
|
41
|
-
#
|
|
42
|
-
# @api private
|
|
43
|
-
#
|
|
44
28
|
def dispatch
|
|
45
29
|
emit_scope
|
|
46
30
|
write(name.to_s)
|
|
47
31
|
end
|
|
48
32
|
|
|
49
|
-
# Emit parent
|
|
50
|
-
#
|
|
51
|
-
# @return [undefined]
|
|
52
|
-
#
|
|
53
|
-
# @api private
|
|
54
|
-
#
|
|
55
33
|
def emit_scope
|
|
56
34
|
return unless scope
|
|
57
35
|
|
|
58
36
|
visit(scope)
|
|
59
|
-
write(
|
|
37
|
+
write('::') unless n_cbase?(scope)
|
|
60
38
|
end
|
|
61
39
|
end
|
|
62
40
|
|
|
63
41
|
# Emitter for nth_ref nodes (regexp captures)
|
|
64
42
|
class NthRef < self
|
|
65
|
-
include Terminated
|
|
66
|
-
|
|
67
43
|
PREFIX = '$'.freeze
|
|
68
44
|
handle :nth_ref
|
|
69
45
|
|
|
@@ -71,12 +47,6 @@ module Unparser
|
|
|
71
47
|
|
|
72
48
|
private
|
|
73
49
|
|
|
74
|
-
# Perform dispatch
|
|
75
|
-
#
|
|
76
|
-
# @return [undefined]
|
|
77
|
-
#
|
|
78
|
-
# @api private
|
|
79
|
-
#
|
|
80
50
|
def dispatch
|
|
81
51
|
write(PREFIX)
|
|
82
52
|
write(name.to_s)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Unparser
|
|
4
|
+
class Emitter
|
|
5
|
+
# Dynamic execute string literal emitter
|
|
6
|
+
class XStr < self
|
|
7
|
+
|
|
8
|
+
handle :xstr
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def dispatch
|
|
13
|
+
if heredoc?
|
|
14
|
+
emit_heredoc
|
|
15
|
+
else
|
|
16
|
+
emit_xstr
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def heredoc?
|
|
21
|
+
children.any? { |node| node.eql?(s(:str, '')) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def emit_heredoc
|
|
25
|
+
write(%(<<~`HEREDOC`))
|
|
26
|
+
buffer.indent
|
|
27
|
+
nl
|
|
28
|
+
children.each do |child|
|
|
29
|
+
if n_str?(child)
|
|
30
|
+
write(child.children.first)
|
|
31
|
+
else
|
|
32
|
+
emit_begin(child)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
buffer.unindent
|
|
36
|
+
write("HEREDOC\n")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def emit_xstr
|
|
40
|
+
write('`')
|
|
41
|
+
children.each do |child|
|
|
42
|
+
if n_begin?(child)
|
|
43
|
+
emit_begin(child)
|
|
44
|
+
else
|
|
45
|
+
emit_string(child)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
write('`')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def emit_string(value)
|
|
52
|
+
write(escape_xstr(value.children.first))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def escape_xstr(input)
|
|
56
|
+
input.chars.map do |char|
|
|
57
|
+
if char.eql?('`')
|
|
58
|
+
'\\`'
|
|
59
|
+
else
|
|
60
|
+
char
|
|
61
|
+
end
|
|
62
|
+
end.join
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def emit_begin(component)
|
|
66
|
+
write('#{')
|
|
67
|
+
visit(unwrap_single_begin(component))
|
|
68
|
+
write('}')
|
|
69
|
+
end
|
|
70
|
+
end # XStr
|
|
71
|
+
end # Emitter
|
|
72
|
+
end # Unparser
|
|
@@ -5,20 +5,12 @@ module Unparser
|
|
|
5
5
|
|
|
6
6
|
# Emitter for yield node
|
|
7
7
|
class Yield < self
|
|
8
|
-
include Terminated
|
|
9
|
-
|
|
10
8
|
handle :yield
|
|
11
9
|
|
|
12
10
|
private
|
|
13
11
|
|
|
14
|
-
# Perform dispatch
|
|
15
|
-
#
|
|
16
|
-
# @return [undefined]
|
|
17
|
-
#
|
|
18
|
-
# @api private
|
|
19
|
-
#
|
|
20
12
|
def dispatch
|
|
21
|
-
write(
|
|
13
|
+
write('yield')
|
|
22
14
|
return if children.empty?
|
|
23
15
|
|
|
24
16
|
parentheses do
|