mirah 0.1.0.pre-java → 0.1.1-java

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