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
data/lib/unparser/cli/source.rb
DELETED
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unparser
|
|
4
|
-
class CLI
|
|
5
|
-
# Source representation for CLI sources
|
|
6
|
-
#
|
|
7
|
-
# ignore :reek:TooManyMethods
|
|
8
|
-
class Source
|
|
9
|
-
include AbstractType, Adamantium::Flat, NodeHelpers
|
|
10
|
-
|
|
11
|
-
# Source state generated after first unparse
|
|
12
|
-
class Generated
|
|
13
|
-
include Concord::Public.new(:source, :ast, :error)
|
|
14
|
-
|
|
15
|
-
# Test if source was generated successfully
|
|
16
|
-
#
|
|
17
|
-
# @return [Boolean]
|
|
18
|
-
#
|
|
19
|
-
# @api private
|
|
20
|
-
#
|
|
21
|
-
def success?
|
|
22
|
-
!error
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Build generated source
|
|
26
|
-
#
|
|
27
|
-
# @param [Parser::AST::Node] ast
|
|
28
|
-
#
|
|
29
|
-
# @api private
|
|
30
|
-
#
|
|
31
|
-
def self.build(ast)
|
|
32
|
-
source = Unparser.unparse(ast)
|
|
33
|
-
new(source, ast, nil)
|
|
34
|
-
rescue StandardError => exception
|
|
35
|
-
new(nil, ast, exception)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Test if source could be unparsed successfully
|
|
40
|
-
#
|
|
41
|
-
# @return [Boolean]
|
|
42
|
-
#
|
|
43
|
-
# @api private
|
|
44
|
-
#
|
|
45
|
-
def success?
|
|
46
|
-
generated.success? && original_ast && generated_ast && original_ast.eql?(generated_ast)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Return error report
|
|
50
|
-
#
|
|
51
|
-
# @return [String]
|
|
52
|
-
#
|
|
53
|
-
# @api private
|
|
54
|
-
#
|
|
55
|
-
def report
|
|
56
|
-
if original_ast && generated_ast
|
|
57
|
-
report_with_ast_diff
|
|
58
|
-
elsif !original_ast
|
|
59
|
-
report_original
|
|
60
|
-
elsif !generated.success?
|
|
61
|
-
report_unparser
|
|
62
|
-
elsif !generated_ast
|
|
63
|
-
report_generated
|
|
64
|
-
else
|
|
65
|
-
raise
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
memoize :report
|
|
69
|
-
|
|
70
|
-
private
|
|
71
|
-
|
|
72
|
-
# Return generated source
|
|
73
|
-
#
|
|
74
|
-
# @return [String]
|
|
75
|
-
#
|
|
76
|
-
# @api private
|
|
77
|
-
#
|
|
78
|
-
def generated
|
|
79
|
-
Source::Generated.build(original_ast)
|
|
80
|
-
end
|
|
81
|
-
memoize :generated
|
|
82
|
-
|
|
83
|
-
# Return stripped source
|
|
84
|
-
#
|
|
85
|
-
# @param [String] source
|
|
86
|
-
#
|
|
87
|
-
# @return [String]
|
|
88
|
-
#
|
|
89
|
-
# @api private
|
|
90
|
-
#
|
|
91
|
-
# ignore :reek:UtilityFunction
|
|
92
|
-
def strip(source)
|
|
93
|
-
source = source.rstrip
|
|
94
|
-
indent = source.scan(/^\s*/).first
|
|
95
|
-
source.gsub(/^#{indent}/, '')
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# Return error report for parsing original
|
|
99
|
-
#
|
|
100
|
-
# @return [String]
|
|
101
|
-
#
|
|
102
|
-
# @api private
|
|
103
|
-
#
|
|
104
|
-
def report_original
|
|
105
|
-
strip(<<-MESSAGE)
|
|
106
|
-
Parsing of original source failed:
|
|
107
|
-
#{original_source}
|
|
108
|
-
MESSAGE
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# Report unparser bug
|
|
112
|
-
#
|
|
113
|
-
# @return [String]
|
|
114
|
-
#
|
|
115
|
-
# @api private
|
|
116
|
-
#
|
|
117
|
-
def report_unparser
|
|
118
|
-
message = ['Unparsing parsed AST failed']
|
|
119
|
-
error = generated.error
|
|
120
|
-
message << error
|
|
121
|
-
error.backtrace.take(20).each(&message.method(:<<))
|
|
122
|
-
message << 'Original-AST:'
|
|
123
|
-
message << original_ast.inspect
|
|
124
|
-
message.join("\n")
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
# Return error report for parsing generated
|
|
128
|
-
#
|
|
129
|
-
# @return [String]
|
|
130
|
-
#
|
|
131
|
-
# @api private
|
|
132
|
-
#
|
|
133
|
-
def report_generated
|
|
134
|
-
strip(<<-MESSAGE)
|
|
135
|
-
Parsing of generated source failed:
|
|
136
|
-
Original-source:
|
|
137
|
-
#{original_source}
|
|
138
|
-
Original-AST:
|
|
139
|
-
#{original_ast.inspect}
|
|
140
|
-
Source:
|
|
141
|
-
#{generated.source}
|
|
142
|
-
MESSAGE
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# Return error report with AST difference
|
|
146
|
-
#
|
|
147
|
-
# @return [String]
|
|
148
|
-
#
|
|
149
|
-
# @api private
|
|
150
|
-
#
|
|
151
|
-
def report_with_ast_diff
|
|
152
|
-
strip(<<-MESSAGE)
|
|
153
|
-
#{ast_diff}
|
|
154
|
-
Original-Source:\n#{original_source}
|
|
155
|
-
Original-AST:\n#{original_ast.inspect}
|
|
156
|
-
Generated-Source:\n#{generated.source}
|
|
157
|
-
Generated-AST:\n#{generated_ast.inspect}
|
|
158
|
-
MESSAGE
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Return ast diff
|
|
162
|
-
#
|
|
163
|
-
# @return [String]
|
|
164
|
-
#
|
|
165
|
-
# @api private
|
|
166
|
-
#
|
|
167
|
-
def ast_diff
|
|
168
|
-
Differ.call(
|
|
169
|
-
original_ast.inspect.lines.map(&:chomp),
|
|
170
|
-
generated_ast.inspect.lines.map(&:chomp)
|
|
171
|
-
)
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
# Return generated AST
|
|
175
|
-
#
|
|
176
|
-
# @return [Parser::AST::Node]
|
|
177
|
-
# if parser was sucessful for generated ast
|
|
178
|
-
#
|
|
179
|
-
# @return [nil]
|
|
180
|
-
# otherwise
|
|
181
|
-
#
|
|
182
|
-
# @api private
|
|
183
|
-
#
|
|
184
|
-
def generated_ast
|
|
185
|
-
generated.success? && Preprocessor.run(Unparser.parse(generated.source))
|
|
186
|
-
rescue Parser::SyntaxError
|
|
187
|
-
nil
|
|
188
|
-
end
|
|
189
|
-
memoize :generated_ast
|
|
190
|
-
|
|
191
|
-
# Return original AST
|
|
192
|
-
#
|
|
193
|
-
# @return [Parser::AST::Node]
|
|
194
|
-
#
|
|
195
|
-
# @api private
|
|
196
|
-
#
|
|
197
|
-
def original_ast
|
|
198
|
-
Preprocessor.run(Unparser.parse(original_source))
|
|
199
|
-
rescue Parser::SyntaxError
|
|
200
|
-
nil
|
|
201
|
-
end
|
|
202
|
-
memoize :original_ast
|
|
203
|
-
|
|
204
|
-
# CLI source from string
|
|
205
|
-
class String < self
|
|
206
|
-
include Concord.new(:original_source)
|
|
207
|
-
|
|
208
|
-
# Return identification
|
|
209
|
-
#
|
|
210
|
-
# @return [String]
|
|
211
|
-
#
|
|
212
|
-
# @api private
|
|
213
|
-
#
|
|
214
|
-
def identification
|
|
215
|
-
'(string)'
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
end # String
|
|
219
|
-
|
|
220
|
-
# CLI source from file
|
|
221
|
-
class File < self
|
|
222
|
-
include Concord.new(:file_name)
|
|
223
|
-
|
|
224
|
-
# Return identification
|
|
225
|
-
#
|
|
226
|
-
# @return [String]
|
|
227
|
-
#
|
|
228
|
-
# @api private
|
|
229
|
-
#
|
|
230
|
-
def identification
|
|
231
|
-
"(#{file_name})"
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
private
|
|
235
|
-
|
|
236
|
-
# Return original source
|
|
237
|
-
#
|
|
238
|
-
# @return [String]
|
|
239
|
-
#
|
|
240
|
-
# @api private
|
|
241
|
-
#
|
|
242
|
-
def original_source
|
|
243
|
-
::File.read(file_name)
|
|
244
|
-
end
|
|
245
|
-
memoize :original_source
|
|
246
|
-
|
|
247
|
-
end # File
|
|
248
|
-
|
|
249
|
-
# Source passed in as node
|
|
250
|
-
class Node < self
|
|
251
|
-
include Concord.new(:original_ast)
|
|
252
|
-
|
|
253
|
-
# Return original source
|
|
254
|
-
#
|
|
255
|
-
# @return [String]
|
|
256
|
-
#
|
|
257
|
-
# @api private
|
|
258
|
-
#
|
|
259
|
-
def original_source
|
|
260
|
-
Unparser.unparse(original_ast)
|
|
261
|
-
end
|
|
262
|
-
memoize :original_source
|
|
263
|
-
end # Node
|
|
264
|
-
|
|
265
|
-
end # Source
|
|
266
|
-
end # CLI
|
|
267
|
-
end # Unparser
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unparser
|
|
4
|
-
class Emitter
|
|
5
|
-
|
|
6
|
-
# Emitter for artifical empty node
|
|
7
|
-
class Empty < self
|
|
8
|
-
|
|
9
|
-
handle :empty
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
# Perform dispatch
|
|
14
|
-
#
|
|
15
|
-
# @return [undefined]
|
|
16
|
-
#
|
|
17
|
-
# @api private
|
|
18
|
-
#
|
|
19
|
-
def dispatch; end
|
|
20
|
-
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end # Unparser
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unparser
|
|
4
|
-
class Emitter
|
|
5
|
-
|
|
6
|
-
# Emitter for ensure nodes
|
|
7
|
-
class Ensure < self
|
|
8
|
-
|
|
9
|
-
handle :ensure
|
|
10
|
-
|
|
11
|
-
children :body, :ensure_body
|
|
12
|
-
|
|
13
|
-
private
|
|
14
|
-
|
|
15
|
-
# Perform dispatch
|
|
16
|
-
#
|
|
17
|
-
# @return [undefined]
|
|
18
|
-
#
|
|
19
|
-
# @api private
|
|
20
|
-
#
|
|
21
|
-
def dispatch
|
|
22
|
-
if body
|
|
23
|
-
visit_indented(body)
|
|
24
|
-
else
|
|
25
|
-
nl
|
|
26
|
-
end
|
|
27
|
-
write(K_ENSURE)
|
|
28
|
-
if ensure_body
|
|
29
|
-
visit_indented(ensure_body)
|
|
30
|
-
else
|
|
31
|
-
nl
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
end # Ensure
|
|
36
|
-
end # Emitter
|
|
37
|
-
end # Unparser
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unparser
|
|
4
|
-
class Emitter
|
|
5
|
-
class Literal
|
|
6
|
-
|
|
7
|
-
# Array literal emitter
|
|
8
|
-
class Array < self
|
|
9
|
-
handle :array
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
# Perform dispatch
|
|
14
|
-
#
|
|
15
|
-
# @return [undefined]
|
|
16
|
-
#
|
|
17
|
-
# @api private
|
|
18
|
-
#
|
|
19
|
-
def dispatch
|
|
20
|
-
parentheses(*BRACKETS_SQUARE) do
|
|
21
|
-
delimited(children)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
end # Array
|
|
26
|
-
|
|
27
|
-
end # Literal
|
|
28
|
-
end # Emitter
|
|
29
|
-
end # Unparser
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unparser
|
|
4
|
-
class Emitter
|
|
5
|
-
class Literal
|
|
6
|
-
|
|
7
|
-
# Base class for dynamic literal emitters
|
|
8
|
-
class Dynamic < self
|
|
9
|
-
|
|
10
|
-
private
|
|
11
|
-
|
|
12
|
-
# Perform dispatch
|
|
13
|
-
#
|
|
14
|
-
# @return [undefined]
|
|
15
|
-
#
|
|
16
|
-
# @api private
|
|
17
|
-
#
|
|
18
|
-
def dispatch
|
|
19
|
-
util = self.class
|
|
20
|
-
visit_parentheses(dynamic_body, util::OPEN, util::CLOSE)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Return dynamic body
|
|
24
|
-
#
|
|
25
|
-
# @return [Parser::AST::Node]
|
|
26
|
-
#
|
|
27
|
-
# @api private
|
|
28
|
-
#
|
|
29
|
-
def dynamic_body
|
|
30
|
-
Parser::AST::Node.new(:dyn_str_body, children)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Dynamic string literal emitter
|
|
34
|
-
class String < self
|
|
35
|
-
|
|
36
|
-
OPEN = CLOSE = '"'.freeze
|
|
37
|
-
handle :dstr
|
|
38
|
-
|
|
39
|
-
end # String
|
|
40
|
-
|
|
41
|
-
# Dynamic symbol literal emitter
|
|
42
|
-
class Symbol < self
|
|
43
|
-
|
|
44
|
-
OPEN = ':"'.freeze
|
|
45
|
-
CLOSE = '"'.freeze
|
|
46
|
-
|
|
47
|
-
handle :dsym
|
|
48
|
-
|
|
49
|
-
end # Symbol
|
|
50
|
-
end # Dynamic
|
|
51
|
-
end # Literal
|
|
52
|
-
end # Emitter
|
|
53
|
-
end # Unparser
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unparser
|
|
4
|
-
class Emitter
|
|
5
|
-
class Literal
|
|
6
|
-
|
|
7
|
-
# Emitter for dynamic bodies
|
|
8
|
-
class DynamicBody < self
|
|
9
|
-
|
|
10
|
-
OPEN = '#{'.freeze
|
|
11
|
-
CLOSE = '}'.freeze
|
|
12
|
-
|
|
13
|
-
# Emitter for interpolated nodes
|
|
14
|
-
class Interpolation < self
|
|
15
|
-
|
|
16
|
-
handle :interpolated
|
|
17
|
-
|
|
18
|
-
children :subject
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
# Perform dispatch
|
|
23
|
-
#
|
|
24
|
-
# @return [undefined]
|
|
25
|
-
#
|
|
26
|
-
# @api private
|
|
27
|
-
#
|
|
28
|
-
def dispatch
|
|
29
|
-
write(OPEN)
|
|
30
|
-
visit_plain(subject)
|
|
31
|
-
write(CLOSE)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
# Perform dispatch
|
|
39
|
-
#
|
|
40
|
-
# @return [undefined]
|
|
41
|
-
#
|
|
42
|
-
# @api private
|
|
43
|
-
#
|
|
44
|
-
def dispatch
|
|
45
|
-
children.each(&method(:emit_segment))
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Emit segment
|
|
49
|
-
#
|
|
50
|
-
# @param [Parser::AST::Node] node
|
|
51
|
-
#
|
|
52
|
-
# @return [undefined]
|
|
53
|
-
#
|
|
54
|
-
# @api private
|
|
55
|
-
#
|
|
56
|
-
def emit_segment(node)
|
|
57
|
-
emit_interpolated_segment(node)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
pairs = Parser::Lexer::ESCAPES.invert.map do |key, value|
|
|
61
|
-
[key, "\\#{value}"] unless key.eql?(WS)
|
|
62
|
-
end.compact
|
|
63
|
-
|
|
64
|
-
pairs << ['#{', '\#{']
|
|
65
|
-
|
|
66
|
-
ESCAPES = ::Hash[pairs]
|
|
67
|
-
|
|
68
|
-
REPLACEMENTS = ::Regexp.union(ESCAPES.keys)
|
|
69
|
-
|
|
70
|
-
# Emit str segment
|
|
71
|
-
#
|
|
72
|
-
# @param [Parser::AST::Node] node
|
|
73
|
-
#
|
|
74
|
-
# @return [undefined]
|
|
75
|
-
#
|
|
76
|
-
# @api private
|
|
77
|
-
#
|
|
78
|
-
def emit_str_segment(node)
|
|
79
|
-
util = self.class
|
|
80
|
-
string = node.children.first
|
|
81
|
-
segment = string
|
|
82
|
-
.gsub(REPLACEMENTS, ESCAPES)
|
|
83
|
-
.gsub(util::DELIMITER, util::REPLACEMENT)
|
|
84
|
-
write(segment)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Emit interpolated segment
|
|
88
|
-
#
|
|
89
|
-
# @param [Parser::AST::Node] node
|
|
90
|
-
#
|
|
91
|
-
# @return [undefined]
|
|
92
|
-
#
|
|
93
|
-
# @api private
|
|
94
|
-
#
|
|
95
|
-
def emit_interpolated_segment(node)
|
|
96
|
-
visit_parentheses(node, OPEN, CLOSE)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# Dynamic string body
|
|
100
|
-
class String < self
|
|
101
|
-
|
|
102
|
-
handle :dyn_str_body
|
|
103
|
-
|
|
104
|
-
DELIMITER = '"'.freeze
|
|
105
|
-
REPLACEMENT = '\"'.freeze
|
|
106
|
-
|
|
107
|
-
end # String
|
|
108
|
-
|
|
109
|
-
# Dynamic regexp body
|
|
110
|
-
class Regexp < self
|
|
111
|
-
|
|
112
|
-
handle :dyn_regexp_body
|
|
113
|
-
|
|
114
|
-
DELIMITER = '/'.freeze
|
|
115
|
-
REPLACEMENT = '\/'.freeze
|
|
116
|
-
|
|
117
|
-
end # Regexp
|
|
118
|
-
|
|
119
|
-
# Dynamic regexp body
|
|
120
|
-
class ExecuteString < self
|
|
121
|
-
|
|
122
|
-
handle :dyn_xstr_body
|
|
123
|
-
|
|
124
|
-
DELIMITER = '`'.freeze
|
|
125
|
-
REPLACEMENT = '\`'.freeze
|
|
126
|
-
|
|
127
|
-
end # ExecuteString
|
|
128
|
-
|
|
129
|
-
end # DynamicBody
|
|
130
|
-
end # Literal
|
|
131
|
-
end # Emitter
|
|
132
|
-
end # Unparser
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Unparser
|
|
4
|
-
class Emitter
|
|
5
|
-
class Literal
|
|
6
|
-
# Emitter for execute strings (xstr) nodes
|
|
7
|
-
class ExecuteString < self
|
|
8
|
-
|
|
9
|
-
OPEN = CLOSE = '`'.freeze
|
|
10
|
-
|
|
11
|
-
handle :xstr
|
|
12
|
-
|
|
13
|
-
private
|
|
14
|
-
|
|
15
|
-
# Perform dispatch
|
|
16
|
-
#
|
|
17
|
-
# @return [undefined]
|
|
18
|
-
#
|
|
19
|
-
# @api private
|
|
20
|
-
#
|
|
21
|
-
def dispatch
|
|
22
|
-
visit_parentheses(dynamic_body, OPEN, CLOSE)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Return dynamic body
|
|
26
|
-
#
|
|
27
|
-
# @return [Parser::AST::Node]
|
|
28
|
-
#
|
|
29
|
-
# @api private
|
|
30
|
-
#
|
|
31
|
-
def dynamic_body
|
|
32
|
-
Parser::AST::Node.new(:dyn_xstr_body, children)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
end # ExecuteString
|
|
36
|
-
end # Literal
|
|
37
|
-
end # Emitter
|
|
38
|
-
end # Unparser
|