unparser 0.4.7 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -9
  3. data/bin/unparser +2 -2
  4. data/lib/unparser/abstract_type.rb +121 -0
  5. data/lib/unparser/adamantium/method_builder.rb +111 -0
  6. data/lib/unparser/adamantium.rb +150 -0
  7. data/lib/unparser/anima/attribute.rb +59 -0
  8. data/lib/unparser/anima/error.rb +23 -0
  9. data/lib/unparser/anima.rb +184 -0
  10. data/lib/unparser/ast/local_variable_scope.rb +6 -76
  11. data/lib/unparser/ast.rb +1 -3
  12. data/lib/unparser/buffer.rb +14 -25
  13. data/lib/unparser/cli.rb +85 -77
  14. data/lib/unparser/{cli/color.rb → color.rb} +4 -14
  15. data/lib/unparser/comments.rb +0 -26
  16. data/lib/unparser/concord.rb +114 -0
  17. data/lib/unparser/constants.rb +4 -53
  18. data/lib/unparser/diff.rb +98 -0
  19. data/lib/unparser/dsl.rb +0 -32
  20. data/lib/unparser/either.rb +153 -0
  21. data/lib/unparser/emitter/alias.rb +2 -8
  22. data/lib/unparser/emitter/args.rb +45 -0
  23. data/lib/unparser/emitter/argument.rb +13 -169
  24. data/lib/unparser/emitter/array.rb +27 -0
  25. data/lib/unparser/emitter/array_pattern.rb +29 -0
  26. data/lib/unparser/emitter/assignment.rb +36 -127
  27. data/lib/unparser/emitter/begin.rb +9 -84
  28. data/lib/unparser/emitter/binary.rb +7 -20
  29. data/lib/unparser/emitter/block.rb +57 -41
  30. data/lib/unparser/emitter/case.rb +6 -48
  31. data/lib/unparser/emitter/case_guard.rb +27 -0
  32. data/lib/unparser/emitter/case_match.rb +40 -0
  33. data/lib/unparser/emitter/cbase.rb +1 -3
  34. data/lib/unparser/emitter/class.rb +6 -26
  35. data/lib/unparser/emitter/const_pattern.rb +24 -0
  36. data/lib/unparser/emitter/def.rb +7 -51
  37. data/lib/unparser/emitter/defined.rb +2 -12
  38. data/lib/unparser/emitter/dstr.rb +22 -0
  39. data/lib/unparser/emitter/dsym.rb +41 -0
  40. data/lib/unparser/emitter/find_pattern.rb +18 -0
  41. data/lib/unparser/emitter/flipflop.rb +11 -10
  42. data/lib/unparser/emitter/float.rb +29 -0
  43. data/lib/unparser/emitter/flow_modifier.rb +15 -53
  44. data/lib/unparser/emitter/for.rb +5 -19
  45. data/lib/unparser/emitter/hash.rb +36 -0
  46. data/lib/unparser/emitter/hash_pattern.rb +67 -0
  47. data/lib/unparser/emitter/hookexe.rb +5 -11
  48. data/lib/unparser/emitter/if.rb +15 -71
  49. data/lib/unparser/emitter/in_match.rb +21 -0
  50. data/lib/unparser/emitter/in_pattern.rb +36 -0
  51. data/lib/unparser/emitter/index.rb +22 -89
  52. data/lib/unparser/emitter/kwargs.rb +13 -0
  53. data/lib/unparser/emitter/kwbegin.rb +31 -0
  54. data/lib/unparser/emitter/lambda.rb +0 -8
  55. data/lib/unparser/emitter/masgn.rb +20 -0
  56. data/lib/unparser/emitter/match.rb +3 -17
  57. data/lib/unparser/emitter/match_alt.rb +23 -0
  58. data/lib/unparser/emitter/match_as.rb +21 -0
  59. data/lib/unparser/emitter/match_pattern.rb +30 -0
  60. data/lib/unparser/emitter/match_pattern_p.rb +20 -0
  61. data/lib/unparser/emitter/match_rest.rb +33 -0
  62. data/lib/unparser/emitter/match_var.rb +19 -0
  63. data/lib/unparser/emitter/mlhs.rb +40 -0
  64. data/lib/unparser/emitter/module.rb +3 -9
  65. data/lib/unparser/emitter/op_assign.rb +14 -29
  66. data/lib/unparser/emitter/pair.rb +33 -0
  67. data/lib/unparser/emitter/pin.rb +19 -0
  68. data/lib/unparser/emitter/primitive.rb +93 -0
  69. data/lib/unparser/emitter/range.rb +35 -0
  70. data/lib/unparser/emitter/regexp.rb +35 -0
  71. data/lib/unparser/emitter/repetition.rb +17 -57
  72. data/lib/unparser/emitter/rescue.rb +1 -97
  73. data/lib/unparser/emitter/root.rb +17 -1
  74. data/lib/unparser/emitter/send.rb +10 -219
  75. data/lib/unparser/emitter/simple.rb +33 -0
  76. data/lib/unparser/emitter/splat.rb +13 -19
  77. data/lib/unparser/emitter/super.rb +1 -29
  78. data/lib/unparser/emitter/undef.rb +1 -9
  79. data/lib/unparser/emitter/variable.rb +1 -31
  80. data/lib/unparser/emitter/xstr.rb +72 -0
  81. data/lib/unparser/emitter/yield.rb +1 -9
  82. data/lib/unparser/emitter.rb +24 -425
  83. data/lib/unparser/equalizer.rb +98 -0
  84. data/lib/unparser/generation.rb +252 -0
  85. data/lib/unparser/node_details/send.rb +65 -0
  86. data/lib/unparser/node_details.rb +21 -0
  87. data/lib/unparser/node_helpers.rb +48 -6
  88. data/lib/unparser/validation.rb +172 -0
  89. data/lib/unparser/writer/binary.rb +99 -0
  90. data/lib/unparser/writer/dynamic_string.rb +211 -0
  91. data/lib/unparser/writer/resbody.rb +40 -0
  92. data/lib/unparser/writer/rescue.rb +43 -0
  93. data/lib/unparser/{emitter → writer}/send/attribute_assignment.rb +11 -26
  94. data/lib/unparser/writer/send/binary.rb +27 -0
  95. data/lib/unparser/writer/send/conditional.rb +25 -0
  96. data/lib/unparser/writer/send/regular.rb +33 -0
  97. data/lib/unparser/{emitter → writer}/send/unary.rb +10 -17
  98. data/lib/unparser/writer/send.rb +115 -0
  99. data/lib/unparser/writer.rb +15 -0
  100. data/lib/unparser.rb +161 -77
  101. metadata +100 -157
  102. data/.circleci/config.yml +0 -49
  103. data/.gitignore +0 -37
  104. data/.rspec +0 -4
  105. data/.rubocop.yml +0 -9
  106. data/Changelog.md +0 -156
  107. data/Gemfile +0 -9
  108. data/Gemfile.lock +0 -181
  109. data/LICENSE +0 -20
  110. data/Rakefile +0 -22
  111. data/config/devtools.yml +0 -2
  112. data/config/flay.yml +0 -3
  113. data/config/flog.yml +0 -2
  114. data/config/mutant.yml +0 -6
  115. data/config/reek.yml +0 -98
  116. data/config/rubocop.yml +0 -122
  117. data/config/yardstick.yml +0 -2
  118. data/lib/unparser/cli/differ.rb +0 -152
  119. data/lib/unparser/cli/source.rb +0 -267
  120. data/lib/unparser/emitter/empty.rb +0 -23
  121. data/lib/unparser/emitter/ensure.rb +0 -37
  122. data/lib/unparser/emitter/literal/array.rb +0 -29
  123. data/lib/unparser/emitter/literal/dynamic.rb +0 -53
  124. data/lib/unparser/emitter/literal/dynamic_body.rb +0 -132
  125. data/lib/unparser/emitter/literal/execute_string.rb +0 -38
  126. data/lib/unparser/emitter/literal/hash.rb +0 -156
  127. data/lib/unparser/emitter/literal/primitive.rb +0 -145
  128. data/lib/unparser/emitter/literal/range.rb +0 -36
  129. data/lib/unparser/emitter/literal/regexp.rb +0 -114
  130. data/lib/unparser/emitter/literal/singleton.rb +0 -26
  131. data/lib/unparser/emitter/literal.rb +0 -10
  132. data/lib/unparser/emitter/meta.rb +0 -16
  133. data/lib/unparser/emitter/redo.rb +0 -25
  134. data/lib/unparser/emitter/resbody.rb +0 -76
  135. data/lib/unparser/emitter/retry.rb +0 -25
  136. data/lib/unparser/emitter/send/binary.rb +0 -57
  137. data/lib/unparser/emitter/send/conditional.rb +0 -40
  138. data/lib/unparser/emitter/send/regular.rb +0 -40
  139. data/lib/unparser/preprocessor.rb +0 -159
  140. data/spec/integration/unparser/corpus_spec.rb +0 -111
  141. data/spec/integrations.yml +0 -92
  142. data/spec/spec_helper.rb +0 -20
  143. data/spec/unit/unparser/buffer/append_spec.rb +0 -24
  144. data/spec/unit/unparser/buffer/append_without_prefix_spec.rb +0 -23
  145. data/spec/unit/unparser/buffer/capture_content_spec.rb +0 -17
  146. data/spec/unit/unparser/buffer/content_spec.rb +0 -38
  147. data/spec/unit/unparser/buffer/fresh_line_spec.rb +0 -20
  148. data/spec/unit/unparser/buffer/indent_spec.rb +0 -20
  149. data/spec/unit/unparser/buffer/nl_spec.rb +0 -16
  150. data/spec/unit/unparser/buffer/unindent_spec.rb +0 -20
  151. data/spec/unit/unparser/comments/consume_spec.rb +0 -22
  152. data/spec/unit/unparser/comments/take_all_spec.rb +0 -19
  153. data/spec/unit/unparser/comments/take_before_spec.rb +0 -46
  154. data/spec/unit/unparser/comments/take_eol_comments_spec.rb +0 -32
  155. data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +0 -17
  156. data/spec/unit/unparser_spec.rb +0 -1849
  157. data/unparser.gemspec +0 -32
@@ -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