mirah 0.1.0.pre-java → 0.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/History.txt +736 -0
  2. data/README.md +71 -0
  3. data/Rakefile +227 -73
  4. data/examples/Fib.class +0 -0
  5. data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +2 -3
  6. data/examples/simple_class.mirah +3 -3
  7. data/examples/{dynamic.mirah → simple_class.mirah~} +7 -12
  8. data/javalib/mirah-bootstrap.jar +0 -0
  9. data/javalib/mirah-builtins.jar +0 -0
  10. data/javalib/mirah-compiler.jar +0 -0
  11. data/javalib/mirah-parser.jar +0 -0
  12. data/javalib/mirah-util.jar +0 -0
  13. data/lib/mirah.rb +8 -1
  14. data/lib/mirah/ast.rb +1 -1
  15. data/lib/mirah/ast/scope.rb +16 -0
  16. data/lib/mirah/commands/base.rb +1 -3
  17. data/lib/mirah/compiler.rb +17 -3
  18. data/lib/mirah/errors.rb +10 -10
  19. data/lib/mirah/generator.rb +21 -9
  20. data/lib/mirah/jvm/compiler.rb +17 -0
  21. data/lib/mirah/jvm/compiler/base.rb +24 -5
  22. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +83 -20
  23. data/lib/mirah/jvm/method_lookup.rb +43 -22
  24. data/lib/mirah/jvm/types.rb +1 -2
  25. data/lib/mirah/jvm/types/array_type.rb +1 -6
  26. data/lib/mirah/jvm/types/ast_ext.rb +31 -0
  27. data/lib/mirah/jvm/types/basic_types.rb +1 -2
  28. data/lib/mirah/jvm/types/boolean.rb +11 -10
  29. data/lib/mirah/jvm/types/extensions.rb +14 -5
  30. data/lib/mirah/jvm/types/factory.rb +128 -43
  31. data/lib/mirah/jvm/types/floats.rb +8 -10
  32. data/lib/mirah/jvm/types/integers.rb +16 -9
  33. data/lib/mirah/jvm/types/intrinsics.rb +17 -69
  34. data/lib/mirah/jvm/types/meta_type.rb +5 -0
  35. data/lib/mirah/jvm/types/methods.rb +317 -151
  36. data/lib/mirah/jvm/types/methods.rb~ +973 -0
  37. data/lib/mirah/jvm/types/number.rb +29 -6
  38. data/lib/mirah/jvm/types/primitive_type.rb +35 -7
  39. data/lib/mirah/jvm/types/source_mirror.rb +11 -6
  40. data/lib/mirah/jvm/types/type.rb +52 -0
  41. data/lib/mirah/jvm/types/type_definition.rb +8 -2
  42. data/lib/mirah/transform/ast_ext.rb +9 -31
  43. data/lib/mirah/transform/transformer.rb +1 -1
  44. data/lib/mirah/typer.rb +2 -1
  45. data/lib/mirah/util/argument_processor.rb +10 -14
  46. data/lib/mirah/util/argument_processor.rb~ +146 -0
  47. data/lib/mirah/util/compilation_state.rb +15 -9
  48. data/lib/mirah/util/process_errors.rb +8 -2
  49. data/lib/mirah/version.rb +2 -2
  50. data/lib/mirah_task.rb +0 -7
  51. data/test/core/typer_test.rb +21 -13
  52. data/test/core/util/argument_processor_test.rb +19 -19
  53. data/test/core/util/class_loader_test.rb +19 -4
  54. data/test/core/util/compilation_state_test.rb +38 -0
  55. data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
  56. data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
  57. data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
  58. data/test/jvm/blocks_test.rb +50 -29
  59. data/test/jvm/bytecode_test_helper.rb +71 -57
  60. data/test/jvm/cast_test.rb +162 -0
  61. data/test/jvm/constructors_test.rb +48 -0
  62. data/test/jvm/enumerable_test.rb +136 -7
  63. data/test/jvm/example_test.rb +39 -0
  64. data/test/jvm/factory_test.rb +6 -0
  65. data/test/jvm/generics_test.rb +0 -5
  66. data/test/jvm/import_test.rb +81 -0
  67. data/test/jvm/interface_test.rb +113 -0
  68. data/test/jvm/java_typer_test.rb +57 -11
  69. data/test/jvm/jvm_commands_test.rb +24 -0
  70. data/test/jvm/jvm_compiler_test.rb +186 -370
  71. data/test/jvm/macros_test.rb +67 -6
  72. data/test/jvm/main_method_test.rb +1 -1
  73. data/test/jvm/mirror_compilation_test_helper.rb +24 -0
  74. data/test/jvm/new_backend_test_helper.rb +25 -0
  75. data/test/jvm/rescue_test.rb +153 -18
  76. data/test/jvm/string_test.rb +41 -0
  77. data/test/jvm/varargs_test.rb +65 -0
  78. data/test/mirrors/base_type_test.rb +96 -0
  79. data/test/mirrors/bytecode_mirror_test.rb +86 -0
  80. data/test/mirrors/generics_test.rb +776 -0
  81. data/test/mirrors/member_test.rb +69 -0
  82. data/test/mirrors/method_lookup_test.rb +574 -0
  83. data/test/mirrors/mirrors_test.rb +562 -0
  84. data/test/mirrors/simple_async_mirror_loader_test.rb +110 -0
  85. data/test/mirrors/simple_mirror_loader_test.rb +104 -0
  86. data/test/test_helper.rb +2 -1
  87. metadata +244 -217
  88. data/README.txt +0 -59
  89. data/javalib/dynalink-0.2.jar +0 -0
  90. data/lib/mirah/jvm/typer.rb +0 -177
  91. data/lib/mirah/jvm/types/dynamic_type.rb +0 -45
  92. data/lib/mirah/jvm/types/unreachable_type.rb +0 -27
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
1
+ # Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
2
2
  # All contributing project authors may be found in the NOTICE file.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,78 +13,73 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  require 'test_helper'
16
- require 'stringio'
17
- require 'fileutils'
16
+ require 'set'
18
17
 
19
18
  module JVMCompiler
19
+ TEST_DEST = File.expand_path(File.dirname(__FILE__)+'/../../tmp_test/') + "/"
20
+ $CLASSPATH << TEST_DEST
21
+
20
22
  import java.lang.System
21
23
  import java.io.PrintStream
22
24
  include Mirah
23
25
 
24
26
  def new_state
25
27
  state = Mirah::Util::CompilationState.new
26
- state.save_extensions = false
28
+ state.save_extensions = true
29
+ state.destination = TEST_DEST
30
+ state.classpath = TEST_DEST
31
+ state.type_system = type_system if type_system
27
32
  state
28
33
  end
29
34
 
35
+ def type_system
36
+ nil
37
+ end
30
38
 
31
- # def create_transformer
32
- # state = Mirah::Util::CompilationState.new
33
- # state.save_extensions = false
34
- #
35
- # transformer = Mirah::Transform::Transformer.new(state)
36
- # Java::MirahImpl::Builtin.initialize_builtins(transformer)
37
- # transformer
38
- # end
39
-
40
-
41
- def clear_tmp_files
39
+ def clean_tmp_files
42
40
  return unless @tmp_classes
43
-
44
41
  File.unlink(*@tmp_classes)
45
- @tmp_classes.clear
46
42
  end
47
43
 
48
44
  def compiler_type
49
45
  JVM::Compiler::JVMBytecode
50
46
  end
51
47
 
48
+ def compiler_name
49
+ "original"
50
+ end
51
+
52
52
  def parse name, code, transformer
53
53
  AST.parse(code, name, true, transformer)
54
54
  end
55
55
 
56
- def infer_and_resolve_types ast, generator
57
- scoper, typer = generator.infer_asts(ast, true)
58
- ast
59
- end
60
-
61
- def parse_and_resolve_types name, code
62
- clear_tmp_files
63
-
64
- state = new_state
65
-
66
- generator = Mirah::Generator.new(state, compiler_type, false, false)
67
- transformer = Mirah::Transform::Transformer.new(state, generator.typer)
56
+ def infer_and_resolve_types ast, generator
57
+ scoper, typer = generator.infer_asts(ast, true)
58
+ ast
59
+ end
68
60
 
69
- #Java::MirahImpl::Builtin.initialize_builtins(transformer)
61
+ def parse_and_resolve_types name, code
62
+ state = new_state
70
63
 
71
- ast = [AST.parse(code, name, true, transformer)]
64
+ generator = Mirah::Generator.new(state, compiler_type, false, false)
65
+ transformer = Mirah::Transform::Transformer.new(state, generator.typer)
72
66
 
73
- infer_and_resolve_types ast, generator
67
+ ast = [AST.parse(code, name, true, transformer)]
74
68
 
75
- ast
76
- end
69
+ infer_and_resolve_types ast, generator
77
70
 
71
+ ast
72
+ end
78
73
 
79
74
  def generate_classes compiler_results
80
75
  classes = {}
81
76
 
82
77
  compiler_results.each do |result|
83
78
  bytes = result.bytes
84
-
85
- FileUtils.mkdir_p(File.dirname(result.filename))
86
- File.open(result.filename, 'wb') { |f| f.write(bytes) }
87
-
79
+ filename = "#{TEST_DEST}#{result.filename}"
80
+ FileUtils.mkdir_p(File.dirname(filename))
81
+ File.open(filename, 'wb') { |f| f.write(bytes) }
82
+ @tmp_classes << filename
88
83
  classes[result.filename[0..-7]] = Mirah::Util::ClassLoader.binary_string bytes
89
84
  end
90
85
 
@@ -92,29 +87,24 @@ module JVMCompiler
92
87
 
93
88
  classes.keys.map do |name|
94
89
  cls = loader.load_class(name.tr('/', '.'))
95
- proxy = JavaUtilities.get_proxy_class(cls.name)
96
- @tmp_classes << "#{name}.class"
97
- proxy
90
+ JavaUtilities.get_proxy_class(cls.name)
98
91
  end
99
92
  end
100
93
 
101
- #def compile_ast ast
102
- # compiler = create_compiler
103
- # compiler.compile(ast)
104
- # compiler
105
- #end
106
-
107
- def compile(code, name = tmp_script_name)
108
- clear_tmp_files
94
+ def compile(code, options = {})
95
+ name = options.delete :name
96
+ name ||= tmp_script_name
109
97
 
110
98
  state = new_state
99
+ java_version = options.delete :java_version
100
+ if java_version
101
+ state.set_jvm_version java_version
102
+ end
111
103
 
112
104
  generator = Mirah::Generator.new(state, compiler_type, false, false)
113
105
  transformer = Mirah::Transform::Transformer.new(state, generator.typer)
114
106
 
115
- #Java::MirahImpl::Builtin.initialize_builtins(transformer)
116
-
117
- ast = [AST.parse(code, name, true, transformer)]
107
+ ast = [AST.parse_ruby(nil, code, name)]
118
108
 
119
109
  scoper, typer = generator.infer_asts(ast, true)
120
110
  compiler_results = generator.compiler.compile_asts(ast, scoper, typer)
@@ -123,7 +113,7 @@ module JVMCompiler
123
113
  end
124
114
 
125
115
  def tmp_script_name
126
- "script" + System.nano_time.to_s
116
+ "script#{name.gsub(/\)|\(/,'_').capitalize}#{System.nano_time}"
127
117
  end
128
118
  end
129
119
 
@@ -156,17 +146,41 @@ module CommonAssertions
156
146
  assert_equal(expected, capture_output(&block))
157
147
  end
158
148
 
149
+ def assert_raise_java(type, message=nil)
150
+ begin
151
+ yield
152
+ rescue Exception => e
153
+ ex = e
154
+ end
155
+ ex = ex.cause if ex.is_a? NativeException
156
+ assert_equal type, ex.class
157
+ if message
158
+ assert_equal message,
159
+ ex.message.to_s,
160
+ "expected error message to be '#{message}' but was '#{ex.message}'"
161
+ end
162
+ ex
163
+ end
164
+ end
165
+
166
+ module DebuggingHelp
167
+ def with_finest_logging
168
+ Mirah::Logging::MirahLogger.level = Mirah::Logging::Level::FINEST
169
+ yield
170
+ ensure
171
+ Mirah::Logging::MirahLogger.level = Mirah::Logging::Level::INFO
172
+ end
159
173
  end
160
174
 
161
175
  class Test::Unit::TestCase
162
176
  include JVMCompiler
177
+ include DebuggingHelp
163
178
 
164
179
  def setup
165
- @tmp_classes = []
180
+ @tmp_classes = Set.new
166
181
  end
167
182
 
168
- def teardown
169
- #reset_type_factory
170
- clear_tmp_files
183
+ def cleanup
184
+ clean_tmp_files
171
185
  end
172
186
  end
@@ -0,0 +1,162 @@
1
+ # Copyright (c) 2013 The Mirah project authors. All Rights Reserved.
2
+ # All contributing project authors may be found in the NOTICE file.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ class CastTest < Test::Unit::TestCase
17
+
18
+ def test_cast
19
+ cls, = compile(<<-EOF)
20
+ def f2b; byte(1.0); end
21
+ def f2s; short(1.0); end
22
+ def f2c; char(1.0); end
23
+ def f2i; int(1.0); end
24
+ def f2l; long(1.0); end
25
+ def f2d; int(1.0); end
26
+
27
+ def i2b; byte(1); end
28
+ def i2s; short(1); end
29
+ def i2c; char(1); end
30
+ def i2l; long(1); end
31
+ def i2f; float(1); end
32
+ def i2d; int(1); end
33
+
34
+ def b2s; short(byte(1)); end
35
+ def b2c; char(byte(1)); end
36
+ def b2i; int(byte(1)); end
37
+ def b2l; long(byte(1)); end
38
+ def b2f; float(byte(1)); end
39
+ def b2d; double(byte(1)); end
40
+
41
+ def s2b; byte(short(1)); end
42
+ def s2c; char(short(1)); end
43
+ def s2i; int(short(1)); end
44
+ def s2l; long(short(1)); end
45
+ def s2f; float(short(1)); end
46
+ def s2d; double(short(1)); end
47
+
48
+ def c2b; byte(char(1)); end
49
+ def c2s; short(char(1)); end
50
+ def c2i; int(char(1)); end
51
+ def c2l; long(char(1)); end
52
+ def c2f; float(char(1)); end
53
+ def c2d; double(char(1)); end
54
+
55
+ def l2b; byte(long(1)); end
56
+ def l2c; char(long(1)); end
57
+ def l2i; int(long(1)); end
58
+ def l2l; long(long(1)); end
59
+ def l2f; float(long(1)); end
60
+ def l2d; double(long(1)); end
61
+
62
+ def d2b; byte(1.0); end
63
+ def d2s; short(1.0); end
64
+ def d2c; char(1.0); end
65
+ def d2i; int(1.0); end
66
+ def d2l; long(1.0); end
67
+ def d2f; float(1.0); end
68
+
69
+ def hard_i2f(a:int)
70
+ float(if a < 0
71
+ a *= -1
72
+ a * 2
73
+ else
74
+ a * 2
75
+ end)
76
+ end
77
+ EOF
78
+
79
+ assert_equal 1, cls.b2s
80
+ assert_equal 1, cls.b2c
81
+ assert_equal 1, cls.b2i
82
+ assert_equal 1, cls.b2l
83
+ assert_equal 1.0, cls.b2f
84
+ assert_equal 1.0, cls.b2d
85
+
86
+ assert_equal 1, cls.s2b
87
+ assert_equal 1, cls.s2c
88
+ assert_equal 1, cls.s2i
89
+ assert_equal 1, cls.s2l
90
+ assert_equal 1.0, cls.s2f
91
+ assert_equal 1.0, cls.s2d
92
+
93
+ assert_equal 1, cls.c2b
94
+ assert_equal 1, cls.c2s
95
+ assert_equal 1, cls.c2i
96
+ assert_equal 1, cls.c2l
97
+ assert_equal 1.0, cls.c2f
98
+ assert_equal 1.0, cls.c2d
99
+
100
+ assert_equal 1, cls.i2b
101
+ assert_equal 1, cls.i2s
102
+ assert_equal 1, cls.i2c
103
+ assert_equal 1, cls.i2l
104
+ assert_equal 1.0, cls.i2f
105
+ assert_equal 1.0, cls.i2d
106
+
107
+ assert_equal 1, cls.f2b
108
+ assert_equal 1, cls.f2s
109
+ assert_equal 1, cls.f2c
110
+ assert_equal 1, cls.f2i
111
+ assert_equal 1, cls.f2l
112
+ assert_equal 1.0, cls.f2d
113
+
114
+ assert_equal 1, cls.d2b
115
+ assert_equal 1, cls.d2s
116
+ assert_equal 1, cls.d2c
117
+ assert_equal 1, cls.d2i
118
+ assert_equal 1, cls.d2l
119
+ assert_equal 1.0, cls.d2f
120
+
121
+ assert_equal 2.0, cls.hard_i2f(1)
122
+ assert_equal 4.0, cls.hard_i2f(-2)
123
+ end
124
+
125
+ def test_java_lang_cast
126
+ cls, = compile(<<-EOF)
127
+ def foo(a:Object)
128
+ Integer(a).intValue
129
+ end
130
+ EOF
131
+
132
+ assert_equal(2, cls.foo(java.lang.Integer.new(2)))
133
+ end
134
+
135
+ def test_array_cast
136
+ cls, = compile(<<-EOF)
137
+ def foo(a:Object)
138
+ bar(String[].cast(a))
139
+ end
140
+
141
+ def bar(a:String[])
142
+ a[0]
143
+ end
144
+ EOF
145
+
146
+ assert_equal("foo", cls.foo(["foo", "bar"].to_java(:string)))
147
+ end
148
+
149
+ def test_array_cast_primitive
150
+ cls, = compile(<<-EOF)
151
+ def foo(a:Object)
152
+ bar(int[].cast(a))
153
+ end
154
+
155
+ def bar(a:int[])
156
+ a[0]
157
+ end
158
+ EOF
159
+
160
+ assert_equal(2, cls.foo([2, 3].to_java(:int)))
161
+ end
162
+ end
@@ -73,6 +73,54 @@ class ConstructorsTest < Test::Unit::TestCase
73
73
  end
74
74
  end
75
75
 
76
+ def test_super_constructor_inferred_args_like_ruby
77
+ sc_a, sc_b = compile(<<-EOF)
78
+ class SuperCA
79
+ def initialize(a: int)
80
+ System.out.println "A \#{a}"
81
+ end
82
+ end
83
+
84
+ class SuperCB < SuperCA
85
+ def initialize a: int
86
+ super
87
+ System.out.println "B \#{a}"
88
+ end
89
+ end
90
+ EOF
91
+ assert_output("A 1\nB 1\n") do
92
+ sc_b.new 1
93
+ end
94
+ end
95
+
96
+ def test_when_inferred_args_dont_match_super_has_error
97
+ error = assert_raises Mirah::MirahError do
98
+ compile(<<-EOF)
99
+ class SuperCA
100
+ def initialize(a: int);end
101
+ end
102
+
103
+ class SuperCB < SuperCA
104
+ def initialize; super; end
105
+ end
106
+ EOF
107
+ end
108
+ assert_equal "Cannot find instance method initialize() on SuperCA", error.message
109
+ end
110
+
111
+
112
+ def test_when_inferred_args_dont_match_java_super_has_error
113
+ error = assert_raises Mirah::MirahError do
114
+ compile(<<-EOF)
115
+ import java.util.ArrayList
116
+ class SuperArray < ArrayList
117
+ def initialize str: String; super; end
118
+ end
119
+ EOF
120
+ end
121
+ assert_equal "Cannot find instance method initialize(java.lang.String) on java.util.ArrayList", error.message
122
+ end
123
+
76
124
  def test_empty_constructor
77
125
  foo, = compile(<<-EOF)
78
126
  class Foo6
@@ -135,7 +135,7 @@ class EnumerableTest < Test::Unit::TestCase
135
135
  end
136
136
  end
137
137
 
138
- def test_times
138
+ def test_times_with_arg
139
139
  cls, = compile(<<-EOF)
140
140
  def foo(i:int)
141
141
  i.times {|x| System.out.println x }
@@ -145,7 +145,9 @@ class EnumerableTest < Test::Unit::TestCase
145
145
  assert_output("0\n1\n2\n") do
146
146
  cls.foo(3)
147
147
  end
148
+ end
148
149
 
150
+ def test_times_without_arg
149
151
  cls, = compile(<<-EOF)
150
152
  def foo(i:int)
151
153
  i.times { System.out.println "Hi" }
@@ -157,7 +159,7 @@ class EnumerableTest < Test::Unit::TestCase
157
159
  end
158
160
  end
159
161
 
160
- def test_general_loop
162
+ def test_normal_while_loop
161
163
  cls, = compile(<<-EOF)
162
164
  def foo(x:boolean)
163
165
  a = StringBuilder.new
@@ -168,7 +170,9 @@ class EnumerableTest < Test::Unit::TestCase
168
170
  end
169
171
  EOF
170
172
  assert_equal("", cls.foo(false))
173
+ end
171
174
 
175
+ def test_postfix_while_loop
172
176
  cls, = compile(<<-EOF)
173
177
  def foo
174
178
  a = StringBuilder.new
@@ -179,7 +183,9 @@ class EnumerableTest < Test::Unit::TestCase
179
183
  end
180
184
  EOF
181
185
  assert_equal("<body>", cls.foo)
186
+ end
182
187
 
188
+ def test_general_loop
183
189
  cls, = compile(<<-EOF)
184
190
  def foo(x:boolean)
185
191
  a = StringBuilder.new
@@ -239,8 +245,7 @@ class EnumerableTest < Test::Unit::TestCase
239
245
  assert_equal("<init><pre><post><pre><body><post>", cls.foo)
240
246
  end
241
247
 
242
-
243
- def test_each
248
+ def test_each
244
249
  cls, = compile(<<-EOF)
245
250
  def foo
246
251
  [1,2,3].each {|x| System.out.println x}
@@ -260,7 +265,6 @@ class EnumerableTest < Test::Unit::TestCase
260
265
  assert_output("thrice\nthrice\nthrice\n") do
261
266
  cls.foo
262
267
  end
263
-
264
268
  end
265
269
 
266
270
  def test_any
@@ -276,7 +280,7 @@ class EnumerableTest < Test::Unit::TestCase
276
280
  end
277
281
  end
278
282
 
279
- def test_all
283
+ def test_all_empty_block_and_not_with_cast
280
284
  cls, = compile(<<-EOF)
281
285
  import java.lang.Integer
282
286
  def foo
@@ -287,7 +291,8 @@ class EnumerableTest < Test::Unit::TestCase
287
291
  assert_output("true\nfalse\n") do
288
292
  cls.foo
289
293
  end
290
-
294
+ end
295
+ def test_all_with_block_with_no_cast
291
296
  cls, = compile(<<-EOF)
292
297
  def foo
293
298
  System.out.println [1,2,3].all? {|x| x.intValue > 3}
@@ -298,6 +303,130 @@ class EnumerableTest < Test::Unit::TestCase
298
303
  end
299
304
  end
300
305
 
306
+ def test_map
307
+ cls, = compile(<<-EOF)
308
+ def foo
309
+ System.out.println [1,2,3].map {|x:Integer| x.intValue + 1}
310
+ System.out.println [1,2,3].map {|x| x}
311
+ System.out.println [1].map { 'a' }
312
+ System.out.println [].map { 'b' }
313
+ end
314
+ EOF
315
+ assert_output("[2, 3, 4]\n[1, 2, 3]\n[a]\n[]\n") do
316
+ cls.foo
317
+ end
318
+ end
319
+
320
+ def test_zip
321
+ cls, = compile(<<-'EOF')
322
+ def bar
323
+ [1,2,3].zip([4]) {|x, y| puts "#{x}, #{y}"}
324
+ end
325
+ EOF
326
+ assert_output("1, 4\n2, null\n3, null\n") do
327
+ cls.bar
328
+ end
329
+
330
+ cls, = compile(<<-'EOF')
331
+ def foo
332
+ [1,2,3].zip([4, 5, 6]) do |x:Integer, y:Integer|
333
+ puts "#{x} + #{y} = #{x.intValue + y.intValue}"
334
+ end
335
+ end
336
+ EOF
337
+ assert_output("1 + 4 = 5\n2 + 5 = 7\n3 + 6 = 9\n") do
338
+ cls.foo
339
+ end
340
+ end
341
+
342
+ def test_reduce_with_string_array
343
+ cls, = compile(<<-'EOF')
344
+ def foo
345
+ x = ["a", "b", "c"].reduce {|a, b| "#{a}#{b}"}
346
+ puts x
347
+ end
348
+ EOF
349
+ assert_output("abc\n") do
350
+ cls.foo
351
+ end
352
+ end
353
+
354
+ def test_reduce_with_multiple_typed_block_parameters
355
+ cls, = compile(<<-'EOF')
356
+ def foo
357
+ puts [1, 2, 3].reduce {|a:Integer, b:Integer| Integer.new(a.intValue + b.intValue)}
358
+ end
359
+ EOF
360
+ assert_output("6\n") do
361
+ cls.foo
362
+ end
363
+ end
364
+
365
+ def test_reduce_with_one_typed_block_parameters
366
+ cls, = compile(<<-'EOF')
367
+ def foo
368
+ puts ["a", "b", "c"].reduce {|a:Integer| "#{a}a"}
369
+ end
370
+ EOF
371
+ assert_output("aaa\n") do
372
+ cls.foo
373
+ end
374
+ end
375
+
376
+ def test_reduce_with_no_arguments
377
+ cls, = compile(<<-'EOF')
378
+ def foo
379
+ ["a", "b", "c"].reduce {puts "x"}
380
+ end
381
+ EOF
382
+ assert_output("x\nx\n") do
383
+ cls.foo
384
+ end
385
+ end
386
+
387
+ def test_reduce_of_single_element_list_does_not_execute_block
388
+ cls, = compile(<<-'EOF')
389
+ def foo
390
+ puts ["a"].reduce { puts "x"}
391
+ end
392
+ EOF
393
+ assert_output("a\n") do
394
+ cls.foo
395
+ end
396
+ end
397
+
398
+ def test_reduce_of_empty_list_with_some_variable_name_as_outer_scope_does_not_effect_outer_scope
399
+ cls, = compile(<<-'EOF')
400
+ def foo
401
+ a = "foo"
402
+ [].reduce {|a| "#{a}a"}
403
+ puts a
404
+ end
405
+ EOF
406
+ assert_output("null\n") do
407
+ cls.foo
408
+ end
409
+ end
410
+
411
+ def test_reduce_with_int_array
412
+ if compiler_name == 'new'
413
+ cls, = compile(<<-'EOF')
414
+ def baz
415
+ a = int[3]
416
+ a[0] = 1
417
+ a[1] = 2
418
+ a[2] = 4
419
+ puts a.reduce {|x, y| x * y}
420
+ end
421
+ EOF
422
+ assert_output("8\n") do
423
+ cls.baz
424
+ end
425
+ else
426
+ pend 'Generated bad bytecode'
427
+ end
428
+ end
429
+
301
430
  def test_mirah_iterable
302
431
  cls, = compile(<<-EOF)
303
432
  import java.util.Iterator