unparser 0.1.15 → 0.1.16

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