unparser 0.1.15 → 0.1.16

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +6 -0
  3. data/circle.yml +1 -1
  4. data/config/flay.yml +1 -1
  5. data/config/flog.yml +1 -1
  6. data/config/reek.yml +1 -0
  7. data/lib/unparser/ast.rb +1 -1
  8. data/lib/unparser/ast/local_variable_scope.rb +1 -1
  9. data/lib/unparser/cli/differ.rb +1 -1
  10. data/lib/unparser/cli/source.rb +2 -0
  11. data/lib/unparser/constants.rb +0 -11
  12. data/lib/unparser/dsl.rb +1 -1
  13. data/lib/unparser/emitter.rb +41 -13
  14. data/lib/unparser/emitter/argument.rb +22 -34
  15. data/lib/unparser/emitter/assignment.rb +29 -6
  16. data/lib/unparser/emitter/begin.rb +10 -8
  17. data/lib/unparser/emitter/binary.rb +3 -12
  18. data/lib/unparser/emitter/block.rb +1 -0
  19. data/lib/unparser/emitter/case.rb +4 -2
  20. data/lib/unparser/emitter/cbase.rb +1 -0
  21. data/lib/unparser/emitter/class.rb +2 -1
  22. data/lib/unparser/emitter/def.rb +1 -1
  23. data/lib/unparser/emitter/defined.rb +2 -1
  24. data/lib/unparser/emitter/flipflop.rb +3 -2
  25. data/lib/unparser/emitter/flow_modifier.rb +22 -5
  26. data/lib/unparser/emitter/for.rb +2 -1
  27. data/lib/unparser/emitter/if.rb +10 -3
  28. data/lib/unparser/emitter/literal.rb +1 -0
  29. data/lib/unparser/emitter/literal/dynamic_body.rb +1 -1
  30. data/lib/unparser/emitter/literal/hash.rb +1 -1
  31. data/lib/unparser/emitter/literal/primitive.rb +83 -1
  32. data/lib/unparser/emitter/literal/range.rb +3 -2
  33. data/lib/unparser/emitter/match.rb +1 -0
  34. data/lib/unparser/emitter/module.rb +1 -1
  35. data/lib/unparser/emitter/op_assign.rb +3 -1
  36. data/lib/unparser/emitter/redo.rb +1 -0
  37. data/lib/unparser/emitter/repetition.rb +5 -3
  38. data/lib/unparser/emitter/resbody.rb +2 -2
  39. data/lib/unparser/emitter/rescue.rb +2 -1
  40. data/lib/unparser/emitter/retry.rb +1 -0
  41. data/lib/unparser/emitter/send.rb +13 -14
  42. data/lib/unparser/emitter/send/arguments.rb +1 -2
  43. data/lib/unparser/emitter/send/attribute_assignment.rb +3 -2
  44. data/lib/unparser/emitter/send/binary.rb +3 -2
  45. data/lib/unparser/emitter/send/index.rb +16 -2
  46. data/lib/unparser/emitter/send/regular.rb +2 -1
  47. data/lib/unparser/emitter/send/unary.rb +2 -1
  48. data/lib/unparser/emitter/splat.rb +2 -0
  49. data/lib/unparser/emitter/super.rb +2 -0
  50. data/lib/unparser/emitter/undef.rb +1 -0
  51. data/lib/unparser/emitter/variable.rb +4 -0
  52. data/lib/unparser/emitter/yield.rb +1 -0
  53. data/lib/unparser/preprocessor.rb +19 -12
  54. data/spec/integration/unparser/corpus_spec.rb +3 -2
  55. data/spec/integrations.yml +11 -1
  56. data/spec/unit/unparser_spec.rb +190 -183
  57. data/unparser.gemspec +2 -2
  58. metadata +5 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 51f39ff818f38c725475d8e6970391c4f7a771a1
4
- data.tar.gz: 6838c26d95b6bf42ecf19e9b1874c39223d00d6a
3
+ metadata.gz: 8311740d232b8385dfa4e602fdb037769593990f
4
+ data.tar.gz: c2cbcfa29bc39e0affdaa3eb02acddd60a78ec85
5
5
  SHA512:
6
- metadata.gz: e71bf25de61e37a461f9f09d3b1600070d84c7458d9717c11ce768d5eafd3881a5ea1eca3e8926d0704dbc06862d4d1bfb718f335fb2e9a23d9362a3797a0bea
7
- data.tar.gz: 2df198d4fd9b6807af07b7a45f5a781f1b969a4b716fb6ef407f7c3cdca0613b9b66fbf84eddfba9b73b59e81e4b076f86a08f4df823b9e80a46aa3a6b4b799f
6
+ metadata.gz: 664dd07c08c822714a16c4c2ae9758cd270d3a643bebccfc4cee2c1a536cc5a4aa1eff6e80302dbc4438592b3d443787fc6400a4761eda3ef51f497087f4efb9
7
+ data.tar.gz: a9af21984e94034f91b33d8b68b13a5ee045fe6d1e03459e45739c8eaeeedaabf0d3ce41e51957b08d8eec86894388739b97d336df0d428ec5ff8b123cf80901
@@ -1,3 +1,9 @@
1
+ # v0.1.16 2014-11-07
2
+
3
+ * Add emitter for complex and rational literals
4
+ * Fix edge cases for MLHS
5
+ * Fix differencies from 2.2.pre7 series of parser
6
+
1
7
  # v0.1.15 2014-09-24
2
8
 
3
9
  * Handle syntax edge case for MRI 2.1.3 parser.
data/circle.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  machine:
2
2
  ruby:
3
- version: 2.0.0
3
+ version: '2.1'
4
4
  test:
5
5
  override:
6
6
  - bundle exec rake ci
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 13
3
- total_score: 698
3
+ total_score: 679
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 22.1
2
+ threshold: 23.7
@@ -79,6 +79,7 @@ TooManyStatements:
79
79
  - Unparser::CLI#add_options
80
80
  - Unparser::CLI#initialize
81
81
  - Unparser::CLI::Source#report_unparser
82
+ - Unparser::Emitter#delimited
82
83
  DuplicateMethodCall:
83
84
  allow_calls: []
84
85
  exclude: []
@@ -185,7 +185,7 @@ module Unparser
185
185
  return unless controller.call(node)
186
186
  block.call(node)
187
187
  node.children.each do |child|
188
- next unless child.kind_of?(Parser::AST::Node)
188
+ next unless child.is_a?(Parser::AST::Node)
189
189
  call(child)
190
190
  end
191
191
  self
@@ -161,7 +161,7 @@ module Unparser
161
161
  enter(node)
162
162
  yield node, current.dup, before
163
163
  node.children.each do |child|
164
- visit(child, &block) if child.kind_of?(Parser::AST::Node)
164
+ visit(child, &block) if child.is_a?(Parser::AST::Node)
165
165
  end
166
166
  leave(node)
167
167
  end
@@ -101,7 +101,7 @@ module Unparser
101
101
  # @api private
102
102
  #
103
103
  def self.lines(source)
104
- source.lines.map { |line| line.chomp }
104
+ source.lines.map(&:chomp)
105
105
  end
106
106
  private_class_method :lines
107
107
 
@@ -131,6 +131,8 @@ module Unparser
131
131
  def report_generated
132
132
  strip(<<-MESSAGE)
133
133
  Parsing of generated source failed:
134
+ Original-source:
135
+ #{original_source}
134
136
  Original-AST:
135
137
  #{original_ast.inspect}
136
138
  Source:
@@ -98,17 +98,6 @@ module Unparser
98
98
  K_FILE = '__FILE__'
99
99
  K_THEN = 'then'
100
100
 
101
- # Nodes that can be emitted in tokens that terminate their expression.
102
- #
103
- # These nodes dont require parentheses to be exactly reproduced in context of a more complex expression.
104
- #
105
- TERMINATED = symbol_set %w(
106
- int float self kwbegin const regexp args lvar
107
- ivar gvar cvar if case module class sclass super
108
- yield zsuper break next defined? str block while loop until
109
- def defs true false nil array hash sym return match_current_line
110
- )
111
-
112
101
  DEFAULT_DELIMITER = ', '.freeze
113
102
 
114
103
  CURLY_BRACKETS = IceNine.deep_freeze(%w({ }))
@@ -13,7 +13,7 @@ module Unparser
13
13
  # @api private
14
14
  #
15
15
  def define_remaining_children(names)
16
- range = names.length .. -1
16
+ range = names.length..-1
17
17
  define_method(:remaining_children) do
18
18
  children[range]
19
19
  end
@@ -17,6 +17,18 @@ module Unparser
17
17
 
18
18
  CURLY_BRACKETS = IceNine.deep_freeze(%w({ }))
19
19
 
20
+ module Unterminated
21
+ def terminated?
22
+ false
23
+ end
24
+ end
25
+
26
+ module Terminated
27
+ def terminated?
28
+ true
29
+ end
30
+ end
31
+
20
32
  module LocalVariableRoot
21
33
 
22
34
  # Return local variable root
@@ -133,9 +145,7 @@ module Unparser
133
145
  #
134
146
  # @api private
135
147
  #
136
- def terminated?
137
- TERMINATED.include?(node.type)
138
- end
148
+ abstract_method :terminated?
139
149
 
140
150
  protected
141
151
 
@@ -183,12 +193,12 @@ module Unparser
183
193
  #
184
194
  # @api private
185
195
  #
186
- def visit(node)
196
+ def visit_plain(node)
187
197
  emitter = emitter(node)
188
198
  emitter.write_to_buffer
189
199
  end
190
200
 
191
- # Visit unambigous node
201
+ # Visit ambigous node
192
202
  #
193
203
  # @param [Parser::AST::Node] node
194
204
  #
@@ -196,7 +206,7 @@ module Unparser
196
206
  #
197
207
  # @api private
198
208
  #
199
- def visit_terminated(node)
209
+ def visit(node)
200
210
  emitter = emitter(node)
201
211
  conditional_parentheses(!emitter.terminated?) do
202
212
  emitter.write_to_buffer
@@ -213,7 +223,7 @@ module Unparser
213
223
  #
214
224
  def visit_parentheses(node, *arguments)
215
225
  parentheses(*arguments) do
216
- visit(node)
226
+ visit_plain(node)
217
227
  end
218
228
  end
219
229
 
@@ -254,13 +264,27 @@ module Unparser
254
264
  #
255
265
  # @api private
256
266
  #
257
- def delimited(nodes, delimiter = DEFAULT_DELIMITER)
267
+ def delimited_plain(nodes, delimiter = DEFAULT_DELIMITER)
268
+ delimited(nodes, delimiter, &method(:visit_plain))
269
+ end
270
+
271
+ # Emit delimited body
272
+ #
273
+ # @param [Enumerable<Parser::AST::Node>] nodes
274
+ # @param [String] delimiter
275
+ #
276
+ # @return [undefined]
277
+ #
278
+ # @api private
279
+ #
280
+ def delimited(nodes, delimiter = DEFAULT_DELIMITER, &block)
258
281
  return if nodes.empty?
282
+ block ||= method(:visit)
259
283
  head, *tail = nodes
260
- visit(head)
284
+ block.call(head)
261
285
  tail.each do |node|
262
286
  write(delimiter)
263
- visit(node)
287
+ block.call(node)
264
288
  end
265
289
  end
266
290
 
@@ -401,8 +425,12 @@ module Unparser
401
425
  #
402
426
  # @api private
403
427
  #
428
+ # False positive:
429
+ #
430
+ # rubocop:disable MethodCallParentheses
431
+ #
404
432
  def indented
405
- buffer = self.buffer
433
+ buffer = buffer()
406
434
  buffer.indent
407
435
  nl
408
436
  yield
@@ -438,9 +466,9 @@ module Unparser
438
466
  #
439
467
  def visit_indented(node)
440
468
  if NOINDENT.include?(node.type)
441
- visit(node)
469
+ visit_plain(node)
442
470
  else
443
- indented { visit(node) }
471
+ indented { visit_plain(node) }
444
472
  end
445
473
  end
446
474
 
@@ -19,14 +19,13 @@ module Unparser
19
19
  # @api private
20
20
  #
21
21
  def dispatch
22
- parentheses do
23
- visit(body)
24
- end
22
+ visit_parentheses(body)
25
23
  end
26
24
  end # ArgExpr
27
25
 
28
26
  # Arguments emitter
29
27
  class Arguments < self
28
+ include Terminated
30
29
 
31
30
  handle :args
32
31
 
@@ -54,13 +53,7 @@ module Unparser
54
53
  # @api private
55
54
  #
56
55
  def normal_arguments
57
- children.reject(&SHADOWARGS).map do |child|
58
- if child.type.equal?(:mlhs)
59
- Parser::AST::Node.new(:arg_expr, [child])
60
- else
61
- child
62
- end
63
- end
56
+ children.reject(&SHADOWARGS)
64
57
  end
65
58
 
66
59
  # Return shadow args
@@ -76,10 +69,17 @@ module Unparser
76
69
 
77
70
  end # Arguments
78
71
 
79
- # Emitter for block arguments
80
- class Blockarg < self
72
+ # Emitter for block and kwrestarg arguments
73
+ class Morearg < self
74
+ include Terminated
75
+
76
+ MAP = {
77
+ blockarg: T_AMP,
78
+ kwrestarg: T_DSPLAT
79
+ }
81
80
 
82
81
  handle :blockarg
82
+ handle :kwrestarg
83
83
 
84
84
  children :name
85
85
 
@@ -92,13 +92,14 @@ module Unparser
92
92
  # @api private
93
93
  #
94
94
  def dispatch
95
- write(T_AMP, name.to_s)
95
+ write(MAP.fetch(node_type), name.to_s)
96
96
  end
97
97
 
98
98
  end # Blockarg
99
99
 
100
100
  # Optional argument emitter
101
101
  class Optarg < self
102
+ include Terminated
102
103
 
103
104
  handle :optarg
104
105
 
@@ -118,28 +119,10 @@ module Unparser
118
119
  end
119
120
  end
120
121
 
121
- # Keyword rest argument emitter
122
- class KeywordRest < self
123
-
124
- handle :kwrestarg
125
-
126
- children :name
127
-
128
- private
129
-
130
- # Perform dispatch
131
- #
132
- # @return [undefined]
133
- #
134
- # @api private
135
- #
136
- def dispatch
137
- write(T_DSPLAT, name.to_s)
138
- end
139
- end # KeywordRest
140
-
141
122
  # Optional keyword argument emitter
142
123
  class KeywordOptional < self
124
+ include Terminated
125
+
143
126
  handle :kwoptarg
144
127
 
145
128
  children :name, :value
@@ -161,6 +144,8 @@ module Unparser
161
144
 
162
145
  # Keyword argument emitter
163
146
  class Kwarg < self
147
+ include Terminated
148
+
164
149
  handle :kwarg
165
150
 
166
151
  children :name
@@ -181,6 +166,7 @@ module Unparser
181
166
 
182
167
  # Rest argument emitter
183
168
  class Restarg < self
169
+ include Terminated
184
170
 
185
171
  handle :restarg
186
172
 
@@ -202,6 +188,7 @@ module Unparser
202
188
 
203
189
  # Argument emitter
204
190
  class Argument < self
191
+ include Terminated
205
192
 
206
193
  handle :arg, :shadowarg
207
194
 
@@ -223,6 +210,7 @@ module Unparser
223
210
 
224
211
  # Block pass node emitter
225
212
  class BlockPass < self
213
+ include Terminated
226
214
 
227
215
  handle :block_pass
228
216
 
@@ -238,7 +226,7 @@ module Unparser
238
226
  #
239
227
  def dispatch
240
228
  write(T_AMP)
241
- visit_terminated(name)
229
+ visit(name)
242
230
  end
243
231
 
244
232
  end # BlockPass
@@ -22,6 +22,18 @@ module Unparser
22
22
  # Single assignment emitter
23
23
  class Single < self
24
24
 
25
+ # Test for terminated emit
26
+ #
27
+ # @return [Boolean]
28
+ #
29
+ # @api private
30
+ #
31
+ def terminated?
32
+ right_node.nil?
33
+ end
34
+
35
+ private
36
+
25
37
  # Emit right
26
38
  #
27
39
  # @return [undefined]
@@ -86,6 +98,7 @@ module Unparser
86
98
 
87
99
  # Multiple assignment
88
100
  class Multiple < self
101
+ include Unterminated
89
102
 
90
103
  handle :masgn
91
104
 
@@ -100,7 +113,7 @@ module Unparser
100
113
  # @api private
101
114
  #
102
115
  def emit_left
103
- visit(first_child)
116
+ visit_plain(first_child)
104
117
  end
105
118
 
106
119
  # Emit right
@@ -127,12 +140,14 @@ module Unparser
127
140
 
128
141
  # Emitter for multiple assignment left hand side
129
142
  class MLHS < Emitter
143
+ include Unterminated
130
144
 
131
145
  handle :mlhs
132
146
 
133
147
  private
134
148
 
135
- NO_COMMA = [:splat, :restarg, :mlhs].to_set.freeze
149
+ NO_COMMA = [:splat, :restarg].to_set.freeze
150
+ PARENT_MLHS = [:mlhs, :masgn]
136
151
 
137
152
  # Perform dispatch
138
153
  #
@@ -141,11 +156,19 @@ module Unparser
141
156
  # @api private
142
157
  #
143
158
  def dispatch
144
- conditional_parentheses(parent_type.equal?(:mlhs)) do
145
- delimited(children)
146
- end
159
+ delimited(children)
160
+
161
+ write(',') if children.one? && mlhs?
162
+ end
147
163
 
148
- write(',') if children.one? && !NO_COMMA.include?(children.first.type) && !parent_type.equal?(:arg_expr)
164
+ # Test for mlhs context
165
+ #
166
+ # @return [undefined]
167
+ #
168
+ # @api private
169
+ #
170
+ def mlhs?
171
+ !NO_COMMA.include?(first_child.type) && PARENT_MLHS.include?(parent_type)
149
172
  end
150
173
 
151
174
  end # MLHS
@@ -17,7 +17,10 @@ module Unparser
17
17
  # @api private
18
18
  #
19
19
  def emit_inner
20
- delimited(children, NL)
20
+ children.each_with_index do |child, index|
21
+ visit_plain(child)
22
+ write(NL) if index < children.length - 1
23
+ end
21
24
  end
22
25
 
23
26
  # Emitter for implicit begins
@@ -25,8 +28,6 @@ module Unparser
25
28
 
26
29
  handle :begin
27
30
 
28
- NON_EMPTY_PARENS = [:root, :dstr, :dyn_str_body].to_set.freeze
29
-
30
31
  # Test if begin is terminated
31
32
  #
32
33
  # @return [Boolean]
@@ -34,9 +35,11 @@ module Unparser
34
35
  # @api private
35
36
  #
36
37
  def terminated?
37
- children.empty? && !NON_EMPTY_PARENS.include?(parent_type)
38
+ children.empty?
38
39
  end
39
40
 
41
+ TERMINATING_PARENT = [:root, :dyn_str_body].to_set.freeze
42
+
40
43
  private
41
44
 
42
45
  # Perform dispatch
@@ -46,12 +49,10 @@ module Unparser
46
49
  # @api private
47
50
  #
48
51
  def dispatch
49
- if terminated?
52
+ if terminated? && !TERMINATING_PARENT.include?(parent_type)
50
53
  write('()')
51
54
  else
52
- conditional_parentheses(parent_type.equal?(:optarg)) do
53
- emit_inner
54
- end
55
+ emit_inner
55
56
  end
56
57
  end
57
58
 
@@ -59,6 +60,7 @@ module Unparser
59
60
 
60
61
  # Emitter for explicit begins
61
62
  class Explicit < self
63
+ include Terminated
62
64
 
63
65
  handle :kwbegin
64
66