mirah 0.0.7-java → 0.0.8-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. data/History.txt +181 -0
  2. data/README.txt +6 -10
  3. data/Rakefile +86 -9
  4. data/bin/mirah +2 -0
  5. data/bin/mirahc +2 -0
  6. data/bin/mirahp +2 -0
  7. data/{bin/dubyp → examples/interfaces.mirah} +16 -9
  8. data/examples/macros/square.mirah +12 -0
  9. data/examples/macros/square_int.mirah +12 -0
  10. data/examples/macros/string-each-char.mirah +14 -0
  11. data/examples/maven/README.txt +2 -0
  12. data/examples/maven/pom.xml +23 -0
  13. data/examples/maven/src/main/mirah/hello_mirah.mirah +9 -0
  14. data/examples/rosettacode/100-doors.mirah +44 -0
  15. data/examples/rosettacode/99-bottles-of-beer.mirah +13 -0
  16. data/examples/rosettacode/README.txt +9 -0
  17. data/examples/rosettacode/boolean-values.mirah +29 -0
  18. data/examples/rosettacode/comments.mirah +2 -0
  19. data/examples/rosettacode/copy-a-string.mirah +10 -0
  20. data/examples/rosettacode/count-occurrences-of-a-substring.mirah +40 -0
  21. data/examples/rosettacode/create-a-file.mirah +6 -0
  22. data/examples/rosettacode/empty-string.mirah +9 -0
  23. data/examples/rosettacode/factorial.mirah +10 -0
  24. data/examples/rosettacode/fibonacci.mirah +21 -0
  25. data/examples/rosettacode/file-size.mirah +5 -0
  26. data/examples/rosettacode/fizz-buzz.mirah +21 -0
  27. data/examples/rosettacode/flatten-a-list.mirah +24 -0
  28. data/examples/rosettacode/guess-the-number.mirah +21 -0
  29. data/examples/rosettacode/is-string-numeric.mirah +127 -0
  30. data/examples/rosettacode/palindrome.mirah +14 -0
  31. data/examples/rosettacode/repeat-a-string.mirah +9 -0
  32. data/examples/rosettacode/reverse-a-string.mirah +6 -0
  33. data/examples/rosettacode/rot-13.mirah +20 -0
  34. data/examples/rosettacode/user-input.mirah +4 -0
  35. data/examples/sort_closure.mirah +1 -1
  36. data/javalib/dynalink-0.2.jar +0 -0
  37. data/javalib/mirah-bootstrap.jar +0 -0
  38. data/lib/mirah.rb +7 -16
  39. data/lib/mirah/ast.rb +22 -92
  40. data/lib/mirah/ast/call.rb +41 -9
  41. data/lib/mirah/ast/class.rb +34 -6
  42. data/lib/mirah/ast/flow.rb +17 -5
  43. data/lib/mirah/ast/intrinsics.rb +50 -8
  44. data/lib/mirah/ast/literal.rb +7 -0
  45. data/lib/mirah/ast/local.rb +9 -1
  46. data/lib/mirah/ast/method.rb +21 -8
  47. data/lib/mirah/ast/scope.rb +1 -1
  48. data/lib/mirah/ast/structure.rb +81 -15
  49. data/lib/mirah/ast/type.rb +4 -0
  50. data/{bin/dubyc → lib/mirah/commands.rb} +4 -11
  51. data/lib/mirah/commands/base.rb +54 -0
  52. data/lib/mirah/commands/compile.rb +39 -0
  53. data/{examples/wiki/Rakefile → lib/mirah/commands/parse.rb} +18 -17
  54. data/lib/mirah/commands/run.rb +73 -0
  55. data/lib/mirah/compiler.rb +37 -417
  56. data/lib/mirah/compiler/call.rb +45 -0
  57. data/lib/mirah/compiler/class.rb +81 -0
  58. data/lib/mirah/compiler/flow.rb +109 -0
  59. data/lib/mirah/compiler/literal.rb +130 -0
  60. data/lib/mirah/compiler/local.rb +59 -0
  61. data/lib/mirah/compiler/method.rb +44 -0
  62. data/lib/mirah/compiler/structure.rb +65 -0
  63. data/lib/mirah/compiler/type.rb +27 -0
  64. data/lib/mirah/env.rb +4 -6
  65. data/lib/mirah/generator.rb +61 -0
  66. data/lib/mirah/jvm/compiler.rb +8 -867
  67. data/lib/mirah/jvm/compiler/base.rb +270 -0
  68. data/lib/mirah/jvm/compiler/java_source.rb +779 -0
  69. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +851 -0
  70. data/lib/mirah/jvm/method_lookup.rb +21 -2
  71. data/lib/mirah/jvm/source_generator/builder.rb +10 -13
  72. data/lib/mirah/jvm/source_generator/loops.rb +99 -93
  73. data/lib/mirah/jvm/source_generator/precompile.rb +3 -2
  74. data/lib/mirah/jvm/typer.rb +3 -3
  75. data/lib/mirah/jvm/types.rb +10 -426
  76. data/lib/mirah/jvm/types/array_type.rb +62 -0
  77. data/lib/mirah/jvm/types/basic_types.rb +1 -0
  78. data/lib/mirah/jvm/types/dynamic_type.rb +46 -0
  79. data/lib/mirah/jvm/types/factory.rb +23 -5
  80. data/lib/mirah/jvm/types/interface_definition.rb +20 -0
  81. data/lib/mirah/jvm/types/intrinsics.rb +15 -3
  82. data/lib/mirah/jvm/types/meta_type.rb +45 -0
  83. data/lib/mirah/jvm/types/methods.rb +12 -5
  84. data/lib/mirah/jvm/types/null_type.rb +27 -0
  85. data/lib/mirah/jvm/types/primitive_type.rb +38 -0
  86. data/lib/mirah/jvm/types/source_mirror.rb +266 -0
  87. data/lib/mirah/jvm/types/type.rb +173 -0
  88. data/lib/mirah/jvm/types/type_definition.rb +55 -0
  89. data/lib/mirah/jvm/types/unreachable_type.rb +27 -0
  90. data/lib/mirah/jvm/types/void_type.rb +19 -0
  91. data/lib/mirah/parser.rb +90 -0
  92. data/lib/mirah/plugin/gwt.rb +5 -5
  93. data/lib/mirah/plugin/java.rb +1 -1
  94. data/lib/mirah/transform.rb +4 -321
  95. data/lib/mirah/transform/ast_ext.rb +63 -0
  96. data/lib/mirah/transform/error.rb +13 -0
  97. data/lib/mirah/transform/helper.rb +761 -0
  98. data/lib/mirah/transform/transformer.rb +255 -0
  99. data/lib/mirah/typer.rb +2 -383
  100. data/{bin/duby → lib/mirah/typer/base.rb} +12 -10
  101. data/lib/mirah/typer/simple.rb +377 -0
  102. data/lib/mirah/util/argument_processor.rb +114 -0
  103. data/lib/mirah/util/class_loader.rb +37 -0
  104. data/lib/mirah/util/compilation_state.rb +51 -0
  105. data/lib/mirah/util/process_errors.rb +33 -0
  106. data/lib/mirah/version.rb +1 -1
  107. data/lib/mirah_task.rb +3 -2
  108. data/test/{test_ast.rb → core/test_ast.rb} +6 -0
  109. data/test/{test_compilation.rb → core/test_compilation.rb} +0 -0
  110. data/test/{test_env.rb → core/test_env.rb} +24 -25
  111. data/test/{test_macros.rb → core/test_macros.rb} +2 -4
  112. data/test/{test_typer.rb → core/test_typer.rb} +0 -3
  113. data/test/jvm/bytecode_test_helper.rb +181 -0
  114. data/test/{test_javac_compiler.rb → jvm/javac_test_helper.rb} +38 -22
  115. data/test/jvm/test_enumerable.rb +304 -0
  116. data/test/{test_java_typer.rb → jvm/test_java_typer.rb} +2 -4
  117. data/test/{test_jvm_compiler.rb → jvm/test_jvm_compiler.rb} +146 -443
  118. data/test/jvm/test_macros.rb +147 -0
  119. data/test/jvm/test_main_method.rb +15 -0
  120. data/test/{test_gwt.rb → plugins/test_gwt.rb} +0 -2
  121. metadata +103 -91
  122. data/bin/jrubyp +0 -52
  123. data/examples/wiki/src/org/mirah/wiki/MirahWiki.duby +0 -339
  124. data/examples/wiki/src/org/mirah/wiki/edit.eduby.html +0 -42
  125. data/examples/wiki/src/org/mirah/wiki/error.eduby.html +0 -2
  126. data/examples/wiki/src/org/mirah/wiki/layout.eduby.html +0 -69
  127. data/examples/wiki/src/org/mirah/wiki/parser.eduby.html +0 -7
  128. data/examples/wiki/src/org/mirah/wiki/view.eduby.html +0 -15
  129. data/examples/wiki/war/WEB-INF/classes/test/HeredocContext.class +0 -0
  130. data/examples/wiki/war/WEB-INF/classes/test/MirahParser.class +0 -0
  131. data/examples/wiki/war/WEB-INF/lib/appengine-api.jar +0 -0
  132. data/examples/wiki/war/WEB-INF/lib/dubydatastore.jar +0 -0
  133. data/examples/wiki/war/WEB-INF/lib/jmeta-runtime.jar +0 -0
  134. data/examples/wiki/war/WEB-INF/lib/pegdown-stubs.jar +0 -0
  135. data/examples/wiki/war/WEB-INF/pegdown.jar +0 -0
  136. data/examples/wiki/war/app.yaml +0 -21
  137. data/examples/wiki/war/public/favicon.ico +0 -0
  138. data/examples/wiki/war/public/images/appengine_duby.png +0 -0
  139. data/examples/wiki/war/public/images/back.gif +0 -0
  140. data/examples/wiki/war/public/images/dir.gif +0 -0
  141. data/examples/wiki/war/public/images/file.gif +0 -0
  142. data/examples/wiki/war/public/javascripts/prettify.js +0 -61
  143. data/examples/wiki/war/public/robots.txt +0 -0
  144. data/examples/wiki/war/public/stylesheets/main.css +0 -156
  145. data/examples/wiki/war/public/stylesheets/prettify.css +0 -1
  146. data/examples/wiki/war/public/stylesheets/sh_style.css +0 -66
  147. data/examples/wiki/war/public/stylesheets/source.css +0 -21
  148. data/examples/wiki/war/public/wmd/images/bg-fill.png +0 -0
  149. data/examples/wiki/war/public/wmd/images/bg.png +0 -0
  150. data/examples/wiki/war/public/wmd/images/blockquote.png +0 -0
  151. data/examples/wiki/war/public/wmd/images/bold.png +0 -0
  152. data/examples/wiki/war/public/wmd/images/code.png +0 -0
  153. data/examples/wiki/war/public/wmd/images/h1.png +0 -0
  154. data/examples/wiki/war/public/wmd/images/hr.png +0 -0
  155. data/examples/wiki/war/public/wmd/images/img.png +0 -0
  156. data/examples/wiki/war/public/wmd/images/italic.png +0 -0
  157. data/examples/wiki/war/public/wmd/images/link.png +0 -0
  158. data/examples/wiki/war/public/wmd/images/ol.png +0 -0
  159. data/examples/wiki/war/public/wmd/images/redo.png +0 -0
  160. data/examples/wiki/war/public/wmd/images/separator.png +0 -0
  161. data/examples/wiki/war/public/wmd/images/ul.png +0 -0
  162. data/examples/wiki/war/public/wmd/images/undo.png +0 -0
  163. data/examples/wiki/war/public/wmd/images/wmd-on.png +0 -0
  164. data/examples/wiki/war/public/wmd/images/wmd.png +0 -0
  165. data/examples/wiki/war/public/wmd/showdown.js +0 -421
  166. data/examples/wiki/war/public/wmd/wmd-base.js +0 -1799
  167. data/examples/wiki/war/public/wmd/wmd-plus.js +0 -311
  168. data/examples/wiki/war/public/wmd/wmd.js +0 -73
  169. data/examples/wiki/war/src/org/mirah/wiki/MirahWiki.duby +0 -339
  170. data/examples/wiki/war/src/org/mirah/wiki/edit.eduby.html +0 -42
  171. data/examples/wiki/war/src/org/mirah/wiki/error.eduby.html +0 -2
  172. data/examples/wiki/war/src/org/mirah/wiki/layout.eduby.html +0 -69
  173. data/examples/wiki/war/src/org/mirah/wiki/parser.eduby.html +0 -7
  174. data/examples/wiki/war/src/org/mirah/wiki/view.eduby.html +0 -15
  175. data/javalib/dynalink-0.1.jar +0 -0
  176. data/javalib/jsr292-mock.jar +0 -0
  177. data/lib/mirah/class_loader.rb +0 -35
  178. data/lib/mirah/compilation_state.rb +0 -28
  179. data/lib/mirah/impl.rb +0 -273
  180. data/lib/mirah/jvm/base.rb +0 -267
  181. data/lib/mirah/jvm/source_compiler.rb +0 -760
  182. data/lib/mirah/transform2.rb +0 -752
@@ -13,21 +13,27 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
17
-
16
+ require 'bundler/setup'
18
17
  require 'test/unit'
19
18
  require 'mirah'
20
- require 'mirah/jvm/source_compiler'
21
- require 'jruby'
22
- require 'stringio'
23
- require File.join(File.dirname(__FILE__), 'test_jvm_compiler')
19
+
20
+ require 'bytecode_test_helper'
21
+
22
+
23
+ require 'mirah/jvm/compiler/java_source'
24
+
24
25
 
25
26
  # make sure . is in CLASSPATH
26
27
  $CLASSPATH << '.'
27
28
 
28
- class TestJavacCompiler < TestJVMCompiler
29
+
30
+ module JavacCompiler
29
31
  import javax.tools.ToolProvider
30
32
  import java.util.Arrays
33
+ import java.lang.System
34
+ import java.io.PrintStream
35
+ include Mirah
36
+
31
37
  def javac(files)
32
38
  compiler = ToolProvider.system_java_compiler
33
39
  fm = compiler.get_standard_file_manager(nil, nil, nil)
@@ -45,27 +51,25 @@ class TestJavacCompiler < TestJVMCompiler
45
51
  cls = loader.define_class(name[0..-6].tr('/', '.'), bytecode.to_java_bytes)
46
52
  classes << JavaUtilities.get_proxy_class(cls.name)
47
53
  @tmp_classes << name
48
- @tmp_classes << classfile
54
+ @tmp_classes << classfile
55
+ pattern = classfile.sub /\.class$/, '$*.class'
56
+ @tmp_classes.concat(Dir.glob(pattern))
49
57
  end
50
58
  end
51
59
  classes
52
60
  end
53
61
 
54
- def compile(code)
55
- File.unlink(*@tmp_classes)
56
- @tmp_classes.clear
57
- AST.type_factory = Mirah::JVM::Types::TypeFactory.new
58
- state = Mirah::CompilationState.new
59
- state.save_extensions = false
60
- transformer = Mirah::Transform::Transformer.new(state)
61
- Java::MirahImpl::Builtin.initialize_builtins(transformer)
62
- name = "script" + System.nano_time.to_s
63
- ast = AST.parse(code, name, true, transformer)
64
- typer = Typer::JVM.new(transformer)
65
- ast.infer(typer, true)
66
- typer.resolve(true)
67
- compiler = Compiler::JavaSource.new
62
+ def create_compiler
63
+ JVM::Compiler::JavaSource.new
64
+ end
65
+
66
+ def compile_ast ast
67
+ compiler = create_compiler
68
68
  ast.compile(compiler, false)
69
+ compiler
70
+ end
71
+
72
+ def generate_classes compiler
69
73
  java_files = []
70
74
  compiler.generate do |name, builder|
71
75
  bytes = builder.generate
@@ -77,4 +81,16 @@ class TestJavacCompiler < TestJVMCompiler
77
81
  end
78
82
  classes = javac(java_files)
79
83
  end
84
+
85
+ def clear_tmp_files
86
+ super
87
+ # wipe out Script*_xform_* classes, since we're messy
88
+ File.unlink(*Dir['Script*_xform_*.class'])
89
+ end
90
+ end
91
+
92
+
93
+ class Test::Unit::TestCase
94
+ include JavacCompiler
95
+
80
96
  end
@@ -0,0 +1,304 @@
1
+ # Copyright (c) 2010 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 TestEnumerable < Test::Unit::TestCase
17
+ def test_for
18
+ cls, = compile(<<-EOF)
19
+ def foo
20
+ a = int[3]
21
+ count = 0
22
+ for x in a
23
+ count += 1
24
+ end
25
+ count
26
+ end
27
+ EOF
28
+
29
+ cls, = compile(<<-EOF)
30
+ def foo(a:int[])
31
+ count = 0
32
+ for x in a
33
+ count += x
34
+ end
35
+ count
36
+ end
37
+ EOF
38
+
39
+ assert_equal(9, cls.foo([2, 3, 4].to_java(:int)))
40
+
41
+ cls, = compile(<<-EOF)
42
+ def foo(a:Iterable)
43
+ a.each do |x|
44
+ puts x
45
+ end
46
+ end
47
+ EOF
48
+
49
+ assert_output("1\n2\n3\n") do
50
+ list = java.util.ArrayList.new
51
+ list << "1"
52
+ list << "2"
53
+ list << "3"
54
+ cls.foo(list)
55
+ end
56
+
57
+ cls, = compile(<<-EOF)
58
+ import java.util.ArrayList
59
+ def foo(a:ArrayList)
60
+ a.each do |x|
61
+ puts x
62
+ end
63
+ end
64
+ EOF
65
+
66
+ assert_output("1\n2\n3\n") do
67
+ list = java.util.ArrayList.new
68
+ list << "1"
69
+ list << "2"
70
+ list << "3"
71
+ cls.foo(list)
72
+ end
73
+
74
+ cls, = compile(<<-EOF)
75
+ def foo(a:int[])
76
+ a.each {|x| x += 1;puts x; redo if x == 2}
77
+ end
78
+ EOF
79
+
80
+ assert_output("2\n3\n3\n4\n") do
81
+ cls.foo([1,2,3].to_java(:int))
82
+ end
83
+ end
84
+
85
+ def test_all
86
+ cls, = compile(<<-EOF)
87
+ def foo(a:int[])
88
+ a.all? {|x| x % 2 == 0}
89
+ end
90
+ EOF
91
+
92
+ assert_equal(false, cls.foo([2, 3, 4].to_java(:int)))
93
+ assert_equal(true, cls.foo([2, 0, 4].to_java(:int)))
94
+
95
+ cls, = compile(<<-EOF)
96
+ def foo(a:String[])
97
+ a.all?
98
+ end
99
+ EOF
100
+
101
+ assert_equal(true, cls.foo(["a", "", "b"].to_java(:string)))
102
+ assert_equal(false, cls.foo(["a", nil, "b"].to_java(:string)))
103
+ end
104
+
105
+ def test_downto
106
+ cls, = compile(<<-EOF)
107
+ def foo(i:int)
108
+ i.downto(1) {|x| puts x }
109
+ end
110
+ EOF
111
+
112
+ assert_output("3\n2\n1\n") do
113
+ cls.foo(3)
114
+ end
115
+ end
116
+
117
+ def test_upto
118
+ cls, = compile(<<-EOF)
119
+ def foo(i:int)
120
+ i.upto(3) {|x| puts x }
121
+ end
122
+ EOF
123
+
124
+ assert_output("1\n2\n3\n") do
125
+ cls.foo(1)
126
+ end
127
+ end
128
+
129
+ def test_times
130
+ cls, = compile(<<-EOF)
131
+ def foo(i:int)
132
+ i.times {|x| puts x }
133
+ end
134
+ EOF
135
+
136
+ assert_output("0\n1\n2\n") do
137
+ cls.foo(3)
138
+ end
139
+
140
+ cls, = compile(<<-EOF)
141
+ def foo(i:int)
142
+ i.times { puts "Hi" }
143
+ end
144
+ EOF
145
+
146
+ assert_output("Hi\nHi\nHi\n") do
147
+ cls.foo(3)
148
+ end
149
+ end
150
+
151
+ def test_general_loop
152
+ cls, = compile(<<-EOF)
153
+ def foo(x:boolean)
154
+ a = ""
155
+ __gloop__(nil, x, true, nil, nil) {a += "<body>"}
156
+ a
157
+ end
158
+ EOF
159
+ assert_equal("", cls.foo(false))
160
+
161
+ cls, = compile(<<-EOF)
162
+ def foo
163
+ a = ""
164
+ __gloop__(nil, false, false, nil, nil) {a += "<body>"}
165
+ a
166
+ end
167
+ EOF
168
+ assert_equal("<body>", cls.foo)
169
+
170
+ cls, = compile(<<-EOF)
171
+ def foo(x:boolean)
172
+ a = ""
173
+ __gloop__(a += "<init>", x, true, a += "<pre>", a += "<post>") do
174
+ a += "<body>"
175
+ end
176
+ a
177
+ end
178
+ EOF
179
+ assert_equal("<init>", cls.foo(false))
180
+
181
+ cls, = compile(<<-EOF)
182
+ def foo
183
+ a = ""
184
+ __gloop__(a += "<init>", false, false, a += "<pre>", a += "<post>") do
185
+ a += "<body>"
186
+ end
187
+ a
188
+ end
189
+ EOF
190
+ assert_equal("<init><pre><body><post>", cls.foo)
191
+
192
+ cls, = compile(<<-EOF)
193
+ def foo
194
+ a = ""
195
+ __gloop__(a += "<init>", false, false, a += "<pre>", a += "<post>") do
196
+ a += "<body>"
197
+ redo if a.length < 20
198
+ end
199
+ a
200
+ end
201
+ EOF
202
+ assert_equal( "<init><pre><body><body><post>", cls.foo)
203
+
204
+ cls, = compile(<<-EOF)
205
+ def foo
206
+ a = ""
207
+ __gloop__(a += "<init>", a.length < 20, true, a += "<pre>", a += "<post>") do
208
+ next if a.length < 17
209
+ a += "<body>"
210
+ end
211
+ a
212
+ end
213
+ EOF
214
+ assert_equal("<init><pre><post><pre><body><post>", cls.foo)
215
+ end
216
+
217
+
218
+ def test_each
219
+ cls, = compile(<<-EOF)
220
+ def foo
221
+ [1,2,3].each {|x| puts x}
222
+ end
223
+ EOF
224
+ assert_output("1\n2\n3\n") do
225
+ cls.foo
226
+ end
227
+ end
228
+
229
+ def test_each_without_block_arguments
230
+ cls, = compile(<<-EOF)
231
+ def foo
232
+ [1,2,3].each { puts :thrice }
233
+ end
234
+ EOF
235
+ assert_output("thrice\nthrice\nthrice\n") do
236
+ cls.foo
237
+ end
238
+
239
+ end
240
+
241
+ def test_any
242
+ cls, = compile(<<-EOF)
243
+ import java.lang.Integer
244
+ def foo
245
+ puts [1,2,3].any?
246
+ puts [1,2,3].any? {|x| Integer(x).intValue > 3}
247
+ end
248
+ EOF
249
+ assert_output("true\nfalse\n") do
250
+ cls.foo
251
+ end
252
+ end
253
+
254
+ def test_all
255
+ cls, = compile(<<-EOF)
256
+ import java.lang.Integer
257
+ def foo
258
+ puts [1,2,3].all?
259
+ puts [1,2,3].all? {|x| Integer(x).intValue > 3}
260
+ end
261
+ EOF
262
+ assert_output("true\nfalse\n") do
263
+ cls.foo
264
+ end
265
+ end
266
+
267
+ def test_mirah_iterable
268
+ cls, = compile(<<-EOF)
269
+ import java.util.Iterator
270
+ class MyIterator; implements Iterable, Iterator
271
+ def initialize(x:Object)
272
+ @next = x
273
+ end
274
+
275
+ def hasNext
276
+ @next != nil
277
+ end
278
+
279
+ def next
280
+ result = @next
281
+ @next = nil
282
+ result
283
+ end
284
+
285
+ def iterator
286
+ self
287
+ end
288
+
289
+ def remove
290
+ raise UnsupportedOperationException
291
+ end
292
+
293
+ def self.test(x:String)
294
+ MyIterator.new(x).each {|y| puts y}
295
+ end
296
+ end
297
+ EOF
298
+
299
+ assert_output("Hi\n") do
300
+ cls.test("Hi")
301
+ end
302
+ end
303
+
304
+ end
@@ -13,8 +13,6 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
17
-
18
16
  require 'test/unit'
19
17
  require 'mirah'
20
18
 
@@ -23,8 +21,8 @@ class TestJavaTyper < Test::Unit::TestCase
23
21
 
24
22
  def setup
25
23
  AST.type_factory = Mirah::JVM::Types::TypeFactory.new
26
- @typer = Typer::JVM.new(nil)
27
- compiler = Mirah::Compiler::JVM.new
24
+ @typer = Mirah::JVM::Typer.new(nil)
25
+ compiler = Mirah::JVM::Compiler::JVMBytecode.new
28
26
 
29
27
  @java_typer = Typer::JavaTyper.new
30
28
  end
@@ -13,92 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
17
-
18
- require 'test/unit'
19
- require 'mirah'
20
- require 'jruby'
21
- require 'stringio'
22
- require 'fileutils'
23
-
24
- unless Mirah::AST.macro "__gloop__"
25
- Mirah::AST.defmacro "__gloop__" do |transformer, fcall, parent|
26
- Mirah::AST::Loop.new(parent, parent.position, true, false) do |loop|
27
- init, condition, check_first, pre, post = fcall.parameters
28
- loop.check_first = check_first.literal
29
-
30
- nil_t = Mirah::AST::Null
31
- loop.init = init
32
- loop.pre = pre
33
- loop.post = post
34
-
35
- body = fcall.block.body
36
- body.parent = loop
37
- [
38
- Mirah::AST::Condition.new(loop, parent.position) do |c|
39
- condition.parent = c
40
- [condition]
41
- end,
42
- body
43
- ]
44
- end
45
- end
46
- end
47
-
48
16
  class TestJVMCompiler < Test::Unit::TestCase
49
- include Mirah
50
- import java.lang.System
51
- import java.io.PrintStream
52
-
53
- def setup
54
- @tmp_classes = []
55
- end
56
-
57
- def teardown
58
- AST.type_factory = nil
59
- File.unlink(*@tmp_classes)
60
- end
61
-
62
- def assert_include(value, array, message=nil)
63
- message = build_message message, '<?> does not include <?>', array, value
64
- assert_block message do
65
- array.include? value
66
- end
67
- end
68
-
69
- def compile(code)
70
- File.unlink(*@tmp_classes)
71
- @tmp_classes.clear
72
- AST.type_factory = Mirah::JVM::Types::TypeFactory.new
73
- name = "script" + System.nano_time.to_s
74
- state = Mirah::CompilationState.new
75
- state.save_extensions = false
76
- transformer = Mirah::Transform::Transformer.new(state)
77
- Java::MirahImpl::Builtin.initialize_builtins(transformer)
78
- ast = AST.parse(code, name, true, transformer)
79
- typer = Typer::JVM.new(transformer)
80
- ast.infer(typer, true)
81
- typer.resolve(true)
82
- compiler = Compiler::JVM.new
83
- compiler.compile(ast)
84
- classes = {}
85
- loader = Mirah::ClassLoader.new(JRuby.runtime.jruby_class_loader, classes)
86
- compiler.generate do |name, builder|
87
- bytes = builder.generate
88
- FileUtils.mkdir_p(File.dirname(name))
89
- open("#{name}", "wb") do |f|
90
- f << bytes
91
- end
92
- classes[name[0..-7]] = bytes
93
- end
94
-
95
- classes.keys.map do |name|
96
- cls = loader.load_class(name.tr('/', '.'))
97
- proxy = JavaUtilities.get_proxy_class(cls.name)
98
- @tmp_classes << "#{name}.class"
99
- proxy
100
- end
101
- end
102
17
 
103
18
  def test_local
104
19
  cls, = compile("def foo; a = 1; a; end")
@@ -324,7 +239,7 @@ class TestJVMCompiler < Test::Unit::TestCase
324
239
 
325
240
  assert_output("Hello there\n") { cls.foo }
326
241
 
327
- script, a, b = compile(<<-EOF)
242
+ a, b = compile(<<-EOF)
328
243
  class VoidBase
329
244
  def foo
330
245
  returns void
@@ -342,7 +257,6 @@ class TestJVMCompiler < Test::Unit::TestCase
342
257
  end
343
258
  end
344
259
  EOF
345
-
346
260
  assert_output("foo\nbar\n") { b.foobar }
347
261
 
348
262
  end
@@ -397,24 +311,7 @@ class TestJVMCompiler < Test::Unit::TestCase
397
311
  foo, = compile("class ClassDeclTest;end")
398
312
  assert_equal('ClassDeclTest', foo.java_class.name)
399
313
  end
400
-
401
- def capture_output
402
- saved_output = System.out
403
- output = StringIO.new
404
- System.setOut(PrintStream.new(output.to_outputstream))
405
- begin
406
- yield
407
- output.rewind
408
- output.read
409
- ensure
410
- System.setOut(saved_output)
411
- end
412
- end
413
-
414
- def assert_output(expected, &block)
415
- assert_equal(expected, capture_output(&block))
416
- end
417
-
314
+
418
315
  def test_puts
419
316
  cls, = compile("def foo;puts 'Hello World!';end")
420
317
  output = capture_output do
@@ -637,6 +534,32 @@ class TestJVMCompiler < Test::Unit::TestCase
637
534
  cls, = compile(
638
535
  'def foo; a = 0; while a < 2; a+=1; end; end')
639
536
  assert_equal(nil, cls.foo)
537
+
538
+ # TODO: loop doesn't work unless you're explicitly in a class
539
+ # cls, = compile(<<-EOF)
540
+ # def bar(a:fixnum)
541
+ # loop do
542
+ # a += 1
543
+ # break if a > 2
544
+ # end
545
+ # a
546
+ # end
547
+ # EOF
548
+ # assert_equal(3, cls.bar(0))
549
+
550
+ loopy, = compile(<<-EOF)
551
+ class Loopy
552
+ def bar(a:fixnum)
553
+ loop do
554
+ a += 1
555
+ break if a > 2
556
+ end
557
+ a
558
+ end
559
+ end
560
+ EOF
561
+
562
+ assert_equal(3, loopy.new.bar(0))
640
563
  end
641
564
 
642
565
  def test_break
@@ -852,7 +775,7 @@ class TestJVMCompiler < Test::Unit::TestCase
852
775
  end
853
776
 
854
777
  def test_implements
855
- script, cls = compile(<<-EOF)
778
+ cls, = compile(<<-EOF)
856
779
  import java.lang.Iterable
857
780
  class Foo; implements Iterable
858
781
  def iterator
@@ -900,16 +823,16 @@ class TestJVMCompiler < Test::Unit::TestCase
900
823
  end
901
824
 
902
825
  def test_interface_declaration
903
- script, interface = compile('interface A do; end')
826
+ interface = compile('interface A do; end').first
904
827
  assert(interface.java_class.interface?)
905
828
  assert_equal('A', interface.java_class.name)
906
829
 
907
- script, a, b = compile('interface A do; end; interface B < A do; end')
830
+ a, b = compile('interface A do; end; interface B < A do; end')
908
831
  assert_include(a, b.ancestors)
909
832
  assert_equal('A', a.java_class.name)
910
833
  assert_equal('B', b.java_class.name)
911
834
 
912
- script, a, b, c = compile(<<-EOF)
835
+ a, b, c = compile(<<-EOF)
913
836
  interface A do
914
837
  end
915
838
 
@@ -1095,6 +1018,28 @@ class TestJVMCompiler < Test::Unit::TestCase
1095
1018
  cls.foo
1096
1019
  end
1097
1020
  assert_equal("foo\n", output)
1021
+
1022
+
1023
+ cls, = compile(<<-EOF)
1024
+ def foo(x:boolean)
1025
+ throws Exception
1026
+ if x
1027
+ raise Exception, "x"
1028
+ end
1029
+ rescue Exception
1030
+ "x"
1031
+ else
1032
+ raise Exception, "!x"
1033
+ end
1034
+ EOF
1035
+
1036
+ assert_equal "x", cls.foo(true)
1037
+ begin
1038
+ cls.foo(false)
1039
+ fail
1040
+ rescue java.lang.Exception => ex
1041
+ assert_equal "java.lang.Exception: !x", ex.message
1042
+ end
1098
1043
  end
1099
1044
 
1100
1045
  def test_ensure
@@ -1135,7 +1080,6 @@ class TestJVMCompiler < Test::Unit::TestCase
1135
1080
  cls.foo
1136
1081
  end
1137
1082
  assert_equal "Hi\n", output
1138
-
1139
1083
  end
1140
1084
 
1141
1085
  def test_cast
@@ -1266,207 +1210,6 @@ class TestJVMCompiler < Test::Unit::TestCase
1266
1210
  assert_equal(true, cls.foo("a"))
1267
1211
  assert_equal(false, cls.foo(nil))
1268
1212
  end
1269
-
1270
- def test_for
1271
- cls, = compile(<<-EOF)
1272
- def foo
1273
- a = int[3]
1274
- count = 0
1275
- for x in a
1276
- count += 1
1277
- end
1278
- count
1279
- end
1280
- EOF
1281
-
1282
- cls, = compile(<<-EOF)
1283
- def foo(a:int[])
1284
- count = 0
1285
- for x in a
1286
- count += x
1287
- end
1288
- count
1289
- end
1290
- EOF
1291
-
1292
- assert_equal(9, cls.foo([2, 3, 4].to_java(:int)))
1293
-
1294
- cls, = compile(<<-EOF)
1295
- def foo(a:Iterable)
1296
- a.each do |x|
1297
- puts x
1298
- end
1299
- end
1300
- EOF
1301
-
1302
- assert_output("1\n2\n3\n") do
1303
- list = java.util.ArrayList.new
1304
- list << "1"
1305
- list << "2"
1306
- list << "3"
1307
- cls.foo(list)
1308
- end
1309
-
1310
- cls, = compile(<<-EOF)
1311
- import java.util.ArrayList
1312
- def foo(a:ArrayList)
1313
- a.each do |x|
1314
- puts x
1315
- end
1316
- end
1317
- EOF
1318
-
1319
- assert_output("1\n2\n3\n") do
1320
- list = java.util.ArrayList.new
1321
- list << "1"
1322
- list << "2"
1323
- list << "3"
1324
- cls.foo(list)
1325
- end
1326
-
1327
- cls, = compile(<<-EOF)
1328
- def foo(a:int[])
1329
- a.each {|x| x += 1;puts x; redo if x == 2}
1330
- end
1331
- EOF
1332
-
1333
- assert_output("2\n3\n3\n4\n") do
1334
- cls.foo([1,2,3].to_java(:int))
1335
- end
1336
- end
1337
-
1338
- def test_all
1339
- cls, = compile(<<-EOF)
1340
- def foo(a:int[])
1341
- a.all? {|x| x % 2 == 0}
1342
- end
1343
- EOF
1344
-
1345
- assert_equal(false, cls.foo([2, 3, 4].to_java(:int)))
1346
- assert_equal(true, cls.foo([2, 0, 4].to_java(:int)))
1347
-
1348
- cls, = compile(<<-EOF)
1349
- def foo(a:String[])
1350
- a.all?
1351
- end
1352
- EOF
1353
-
1354
- assert_equal(true, cls.foo(["a", "", "b"].to_java(:string)))
1355
- assert_equal(false, cls.foo(["a", nil, "b"].to_java(:string)))
1356
- end
1357
-
1358
- def test_downto
1359
- cls, = compile(<<-EOF)
1360
- def foo(i:int)
1361
- i.downto(1) {|x| puts x }
1362
- end
1363
- EOF
1364
-
1365
- assert_output("3\n2\n1\n") do
1366
- cls.foo(3)
1367
- end
1368
- end
1369
-
1370
- def test_upto
1371
- cls, = compile(<<-EOF)
1372
- def foo(i:int)
1373
- i.upto(3) {|x| puts x }
1374
- end
1375
- EOF
1376
-
1377
- assert_output("1\n2\n3\n") do
1378
- cls.foo(1)
1379
- end
1380
- end
1381
-
1382
- def test_times
1383
- cls, = compile(<<-EOF)
1384
- def foo(i:int)
1385
- i.times {|x| puts x }
1386
- end
1387
- EOF
1388
-
1389
- assert_output("0\n1\n2\n") do
1390
- cls.foo(3)
1391
- end
1392
-
1393
- cls, = compile(<<-EOF)
1394
- def foo(i:int)
1395
- i.times { puts "Hi" }
1396
- end
1397
- EOF
1398
-
1399
- assert_output("Hi\nHi\nHi\n") do
1400
- cls.foo(3)
1401
- end
1402
- end
1403
-
1404
- def test_general_loop
1405
- cls, = compile(<<-EOF)
1406
- def foo(x:boolean)
1407
- a = ""
1408
- __gloop__(nil, x, true, nil, nil) {a += "<body>"}
1409
- a
1410
- end
1411
- EOF
1412
- assert_equal("", cls.foo(false))
1413
-
1414
- cls, = compile(<<-EOF)
1415
- def foo
1416
- a = ""
1417
- __gloop__(nil, false, false, nil, nil) {a += "<body>"}
1418
- a
1419
- end
1420
- EOF
1421
- assert_equal("<body>", cls.foo)
1422
-
1423
- cls, = compile(<<-EOF)
1424
- def foo(x:boolean)
1425
- a = ""
1426
- __gloop__(a += "<init>", x, true, a += "<pre>", a += "<post>") do
1427
- a += "<body>"
1428
- end
1429
- a
1430
- end
1431
- EOF
1432
- assert_equal("<init>", cls.foo(false))
1433
-
1434
- cls, = compile(<<-EOF)
1435
- def foo
1436
- a = ""
1437
- __gloop__(a += "<init>", false, false, a += "<pre>", a += "<post>") do
1438
- a += "<body>"
1439
- end
1440
- a
1441
- end
1442
- EOF
1443
- assert_equal("<init><pre><body><post>", cls.foo)
1444
-
1445
- cls, = compile(<<-EOF)
1446
- def foo
1447
- a = ""
1448
- __gloop__(a += "<init>", false, false, a += "<pre>", a += "<post>") do
1449
- a += "<body>"
1450
- redo if a.length < 20
1451
- end
1452
- a
1453
- end
1454
- EOF
1455
- assert_equal( "<init><pre><body><body><post>", cls.foo)
1456
-
1457
- cls, = compile(<<-EOF)
1458
- def foo
1459
- a = ""
1460
- __gloop__(a += "<init>", a.length < 20, true, a += "<pre>", a += "<post>") do
1461
- next if a.length < 17
1462
- a += "<body>"
1463
- end
1464
- a
1465
- end
1466
- EOF
1467
- assert_equal("<init><pre><post><pre><body><post>", cls.foo)
1468
- end
1469
-
1470
1213
  def test_if_expr
1471
1214
  cls, = compile(<<-EOF)
1472
1215
  def foo(a:int)
@@ -1795,7 +1538,7 @@ class TestJVMCompiler < Test::Unit::TestCase
1795
1538
  end
1796
1539
 
1797
1540
  def test_super_constructor
1798
- cls, a, b = compile(<<-EOF)
1541
+ sc_a, sc_b = compile(<<-EOF)
1799
1542
  class SC_A
1800
1543
  def initialize(a:int)
1801
1544
  puts "A"
@@ -1811,7 +1554,7 @@ class TestJVMCompiler < Test::Unit::TestCase
1811
1554
  EOF
1812
1555
 
1813
1556
  assert_output("A\nB\n") do
1814
- b.new
1557
+ sc_b.new
1815
1558
  end
1816
1559
  end
1817
1560
 
@@ -2073,44 +1816,28 @@ class TestJVMCompiler < Test::Unit::TestCase
2073
1816
  cls.main(nil)
2074
1817
  end
2075
1818
  end
2076
-
2077
- def test_each
1819
+
1820
+ def test_block_with_no_arguments_and_return_value
2078
1821
  cls, = compile(<<-EOF)
2079
- def foo
2080
- [1,2,3].each {|x| puts x}
1822
+ import java.util.concurrent.Callable
1823
+ def foo c:Callable
1824
+ throws Exception
1825
+ puts c.call
2081
1826
  end
2082
- EOF
2083
- assert_output("1\n2\n3\n") do
2084
- cls.foo
2085
- end
2086
- end
2087
-
2088
- def test_any
2089
- cls, = compile(<<-EOF)
2090
- import java.lang.Integer
2091
- def foo
2092
- puts [1,2,3].any?
2093
- puts [1,2,3].any? {|x| Integer(x).intValue > 3}
1827
+ begin
1828
+ foo do
1829
+ "an object"
2094
1830
  end
2095
- EOF
2096
- assert_output("true\nfalse\n") do
2097
- cls.foo
2098
- end
2099
- end
2100
-
2101
- def test_all
2102
- cls, = compile(<<-EOF)
2103
- import java.lang.Integer
2104
- def foo
2105
- puts [1,2,3].all?
2106
- puts [1,2,3].all? {|x| Integer(x).intValue > 3}
1831
+ rescue
1832
+ puts "never get here"
2107
1833
  end
2108
1834
  EOF
2109
- assert_output("true\nfalse\n") do
2110
- cls.foo
1835
+ assert_output("an object\n") do
1836
+ cls.main(nil)
2111
1837
  end
2112
1838
  end
2113
1839
 
1840
+
2114
1841
  def test_optional_args
2115
1842
  cls, = compile(<<-EOF)
2116
1843
  def foo(a:int, b:int = 1, c:int = 2)
@@ -2165,7 +1892,7 @@ class TestJVMCompiler < Test::Unit::TestCase
2165
1892
  end
2166
1893
 
2167
1894
  def test_duby_iterable
2168
- script, cls = compile(<<-EOF)
1895
+ cls, = compile(<<-EOF)
2169
1896
  import java.util.Iterator
2170
1897
  class MyIterator; implements Iterable, Iterator
2171
1898
  def initialize(x:Object)
@@ -2195,6 +1922,7 @@ class TestJVMCompiler < Test::Unit::TestCase
2195
1922
  end
2196
1923
  end
2197
1924
  EOF
1925
+
2198
1926
  assert_output("Hi\n") do
2199
1927
  cls.test("Hi")
2200
1928
  end
@@ -2318,21 +2046,6 @@ class TestJVMCompiler < Test::Unit::TestCase
2318
2046
  assert_equal("java.lang.Character$UnicodeBlock", subset.java_class.name)
2319
2047
  end
2320
2048
 
2321
- def test_defmacro
2322
- cls, = compile(<<-EOF)
2323
- defmacro bar(x) do
2324
- x
2325
- end
2326
-
2327
- def foo
2328
- bar("bar")
2329
- end
2330
- EOF
2331
-
2332
- assert_equal("bar", cls.foo)
2333
- assert(!cls.respond_to?(:bar))
2334
- end
2335
-
2336
2049
  def test_default_constructor
2337
2050
  script, cls = compile(<<-EOF)
2338
2051
  class DefaultConstructable
@@ -2377,66 +2090,6 @@ class TestJVMCompiler < Test::Unit::TestCase
2377
2090
  assert_equal(false, cls.dynamic(java.lang.Object, nil))
2378
2091
  end
2379
2092
 
2380
- def test_instance_macro
2381
- # TODO fix annotation output and create a duby.anno.Extensions annotation.
2382
- return if self.class.name == 'TestJavacCompiler'
2383
- script, cls = compile(<<-EOF)
2384
- class InstanceMacros
2385
- def foobar
2386
- "foobar"
2387
- end
2388
-
2389
- macro def macro_foobar
2390
- quote {foobar}
2391
- end
2392
-
2393
- def call_foobar
2394
- macro_foobar
2395
- end
2396
- end
2397
-
2398
- def macro
2399
- InstanceMacros.new.macro_foobar
2400
- end
2401
-
2402
- def function
2403
- InstanceMacros.new.call_foobar
2404
- end
2405
- EOF
2406
-
2407
- assert_equal("foobar", script.function)
2408
- assert_equal("foobar", script.macro)
2409
- end
2410
-
2411
- def test_unquote
2412
- # TODO fix annotation output and create a duby.anno.Extensions annotation.
2413
- return if self.class.name == 'TestJavacCompiler'
2414
-
2415
- script, cls = compile(<<-'EOF')
2416
- class UnquoteMacros
2417
- macro def make_attr(name_node, type)
2418
- name = name_node.string_value
2419
- quote do
2420
- def `name`
2421
- @`name`
2422
- end
2423
- def `"#{name}_set"`(`name`:`type`)
2424
- @`name` = `name`
2425
- end
2426
- end
2427
- end
2428
-
2429
- make_attr :foo, :int
2430
- end
2431
-
2432
- x = UnquoteMacros.new
2433
- puts x.foo
2434
- x.foo = 3
2435
- puts x.foo
2436
- EOF
2437
- assert_output("0\n3\n") {script.main(nil)}
2438
- end
2439
-
2440
2093
  def test_static_import
2441
2094
  cls, = compile(<<-EOF)
2442
2095
  import java.util.Arrays
@@ -2451,7 +2104,7 @@ class TestJVMCompiler < Test::Unit::TestCase
2451
2104
  assert_kind_of(Java::JavaUtil::List, list)
2452
2105
  assert_equal(["1", "2", "3"], list.to_a)
2453
2106
 
2454
- scripe, cls = compile(<<-EOF)
2107
+ cls, = compile(<<-EOF)
2455
2108
  import java.util.Arrays
2456
2109
  class StaticImports
2457
2110
  include Arrays
@@ -2568,7 +2221,7 @@ class TestJVMCompiler < Test::Unit::TestCase
2568
2221
  end
2569
2222
 
2570
2223
  def test_abstract
2571
- script, cls1, cls2 = compile(<<-EOF)
2224
+ abstract_class, concrete_class = compile(<<-EOF)
2572
2225
  abstract class Abstract
2573
2226
  abstract def foo:void; end
2574
2227
  def bar; puts "bar"; end
@@ -2579,12 +2232,12 @@ class TestJVMCompiler < Test::Unit::TestCase
2579
2232
  EOF
2580
2233
 
2581
2234
  assert_output("foo\nbar\n") do
2582
- a = cls2.new
2235
+ a = concrete_class.new
2583
2236
  a.foo
2584
2237
  a.bar
2585
2238
  end
2586
2239
  begin
2587
- cls1.new
2240
+ abstract_class.new
2588
2241
  fail "Expected InstantiationException"
2589
2242
  rescue java.lang.InstantiationException
2590
2243
  # expected
@@ -2697,26 +2350,6 @@ class TestJVMCompiler < Test::Unit::TestCase
2697
2350
  assert_equal("value", map["key"])
2698
2351
  end
2699
2352
 
2700
- def test_macro_hygene
2701
- cls, = compile(<<-EOF)
2702
- macro def doubleIt(arg)
2703
- quote do
2704
- x = `arg`
2705
- x = x + x
2706
- x
2707
- end
2708
- end
2709
-
2710
- def foo
2711
- x = "1"
2712
- puts doubleIt(x)
2713
- puts x
2714
- end
2715
- EOF
2716
-
2717
- assert_output("11\n1\n") {cls.foo}
2718
- end
2719
-
2720
2353
  def test_wide_nonexpressions
2721
2354
  script, cls1, cls2 = compile(<<-EOF)
2722
2355
  class WideA
@@ -2775,4 +2408,74 @@ class TestJVMCompiler < Test::Unit::TestCase
2775
2408
 
2776
2409
  assert_kind_of(java.util.HashSet, cls.foo)
2777
2410
  end
2411
+
2412
+ def test_colon2_cast
2413
+ cls, = compile(<<-EOF)
2414
+ def foo(x:Object)
2415
+ java.util::Map.Entry(x)
2416
+ end
2417
+ EOF
2418
+
2419
+ entry = java.util.HashMap.new(:a => 1).entrySet.iterator.next
2420
+ assert_equal(entry, cls.foo(entry))
2421
+ end
2422
+
2423
+ def test_covariant_arrays
2424
+ cls, = compile(<<-EOF)
2425
+ puts java::util::Arrays.toString(String[5])
2426
+ EOF
2427
+
2428
+ assert_output("[null, null, null, null, null]\n") do
2429
+ cls.main(nil)
2430
+ end
2431
+ end
2432
+
2433
+ def test_getClass_on_object_array
2434
+ cls, = compile(<<-EOF)
2435
+ puts Object[0].getClass.getName
2436
+ EOF
2437
+
2438
+ assert_output("[Ljava.lang.Object;\n") do
2439
+ cls.main(nil)
2440
+ end
2441
+ end
2442
+
2443
+ def test_nil_assign
2444
+ cls, = compile(<<-EOF)
2445
+ def foo
2446
+ a = nil
2447
+ a = 'hello'
2448
+ a.length
2449
+ end
2450
+ EOF
2451
+
2452
+ assert_equal(5, cls.foo)
2453
+
2454
+ cls, = compile(<<-EOF)
2455
+ a = nil
2456
+ puts a
2457
+ EOF
2458
+
2459
+ assert_output("null\n") do
2460
+ cls.main(nil)
2461
+ end
2462
+ end
2463
+
2464
+ def test_empty_rescues
2465
+ cls, = compile(<<-EOF)
2466
+ begin
2467
+ rescue
2468
+ nil
2469
+ end
2470
+ EOF
2471
+
2472
+ cls, = compile(<<-EOF)
2473
+ begin
2474
+ ""
2475
+ rescue
2476
+ nil
2477
+ end
2478
+ nil
2479
+ EOF
2480
+ end
2778
2481
  end