unparser 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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