unparser 0.0.1

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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.circle.yml +4 -0
  3. data/.gitignore +2 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +16 -0
  6. data/Changelog.md +3 -0
  7. data/Gemfile +6 -0
  8. data/Gemfile.devtools +60 -0
  9. data/Guardfile +18 -0
  10. data/README.md +41 -0
  11. data/Rakefile +24 -0
  12. data/TODO +1 -0
  13. data/config/devtools.yml +2 -0
  14. data/config/flay.yml +3 -0
  15. data/config/flog.yml +2 -0
  16. data/config/mutant.yml +3 -0
  17. data/config/reek.yml +107 -0
  18. data/config/yardstick.yml +2 -0
  19. data/lib/unparser/buffer.rb +93 -0
  20. data/lib/unparser/constants.rb +87 -0
  21. data/lib/unparser/emitter/alias.rb +27 -0
  22. data/lib/unparser/emitter/argument.rb +154 -0
  23. data/lib/unparser/emitter/assignment.rb +140 -0
  24. data/lib/unparser/emitter/begin.rb +179 -0
  25. data/lib/unparser/emitter/binary.rb +52 -0
  26. data/lib/unparser/emitter/block.rb +53 -0
  27. data/lib/unparser/emitter/break.rb +28 -0
  28. data/lib/unparser/emitter/case.rb +97 -0
  29. data/lib/unparser/emitter/cbase.rb +22 -0
  30. data/lib/unparser/emitter/class.rb +72 -0
  31. data/lib/unparser/emitter/def.rb +107 -0
  32. data/lib/unparser/emitter/defined.rb +27 -0
  33. data/lib/unparser/emitter/for.rb +50 -0
  34. data/lib/unparser/emitter/hookexe.rb +42 -0
  35. data/lib/unparser/emitter/if.rb +85 -0
  36. data/lib/unparser/emitter/literal/composed.rb +64 -0
  37. data/lib/unparser/emitter/literal/dynamic.rb +54 -0
  38. data/lib/unparser/emitter/literal/dynamic_body.rb +109 -0
  39. data/lib/unparser/emitter/literal/execute_string.rb +38 -0
  40. data/lib/unparser/emitter/literal/primitive.rb +49 -0
  41. data/lib/unparser/emitter/literal/range.rb +33 -0
  42. data/lib/unparser/emitter/literal/regexp.rb +96 -0
  43. data/lib/unparser/emitter/literal/singleton.rb +24 -0
  44. data/lib/unparser/emitter/literal.rb +7 -0
  45. data/lib/unparser/emitter/module.rb +37 -0
  46. data/lib/unparser/emitter/next.rb +22 -0
  47. data/lib/unparser/emitter/not.rb +25 -0
  48. data/lib/unparser/emitter/op_assign.rb +63 -0
  49. data/lib/unparser/emitter/redo.rb +22 -0
  50. data/lib/unparser/emitter/repetition.rb +33 -0
  51. data/lib/unparser/emitter/retry.rb +22 -0
  52. data/lib/unparser/emitter/return.rb +38 -0
  53. data/lib/unparser/emitter/root.rb +7 -0
  54. data/lib/unparser/emitter/send/binary.rb +100 -0
  55. data/lib/unparser/emitter/send/index.rb +82 -0
  56. data/lib/unparser/emitter/send/unary.rb +29 -0
  57. data/lib/unparser/emitter/send.rb +273 -0
  58. data/lib/unparser/emitter/splat.rb +24 -0
  59. data/lib/unparser/emitter/super.rb +46 -0
  60. data/lib/unparser/emitter/undef.rb +25 -0
  61. data/lib/unparser/emitter/variable.rb +83 -0
  62. data/lib/unparser/emitter/yield.rb +28 -0
  63. data/lib/unparser/emitter.rb +308 -0
  64. data/lib/unparser.rb +87 -0
  65. data/spec/integration/unparser/spike_spec.rb +914 -0
  66. data/spec/spec_helper.rb +13 -0
  67. data/spec/unit/unparser/buffer/append_spec.rb +23 -0
  68. data/spec/unit/unparser/buffer/content_spec.rb +38 -0
  69. data/spec/unit/unparser/buffer/indent_spec.rb +18 -0
  70. data/spec/unit/unparser/buffer/nl_spec.rb +16 -0
  71. data/spec/unit/unparser/buffer/unindent_spec.rb +18 -0
  72. data/spec/unit/unparser/class_methods/unparse_spec.rb +16 -0
  73. data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +17 -0
  74. data/spec/unit/unparser/emitter/class_methods/visit_spec.rb +37 -0
  75. data/spec/unit/unparser/emitter/source_map/class_methods/emit_spec.rb +20 -0
  76. data/unparser.gemspec +24 -0
  77. metadata +201 -0
@@ -0,0 +1,273 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for send
4
+ class Send < self
5
+
6
+ handle :send
7
+
8
+ INDEX_PARENS = IceNine.deep_freeze(%w([ ]))
9
+ NORMAL_PARENS = IceNine.deep_freeze(%w[( )])
10
+
11
+ INDEX_REFERENCE = '[]'.freeze
12
+ INDEX_ASSIGN = '[]='.freeze
13
+ ASSIGN_SUFFIX = '='.freeze
14
+
15
+ AMBIGOUS = [:irange, :erange].to_set.freeze
16
+
17
+ # Tell node needs begin
18
+ #
19
+ # @return [true]
20
+ #
21
+ # @api private
22
+ #
23
+ def needs_begin?
24
+ true
25
+ end
26
+
27
+ private
28
+
29
+ # Perform dispatch
30
+ #
31
+ # @return [undefined]
32
+ #
33
+ # @api private
34
+ #
35
+ def dispatch
36
+ case selector
37
+ when INDEX_REFERENCE
38
+ run(Index::Reference)
39
+ when INDEX_ASSIGN
40
+ run(Index::Assign)
41
+ else
42
+ non_index_dispatch
43
+ end
44
+ end
45
+
46
+ # Emit unambiguous receiver
47
+ #
48
+ # @return [undefined]
49
+ #
50
+ # @api private
51
+ #
52
+ def emit_unambiguous_receiver
53
+ receiver = effective_receiver
54
+ if AMBIGOUS.include?(receiver.type) or binary_receiver?
55
+ parentheses { visit(receiver) }
56
+ return
57
+ end
58
+
59
+ visit(receiver)
60
+ end
61
+
62
+ # Return effective receiver
63
+ #
64
+ # @return [Parser::AST::Node]
65
+ #
66
+ # @api private
67
+ #
68
+ def effective_receiver
69
+ receiver = first_child
70
+ children = receiver.children
71
+ if receiver.type == :begin && children.length == 1
72
+ receiver = children.first
73
+ end
74
+ receiver
75
+ end
76
+
77
+ # Test for binary receiver
78
+ #
79
+ # @return [true]
80
+ # if receiver is a binary operation implemented by a method
81
+ #
82
+ # @return [false]
83
+ # otherwise
84
+ #
85
+ # @api private
86
+ #
87
+ def binary_receiver?
88
+ receiver = effective_receiver
89
+ case receiver.type
90
+ when :or_asgn, :and_asgn
91
+ true
92
+ when :send
93
+ BINARY_OPERATORS.include?(receiver.children[1])
94
+ else
95
+ false
96
+ end
97
+ end
98
+
99
+ # Delegate to emitter
100
+ #
101
+ # @param [Class:Emitter] emitter
102
+ #
103
+ # @return [undefined]
104
+ #
105
+ # @api private
106
+ #
107
+ def run(emitter)
108
+ emitter.emit(node, buffer, self)
109
+ end
110
+
111
+ # Perform non index dispatch
112
+ #
113
+ # @return [undefined]
114
+ #
115
+ # @api private
116
+ #
117
+ def non_index_dispatch
118
+ if binary?
119
+ run(Binary)
120
+ return
121
+ elsif unary?
122
+ run(Unary)
123
+ return
124
+ end
125
+ regular_dispatch
126
+ end
127
+
128
+ # Perform regular dispatch
129
+ #
130
+ # @return [undefined]
131
+ #
132
+ # @api private
133
+ #
134
+ def regular_dispatch
135
+ emit_receiver
136
+ emit_selector
137
+ emit_arguments
138
+ end
139
+
140
+ # Return receiver
141
+ #
142
+ # @return [Parser::AST::Node]
143
+ #
144
+ # @api private
145
+ #
146
+ def emit_receiver
147
+ return unless first_child
148
+ emit_unambiguous_receiver
149
+ write(O_DOT)
150
+ end
151
+
152
+ # Test for unary operator implemented as method
153
+ #
154
+ # @return [true]
155
+ # if node is a unary operator
156
+ #
157
+ # @return [false]
158
+ # otherwise
159
+ #
160
+ # @api private
161
+ #
162
+ def unary?
163
+ UNARY_OPERATORS.include?(children[1])
164
+ end
165
+
166
+ # Test for binary operator implemented as method
167
+ #
168
+ # @return [true]
169
+ # if node is a binary operator
170
+ #
171
+ # @return [false]
172
+ # otherwise
173
+ #
174
+ # @api private
175
+ #
176
+ def binary?
177
+ BINARY_OPERATORS.include?(children[1])
178
+ end
179
+
180
+ # Emit selector
181
+ #
182
+ # @return [undefined]
183
+ #
184
+ # @api private
185
+ #
186
+ def emit_selector
187
+ name = selector
188
+ if mlhs?
189
+ name = name[0..-2]
190
+ end
191
+ write(name)
192
+ end
193
+
194
+ # Test for mlhs
195
+ #
196
+ # @return [true]
197
+ # if node is within an mlhs
198
+ #
199
+ # @return [false]
200
+ # otherwise
201
+ #
202
+ # @api private
203
+ #
204
+ def mlhs?
205
+ assignment? && !arguments?
206
+ end
207
+
208
+ # Test for assigment
209
+ #
210
+ # @return [true]
211
+ # if node represents attribute / element assignment
212
+ #
213
+ # @return [false]
214
+ # otherwise
215
+ #
216
+ # @api private
217
+ #
218
+ def assignment?
219
+ selector[-1] == ASSIGN_SUFFIX
220
+ end
221
+
222
+ # Return selector
223
+ #
224
+ # @return [String]
225
+ #
226
+ # @api private
227
+ #
228
+ def selector
229
+ children[1].to_s
230
+ end
231
+ memoize :selector
232
+
233
+ # Test for empty arguments
234
+ #
235
+ # @return [true]
236
+ # if arguments are empty
237
+ #
238
+ # @return [false]
239
+ # otherwise
240
+ #
241
+ # @api private
242
+ #
243
+ def arguments?
244
+ arguments.any?
245
+ end
246
+
247
+ # Return argument nodes
248
+ #
249
+ # @return [Array<Parser::AST::Node>]
250
+ #
251
+ # @api private
252
+ #
253
+ def arguments
254
+ children[2..-1]
255
+ end
256
+
257
+ # Emit arguments
258
+ #
259
+ # @return [undefined]
260
+ #
261
+ # @api private
262
+ #
263
+ def emit_arguments
264
+ args = arguments
265
+ return if args.empty?
266
+ parentheses do
267
+ delimited(args)
268
+ end
269
+ end
270
+
271
+ end # Send
272
+ end # Emitter
273
+ end # Unparser
@@ -0,0 +1,24 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for splats
4
+ class Splat < self
5
+
6
+ handle :splat
7
+
8
+ children :subject
9
+
10
+ private
11
+
12
+ # Perform dispatch
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ write(O_SPLAT)
20
+ visit(subject) if subject
21
+ end
22
+ end
23
+ end
24
+ end # Unparser
@@ -0,0 +1,46 @@
1
+ module Unparser
2
+ class Emitter
3
+
4
+ # Emitter for zsuper nodes
5
+ class ZSuper < self
6
+
7
+ handle :zsuper
8
+
9
+ private
10
+
11
+ # Perform dispatch
12
+ #
13
+ # @return [undefined]
14
+ #
15
+ # @api private
16
+ #
17
+ def dispatch
18
+ write(K_SUPER)
19
+ end
20
+
21
+ end # ZSuper
22
+
23
+ # Emitter for super nodes
24
+ class Super < self
25
+
26
+ handle :super
27
+
28
+ private
29
+
30
+ # Perform dispatch
31
+ #
32
+ # @return [undefined]
33
+ #
34
+ # @api private
35
+ #
36
+ def dispatch
37
+ write(K_SUPER)
38
+ parentheses do
39
+ delimited(children)
40
+ end
41
+ end
42
+
43
+ end # Super
44
+
45
+ end # Emitter
46
+ end # Unparser
@@ -0,0 +1,25 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for undef nodes
4
+ class Undef < self
5
+
6
+ handle :undef
7
+
8
+ children :subject
9
+
10
+ private
11
+
12
+ # Perform dispatch
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ write(K_UNDEF, WS)
20
+ visit(subject)
21
+ end
22
+
23
+ end # Undef
24
+ end # Emitter
25
+ end # Unparser
@@ -0,0 +1,83 @@
1
+ module Unparser
2
+ class Emitter
3
+
4
+ # Emitter for various variable accesses
5
+ class Variable < self
6
+
7
+ handle :ivar, :lvar, :cvar, :gvar, :back_ref
8
+
9
+ children :name
10
+
11
+ private
12
+
13
+ # Perform dispatch
14
+ #
15
+ # @return [undefined]
16
+ #
17
+ # @api private
18
+ #
19
+ def dispatch
20
+ write(name.to_s)
21
+ end
22
+
23
+ end # Access
24
+
25
+ # Emitter for constant access
26
+ class Const < self
27
+
28
+ handle :const
29
+
30
+ children :parent, :name
31
+
32
+ private
33
+
34
+ # Perform dispatch
35
+ #
36
+ # @return [undefined]
37
+ #
38
+ # @api private
39
+ #
40
+ def dispatch
41
+ emit_parent
42
+ write(name.to_s)
43
+ end
44
+
45
+ # Emit parent
46
+ #
47
+ # @return [undefined]
48
+ #
49
+ # @api private
50
+ #
51
+ def emit_parent
52
+ return unless parent
53
+ visit(parent)
54
+ if parent.type != :cbase
55
+ write(O_DCL)
56
+ end
57
+ end
58
+ end
59
+
60
+ # Emitter for nth_ref nodes (regexp captures)
61
+ class NthRef < self
62
+ PREFIX = '$'.freeze
63
+ handle :nth_ref
64
+
65
+ children :name
66
+
67
+ private
68
+
69
+ # Perform dispatch
70
+ #
71
+ # @return [undefined]
72
+ #
73
+ # @api private
74
+ #
75
+ def dispatch
76
+ write(PREFIX)
77
+ write(name.to_s)
78
+ end
79
+
80
+ end # NthRef
81
+
82
+ end # Emitter
83
+ end # Unparser
@@ -0,0 +1,28 @@
1
+ module Unparser
2
+ class Emitter
3
+
4
+ # Emitter for yield node
5
+ class Yield < self
6
+
7
+ handle :yield
8
+
9
+ private
10
+
11
+ # Perform dispatch
12
+ #
13
+ # @return [undefined]
14
+ #
15
+ # @api private
16
+ #
17
+ def dispatch
18
+ write(K_YIELD)
19
+ return if children.empty?
20
+ parentheses do
21
+ delimited(children)
22
+ end
23
+ end
24
+
25
+ end # Yield
26
+
27
+ end # Emitter
28
+ end # Unparser