ruby2ruby 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
data/History.txt CHANGED
@@ -1,3 +1,22 @@
1
+ === 1.3.1 / 2011-09-22
2
+
3
+ * 1 minor enhancement:
4
+
5
+ * Added parenthesize to add parens in certain contexts.
6
+
7
+ * 10 bug fixes:
8
+
9
+ * Add newline to 'do nothing' comment in a block... seems contrived. (andreacampi)
10
+ * Binary operations not work properly with some complex statements. (smorss)
11
+ * Fixed if statements with no body (smorss)
12
+ * Fixed logic for call with hash args in various locations (smorss)
13
+ * Fixed match3 on an assignment. (smorss)
14
+ * Fixed multiple nested rescue/ensure exprs (larsch)
15
+ * Fixed process_alias to parenthesize (smorss)
16
+ * Fixed process_and to parenthenize only when it makes sense.
17
+ * Fixed rescue with 2+ statements in resbody (smorss)
18
+ * Regexps with options other than /o were not showing flags. (smorss)
19
+
1
20
  === 1.3.0 / 2011-09-01
2
21
 
3
22
  * 1 minor enhancement:
data/lib/ruby2ruby.rb CHANGED
@@ -3,14 +3,36 @@
3
3
  require 'rubygems'
4
4
  require 'sexp_processor'
5
5
 
6
+ # REFACTOR: stolen from ruby_parser
7
+ class Regexp
8
+ unless defined? ENC_NONE then
9
+ ENC_NONE = /x/n.options
10
+ ENC_EUC = /x/e.options
11
+ ENC_SJIS = /x/s.options
12
+ ENC_UTF8 = /x/u.options
13
+
14
+ CODES = {
15
+ EXTENDED => 'x',
16
+ IGNORECASE => 'i',
17
+ MULTILINE => 'm',
18
+ ENC_NONE => 'n',
19
+ ENC_EUC => 'e',
20
+ ENC_SJIS => 's',
21
+ ENC_UTF8 => 'u',
22
+ }
23
+ end
24
+ end
25
+
6
26
  class Ruby2Ruby < SexpProcessor
7
- VERSION = '1.3.0'
27
+ VERSION = '1.3.1'
8
28
  LINE_LENGTH = 78
9
29
 
10
30
  BINARY = [:<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>>, :**]
11
31
 
12
32
  ##
13
33
  # Nodes that represent assignment and probably need () around them.
34
+ #
35
+ # TODO: this should be replaced with full precedence support :/
14
36
 
15
37
  ASSIGN_NODES = [
16
38
  :dasgn,
@@ -24,6 +46,7 @@ class Ruby2Ruby < SexpProcessor
24
46
  :op_asgn_and,
25
47
  :op_asgn_or,
26
48
  :return,
49
+ :if, # HACK
27
50
  ]
28
51
 
29
52
  def initialize
@@ -42,11 +65,11 @@ class Ruby2Ruby < SexpProcessor
42
65
  # Processors
43
66
 
44
67
  def process_alias(exp)
45
- "alias #{process(exp.shift)} #{process(exp.shift)}"
68
+ parenthesize "alias #{process(exp.shift)} #{process(exp.shift)}"
46
69
  end
47
70
 
48
71
  def process_and(exp)
49
- "(#{process exp.shift} and #{process exp.shift})"
72
+ parenthesize "#{process exp.shift} and #{process exp.shift}"
50
73
  end
51
74
 
52
75
  def process_arglist(exp) # custom made node
@@ -118,7 +141,7 @@ class Ruby2Ruby < SexpProcessor
118
141
  code << "begin"
119
142
  until exp.empty?
120
143
  src = process(exp.shift)
121
- src = indent(src) unless src =~ /(^|\n)rescue/ # ensure no level 0 rescues
144
+ src = indent(src) unless src =~ /(^|\n)(rescue|ensure)/ # ensure no level 0 rescues
122
145
  code << src
123
146
  end
124
147
  code << "end"
@@ -132,24 +155,27 @@ class Ruby2Ruby < SexpProcessor
132
155
  until exp.empty? do
133
156
  code = exp.shift
134
157
  if code.nil? or code.first == :nil then
135
- result << "# do nothing"
158
+ result << "# do nothing\n"
136
159
  else
137
160
  result << process(code)
138
161
  end
139
162
  end
140
163
 
141
- result = result.join "\n"
142
-
143
- result = case self.context[1]
144
- when nil, :scope, :if, :iter, :resbody, :when, :while then
145
- result + "\n"
146
- else
147
- "(#{result})"
148
- end
164
+ result = parenthesize result.join "\n"
165
+ result += "\n" unless result.start_with? "("
149
166
 
150
167
  return result
151
168
  end
152
169
 
170
+ def parenthesize exp
171
+ case self.context[1]
172
+ when nil, :scope, :if, :iter, :resbody, :when, :while then
173
+ exp
174
+ else
175
+ "(#{exp})"
176
+ end
177
+ end
178
+
153
179
  def process_block_pass exp
154
180
  raise "huh?: #{exp.inspect}" if exp.size > 1
155
181
 
@@ -169,9 +195,7 @@ class Ruby2Ruby < SexpProcessor
169
195
  def process_call(exp)
170
196
  receiver_node_type = exp.first.nil? ? nil : exp.first.first
171
197
  receiver = process exp.shift
172
-
173
- receiver = "(#{receiver})" if
174
- Ruby2Ruby::ASSIGN_NODES.include? receiver_node_type
198
+ receiver = "(#{receiver})" if ASSIGN_NODES.include? receiver_node_type
175
199
 
176
200
  name = exp.shift
177
201
  args = []
@@ -183,8 +207,20 @@ class Ruby2Ruby < SexpProcessor
183
207
 
184
208
  in_context :arglist do
185
209
  until exp.empty? do
210
+ arg_type = exp.first.sexp_type
186
211
  arg = process exp.shift
187
- args << arg unless arg.empty?
212
+
213
+ next if arg.empty?
214
+
215
+ strip_hash = (arg_type == :hash and
216
+ not BINARY.include? name and
217
+ (exp.empty? or exp.first.sexp_type == :splat))
218
+ wrap_arg = Ruby2Ruby::ASSIGN_NODES.include? arg_type
219
+
220
+ arg = arg[2..-3] if strip_hash
221
+ arg = "(#{arg})" if wrap_arg
222
+
223
+ args << arg
188
224
  end
189
225
  end
190
226
 
@@ -332,8 +368,15 @@ class Ruby2Ruby < SexpProcessor
332
368
  "(#{process exp.shift}...#{process exp.shift})"
333
369
  end
334
370
 
371
+ def re_opt options
372
+ bits = (0..8).map { |n| options[n] * 2**n }
373
+ bits.delete 0
374
+ bits.map { |n| Regexp::CODES[n] }.join
375
+ end
376
+
335
377
  def process_dregx(exp)
336
- "/" << util_dthing(:dregx, exp) << "/"
378
+ options = re_opt exp.pop if Fixnum === exp.last
379
+ "/" << util_dthing(:dregx, exp) << "/#{options}"
337
380
  end
338
381
 
339
382
  def process_dregx_once(exp)
@@ -357,8 +400,10 @@ class Ruby2Ruby < SexpProcessor
357
400
  ens = exp.shift
358
401
  ens = nil if ens == s(:nil)
359
402
  ens = process(ens) || "# do nothing"
403
+ ens = "begin\n#{ens}\nend\n" if ens =~ /(^|\n)rescue/
360
404
 
361
405
  body.sub!(/\n\s*end\z/, '')
406
+ body = indent(body) unless body =~ /(^|\n)rescue/
362
407
 
363
408
  return "#{body}\nensure\n#{indent ens}"
364
409
  end
@@ -401,6 +446,7 @@ class Ruby2Ruby < SexpProcessor
401
446
 
402
447
  def process_hash(exp)
403
448
  result = []
449
+
404
450
  until exp.empty?
405
451
  lhs = process(exp.shift)
406
452
  rhs = exp.shift
@@ -411,21 +457,7 @@ class Ruby2Ruby < SexpProcessor
411
457
  result << "#{lhs} => #{rhs}"
412
458
  end
413
459
 
414
- case self.context[1]
415
- when :arglist, :argscat then
416
- unless result.empty? then
417
- # HACK - this will break w/ 2 hashes as args
418
- if BINARY.include? @calls.last then
419
- return "{ #{result.join(', ')} }"
420
- else
421
- return "#{result.join(', ')}"
422
- end
423
- else
424
- return "{}"
425
- end
426
- else
427
- return "{ #{result.join(', ')} }"
428
- end
460
+ return "{ #{result.join(', ')} }"
429
461
  end
430
462
 
431
463
  def process_iasgn(exp)
@@ -461,12 +493,15 @@ class Ruby2Ruby < SexpProcessor
461
493
  r << "end"
462
494
 
463
495
  r
464
- else
496
+ elsif f
465
497
  unless expand then
466
498
  r = "#{f} unless #{c}"
467
499
  return r if (@indent+r).size < LINE_LENGTH and r !~ /\n/
468
500
  end
469
501
  "unless #{c} then\n#{indent(f)}\nend"
502
+ else
503
+ # empty if statement, just do it in case of side effects from condition
504
+ "if #{c} then\n#{indent '# do nothing'}\nend"
470
505
  end
471
506
  end
472
507
 
@@ -587,8 +622,14 @@ class Ruby2Ruby < SexpProcessor
587
622
 
588
623
  def process_match3(exp)
589
624
  rhs = process(exp.shift)
625
+ left_type = exp.first.sexp_type
590
626
  lhs = process(exp.shift)
591
- "#{lhs} =~ #{rhs}"
627
+
628
+ if ASSIGN_NODES.include? left_type then
629
+ "(#{lhs}) =~ #{rhs}"
630
+ else
631
+ "#{lhs} =~ #{rhs}"
632
+ end
592
633
  end
593
634
 
594
635
  def process_module(exp)
@@ -681,12 +722,14 @@ class Ruby2Ruby < SexpProcessor
681
722
  els = process(exp.pop) unless exp.last.first == :resbody
682
723
 
683
724
  body ||= "# do nothing"
684
- simple = exp.size == 1
725
+ simple = exp.size == 1 && !exp.resbody.block
726
+
685
727
 
686
728
  resbodies = []
687
729
  until exp.empty? do
688
730
  resbody = exp.shift
689
- simple &&= resbody[1] == s(:array) && resbody[2] != nil
731
+ simple &&= resbody[1] == s(:array)
732
+ simple &&= resbody[2] != nil && resbody[2].node_type != :block
690
733
  resbodies << process(resbody)
691
734
  end
692
735
 
@@ -866,9 +909,10 @@ class Ruby2Ruby < SexpProcessor
866
909
  def rewrite_rescue exp
867
910
  complex = false
868
911
  complex ||= exp.size > 3
869
- complex ||= exp.block
912
+ complex ||= exp.resbody.block
870
913
  complex ||= exp.find_nodes(:resbody).any? { |n| n[1] != s(:array) }
871
914
  complex ||= exp.find_nodes(:resbody).any? { |n| n.last.nil? }
915
+ complex ||= exp.find_nodes(:resbody).any? { |n| n[2] and n[2].node_type == :block }
872
916
 
873
917
  handled = context.first == :ensure
874
918
 
@@ -924,8 +968,7 @@ class Ruby2Ruby < SexpProcessor
924
968
  raise "unknown type: #{pt.inspect}"
925
969
  end
926
970
  else
927
- # HACK: raise "huh?: #{pt.inspect}" -- hitting # constants in regexps
928
- # do nothing for now
971
+ raise "unhandled value in d-thing: #{pt.inspect}"
929
972
  end
930
973
  end
931
974
 
@@ -72,6 +72,12 @@ class TestRuby2Ruby < R2RTestCase
72
72
  assert_equal exp, eval(out)
73
73
  end
74
74
 
75
+ def test_and_alias
76
+ inn = s(:and, s(:true), s(:alias, s(:lit, :a), s(:lit, :b)))
77
+ out = "true and (alias :a :b)"
78
+ util_compare inn, out
79
+ end
80
+
75
81
  def test_dregx_slash
76
82
  inn = util_thingy(:dregx)
77
83
  out = '/a"b#{(1 + 1)}c"d\/e/'
@@ -103,6 +109,51 @@ class TestRuby2Ruby < R2RTestCase
103
109
  "self[42] = 24")
104
110
  end
105
111
 
112
+ def test_call_arglist_hash_first
113
+ inn = s(:call, nil, :method,
114
+ s(:arglist,
115
+ s(:hash, s(:lit, :a), s(:lit, 1)),
116
+ s(:call, nil, :b, s(:arglist))))
117
+ out = "method({ :a => 1 }, b)"
118
+
119
+ util_compare inn, out
120
+ end
121
+
122
+ def test_call_arglist_hash_first_last
123
+ inn = s(:call, nil, :method,
124
+ s(:arglist,
125
+ s(:hash, s(:lit, :a), s(:lit, 1)),
126
+ s(:call, nil, :b, s(:arglist)),
127
+ s(:hash, s(:lit, :c), s(:lit, 1))))
128
+ out = "method({ :a => 1 }, b, :c => 1)"
129
+
130
+ util_compare inn, out
131
+ end
132
+
133
+ def test_call_arglist_hash_last
134
+ inn = s(:call, nil, :method,
135
+ s(:arglist,
136
+ s(:call, nil, :b, s(:arglist)),
137
+ s(:hash, s(:lit, :a), s(:lit, 1))))
138
+ out = "method(b, :a => 1)"
139
+
140
+ util_compare inn, out
141
+ end
142
+
143
+ def test_call_arglist_if
144
+ inn = s(:call,
145
+ s(:call, nil, :a, s(:arglist)),
146
+ :+,
147
+ s(:arglist,
148
+ s(:if,
149
+ s(:call, nil, :b, s(:arglist)),
150
+ s(:call, nil, :c, s(:arglist)),
151
+ s(:call, nil, :d, s(:arglist)))))
152
+
153
+ out = "(a + (b ? (c) : (d)))"
154
+ util_compare inn, out
155
+ end
156
+
106
157
  def test_masgn_wtf
107
158
  inn = s(:block,
108
159
  s(:masgn,
@@ -124,7 +175,6 @@ class TestRuby2Ruby < R2RTestCase
124
175
  util_compare inn, out
125
176
  end
126
177
 
127
-
128
178
  def test_masgn_splat_wtf
129
179
  inn = s(:masgn,
130
180
  s(:array, s(:lasgn, :k), s(:lasgn, :v)),
@@ -138,6 +188,13 @@ class TestRuby2Ruby < R2RTestCase
138
188
  util_compare inn, out
139
189
  end
140
190
 
191
+ def test_match3_asgn
192
+ inn = s(:match3, s(:lit, //), s(:lasgn, :y, s(:call, nil, :x, s(:arglist))))
193
+ out = "(y = x) =~ //"
194
+ # "y = x =~ //", which matches on x and assigns to y (not what sexp says).
195
+ util_compare inn, out
196
+ end
197
+
141
198
  def test_splat_call
142
199
  inn = s(:call, nil, :x,
143
200
  s(:arglist,
@@ -151,6 +208,19 @@ class TestRuby2Ruby < R2RTestCase
151
208
  util_compare inn, out
152
209
  end
153
210
 
211
+ def test_resbody_block
212
+ inn = s(:rescue,
213
+ s(:call, nil, :x1, s(:arglist)),
214
+ s(:resbody,
215
+ s(:array),
216
+ s(:block,
217
+ s(:call, nil, :x2, s(:arglist)),
218
+ s(:call, nil, :x3, s(:arglist)))))
219
+
220
+ out = "begin\n x1\nrescue\n x2\n x3\nend"
221
+ util_compare inn, out
222
+ end
223
+
154
224
  def test_resbody_short_with_begin_end
155
225
  # "begin; blah; rescue; []; end"
156
226
  inn = s(:rescue,
@@ -160,6 +230,18 @@ class TestRuby2Ruby < R2RTestCase
160
230
  util_compare inn, out
161
231
  end
162
232
 
233
+ def test_regexp_options
234
+ inn = s(:match3,
235
+ s(:dregx,
236
+ "abc",
237
+ s(:evstr, s(:call, nil, :x, s(:arglist))),
238
+ s(:str, "def"),
239
+ 4),
240
+ s(:str, "a"))
241
+ out = '"a" =~ /abc#{x}def/m'
242
+ util_compare inn, out
243
+ end
244
+
163
245
  def test_resbody_short_with_rescue_args
164
246
  inn = s(:rescue,
165
247
  s(:call, nil, :blah, s(:arglist)),
@@ -184,6 +266,12 @@ class TestRuby2Ruby < R2RTestCase
184
266
  util_compare inn, out
185
267
  end
186
268
 
269
+ def test_if_empty
270
+ inn = s(:if, s(:call, nil, :x, s(:arglist)), nil, nil)
271
+ out = "if x then\n # do nothing\nend"
272
+ util_compare inn, out
273
+ end
274
+
187
275
  def test_interpolation_and_escapes
188
276
  # log_entry = " \e[#{message_color}m#{message}\e[0m "
189
277
  inn = s(:lasgn, :log_entry,
@@ -218,6 +306,47 @@ class TestRuby2Ruby < R2RTestCase
218
306
  util_compare inn, out
219
307
  end
220
308
 
309
+ def test_basic_ensure
310
+ inn = s(:ensure, s(:lit, 1), s(:lit, 2))
311
+ out = "begin\n 1\nensure\n 2\nend"
312
+ util_compare inn, out
313
+ end
314
+
315
+ def test_nested_ensure
316
+ inn = s(:ensure, s(:lit, 1), s(:ensure, s(:lit, 2), s(:lit, 3)))
317
+ out = "begin\n 1\nensure\n begin\n 2\n ensure\n 3\n end\nend"
318
+ util_compare inn, out
319
+ end
320
+
321
+ def test_nested_rescue
322
+ inn = s(:ensure, s(:lit, 1), s(:rescue, s(:lit, 2), s(:resbody, s(:array), s(:lit, 3))))
323
+ out = "begin\n 1\nensure\n 2 rescue 3\nend"
324
+ util_compare inn, out
325
+ end
326
+
327
+ def test_nested_rescue_exception
328
+ inn = s(:ensure, s(:lit, 1), s(:rescue, s(:lit, 2), s(:resbody, s(:array, s(:const, :Exception)), s(:lit, 3))))
329
+ out = "begin\n 1\nensure\n begin\n 2\n rescue Exception\n 3\n end\nend"
330
+ util_compare inn, out
331
+ end
332
+
333
+ def test_nested_rescue_exception2
334
+ inn = s(:ensure, s(:rescue, s(:lit, 2), s(:resbody, s(:array, s(:const, :Exception)), s(:lit, 3))), s(:lit, 1))
335
+ out = "begin\n 2\nrescue Exception\n 3\nensure\n 1\nend"
336
+ util_compare inn, out
337
+ end
338
+
339
+ def test_rescue_block
340
+ inn = s(:rescue,
341
+ s(:call, nil, :alpha, s(:arglist)),
342
+ s(:resbody, s(:array),
343
+ s(:block,
344
+ s(:call, nil, :beta, s(:arglist)),
345
+ s(:call, nil, :gamma, s(:arglist)))))
346
+ out = "begin\n alpha\nrescue\n beta\n gamma\nend"
347
+ util_compare inn, out
348
+ end
349
+
221
350
  def util_compare sexp, expected_ruby, expected_eval = nil
222
351
  assert_equal expected_ruby, @processor.process(sexp)
223
352
  assert_equal expected_eval, eval(expected_ruby) if expected_eval
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby2ruby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 0
10
- version: 1.3.0
9
+ - 1
10
+ version: 1.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Davis
@@ -36,7 +36,7 @@ cert_chain:
36
36
  FBHgymkyj/AOSqKRIpXPhjC6
37
37
  -----END CERTIFICATE-----
38
38
 
39
- date: 2011-09-01 00:00:00 Z
39
+ date: 2011-09-22 00:00:00 Z
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sexp_processor
metadata.gz.sig CHANGED
Binary file