ruby2ruby 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,16 @@
1
+ == 1.1.4 / 2007-01-15
2
+
3
+ * 4 minor enhancements:
4
+ * Added some extra rewriting code and tests for various bmethods. Ugh.
5
+ * Added support for splatted block args.
6
+ * Refactored class/module and dsym/dstr.
7
+ * Short if/unless statements are now post-conditional expressions.
8
+ * 4 bug fixes:
9
+ * Finally fixed eric's nebulous proc code-in-goalposts bug.
10
+ * Fixed dasgn_curr so block's dasgn vars decl goes away (bug 7420).
11
+ * Fixed dmethod. I think the tests were bogus before.
12
+ * Fixed improper end in method rescues (bug 7396).
13
+
1
14
  == 1.1.3 / 2006-12-20
2
15
 
3
16
  * 1 minor enhancement
data/Rakefile CHANGED
@@ -1,5 +1,9 @@
1
1
  # -*- ruby -*-
2
2
 
3
+ dirs = %w(../../ParseTree/dev/lib ../../ParseTree/dev/test:lib)
4
+ $:.push(*dirs)
5
+ ENV['RUBY_FLAGS'] = "-I" + dirs.join(":")
6
+
3
7
  require 'rubygems'
4
8
  require 'hoe'
5
9
  require './lib/ruby2ruby.rb'
@@ -10,6 +14,7 @@ Hoe.new('ruby2ruby', RubyToRuby::VERSION) do |p|
10
14
  p.description = p.paragraphs_of('README.txt', 2).join
11
15
  p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1].map {|u| u.strip }
12
16
  p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
17
+ p.clean_globs << File.expand_path("~/.ruby_inline")
13
18
  p.extra_deps << "ParseTree"
14
19
  end
15
20
 
data/lib/ruby2ruby.rb CHANGED
@@ -11,7 +11,7 @@ class NilClass # Objective-C trick
11
11
  end
12
12
 
13
13
  class RubyToRuby < SexpProcessor
14
- VERSION = '1.1.3'
14
+ VERSION = '1.1.4'
15
15
 
16
16
  def self.translate(klass_or_str, method = nil)
17
17
  self.new.process(ParseTree.translate(klass_or_str, method))
@@ -148,18 +148,11 @@ class RubyToRuby < SexpProcessor
148
148
  result = []
149
149
 
150
150
  until exp.empty? do
151
- found = exp.first.first == :block_arg rescue false
152
-
153
- if found then
154
- raise "wtf"
155
- result[-1] = result[-1][0..-2] + ", #{process(exp.shift)})"
151
+ code = exp.shift
152
+ if code.nil? or code.first == :nil then
153
+ result << "# do nothing"
156
154
  else
157
- code = exp.shift
158
- if code.nil? or code.first == :nil then
159
- result << "# do nothing"
160
- else
161
- result << process(code)
162
- end
155
+ result << process(code)
163
156
  end
164
157
  end
165
158
 
@@ -236,23 +229,7 @@ class RubyToRuby < SexpProcessor
236
229
  end
237
230
 
238
231
  def process_class(exp)
239
- s = "class #{exp.shift}"
240
- superk = process(exp.shift)
241
-
242
- s << " < #{superk}" if superk
243
- s << "\n"
244
-
245
- body = []
246
- begin
247
- code = process(exp.shift).chomp
248
- body << code unless code.nil? or code.empty?
249
- end until exp.empty?
250
- unless body.empty? then
251
- body = indent(body.join("\n\n")) + "\n"
252
- else
253
- body = ""
254
- end
255
- s + body + "end"
232
+ "class #{util_module_or_class(exp, true)}"
256
233
  end
257
234
 
258
235
  def process_colon2(exp)
@@ -279,10 +256,23 @@ class RubyToRuby < SexpProcessor
279
256
  "#{exp.shift} = #{process(exp.shift)}"
280
257
  end
281
258
 
259
+ # (a, lit1) => "a = 1"
260
+ # (a, (b, lit2)) => "a = b = 2"
261
+ # (a, (b)) => ""
262
+
282
263
  def process_dasgn_curr(exp)
283
- s = exp.shift.to_s
284
- s += "=" + process(exp.shift) unless exp.empty?
285
- s
264
+ lhs = exp.shift.to_s
265
+ rhs = exp.shift
266
+ return lhs if rhs.nil?
267
+ return "#{lhs} = #{process rhs}" unless rhs.first == :dasgn_curr
268
+
269
+ # keep recursing. ensure that the leaf node assigns to _something_
270
+ rhs = process rhs
271
+ if rhs =~ /=/ then
272
+ "#{lhs} = #{rhs}"
273
+ else
274
+ ""
275
+ end
286
276
  end
287
277
 
288
278
  def process_dasgn(exp)
@@ -374,16 +364,7 @@ class RubyToRuby < SexpProcessor
374
364
  end
375
365
 
376
366
  def process_dsym(exp)
377
- s = ":" + exp.shift.dump[0..-2]
378
- until exp.empty?
379
- pt = exp.shift
380
- if pt.first == :str
381
- s << process(pt)[1..-2]
382
- else
383
- s << '#{' + process(pt) + '}'
384
- end
385
- end
386
- s + '"'
367
+ ":" + process_dstr(exp)
387
368
  end
388
369
 
389
370
  def process_dvar(exp)
@@ -466,11 +447,17 @@ class RubyToRuby < SexpProcessor
466
447
  f = process exp.shift
467
448
 
468
449
  if t then
450
+ unless f then
451
+ r = "#{t} if #{c}"
452
+ return r if (@indent+r).size < 78 and r !~ /\n/
453
+ end
469
454
  r = "if #{c} then\n#{indent(t)}\n"
470
455
  r << "else\n#{indent(f)}\n" if f
471
456
  r << "end"
472
457
  r
473
458
  else
459
+ r = "#{f} unless #{c}"
460
+ return r if (@indent+r).size < 78 and r !~ /\n/
474
461
  "unless #{c} then\n#{indent(f)}\nend"
475
462
  end
476
463
  end
@@ -493,7 +480,7 @@ class RubyToRuby < SexpProcessor
493
480
  result << " |#{args}|" if args
494
481
  if body then
495
482
  result << "\n"
496
- result << indent(body).chomp
483
+ result << indent(body.strip)
497
484
  result << "\n"
498
485
  else
499
486
  result << ' '
@@ -561,18 +548,7 @@ class RubyToRuby < SexpProcessor
561
548
  end
562
549
 
563
550
  def process_module(exp)
564
- s = "module #{exp.shift}\n"
565
- body = []
566
- begin
567
- code = process exp.shift
568
- body << code unless code.nil? or code.empty?
569
- end until exp.empty?
570
- unless body.empty? then
571
- body = indent(body.join("\n\n")) + "\n"
572
- else
573
- body = ""
574
- end
575
- s + body + "end"
551
+ "module #{util_module_or_class(exp)}"
576
552
  end
577
553
 
578
554
  def process_next(exp)
@@ -697,7 +673,7 @@ class RubyToRuby < SexpProcessor
697
673
  code << "else"
698
674
  code << indent(els)
699
675
  else
700
- code << "end\n"
676
+ code << "end\n" unless stack.first == "process_block"
701
677
  end
702
678
  code.join("\n")
703
679
  else # a rescue b and others
@@ -845,6 +821,12 @@ class RubyToRuby < SexpProcessor
845
821
  rewrite_defn(exp)
846
822
  end
847
823
 
824
+ # s(:defn, :name, s(:scope, s(:block, s(:args, ...), ...)))
825
+ # s(:defn, :name, s(:bmethod, s(:masgn, s(:dasgn_curr, :args)), s(:block, ...)))
826
+ # s(:defn, :name, s(:fbody, s(:bmethod, s(:masgn, s(:dasgn_curr, :params)), s(:block, ...))))
827
+ # =>
828
+ # s(:defn, :name, s(:args, ...), s(:scope, s:(block, ...)))
829
+
848
830
  def rewrite_defn(exp)
849
831
  # REFACTOR this needs help now
850
832
  exp.shift # :defn
@@ -861,18 +843,38 @@ class RubyToRuby < SexpProcessor
861
843
  assert_type body[1], :block
862
844
  when :scope, :fbody then
863
845
  body = body[1] if body.first == :fbody
864
- args = body.last.delete_at 1
865
- assert_type args, :args
866
- assert_type body, :scope
867
- assert_type body[1], :block
868
-
869
- if body[1][1].first == :block_arg then
870
- block_arg = body[1].delete_at 1
871
- args << block_arg
846
+ case body.first
847
+ when :scope then
848
+ args = body.block.args(true)
849
+ assert_type body, :scope
850
+ assert_type body[1], :block
851
+
852
+ if body[1][1].first == :block_arg then
853
+ block_arg = body[1].delete_at 1
854
+ args << block_arg
855
+ end
856
+ when :bmethod then
857
+ body[0] = :scope
858
+ body.block.delete_at(1) # nuke the decl # REFACTOR
859
+ masgn = body.masgn(true)
860
+ if masgn then
861
+ splat = :"*#{masgn[-1][-1]}"
862
+ args.push(splat)
863
+ else
864
+ dasgn_curr = body.dasgn_curr(true)
865
+ if dasgn_curr then
866
+ arg = :"*#{dasgn_curr[-1]}"
867
+ args.push(arg)
868
+ end
869
+ end
870
+ body.find_and_replace_all(:dvar, :lvar)
871
+ else
872
+ raise "no: #{body.first} / #{body.inspect}"
872
873
  end
873
874
  when :bmethod then
874
875
  body.shift # :bmethod
875
- if body.first.first == :dasgn_curr then
876
+ case body.first.first
877
+ when :dasgn_curr then
876
878
  # WARN: there are some implications here of having an empty
877
879
  # :args below namely, "proc { || " does not allow extra args
878
880
  # passed in.
@@ -881,7 +883,15 @@ class RubyToRuby < SexpProcessor
881
883
  dasgn.shift # type
882
884
  args.push(*dasgn)
883
885
  body.find_and_replace_all(:dvar, :lvar)
886
+ when :masgn then
887
+ dasgn = body.masgn(true)
888
+ # DAMNIT body.block.dasgn_curr(true) - multiple values so can't use
889
+ body.block.delete_at(1) # nuke the decl
890
+ splat = :"*#{dasgn[-1][-1]}"
891
+ args.push(splat)
892
+ body.find_and_replace_all(:dvar, :lvar)
884
893
  end
894
+
885
895
  if body.first.first == :block then
886
896
  body = s(:scope, body.shift)
887
897
  else
@@ -890,12 +900,9 @@ class RubyToRuby < SexpProcessor
890
900
  when :dmethod
891
901
  # BEFORE: [:defn, :dmethod_added, [:dmethod, :bmethod_maker, ...]]
892
902
  # AFTER: [:defn, :dmethod_added, ...]
893
- iter = body[2][1][2] # UGH! FIX
894
- iter.delete_at 1 # fcall define_method
895
- args = iter[1].find_and_replace_all(:dasgn_curr, :args)
896
- iter.delete_at 1 # args
897
- iter[0] = :block
898
- body = s(:scope, iter.find_and_replace_all(:dvar, :lvar))
903
+ body[0] = :scope
904
+ body.delete_at 1 # method name
905
+ args = body.scope.block.args(true)
899
906
  when :ivar, :attrset then
900
907
  # do nothing
901
908
  else
@@ -943,6 +950,29 @@ class RubyToRuby < SexpProcessor
943
950
  ############################################################
944
951
  # Utility Methods:
945
952
 
953
+ def util_module_or_class(exp, is_class=false)
954
+ s = "#{exp.shift}"
955
+
956
+ if is_class then
957
+ superk = process(exp.shift)
958
+ s << " < #{superk}" if superk
959
+ end
960
+
961
+ s << "\n"
962
+
963
+ body = []
964
+ begin
965
+ code = process(exp.shift).chomp
966
+ body << code unless code.nil? or code.empty?
967
+ end until exp.empty?
968
+ unless body.empty? then
969
+ body = indent(body.join("\n\n")) + "\n"
970
+ else
971
+ body = ""
972
+ end
973
+ s + body + "end"
974
+ end
975
+
946
976
  def indent(s)
947
977
  s.to_s.map{|line| @indent + line}.join
948
978
  end
@@ -1003,8 +1033,11 @@ class Proc
1003
1033
  end
1004
1034
 
1005
1035
  def to_ruby
1006
- name = ProcStoreTmp.name
1007
- self.to_method.to_ruby.sub(/def [^\(]+\(([^\)]*)\)/,
1008
- 'proc { |\1|').sub(/end\Z/, '}')
1036
+ ruby = self.to_method.to_ruby
1037
+ ruby.sub!(/\A(def \S+)\(([^\)]*)\)/, '\1 |\2|') # move args
1038
+ ruby.sub!(/\Adef[^\n\|]+/, 'proc { ') # strip def name
1039
+ ruby.sub!(/end\Z/, '}') # strip end
1040
+ ruby.gsub!(/\s+$/, '') # trailing WS bugs me
1041
+ ruby
1009
1042
  end
1010
1043
  end
@@ -10,6 +10,40 @@ class TestRubyToRuby < Test::Unit::TestCase
10
10
  @processor = RubyToRuby.new
11
11
  end
12
12
 
13
+ def test_rewrite_defn_define_method
14
+ inn = s(:defn, :splatted,
15
+ s(:bmethod,
16
+ s(:masgn, s(:dasgn_curr, :args)),
17
+ s(:block,
18
+ s(:dasgn_curr, :y),
19
+ s(:dasgn_curr, :y, s(:call, s(:dvar, :args), :first)),
20
+ s(:call, s(:dvar, :y), :+, s(:array, s(:lit, 42))))))
21
+ out = s(:defn, :splatted,
22
+ s(:args, :"*args"),
23
+ s(:scope,
24
+ s(:block,
25
+ s(:dasgn_curr, :y, s(:call, s(:lvar, :args), :first)),
26
+ s(:call, s(:lvar, :y), :+, s(:array, s(:lit, 42))))))
27
+
28
+ assert_equal out, @processor.rewrite_defn(inn)
29
+ end
30
+
31
+ def test_rewrite_defn_bmethod
32
+ inn = s(:defn, :group,
33
+ s(:fbody,
34
+ s(:bmethod,
35
+ s(:masgn, s(:dasgn_curr, :params)),
36
+ s(:block,
37
+ s(:dasgn_curr, :force_reload, s(:dasgn_curr, :association, s(:dasgn_curr, :retval))),
38
+ s(:lit, 42)))))
39
+ out = s(:defn, :group,
40
+ s(:args, :"*params"),
41
+ s(:scope,
42
+ s(:block, s(:lit, 42))))
43
+
44
+ assert_equal out, @processor.rewrite_defn(inn)
45
+ end
46
+
13
47
  def test_rewrite_resbody
14
48
  inn = [:resbody,
15
49
  [:array, [:const, :SyntaxError]],
@@ -60,7 +94,15 @@ class TestRubyToRuby < Test::Unit::TestCase
60
94
  end
61
95
 
62
96
  # Self-Translation: 1st Generation
63
- eval RubyToRuby.translate(RubyToRuby).sub("RubyToRuby", "RubyToRuby2")
97
+ ruby = RubyToRuby.translate(RubyToRuby).sub("RubyToRuby", "RubyToRuby2")
98
+ begin
99
+ eval ruby
100
+ rescue SyntaxError => e
101
+ puts "SyntaxError: #{e.message}"
102
+ puts
103
+ puts ruby
104
+ exit 1
105
+ end
64
106
 
65
107
  class TestRubyToRuby2 < TestRubyToRuby
66
108
  def setup
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.0.9
3
3
  specification_version: 1
4
4
  name: ruby2ruby
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.1.3
7
- date: 2006-12-20 00:00:00 -08:00
6
+ version: 1.1.4
7
+ date: 2007-01-15 00:00:00 -08:00
8
8
  summary: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps.
9
9
  require_paths:
10
10
  - lib
@@ -49,20 +49,20 @@ requirements: []
49
49
 
50
50
  dependencies:
51
51
  - !ruby/object:Gem::Dependency
52
- name: hoe
52
+ name: ParseTree
53
53
  version_requirement:
54
54
  version_requirements: !ruby/object:Gem::Version::Requirement
55
55
  requirements:
56
- - - ">="
56
+ - - ">"
57
57
  - !ruby/object:Gem::Version
58
- version: 1.1.4
58
+ version: 0.0.0
59
59
  version:
60
60
  - !ruby/object:Gem::Dependency
61
- name: ParseTree
61
+ name: hoe
62
62
  version_requirement:
63
63
  version_requirements: !ruby/object:Gem::Version::Requirement
64
64
  requirements:
65
- - - ">"
65
+ - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: 0.0.0
67
+ version: 1.1.7
68
68
  version: