unparser 0.4.7 → 0.5.2
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 +1 -2
- data/bin/unparser +1 -1
- data/lib/unparser.rb +134 -62
- data/lib/unparser/ast.rb +0 -1
- data/lib/unparser/ast/local_variable_scope.rb +6 -76
- data/lib/unparser/buffer.rb +19 -16
- data/lib/unparser/cli.rb +84 -77
- data/lib/unparser/{cli/color.rb → color.rb} +0 -13
- data/lib/unparser/comments.rb +0 -26
- data/lib/unparser/constants.rb +4 -53
- data/lib/unparser/diff.rb +98 -0
- data/lib/unparser/dsl.rb +0 -32
- data/lib/unparser/emitter.rb +24 -425
- data/lib/unparser/emitter/alias.rb +2 -8
- data/lib/unparser/emitter/args.rb +45 -0
- data/lib/unparser/emitter/argument.rb +8 -166
- 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/flipflop.rb +11 -10
- data/lib/unparser/emitter/float.rb +29 -0
- data/lib/unparser/emitter/flow_modifier.rb +8 -55
- data/lib/unparser/emitter/for.rb +5 -19
- data/lib/unparser/emitter/hash.rb +74 -0
- data/lib/unparser/emitter/hash_pattern.rb +67 -0
- data/lib/unparser/emitter/hookexe.rb +5 -11
- data/lib/unparser/emitter/if.rb +9 -73
- data/lib/unparser/emitter/in_match.rb +21 -0
- data/lib/unparser/emitter/in_pattern.rb +34 -0
- data/lib/unparser/emitter/index.rb +21 -88
- 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_rest.rb +26 -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 +12 -27
- 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 +2 -18
- 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/generation.rb +250 -0
- data/lib/unparser/node_details.rb +21 -0
- data/lib/unparser/node_details/send.rb +62 -0
- data/lib/unparser/node_helpers.rb +45 -6
- data/lib/unparser/validation.rb +172 -0
- data/lib/unparser/writer.rb +15 -0
- data/lib/unparser/writer/binary.rb +99 -0
- data/lib/unparser/writer/dynamic_string.rb +233 -0
- data/lib/unparser/writer/resbody.rb +40 -0
- data/lib/unparser/writer/rescue.rb +39 -0
- data/lib/unparser/writer/send.rb +124 -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
- metadata +127 -104
- 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.rb +0 -10
- 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/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
data/lib/unparser/dsl.rb
CHANGED
|
@@ -6,14 +6,6 @@ module Unparser
|
|
|
6
6
|
|
|
7
7
|
private
|
|
8
8
|
|
|
9
|
-
# Define remaining children
|
|
10
|
-
#
|
|
11
|
-
# @param [Enumerable<Symbol>] names
|
|
12
|
-
#
|
|
13
|
-
# @return [undefined]
|
|
14
|
-
#
|
|
15
|
-
# @api private
|
|
16
|
-
#
|
|
17
9
|
def define_remaining_children(names)
|
|
18
10
|
range = names.length..-1
|
|
19
11
|
define_method(:remaining_children) do
|
|
@@ -22,15 +14,6 @@ module Unparser
|
|
|
22
14
|
private :remaining_children
|
|
23
15
|
end
|
|
24
16
|
|
|
25
|
-
# Define named child
|
|
26
|
-
#
|
|
27
|
-
# @param [Symbol] name
|
|
28
|
-
# @param [Fixnum] index
|
|
29
|
-
#
|
|
30
|
-
# @return [undefined]
|
|
31
|
-
#
|
|
32
|
-
# @api private
|
|
33
|
-
#
|
|
34
17
|
def define_child(name, index)
|
|
35
18
|
define_method(name) do
|
|
36
19
|
children.at(index)
|
|
@@ -38,15 +21,6 @@ module Unparser
|
|
|
38
21
|
private name
|
|
39
22
|
end
|
|
40
23
|
|
|
41
|
-
# Define a group of children
|
|
42
|
-
#
|
|
43
|
-
# @param [Symbol] name
|
|
44
|
-
# @param [Range] range
|
|
45
|
-
#
|
|
46
|
-
# @return [undefined]
|
|
47
|
-
#
|
|
48
|
-
# @api private
|
|
49
|
-
#
|
|
50
24
|
def define_group(name, range)
|
|
51
25
|
define_method(name) do
|
|
52
26
|
children[range]
|
|
@@ -55,12 +29,6 @@ module Unparser
|
|
|
55
29
|
memoize(name)
|
|
56
30
|
end
|
|
57
31
|
|
|
58
|
-
# Create name helpers
|
|
59
|
-
#
|
|
60
|
-
# @return [undefined]
|
|
61
|
-
#
|
|
62
|
-
# @api private
|
|
63
|
-
#
|
|
64
32
|
def children(*names)
|
|
65
33
|
define_remaining_children(names)
|
|
66
34
|
|
data/lib/unparser/emitter.rb
CHANGED
|
@@ -1,36 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Unparser
|
|
4
|
+
UnknownNodeError = Class.new(ArgumentError)
|
|
4
5
|
|
|
5
6
|
# Emitter base class
|
|
6
|
-
#
|
|
7
|
-
# buggy, argument values are sends to self
|
|
8
|
-
#
|
|
9
|
-
# ignore :reek:TooManyMethods
|
|
10
7
|
class Emitter
|
|
11
|
-
include Adamantium::Flat, AbstractType, Constants, NodeHelpers
|
|
12
|
-
include
|
|
13
|
-
extend DSL
|
|
8
|
+
include Adamantium::Flat, AbstractType, Constants, Generation, NodeHelpers
|
|
9
|
+
include Anima.new(:buffer, :comments, :node, :local_variable_scope)
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
REGISTRY = {} # rubocop:disable MutableConstant
|
|
11
|
+
public :node
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
extend DSL
|
|
19
14
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
false
|
|
23
|
-
end
|
|
24
|
-
end
|
|
15
|
+
# Registry for node emitters
|
|
16
|
+
REGISTRY = {} # rubocop:disable Style/MutableConstant
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
def terminated?
|
|
28
|
-
true
|
|
29
|
-
end
|
|
30
|
-
end
|
|
18
|
+
NO_INDENT = %i[ensure rescue].freeze
|
|
31
19
|
|
|
32
20
|
module LocalVariableRoot
|
|
33
|
-
|
|
34
21
|
# Return local variable root
|
|
35
22
|
#
|
|
36
23
|
# @return [Parser::AST::Node]
|
|
@@ -46,33 +33,8 @@ module Unparser
|
|
|
46
33
|
memoize :local_variable_scope
|
|
47
34
|
end
|
|
48
35
|
end
|
|
49
|
-
|
|
50
36
|
end # LocalVariableRoot
|
|
51
37
|
|
|
52
|
-
# Return local variable root
|
|
53
|
-
#
|
|
54
|
-
# @return [Parser::AST::Node]
|
|
55
|
-
#
|
|
56
|
-
# @api private
|
|
57
|
-
#
|
|
58
|
-
def local_variable_scope
|
|
59
|
-
parent.local_variable_scope
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Return assigned lvars
|
|
63
|
-
#
|
|
64
|
-
# @return [Array<Symbol>]
|
|
65
|
-
#
|
|
66
|
-
# @api private
|
|
67
|
-
#
|
|
68
|
-
abstract_method :local_variables
|
|
69
|
-
|
|
70
|
-
# Return node type
|
|
71
|
-
#
|
|
72
|
-
# @return [Symbol]
|
|
73
|
-
#
|
|
74
|
-
# @api private
|
|
75
|
-
#
|
|
76
38
|
def node_type
|
|
77
39
|
node.type
|
|
78
40
|
end
|
|
@@ -87,25 +49,16 @@ module Unparser
|
|
|
87
49
|
#
|
|
88
50
|
def self.handle(*types)
|
|
89
51
|
types.each do |type|
|
|
52
|
+
fail "Handler for type: #{type} already registered" if REGISTRY.key?(type)
|
|
53
|
+
|
|
90
54
|
REGISTRY[type] = self
|
|
91
55
|
end
|
|
92
56
|
end
|
|
93
57
|
private_class_method :handle
|
|
94
58
|
|
|
95
|
-
|
|
96
|
-
#
|
|
97
|
-
# @return [self]
|
|
98
|
-
#
|
|
99
|
-
# @api private
|
|
100
|
-
#
|
|
101
|
-
def write_to_buffer
|
|
102
|
-
emit_comments_before if buffer.fresh_line?
|
|
59
|
+
def emit_mlhs
|
|
103
60
|
dispatch
|
|
104
|
-
comments.consume(node)
|
|
105
|
-
emit_eof_comments if parent.is_a?(Root)
|
|
106
|
-
self
|
|
107
61
|
end
|
|
108
|
-
memoize :write_to_buffer
|
|
109
62
|
|
|
110
63
|
# Return emitter
|
|
111
64
|
#
|
|
@@ -113,384 +66,30 @@ module Unparser
|
|
|
113
66
|
#
|
|
114
67
|
# @api private
|
|
115
68
|
#
|
|
116
|
-
|
|
69
|
+
# rubocop:disable Metrics/ParameterLists
|
|
70
|
+
def self.emitter(buffer:, comments:, node:, local_variable_scope:)
|
|
117
71
|
type = node.type
|
|
118
|
-
klass = REGISTRY.fetch(type) do
|
|
119
|
-
raise ArgumentError, "No emitter for node: #{type.inspect}"
|
|
120
|
-
end
|
|
121
|
-
klass.new(node, parent)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Dispatch node
|
|
125
|
-
#
|
|
126
|
-
# @return [undefined]
|
|
127
|
-
#
|
|
128
|
-
# @api private
|
|
129
|
-
#
|
|
130
|
-
abstract_method :dispatch
|
|
131
|
-
|
|
132
|
-
# Test if node is emitted as terminated expression
|
|
133
|
-
#
|
|
134
|
-
# @return [Boolean]
|
|
135
|
-
#
|
|
136
|
-
# @api private
|
|
137
|
-
#
|
|
138
|
-
abstract_method :terminated?
|
|
139
72
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
# Return buffer
|
|
143
|
-
#
|
|
144
|
-
# @return [Buffer] buffer
|
|
145
|
-
#
|
|
146
|
-
# @api private
|
|
147
|
-
#
|
|
148
|
-
def buffer
|
|
149
|
-
parent.buffer
|
|
150
|
-
end
|
|
151
|
-
memoize :buffer, freezer: :noop
|
|
152
|
-
|
|
153
|
-
# Return comments
|
|
154
|
-
#
|
|
155
|
-
# @return [Comments] comments
|
|
156
|
-
#
|
|
157
|
-
# @api private
|
|
158
|
-
#
|
|
159
|
-
def comments
|
|
160
|
-
parent.comments
|
|
161
|
-
end
|
|
162
|
-
memoize :comments, freezer: :noop
|
|
163
|
-
|
|
164
|
-
private
|
|
165
|
-
|
|
166
|
-
# Emit contents of block within parentheses
|
|
167
|
-
#
|
|
168
|
-
# @return [undefined]
|
|
169
|
-
#
|
|
170
|
-
# @api private
|
|
171
|
-
#
|
|
172
|
-
def parentheses(open = M_PO, close = M_PC)
|
|
173
|
-
write(open)
|
|
174
|
-
yield
|
|
175
|
-
write(close)
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
# Visit node
|
|
179
|
-
#
|
|
180
|
-
# @param [Parser::AST::Node] node
|
|
181
|
-
#
|
|
182
|
-
# @return [undefined]
|
|
183
|
-
#
|
|
184
|
-
# @api private
|
|
185
|
-
#
|
|
186
|
-
def visit_plain(node)
|
|
187
|
-
emitter = emitter(node)
|
|
188
|
-
emitter.write_to_buffer
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
# Visit ambiguous node
|
|
192
|
-
#
|
|
193
|
-
# @param [Parser::AST::Node] node
|
|
194
|
-
#
|
|
195
|
-
# @return [undefined]
|
|
196
|
-
#
|
|
197
|
-
# @api private
|
|
198
|
-
#
|
|
199
|
-
def visit(node)
|
|
200
|
-
emitter = emitter(node)
|
|
201
|
-
conditional_parentheses(!emitter.terminated?) do
|
|
202
|
-
emitter.write_to_buffer
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
# Visit within parentheses
|
|
207
|
-
#
|
|
208
|
-
# @param [Parser::AST::Node] node
|
|
209
|
-
#
|
|
210
|
-
# @return [undefined]
|
|
211
|
-
#
|
|
212
|
-
# @api private
|
|
213
|
-
#
|
|
214
|
-
def visit_parentheses(node, *arguments)
|
|
215
|
-
parentheses(*arguments) do
|
|
216
|
-
visit_plain(node)
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
# Call block in optional parentheses
|
|
221
|
-
#
|
|
222
|
-
# @param [true, false] flag
|
|
223
|
-
#
|
|
224
|
-
# @return [undefined]
|
|
225
|
-
#
|
|
226
|
-
# @api private
|
|
227
|
-
#
|
|
228
|
-
# ignore :reek:ControlParameter
|
|
229
|
-
def conditional_parentheses(flag)
|
|
230
|
-
if flag
|
|
231
|
-
parentheses { yield }
|
|
232
|
-
else
|
|
233
|
-
yield
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# Return emitter for node
|
|
238
|
-
#
|
|
239
|
-
# @param [Parser::AST::Node] node
|
|
240
|
-
#
|
|
241
|
-
# @return [Emitter]
|
|
242
|
-
#
|
|
243
|
-
# @api private
|
|
244
|
-
#
|
|
245
|
-
def emitter(node)
|
|
246
|
-
self.class.emitter(node, self)
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
# Emit delimited body
|
|
250
|
-
#
|
|
251
|
-
# @param [Enumerable<Parser::AST::Node>] nodes
|
|
252
|
-
#
|
|
253
|
-
# @return [undefined]
|
|
254
|
-
#
|
|
255
|
-
# @api private
|
|
256
|
-
#
|
|
257
|
-
def delimited_plain(nodes)
|
|
258
|
-
delimited(nodes, &method(:visit_plain))
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
# Emit delimited body
|
|
262
|
-
#
|
|
263
|
-
# @param [Enumerable<Parser::AST::Node>] nodes
|
|
264
|
-
#
|
|
265
|
-
# @return [undefined]
|
|
266
|
-
#
|
|
267
|
-
# @api private
|
|
268
|
-
#
|
|
269
|
-
def delimited(nodes, &block)
|
|
270
|
-
return if nodes.empty?
|
|
271
|
-
|
|
272
|
-
block ||= method(:visit)
|
|
273
|
-
head, *tail = nodes
|
|
274
|
-
block.call(head)
|
|
275
|
-
tail.each do |node|
|
|
276
|
-
write(DEFAULT_DELIMITER)
|
|
277
|
-
block.call(node)
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
# Return children of node
|
|
282
|
-
#
|
|
283
|
-
# @return [Array<Parser::AST::Node>]
|
|
284
|
-
#
|
|
285
|
-
# @api private
|
|
286
|
-
#
|
|
287
|
-
def children
|
|
288
|
-
node.children
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
# Write newline
|
|
292
|
-
#
|
|
293
|
-
# @return [undefined]
|
|
294
|
-
#
|
|
295
|
-
# @api private
|
|
296
|
-
#
|
|
297
|
-
def nl
|
|
298
|
-
emit_eol_comments
|
|
299
|
-
buffer.nl
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
# Write comments that appeared before source_part in the source
|
|
303
|
-
#
|
|
304
|
-
# @param [Symbol] source_part
|
|
305
|
-
#
|
|
306
|
-
# @return [undefined]
|
|
307
|
-
#
|
|
308
|
-
# @api private
|
|
309
|
-
#
|
|
310
|
-
def emit_comments_before(source_part = :expression)
|
|
311
|
-
comments_before = comments.take_before(node, source_part)
|
|
312
|
-
return if comments_before.empty?
|
|
313
|
-
|
|
314
|
-
emit_comments(comments_before)
|
|
315
|
-
buffer.nl
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# Write end-of-line comments
|
|
319
|
-
#
|
|
320
|
-
# @return [undefined]
|
|
321
|
-
#
|
|
322
|
-
# @api private
|
|
323
|
-
#
|
|
324
|
-
def emit_eol_comments
|
|
325
|
-
comments.take_eol_comments.each do |comment|
|
|
326
|
-
write(WS, comment.text)
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
# Write end-of-file comments
|
|
331
|
-
#
|
|
332
|
-
# @return [undefined]
|
|
333
|
-
#
|
|
334
|
-
# @api private
|
|
335
|
-
#
|
|
336
|
-
def emit_eof_comments
|
|
337
|
-
emit_eol_comments
|
|
338
|
-
comments_left = comments.take_all
|
|
339
|
-
return if comments_left.empty?
|
|
340
|
-
|
|
341
|
-
buffer.nl
|
|
342
|
-
emit_comments(comments_left)
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
# Write each comment to a separate line
|
|
346
|
-
#
|
|
347
|
-
# @param [Array] comments
|
|
348
|
-
#
|
|
349
|
-
# @return [undefined]
|
|
350
|
-
#
|
|
351
|
-
# @api private
|
|
352
|
-
#
|
|
353
|
-
def emit_comments(comments)
|
|
354
|
-
max = comments.size - 1
|
|
355
|
-
comments.each_with_index do |comment, index|
|
|
356
|
-
if comment.type.equal?(:document)
|
|
357
|
-
buffer.append_without_prefix(comment.text.chomp)
|
|
358
|
-
else
|
|
359
|
-
write(comment.text)
|
|
360
|
-
end
|
|
361
|
-
buffer.nl if index < max
|
|
362
|
-
end
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
# Write strings into buffer
|
|
366
|
-
#
|
|
367
|
-
# @return [undefined]
|
|
368
|
-
#
|
|
369
|
-
# @api private
|
|
370
|
-
#
|
|
371
|
-
def write(*strings)
|
|
372
|
-
strings.each do |string|
|
|
373
|
-
buffer.append(string)
|
|
374
|
-
end
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
# Write end keyword
|
|
378
|
-
#
|
|
379
|
-
# @return [undefined]
|
|
380
|
-
#
|
|
381
|
-
# @api private
|
|
382
|
-
#
|
|
383
|
-
def k_end
|
|
384
|
-
buffer.indent
|
|
385
|
-
emit_comments_before(:end)
|
|
386
|
-
buffer.unindent
|
|
387
|
-
write(K_END)
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
# Return first child
|
|
391
|
-
#
|
|
392
|
-
# @return [Parser::AST::Node]
|
|
393
|
-
# if present
|
|
394
|
-
#
|
|
395
|
-
# @return [nil]
|
|
396
|
-
# otherwise
|
|
397
|
-
#
|
|
398
|
-
# @api private
|
|
399
|
-
#
|
|
400
|
-
def first_child
|
|
401
|
-
children.first
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
# Write whitespace
|
|
405
|
-
#
|
|
406
|
-
# @return [undefined]
|
|
407
|
-
#
|
|
408
|
-
# @api private
|
|
409
|
-
#
|
|
410
|
-
def ws
|
|
411
|
-
write(WS)
|
|
412
|
-
end
|
|
413
|
-
|
|
414
|
-
# Call emit contents of block indented
|
|
415
|
-
#
|
|
416
|
-
# @return [undefined]
|
|
417
|
-
#
|
|
418
|
-
# @api private
|
|
419
|
-
#
|
|
420
|
-
# False positive:
|
|
421
|
-
#
|
|
422
|
-
def indented
|
|
423
|
-
buffer = buffer()
|
|
424
|
-
buffer.indent
|
|
425
|
-
nl
|
|
426
|
-
yield
|
|
427
|
-
nl
|
|
428
|
-
buffer.unindent
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
# Emit non nil body
|
|
432
|
-
#
|
|
433
|
-
# @param [Parser::AST::Node] body
|
|
434
|
-
#
|
|
435
|
-
# @return [undefined]
|
|
436
|
-
#
|
|
437
|
-
# @api private
|
|
438
|
-
#
|
|
439
|
-
# rubocop:disable MethodCallWithoutArgsParentheses
|
|
440
|
-
def emit_body(body = body())
|
|
441
|
-
unless body
|
|
442
|
-
buffer.indent
|
|
443
|
-
nl
|
|
444
|
-
buffer.unindent
|
|
445
|
-
return
|
|
446
|
-
end
|
|
447
|
-
visit_indented(body)
|
|
448
|
-
end
|
|
449
|
-
# rubocop:enable MethodCallWithoutArgsParentheses
|
|
450
|
-
|
|
451
|
-
# Visit indented node
|
|
452
|
-
#
|
|
453
|
-
# @param [Parser::AST::Node] node
|
|
454
|
-
#
|
|
455
|
-
# @return [undefined]
|
|
456
|
-
#
|
|
457
|
-
# @api private
|
|
458
|
-
#
|
|
459
|
-
def visit_indented(node)
|
|
460
|
-
if NOINDENT.include?(node.type)
|
|
461
|
-
visit_plain(node)
|
|
462
|
-
else
|
|
463
|
-
indented { visit_plain(node) }
|
|
73
|
+
klass = REGISTRY.fetch(type) do
|
|
74
|
+
fail UnknownNodeError, "Unknown node type: #{type.inspect}"
|
|
464
75
|
end
|
|
465
|
-
end
|
|
466
76
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
# otherwise
|
|
474
|
-
#
|
|
475
|
-
# @api private
|
|
476
|
-
#
|
|
477
|
-
def parent_type
|
|
478
|
-
parent.node_type
|
|
77
|
+
klass.new(
|
|
78
|
+
buffer: buffer,
|
|
79
|
+
comments: comments,
|
|
80
|
+
local_variable_scope: local_variable_scope,
|
|
81
|
+
node: node
|
|
82
|
+
)
|
|
479
83
|
end
|
|
84
|
+
# rubocop:enable Metrics/ParameterLists
|
|
480
85
|
|
|
481
|
-
#
|
|
482
|
-
#
|
|
483
|
-
# @param [Class:Emitter] emitter
|
|
86
|
+
# Dispatch node write as statement
|
|
484
87
|
#
|
|
485
88
|
# @return [undefined]
|
|
486
89
|
#
|
|
487
90
|
# @api private
|
|
488
91
|
#
|
|
489
|
-
|
|
490
|
-
def run(emitter, node = node())
|
|
491
|
-
emitter.new(node, self).write_to_buffer
|
|
492
|
-
end
|
|
493
|
-
# rubocop:enable MethodCallWithoutArgsParentheses
|
|
92
|
+
abstract_method :dispatch
|
|
494
93
|
|
|
495
94
|
end # Emitter
|
|
496
95
|
end # Unparser
|