ruby2ruby 1.2.4 → 1.2.5

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.
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