ruby2ruby 1.2.4 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig ADDED
Binary file
data/.autotest CHANGED
@@ -3,6 +3,9 @@
3
3
  require 'autotest/restart'
4
4
 
5
5
  Autotest.add_hook :initialize do |at|
6
+ at.order = :random
7
+ at.testlib = "minitest/autorun"
8
+
6
9
  at.extra_files << "../../ParseTree/dev/test/pt_testcase.rb"
7
10
  at.extra_files << "../../ParseTree/dev/lib/unified_ruby.rb"
8
11
  at.libs << ":../../sexp_processor/dev/lib:../../ParseTree/dev/lib:../../ParseTree/dev/test"
data/History.txt CHANGED
@@ -1,3 +1,17 @@
1
+ === 1.2.5 / 2010-09-01
2
+
3
+ * 4 minor enhancements:
4
+
5
+ * Added braces to hash args surrounded if in a binary method call.
6
+ * Added rewrite_resbody to double check structure and freak if necessary.
7
+ * Added stress task
8
+ * rewrite_rescue now detects rescue with multiple arguments.
9
+
10
+ * 2 bug fixes:
11
+
12
+ * Fixed dstr/dregex/d* roundtripping problem
13
+ * Fixed up call arg processing to be more correct and to work with the new sexp form
14
+
1
15
  === 1.2.4 / 2009-08-14
2
16
 
3
17
  * 2 bug fixes:
data/Rakefile CHANGED
@@ -20,4 +20,39 @@ Hoe.spec 'ruby2ruby' do
20
20
  extra_dev_deps << ["ParseTree", "~> 3.0"]
21
21
  end
22
22
 
23
+ task :stress do
24
+ $: << "lib"
25
+ $: << "../../ruby_parser/dev/lib"
26
+ require "ruby_parser"
27
+ require "ruby2ruby"
28
+ require "pp"
29
+
30
+ files = Dir["../../*/dev/**/*.rb"]
31
+
32
+ warn "Stress testing against #{files.size} files"
33
+ parser = RubyParser.new
34
+ ruby2ruby = Ruby2Ruby.new
35
+
36
+ bad = {}
37
+
38
+ files.each do |file|
39
+ warn file
40
+ ruby = File.read(file)
41
+
42
+ begin
43
+ sexp = parser.process(ruby, file)
44
+
45
+ # $stderr.puts sexp.pretty_inspect
46
+
47
+ ruby2ruby.process(sexp)
48
+ rescue Interrupt => e
49
+ raise e
50
+ rescue Exception => e
51
+ bad[file] = e
52
+ end
53
+ end
54
+
55
+ pp bad
56
+ end
57
+
23
58
  # vim: syntax=ruby
data/lib/ruby2ruby.rb CHANGED
@@ -4,9 +4,11 @@ require 'rubygems'
4
4
  require 'sexp_processor'
5
5
 
6
6
  class Ruby2Ruby < SexpProcessor
7
- VERSION = '1.2.4'
7
+ VERSION = '1.2.5'
8
8
  LINE_LENGTH = 78
9
9
 
10
+ BINARY = [:<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>>, :**]
11
+
10
12
  ##
11
13
  # Nodes that represent assignment and probably need () around them.
12
14
 
@@ -31,6 +33,8 @@ class Ruby2Ruby < SexpProcessor
31
33
  self.strict = true
32
34
  self.expected = String
33
35
 
36
+ @calls = []
37
+
34
38
  # self.debug[:defn] = /zsuper/
35
39
  end
36
40
 
@@ -170,30 +174,43 @@ class Ruby2Ruby < SexpProcessor
170
174
  Ruby2Ruby::ASSIGN_NODES.include? receiver_node_type
171
175
 
172
176
  name = exp.shift
173
- args = exp.shift rescue nil
177
+ args = []
178
+
179
+ # this allows us to do both old and new sexp forms:
180
+ exp.push(*exp.pop[1..-1]) if exp.size == 1 && exp.first.first == :arglist
181
+
182
+ @calls.push name
183
+
184
+ in_context :arglist do
185
+ until exp.empty? do
186
+ arg = process exp.shift
187
+ args << arg unless arg.empty?
188
+ end
189
+ end
174
190
 
175
191
  case name
176
- when :<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>>, :** then
177
- "(#{receiver} #{name} #{process args})"
192
+ when *BINARY then
193
+ "(#{receiver} #{name} #{args.join(', ')})"
178
194
  when :[] then
179
- receiver = "self" if receiver.nil?
180
- "#{receiver}[#{process args}]"
195
+ receiver ||= "self"
196
+ "#{receiver}[#{args.join(', ')}]"
181
197
  when :[]= then
182
- receiver = "self" if receiver.nil?
183
- lhs = args.pop
184
- "#{receiver}[#{process args}] = #{process lhs}"
198
+ receiver ||= "self"
199
+ rhs = args.pop
200
+ "#{receiver}[#{args.join(', ')}] = #{rhs}"
185
201
  when :"-@" then
186
202
  "-#{receiver}"
187
203
  when :"+@" then
188
204
  "+#{receiver}"
189
205
  else
190
- args = process args
191
- args = nil if args.empty?
192
- args = "(#{args})" if args
193
- receiver = "#{receiver}." if receiver
206
+ args = nil if args.empty?
207
+ args = "(#{args.join(', ')})" if args
208
+ receiver = "#{receiver}." if receiver
194
209
 
195
210
  "#{receiver}#{name}#{args}"
196
211
  end
212
+ ensure
213
+ @calls.pop
197
214
  end
198
215
 
199
216
  def process_case(exp)
@@ -284,7 +301,11 @@ class Ruby2Ruby < SexpProcessor
284
301
  name = exp.shift
285
302
  args = process(exp.shift)
286
303
  args = "" if args == "()"
287
- body = indent(process(exp.shift))
304
+ body = []
305
+ until exp.empty? do
306
+ body << indent(process(exp.shift))
307
+ end
308
+ body = body.join("\n")
288
309
  return "def #{name}#{args}\n#{body}\nend".gsub(/\n\s*\n+/, "\n")
289
310
  else
290
311
  raise "Unknown defn type: #{type1} for #{exp.inspect}"
@@ -312,7 +333,7 @@ class Ruby2Ruby < SexpProcessor
312
333
  end
313
334
 
314
335
  def process_dregx(exp)
315
- "/" << util_dthing(exp, true) << "/"
336
+ "/" << util_dthing(:dregx, exp) << "/"
316
337
  end
317
338
 
318
339
  def process_dregx_once(exp)
@@ -320,15 +341,15 @@ class Ruby2Ruby < SexpProcessor
320
341
  end
321
342
 
322
343
  def process_dstr(exp)
323
- "\"#{util_dthing(exp)}\""
344
+ "\"#{util_dthing(:dstr, exp)}\""
324
345
  end
325
346
 
326
347
  def process_dsym(exp)
327
- ":#{process_dstr(exp)}"
348
+ ":\"#{util_dthing(:dsym, exp)}\""
328
349
  end
329
350
 
330
351
  def process_dxstr(exp)
331
- "`#{process_dstr(exp)[1..-2]}`"
352
+ "`#{util_dthing(:dxstr, exp)}`"
332
353
  end
333
354
 
334
355
  def process_ensure(exp)
@@ -393,7 +414,12 @@ class Ruby2Ruby < SexpProcessor
393
414
  case self.context[1]
394
415
  when :arglist, :argscat then
395
416
  unless result.empty? then
396
- return "#{result.join(', ')}" # HACK - this will break w/ 2 hashes as args
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
397
423
  else
398
424
  return "{}"
399
425
  end
@@ -830,11 +856,18 @@ class Ruby2Ruby < SexpProcessor
830
856
  exp
831
857
  end
832
858
 
859
+ def rewrite_resbody exp
860
+ raise "no exception list in #{exp.inspect}" unless exp.size > 2 && exp[1]
861
+ raise exp[1].inspect if exp[1][0] != :array
862
+ # for now, do nothing, just check and freak if we see an errant structure
863
+ exp
864
+ end
865
+
833
866
  def rewrite_rescue exp
834
867
  complex = false
835
868
  complex ||= exp.size > 3
836
869
  complex ||= exp.block
837
- complex ||= exp.find_nodes(:resbody).any? { |n| n.array != s(:array) }
870
+ complex ||= exp.find_nodes(:resbody).any? { |n| n[1] != s(:array) }
838
871
  complex ||= exp.find_nodes(:resbody).any? { |n| n.last.nil? }
839
872
 
840
873
  handled = context.first == :ensure
@@ -858,27 +891,40 @@ class Ruby2Ruby < SexpProcessor
858
891
  ############################################################
859
892
  # Utility Methods:
860
893
 
861
- def util_dthing(exp, regx = false)
894
+ def dthing_escape type, lit
895
+ lit = lit.gsub(/\n/, '\n')
896
+ case type
897
+ when :dregx then
898
+ lit.gsub(/(\A|[^\\])\//, '\1\/')
899
+ when :dstr, :dsym then
900
+ lit.gsub(/"/, '\"')
901
+ when :dxstr then
902
+ lit.gsub(/`/, '\`')
903
+ else
904
+ raise "unsupported type #{type.inspect}"
905
+ end
906
+ end
907
+
908
+ def util_dthing(type, exp)
862
909
  s = []
863
- suck = true
864
- x = exp.shift.gsub(/"/, '\"').gsub(/\n/, '\n')
865
- x.gsub!(/\//, '\/') if regx
866
910
 
867
- s << x
911
+ # first item in sexp is a string literal
912
+ s << dthing_escape(type, exp.shift)
913
+
868
914
  until exp.empty?
869
915
  pt = exp.shift
870
916
  case pt
871
917
  when Sexp then
872
918
  case pt.first
873
919
  when :str then
874
- x = pt.last.gsub(/"/, '\"').gsub(/\n/, '\n')
875
- x.gsub!(/\//, '\/') if regx
876
- s << x
877
- else
920
+ s << dthing_escape(type, pt.last)
921
+ when :evstr then
878
922
  s << '#{' << process(pt) << '}' # do not use interpolation here
923
+ else
924
+ raise "unknown type: #{pt.inspect}"
879
925
  end
880
926
  else
881
- # HACK: raise "huh?: #{pt.inspect}"
927
+ # HACK: raise "huh?: #{pt.inspect}" -- hitting # constants in regexps
882
928
  # do nothing for now
883
929
  end
884
930
  end
@@ -40,22 +40,54 @@ class TestRuby2Ruby < R2RTestCase
40
40
  @processor = Ruby2Ruby.new
41
41
  end
42
42
 
43
+ def test_util_dthing_dregx
44
+ inn = util_thingy(:dregx)
45
+ inn.shift
46
+ out = '/a"b#{(1 + 1)}c"d\/e/'
47
+ exp = /a"b2c"d\/e/
48
+
49
+ assert_equal exp, eval(out)
50
+
51
+ assert_equal out[1..-2], @processor.util_dthing(:dregx, inn)
52
+ end
53
+
54
+ def test_util_dthing_dstr
55
+ inn = util_thingy(:dstr)
56
+ inn.shift
57
+ out = '"a\"b#{(1 + 1)}c\"d/e"'
58
+ exp = 'a"b2c"d/e'
59
+
60
+ assert_equal exp, eval(out)
61
+
62
+ assert_equal out[1..-2], @processor.util_dthing(:dstr, inn)
63
+ end
64
+
65
+ def test_util_dthing_dregx_bug?
66
+ inn = s(:dregx, '[\/\"]', s(:evstr, s(:lit, 42)))
67
+ inn.shift
68
+ out = '/[\/\"]#{42}/'
69
+ exp = /[\/\"]42/
70
+
71
+ assert_equal out[1..-2], @processor.util_dthing(:dregx, inn)
72
+ assert_equal exp, eval(out)
73
+ end
74
+
43
75
  def test_dregx_slash
44
76
  inn = util_thingy(:dregx)
45
- out = "/blah\\\"blah#\{(1 + 1)}blah\\\"blah\\/blah/"
46
- util_compare inn, out, /blah\"blah2blah\"blah\/blah/
77
+ out = '/a"b#{(1 + 1)}c"d\/e/'
78
+ util_compare inn, out, /a"b2c"d\/e/
47
79
  end
48
80
 
49
81
  def test_dstr_quote
50
82
  inn = util_thingy(:dstr)
51
- out = "\"blah\\\"blah#\{(1 + 1)}blah\\\"blah/blah\""
52
- util_compare inn, out, "blah\"blah2blah\"blah/blah"
83
+ out = '"a\"b#{(1 + 1)}c\"d/e"'
84
+ util_compare inn, out, 'a"b2c"d/e'
53
85
  end
54
86
 
55
87
  def test_dsym_quote
56
88
  inn = util_thingy(:dsym)
57
- out = ":\"blah\\\"blah#\{(1 + 1)}blah\\\"blah/blah\""
58
- util_compare inn, out, :"blah\"blah2blah\"blah/blah"
89
+ out = ':"a\"b#{(1 + 1)}c\"d/e"'
90
+ util_compare inn, out, :'a"b2c"d/e'
59
91
  end
60
92
 
61
93
  def test_lit_regexp_slash
@@ -119,6 +151,52 @@ class TestRuby2Ruby < R2RTestCase
119
151
  util_compare inn, out
120
152
  end
121
153
 
154
+ def test_resbody_short_with_begin_end
155
+ # "begin; blah; rescue; []; end"
156
+ inn = s(:rescue,
157
+ s(:call, nil, :blah, s(:arglist)),
158
+ s(:resbody, s(:array), s(:array)))
159
+ out = "blah rescue []"
160
+ util_compare inn, out
161
+ end
162
+
163
+ def test_resbody_short_with_rescue_args
164
+ inn = s(:rescue,
165
+ s(:call, nil, :blah, s(:arglist)),
166
+ s(:resbody, s(:array, s(:const, :A), s(:const, :B)), s(:array)))
167
+ out = "begin\n blah\nrescue A, B\n []\nend"
168
+ util_compare inn, out
169
+ end
170
+
171
+ def test_call_binary_call_with_hash_arg
172
+ # if 42
173
+ # args << {:key => 24}
174
+ # end
175
+
176
+ inn = s(:if, s(:lit, 42),
177
+ s(:call, s(:call, nil, :args, s(:arglist)),
178
+ :<<,
179
+ s(:arglist, s(:hash, s(:lit, :key), s(:lit, 24)))),
180
+ nil)
181
+
182
+ out = "(args << { :key => 24 }) if 42"
183
+
184
+ util_compare inn, out
185
+ end
186
+
187
+ def test_interpolation_and_escapes
188
+ # log_entry = " \e[#{message_color}m#{message}\e[0m "
189
+ inn = s(:lasgn, :log_entry,
190
+ s(:dstr, " \e[",
191
+ s(:evstr, s(:call, nil, :message_color, s(:arglist))),
192
+ s(:str, "m"),
193
+ s(:evstr, s(:call, nil, :message, s(:arglist))),
194
+ s(:str, "\e[0m ")))
195
+ out = "log_entry = \" \e[#\{message_color}m#\{message}\e[0m \""
196
+
197
+ util_compare inn, out
198
+ end
199
+
122
200
  def util_compare sexp, expected_ruby, expected_eval = nil
123
201
  assert_equal expected_ruby, @processor.process(sexp)
124
202
  assert_equal expected_eval, eval(expected_ruby) if expected_eval
@@ -126,9 +204,9 @@ class TestRuby2Ruby < R2RTestCase
126
204
 
127
205
  def util_thingy(type)
128
206
  s(type,
129
- 'blah"blah',
130
- s(:call, s(:lit, 1), :+, s(:arglist, s(:lit, 1))),
131
- s(:str, 'blah"blah/blah'))
207
+ 'a"b',
208
+ s(:evstr, s(:call, s(:lit, 1), :+, s(:arglist, s(:lit, 1)))),
209
+ s(:str, 'c"d/e'))
132
210
  end
133
211
  end
134
212
 
metadata CHANGED
@@ -1,57 +1,137 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby2ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 2
9
+ - 5
10
+ version: 1.2.5
5
11
  platform: ruby
6
12
  authors:
7
13
  - Ryan Davis
8
14
  autorequire:
9
15
  bindir: bin
10
- cert_chain: []
16
+ cert_chain:
17
+ - |
18
+ -----BEGIN CERTIFICATE-----
19
+ MIIDPjCCAiagAwIBAgIBADANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
20
+ ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
21
+ GRYDY29tMB4XDTA5MDMwNjE4NTMxNVoXDTEwMDMwNjE4NTMxNVowRTETMBEGA1UE
22
+ AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
23
+ JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
24
+ b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
25
+ taCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT
26
+ oOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh
27
+ GiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt
28
+ qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
29
+ gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
30
+ HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB
31
+ AQAY59gYvDxqSqgC92nAP9P8dnGgfZgLxP237xS6XxFGJSghdz/nI6pusfCWKM8m
32
+ vzjjH2wUMSSf3tNudQ3rCGLf2epkcU13/rguI88wO6MrE0wi4ZqLQX+eZQFskJb/
33
+ w6x9W1ur8eR01s397LSMexySDBrJOh34cm2AlfKr/jokKCTwcM0OvVZnAutaovC0
34
+ l1SVZ0ecg88bsWHA0Yhh7NFxK1utWoIhtB6AFC/+trM0FQEB/jZkIS8SaNzn96Rl
35
+ n0sZEf77FLf5peR8TP/PtmIg7Cyqz23sLM4mCOoTGIy5OcZ8TdyiyINUHtb5ej/T
36
+ FBHgymkyj/AOSqKRIpXPhjC6
37
+ -----END CERTIFICATE-----
11
38
 
12
- date: 2009-08-14 00:00:00 -07:00
39
+ date: 2010-09-01 00:00:00 -07:00
13
40
  default_executable:
14
41
  dependencies:
15
42
  - !ruby/object:Gem::Dependency
16
43
  name: sexp_processor
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
44
+ prerelease: false
45
+ requirement: &id001 !ruby/object:Gem::Requirement
46
+ none: false
20
47
  requirements:
21
48
  - - ~>
22
49
  - !ruby/object:Gem::Version
50
+ hash: 7
51
+ segments:
52
+ - 3
53
+ - 0
23
54
  version: "3.0"
24
- version:
55
+ type: :runtime
56
+ version_requirements: *id001
25
57
  - !ruby/object:Gem::Dependency
26
58
  name: ruby_parser
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
59
+ prerelease: false
60
+ requirement: &id002 !ruby/object:Gem::Requirement
61
+ none: false
30
62
  requirements:
31
63
  - - ~>
32
64
  - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 2
68
+ - 0
33
69
  version: "2.0"
34
- version:
70
+ type: :runtime
71
+ version_requirements: *id002
35
72
  - !ruby/object:Gem::Dependency
36
- name: ParseTree
73
+ name: rubyforge
74
+ prerelease: false
75
+ requirement: &id003 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ hash: 7
81
+ segments:
82
+ - 2
83
+ - 0
84
+ - 4
85
+ version: 2.0.4
86
+ type: :development
87
+ version_requirements: *id003
88
+ - !ruby/object:Gem::Dependency
89
+ name: minitest
90
+ prerelease: false
91
+ requirement: &id004 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ hash: 9
97
+ segments:
98
+ - 1
99
+ - 7
100
+ - 1
101
+ version: 1.7.1
37
102
  type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
103
+ version_requirements: *id004
104
+ - !ruby/object:Gem::Dependency
105
+ name: ParseTree
106
+ prerelease: false
107
+ requirement: &id005 !ruby/object:Gem::Requirement
108
+ none: false
40
109
  requirements:
41
110
  - - ~>
42
111
  - !ruby/object:Gem::Version
112
+ hash: 7
113
+ segments:
114
+ - 3
115
+ - 0
43
116
  version: "3.0"
44
- version:
117
+ type: :development
118
+ version_requirements: *id005
45
119
  - !ruby/object:Gem::Dependency
46
120
  name: hoe
47
- type: :development
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
121
+ prerelease: false
122
+ requirement: &id006 !ruby/object:Gem::Requirement
123
+ none: false
50
124
  requirements:
51
125
  - - ">="
52
126
  - !ruby/object:Gem::Version
53
- version: 2.3.3
54
- version:
127
+ hash: 19
128
+ segments:
129
+ - 2
130
+ - 6
131
+ - 2
132
+ version: 2.6.2
133
+ type: :development
134
+ version_requirements: *id006
55
135
  description: |-
56
136
  ruby2ruby provides a means of generating pure ruby code easily from
57
137
  RubyParser compatible Sexps. This makes making dynamic language
@@ -86,21 +166,27 @@ rdoc_options:
86
166
  require_paths:
87
167
  - lib
88
168
  required_ruby_version: !ruby/object:Gem::Requirement
169
+ none: false
89
170
  requirements:
90
171
  - - ">="
91
172
  - !ruby/object:Gem::Version
173
+ hash: 3
174
+ segments:
175
+ - 0
92
176
  version: "0"
93
- version:
94
177
  required_rubygems_version: !ruby/object:Gem::Requirement
178
+ none: false
95
179
  requirements:
96
180
  - - ">="
97
181
  - !ruby/object:Gem::Version
182
+ hash: 3
183
+ segments:
184
+ - 0
98
185
  version: "0"
99
- version:
100
186
  requirements: []
101
187
 
102
188
  rubyforge_project: seattlerb
103
- rubygems_version: 1.3.5
189
+ rubygems_version: 1.3.7
104
190
  signing_key:
105
191
  specification_version: 3
106
192
  summary: ruby2ruby provides a means of generating pure ruby code easily from RubyParser compatible Sexps
metadata.gz.sig ADDED
Binary file