mirah 0.0.12-java → 0.1.0-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 (171) hide show
  1. data/History.txt +372 -0
  2. data/README.txt +4 -5
  3. data/Rakefile +178 -55
  4. data/examples/appengine/Readme +3 -3
  5. data/examples/appengine/src/org/mirah/MirahApp.mirah +1 -1
  6. data/examples/appengine/src/org/mirah/list.dhtml +1 -1
  7. data/examples/bintrees.mirah +1 -1
  8. data/examples/edb.mirah +1 -1
  9. data/examples/fib.mirah +1 -1
  10. data/examples/interfaces.mirah +1 -1
  11. data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +4 -5
  12. data/examples/maven/README.txt +1 -1
  13. data/examples/maven/src/main/mirah/hello_mirah.mirah +1 -1
  14. data/examples/plugins/appengine/Rakefile +1 -1
  15. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +1 -1
  16. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +1 -1
  17. data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +1 -1
  18. data/examples/rosettacode/100-doors.mirah +6 -6
  19. data/examples/rosettacode/README.txt +3 -3
  20. data/examples/rosettacode/boolean-values.mirah +1 -1
  21. data/examples/rosettacode/comments.mirah +1 -1
  22. data/examples/rosettacode/count-occurrences-of-a-substring.mirah +1 -1
  23. data/examples/rosettacode/factorial.mirah +1 -1
  24. data/examples/rosettacode/fibonacci.mirah +1 -1
  25. data/examples/rosettacode/fizz-buzz.mirah +2 -2
  26. data/examples/rosettacode/flatten-a-list.mirah +4 -4
  27. data/examples/rosettacode/guess-the-number.mirah +2 -2
  28. data/examples/rosettacode/hamming-numbers.mirah +4 -4
  29. data/examples/rosettacode/is-string-numeric.mirah +22 -22
  30. data/examples/rosettacode/palindrome.mirah +2 -2
  31. data/examples/rosettacode/random-numbers.mirah +1 -1
  32. data/examples/rosettacode/repeat-a-string.mirah +1 -1
  33. data/examples/rosettacode/reverse-a-string.mirah +1 -1
  34. data/examples/rosettacode/rot-13.mirah +5 -5
  35. data/examples/rosettacode/secure-temporary-file.mirah +2 -2
  36. data/examples/rosettacode/sleep.mirah +1 -1
  37. data/examples/rosettacode/string-length.mirah +5 -5
  38. data/examples/swing.mirah +1 -1
  39. data/examples/test.edb +1 -1
  40. data/javalib/mirah-bootstrap.jar +0 -0
  41. data/javalib/mirah-builtins.jar +0 -0
  42. data/javalib/mirah-parser.jar +0 -0
  43. data/javalib/mirah-util.jar +0 -0
  44. data/lib/duby.rb +1 -1
  45. data/lib/mirah.rb +50 -28
  46. data/lib/mirah/ast.rb +15 -605
  47. data/lib/mirah/ast/scope.rb +98 -69
  48. data/lib/mirah/commands.rb +1 -1
  49. data/lib/mirah/commands/base.rb +7 -7
  50. data/lib/mirah/commands/compile.rb +3 -3
  51. data/lib/mirah/commands/parse.rb +7 -5
  52. data/lib/mirah/commands/run.rb +12 -19
  53. data/lib/mirah/compiler.rb +15 -23
  54. data/lib/mirah/errors.rb +16 -1
  55. data/lib/mirah/generator.rb +79 -39
  56. data/lib/mirah/jvm/compiler.rb +1 -19
  57. data/lib/mirah/jvm/compiler/base.rb +233 -90
  58. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +675 -363
  59. data/lib/mirah/jvm/method_lookup.rb +134 -65
  60. data/lib/mirah/jvm/typer.rb +10 -5
  61. data/lib/mirah/jvm/types.rb +10 -2
  62. data/lib/mirah/jvm/types/array_type.rb +10 -12
  63. data/lib/mirah/{compiler/type.rb → jvm/types/ast_ext.rb} +12 -8
  64. data/lib/mirah/jvm/types/basic_types.rb +26 -33
  65. data/lib/mirah/jvm/types/bitescript_ext.rb +1 -1
  66. data/lib/mirah/jvm/types/block_type.rb +15 -0
  67. data/lib/mirah/jvm/types/boolean.rb +8 -4
  68. data/lib/mirah/jvm/types/dynamic_type.rb +12 -13
  69. data/lib/mirah/jvm/types/enumerable.rb +7 -7
  70. data/lib/mirah/jvm/types/extensions.rb +11 -6
  71. data/lib/mirah/jvm/types/factory.rb +624 -94
  72. data/lib/mirah/jvm/types/floats.rb +21 -15
  73. data/lib/mirah/jvm/types/generic_type.rb +72 -0
  74. data/lib/mirah/jvm/types/implicit_nil_type.rb +29 -0
  75. data/lib/mirah/jvm/types/integers.rb +26 -71
  76. data/lib/mirah/jvm/types/interface_definition.rb +3 -3
  77. data/lib/mirah/jvm/types/intrinsics.rb +203 -168
  78. data/lib/mirah/jvm/types/literals.rb +6 -6
  79. data/lib/mirah/jvm/types/meta_type.rb +13 -4
  80. data/lib/mirah/jvm/types/methods.rb +281 -93
  81. data/lib/mirah/jvm/types/null_type.rb +17 -5
  82. data/lib/mirah/jvm/types/number.rb +10 -7
  83. data/lib/mirah/jvm/types/primitive_type.rb +17 -6
  84. data/lib/mirah/jvm/types/source_mirror.rb +12 -7
  85. data/lib/mirah/jvm/types/type.rb +107 -23
  86. data/lib/mirah/jvm/types/type_definition.rb +25 -10
  87. data/lib/mirah/jvm/types/unreachable_type.rb +1 -1
  88. data/lib/mirah/jvm/types/void_type.rb +3 -3
  89. data/lib/mirah/parser.rb +154 -16
  90. data/lib/mirah/plugin/edb.rb +1 -1
  91. data/lib/mirah/transform.rb +1 -2
  92. data/lib/mirah/transform/ast_ext.rb +24 -43
  93. data/lib/mirah/transform/transformer.rb +29 -224
  94. data/lib/mirah/typer.rb +2 -16
  95. data/lib/mirah/util/argument_processor.rb +25 -10
  96. data/lib/mirah/util/class_loader.rb +1 -1
  97. data/lib/mirah/util/compilation_state.rb +16 -17
  98. data/lib/mirah/util/delegate.rb +2 -2
  99. data/lib/mirah/util/logging.rb +110 -0
  100. data/lib/mirah/util/process_errors.rb +69 -11
  101. data/lib/mirah/version.rb +1 -1
  102. data/test/core/commands_test.rb +6 -24
  103. data/test/core/env_test.rb +5 -5
  104. data/{lib/mirah/jvm/source_generator/typer.rb → test/core/generator_test.rb} +9 -9
  105. data/test/core/typer_test.rb +196 -158
  106. data/test/core/util/argument_processor_test.rb +10 -10
  107. data/test/core/util/class_loader_test.rb +6 -5
  108. data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
  109. data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
  110. data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
  111. data/test/jvm/annotations_test.rb +5 -5
  112. data/test/jvm/blocks_test.rb +140 -88
  113. data/test/jvm/bytecode_test_helper.rb +112 -94
  114. data/test/jvm/cast_test.rb +162 -0
  115. data/test/jvm/constructors_test.rb +18 -8
  116. data/test/jvm/enumerable_test.rb +77 -44
  117. data/test/jvm/example_test.rb +53 -0
  118. data/test/jvm/factory_test.rb +7 -1
  119. data/test/jvm/generics_test.rb +57 -0
  120. data/test/jvm/hash_test.rb +106 -0
  121. data/test/jvm/import_test.rb +81 -0
  122. data/test/jvm/interface_test.rb +73 -0
  123. data/test/jvm/java_typer_test.rb +92 -66
  124. data/{lib/mirah/typer/base.rb → test/jvm/jvm_commands_test.rb} +6 -10
  125. data/test/jvm/jvm_compiler_test.rb +170 -604
  126. data/test/jvm/list_extensions_test.rb +23 -0
  127. data/test/jvm/macros_test.rb +197 -32
  128. data/test/jvm/main_method_test.rb +4 -4
  129. data/test/jvm/numeric_extensions_test.rb +13 -0
  130. data/test/jvm/rescue_test.rb +73 -16
  131. data/test/jvm/varargs_test.rb +65 -0
  132. data/test/test_helper.rb +1 -2
  133. metadata +234 -251
  134. data/examples/SortClosure$__xform_tmp_1.class +0 -0
  135. data/examples/SortClosure$__xform_tmp_2.class +0 -0
  136. data/examples/SortClosure.class +0 -0
  137. data/examples/macros/StringEachChar$Extension1.class +0 -0
  138. data/lib/mirah/ast/call.rb +0 -345
  139. data/lib/mirah/ast/class.rb +0 -359
  140. data/lib/mirah/ast/flow.rb +0 -381
  141. data/lib/mirah/ast/intrinsics.rb +0 -563
  142. data/lib/mirah/ast/literal.rb +0 -178
  143. data/lib/mirah/ast/local.rb +0 -112
  144. data/lib/mirah/ast/method.rb +0 -408
  145. data/lib/mirah/ast/structure.rb +0 -387
  146. data/lib/mirah/ast/type.rb +0 -146
  147. data/lib/mirah/commands/base.rb~ +0 -57
  148. data/lib/mirah/compiler/call.rb +0 -45
  149. data/lib/mirah/compiler/class.rb +0 -81
  150. data/lib/mirah/compiler/flow.rb +0 -109
  151. data/lib/mirah/compiler/literal.rb +0 -130
  152. data/lib/mirah/compiler/local.rb +0 -59
  153. data/lib/mirah/compiler/method.rb +0 -44
  154. data/lib/mirah/compiler/structure.rb +0 -65
  155. data/lib/mirah/jvm/compiler/java_source.rb +0 -787
  156. data/lib/mirah/jvm/method_lookup.rb~ +0 -247
  157. data/lib/mirah/jvm/source_generator/builder.rb +0 -468
  158. data/lib/mirah/jvm/source_generator/loops.rb +0 -131
  159. data/lib/mirah/jvm/source_generator/precompile.rb +0 -210
  160. data/lib/mirah/plugin/gwt.rb +0 -189
  161. data/lib/mirah/plugin/java.rb +0 -70
  162. data/lib/mirah/transform/error.rb +0 -13
  163. data/lib/mirah/transform/helper.rb +0 -765
  164. data/lib/mirah/typer/simple.rb +0 -384
  165. data/lib/mirah/version.rb~ +0 -18
  166. data/test/core/ast_test.rb +0 -382
  167. data/test/core/compilation_test.rb +0 -130
  168. data/test/core/macros_test.rb +0 -61
  169. data/test/jvm/javac_test_helper.rb +0 -89
  170. data/test/jvm/jvm_compiler_test.rb~ +0 -2181
  171. data/test/plugins/gwt_test.rb +0 -69
@@ -27,16 +27,16 @@ class ArgumentProcessorTest < Test::Unit::TestCase
27
27
  assert_equal 1, processor.exit_status_code
28
28
  end
29
29
 
30
- def test_arg_bootclasspath_sets_bootclasspath_on_type_factory_ugh
31
- Mirah::AST.type_factory = Mirah::JVM::Types::TypeFactory.new # global state grumble grumble
32
-
33
- path = "class:path"
34
- state = Mirah::Util::CompilationState.new
35
- processor = Mirah::Util::ArgumentProcessor.new state, ["--bootclasspath", path]
36
- processor.process
37
-
38
- assert_equal path, Mirah::AST.type_factory.bootclasspath
39
- end
30
+ # def test_arg_bootclasspath_sets_bootclasspath_on_type_factory_ugh
31
+ # Mirah::AST.type_factory = Mirah::JVM::Types::TypeFactory.new # global state grumble grumble
32
+ #
33
+ # path = "class:path"
34
+ # state = Mirah::Util::CompilationState.new
35
+ # processor = Mirah::Util::ArgumentProcessor.new state, ["--bootclasspath", path]
36
+ # processor.process
37
+ #
38
+ # assert_equal path, Mirah::AST.type_factory.bootclasspath
39
+ # end
40
40
 
41
41
  def test_dash_j_fails_when_not_compiling
42
42
  state = Mirah::Util::CompilationState.new
@@ -16,13 +16,14 @@ class ClassLoaderTest < Test::Unit::TestCase
16
16
  def test_mirah_class_loader_w_missing_class_raises_class_not_found
17
17
  class_loader = Mirah::Util::ClassLoader.new nil, {}
18
18
 
19
- ex = assert_raise NativeException do
20
- class_loader.find_class 'org.doesnt.exist.Class'
19
+ begin
20
+ klass = class_loader.find_class 'org.doesnt.exist.Class'
21
+ fail 'Expected ClassNotFoundException'
22
+ rescue java.lang.ClassNotFoundException
23
+ # expected
21
24
  end
22
- assert_equal java.lang.ClassNotFoundException, ex.cause.class
23
25
  end
24
-
25
-
26
+
26
27
  def test_isolated_resource_loader_only_finds_resources_given_to_it
27
28
  loader = Mirah::Util::IsolatedResourceLoader.new [java.net.URL.new("file:#{FIXTURES}")]
28
29
  url = loader.get_resource "my.properties"
@@ -0,0 +1,7 @@
1
+ package org.foo;
2
+
3
+ public class LowerCaseInnerClass {
4
+ public static final class inner {
5
+ public static final int field = 1234;
6
+ }
7
+ }
@@ -14,16 +14,16 @@ class AnnotationsTest < Test::Unit::TestCase
14
14
  assert_not_nil cls.java_class.java_method('foo').annotation(deprecated)
15
15
  assert_nil cls.java_class.annotation(deprecated)
16
16
  end
17
-
17
+
18
18
  def test_annotation_on_a_class
19
- script, cls = compile(<<-EOF)
19
+ cls, = compile(<<-EOF)
20
20
  $Deprecated
21
21
  class Annotated
22
22
  end
23
23
  EOF
24
24
  assert_not_nil cls.java_class.annotation(deprecated)
25
25
  end
26
-
26
+
27
27
  def test_annotation_on_a_field
28
28
  cls, = compile(<<-EOF)
29
29
  class AnnotatedField
@@ -36,7 +36,7 @@ class AnnotationsTest < Test::Unit::TestCase
36
36
 
37
37
  assert_not_nil cls.java_class.declared_fields[0].annotation(deprecated)
38
38
  end
39
-
39
+
40
40
  def test_annotation_with_an_integer
41
41
  jruby_method = Java::OrgJrubyAnno::JRubyMethod.java_class
42
42
 
@@ -46,7 +46,7 @@ class AnnotationsTest < Test::Unit::TestCase
46
46
  import org.jruby.runtime.*
47
47
  import org.jruby.runtime.builtin.*
48
48
 
49
- $JRubyMethod["name" => "bar", "optional" => 1]
49
+ $JRubyMethod["name" => ["bar"], "optional" => 1]
50
50
  def bar(baz:int)
51
51
  end
52
52
  EOF
@@ -15,12 +15,6 @@
15
15
 
16
16
  class BlocksTest < Test::Unit::TestCase
17
17
 
18
- def setup
19
- super
20
- clear_tmp_files
21
- reset_type_factory
22
- end
23
-
24
18
  def parse_and_type code, name=tmp_script_name
25
19
  parse_and_resolve_types name, code
26
20
  end
@@ -30,8 +24,9 @@ class BlocksTest < Test::Unit::TestCase
30
24
  assert_nothing_raised do
31
25
  parse_and_type(<<-CODE)
32
26
  interface Bar do;def run:void;end;end
33
-
27
+
34
28
  class Foo
29
+ def initialize; end
35
30
  def foo(a:Bar)
36
31
  1
37
32
  end
@@ -41,34 +36,16 @@ class BlocksTest < Test::Unit::TestCase
41
36
  CODE
42
37
  end
43
38
  end
44
-
39
+
45
40
  def test_non_empty_block_parses_and_types_without_error
46
41
  assert_nothing_raised do
47
42
  parse_and_type(<<-CODE)
48
- interface Bar do;def run:void;end;end
49
-
50
- class Foo
51
- def foo(a:Bar)
52
- 1
53
- end
54
- end
55
- Foo.new.foo do
56
- 1
43
+ interface Bar
44
+ def run:void; end
57
45
  end
58
- CODE
59
- end
60
- end
61
46
 
62
-
63
- def test_block_impling_interface_w_multiple_methods
64
- assert_raises Mirah::NodeError do
65
- parse_and_type(<<-CODE)
66
- interface Bar do
67
- def run:void;end
68
- def run2:void;end;
69
- end
70
-
71
47
  class Foo
48
+ def initialize; end
72
49
  def foo(a:Bar)
73
50
  1
74
51
  end
@@ -76,93 +53,59 @@ class BlocksTest < Test::Unit::TestCase
76
53
  Foo.new.foo do
77
54
  1
78
55
  end
79
- CODE
56
+ CODE
80
57
  end
81
58
  end
82
59
 
83
- def test_block_with_no_params_on_interface_with
84
- assert_raises Mirah::NodeError do
85
- parse_and_type(<<-CODE)
86
- interface Bar do
87
- def run(a:string):void;end
88
- end
89
-
90
- class Foo
91
- def foo(a:Bar)
92
- 1
93
- end
94
- end
95
- Foo.new.foo do
96
- 1
97
- end
98
- CODE
99
- end
100
- end
101
-
102
- def test_block_with_too_many_params
103
- assert_raises Mirah::NodeError do
104
- parse_and_type(<<-CODE)
105
- interface Bar do
106
- def run(a:string):void;end
107
- end
108
-
109
- class Foo
110
- def foo(a:Bar)
111
- 1
112
- end
113
- end
114
- Foo.new.foo do |a, b|
115
- 1
116
- end
117
- CODE
118
- end
119
- end
120
60
 
121
- def test_block
61
+ def test_simple_block
122
62
  cls, = compile(<<-EOF)
123
63
  thread = Thread.new do
124
- puts "Hello"
64
+ System.out.println "Hello"
125
65
  end
126
66
  begin
127
67
  thread.run
128
68
  thread.join
129
69
  rescue
130
- puts "Uh Oh!"
70
+ System.out.println "Uh Oh!"
131
71
  end
132
72
  EOF
133
73
  assert_output("Hello\n") do
134
74
  cls.main([].to_java :string)
135
75
  end
76
+ end
136
77
 
78
+ def test_arg_types_inferred_from_interface
137
79
  script, cls = compile(<<-EOF)
138
80
  import java.util.Observable
139
81
  class MyObservable < Observable
140
82
  def initialize
141
- super
142
83
  setChanged
143
84
  end
144
85
  end
145
86
 
146
87
  o = MyObservable.new
147
- o.addObserver {|x, a| puts a}
88
+ o.addObserver {|x, a| System.out.println a}
148
89
  o.notifyObservers("Hello Observer")
149
90
  EOF
150
91
  assert_output("Hello Observer\n") do
151
92
  script.main([].to_java :string)
152
93
  end
94
+ end
153
95
 
96
+ def test_closure
154
97
  cls, = compile(<<-EOF)
155
98
  def foo
156
99
  a = "Hello"
157
100
  thread = Thread.new do
158
- puts a
101
+ System.out.println a
159
102
  end
160
103
  begin
161
104
  a = a + " Closures"
162
105
  thread.run
163
106
  thread.join
164
107
  rescue
165
- puts "Uh Oh!"
108
+ System.out.println "Uh Oh!"
166
109
  end
167
110
  return
168
111
  end
@@ -170,7 +113,9 @@ class BlocksTest < Test::Unit::TestCase
170
113
  assert_output("Hello Closures\n") do
171
114
  cls.foo
172
115
  end
116
+ end
173
117
 
118
+ def test_int_closure
174
119
  cls, = compile(<<-EOF)
175
120
  def run(x:Runnable)
176
121
  x.run
@@ -197,7 +142,7 @@ class BlocksTest < Test::Unit::TestCase
197
142
  String(a).compareToIgnoreCase(String(b))
198
143
  end
199
144
  end
200
- list.each {|x| puts x}
145
+ list.each {|x| System.out.println x}
201
146
  EOF
202
147
 
203
148
  assert_output("a\nABC\nb\nCats\n") do
@@ -209,33 +154,32 @@ class BlocksTest < Test::Unit::TestCase
209
154
  # Comparator interface also defines equals(Object) as abstract,
210
155
  # but it can be inherited from Object. We test that here.
211
156
  cls, = compile(<<-EOF)
212
- import java.util.ArrayList
213
157
  import java.util.Collections
214
- list = ArrayList.new(["a", "ABC", "Cats", "b"])
215
- Collections.sort(list) do |a, b|
216
- String(a).compareToIgnoreCase(String(b))
158
+ import java.util.List
159
+ def sort(l:List)
160
+ Collections.sort(l) do |a:Object, b:Object|
161
+ String(a).compareToIgnoreCase(String(b))
162
+ end
163
+ l
217
164
  end
218
- list.each {|x| puts x}
219
165
  EOF
220
166
 
221
- assert_output("a\nABC\nb\nCats\n") do
222
- cls.main(nil)
223
- end
167
+ assert_equal(["a", "ABC", "b", "Cats"], cls.sort(["a", "ABC", "Cats", "b"]))
224
168
  end
225
-
169
+
226
170
  def test_block_with_no_arguments_and_return_value
227
171
  cls, = compile(<<-EOF)
228
172
  import java.util.concurrent.Callable
229
173
  def foo c:Callable
230
- throws Exception
231
- puts c.call
174
+ # throws Exception
175
+ System.out.println c.call
232
176
  end
233
177
  begin
234
178
  foo do
235
179
  "an object"
236
180
  end
237
181
  rescue
238
- puts "never get here"
182
+ System.out.println "never get here"
239
183
  end
240
184
  EOF
241
185
  assert_output("an object\n") do
@@ -243,10 +187,118 @@ class BlocksTest < Test::Unit::TestCase
243
187
  end
244
188
  end
245
189
 
190
+ def test_parameter_used_in_block
191
+ cls, = compile(<<-EOF)
192
+ def foo(x:String):void
193
+ thread = Thread.new do
194
+ System.out.println "Hello \#{x}"
195
+ end
196
+ begin
197
+ thread.run
198
+ thread.join
199
+ rescue
200
+ System.out.println "Uh Oh!"
201
+ end
202
+ end
203
+
204
+ foo('there')
205
+ EOF
206
+ assert_output("Hello there\n") do
207
+ cls.main(nil)
208
+ end
209
+ end
210
+
211
+ def test_block_with_mirah_interface
212
+ cls, interface = compile(<<-EOF)
213
+ interface MyProc do
214
+ def call:void; end
215
+ end
216
+ def foo(b:MyProc)
217
+ b.call
218
+ end
219
+ def bar
220
+ foo {System.out.println "Hi"}
221
+ end
222
+ EOF
223
+ assert_output("Hi\n") do
224
+ cls.bar
225
+ end
226
+ end
227
+
228
+ def assert_jraise(klass)
229
+ assert_block("#{klass} expected, but none thrown") do
230
+ begin
231
+ yield
232
+ rescue klass
233
+ break
234
+ end
235
+ false
236
+ end
237
+ end
238
+
239
+ def test_block_impling_interface_w_multiple_methods
240
+ assert_jraise java.lang.UnsupportedOperationException do
241
+ parse_and_type(<<-CODE)
242
+ interface Bar do
243
+ def run:void;end
244
+ def run2:void;end;
245
+ end
246
+
247
+ class Foo
248
+ def foo(a:Bar)
249
+ 1
250
+ end
251
+ end
252
+ Foo.new.foo do
253
+ 1
254
+ end
255
+ CODE
256
+ end
257
+ end
258
+
259
+ def test_block_with_missing_params
260
+ cls, = compile(<<-CODE)
261
+ interface Bar do
262
+ def run(a:string):void;end
263
+ end
264
+
265
+ class TakesABar
266
+ def foo(a:Bar)
267
+ a.run("x")
268
+ end
269
+ end
270
+ TakesABar.new.foo do
271
+ puts "hi"
272
+ end
273
+ CODE
274
+ assert_output "hi\n" do
275
+ cls.main(nil)
276
+ end
277
+ end
278
+
279
+ def test_block_with_too_many_params
280
+ assert_raises Mirah::MirahError do
281
+ parse_and_type(<<-CODE)
282
+ interface SingleArgMethod do
283
+ def run(a:string):void;end
284
+ end
285
+
286
+ class ExpectsSingleArgMethod
287
+ def foo(a:SingleArgMethod)
288
+ 1
289
+ end
290
+ end
291
+ ExpectsSingleArgMethod.new.foo do |a, b|
292
+ 1
293
+ end
294
+ CODE
295
+ end
296
+ end
297
+
246
298
  def test_closure_in_closure_doesnt_raise_error
247
299
  parse_and_type(<<-CODE)
248
300
  interface Bar do;def run:void;end;end
249
-
301
+
250
302
  class Foo
251
303
  def foo(a:Bar)
252
304
  1
@@ -16,135 +16,153 @@ require 'test_helper'
16
16
  require 'stringio'
17
17
  require 'fileutils'
18
18
 
19
- unless Mirah::AST.macro "__gloop__"
20
- Mirah::AST.defmacro "__gloop__" do |transformer, fcall, parent|
21
- Mirah::AST::Loop.new(parent, parent.position, true, false) do |loop|
22
- init, condition, check_first, pre, post = fcall.parameters
23
- loop.check_first = check_first.literal
24
-
25
- nil_t = Mirah::AST::Null
26
- loop.init = init
27
- loop.pre = pre
28
- loop.post = post
29
-
30
- body = fcall.block.body
31
- body.parent = loop
32
- [
33
- Mirah::AST::Condition.new(loop, parent.position) do |c|
34
- condition.parent = c
35
- [condition]
36
- end,
37
- body
38
- ]
39
- end
40
- end
41
- end
42
-
43
-
44
-
45
19
  module JVMCompiler
20
+ TEST_DEST = File.expand_path(File.dirname(__FILE__)+'/../../tmp_test/') + "/"
21
+ $CLASSPATH << TEST_DEST
22
+
46
23
  import java.lang.System
47
24
  import java.io.PrintStream
48
25
  include Mirah
49
-
50
- def create_transformer
26
+
27
+ def new_state
51
28
  state = Mirah::Util::CompilationState.new
52
- state.save_extensions = false
53
-
54
- transformer = Mirah::Transform::Transformer.new(state)
55
- Java::MirahImpl::Builtin.initialize_builtins(transformer)
56
- transformer
57
- end
58
-
59
- def reset_type_factory
60
- AST.type_factory = Mirah::JVM::Types::TypeFactory.new
29
+ state.save_extensions = true
30
+ state.destination = TEST_DEST
31
+ state.classpath = TEST_DEST
32
+ state
61
33
  end
62
-
63
- def clear_tmp_files
64
- File.unlink(*@tmp_classes)
65
- @tmp_classes.clear
34
+
35
+ def clean_tmp_files
36
+ return unless @tmp_classes
37
+ File.unlink(*@tmp_classes.uniq)
66
38
  end
67
-
68
- def create_compiler
69
- JVM::Compiler::JVMBytecode.new
39
+
40
+ def compiler_type
41
+ JVM::Compiler::JVMBytecode
70
42
  end
71
-
43
+
72
44
  def parse name, code, transformer
73
45
  AST.parse(code, name, true, transformer)
74
46
  end
75
-
76
- def infer_and_resolve_types ast, transformer
77
- typer = JVM::Typer.new(transformer)
78
-
79
- ast.infer(typer, true)
80
-
81
- typer.resolve(true)
47
+
48
+ def infer_and_resolve_types ast, generator
49
+ scoper, typer = generator.infer_asts(ast, true)
50
+ ast
82
51
  end
83
-
84
- def parse_and_resolve_types name, code
85
- transformer = create_transformer
86
-
87
- ast = parse name, code, transformer
88
-
89
- infer_and_resolve_types ast, transformer
90
-
52
+
53
+ def parse_and_resolve_types name, code
54
+ state = new_state
55
+
56
+ generator = Mirah::Generator.new(state, compiler_type, false, false)
57
+ transformer = Mirah::Transform::Transformer.new(state, generator.typer)
58
+
59
+ ast = [AST.parse(code, name, true, transformer)]
60
+
61
+ infer_and_resolve_types ast, generator
62
+
91
63
  ast
92
64
  end
93
-
94
-
95
- def generate_classes compiler
65
+
66
+ def generate_classes compiler_results
96
67
  classes = {}
97
68
 
98
- compiler.generate do |filename, builder|
99
- bytes = builder.generate
69
+ compiler_results.each do |result|
70
+ bytes = result.bytes
71
+ filename = "#{TEST_DEST}#{result.filename}"
100
72
  FileUtils.mkdir_p(File.dirname(filename))
101
- open("#{filename}", "wb") do |f|
102
- f << bytes
103
- end
104
- classes[filename[0..-7]] = Mirah::Util::ClassLoader.binary_string bytes
73
+ File.open(filename, 'wb') { |f| f.write(bytes) }
74
+ @tmp_classes << filename
75
+ classes[result.filename[0..-7]] = Mirah::Util::ClassLoader.binary_string bytes
105
76
  end
106
77
 
107
78
  loader = Mirah::Util::ClassLoader.new(JRuby.runtime.jruby_class_loader, classes)
79
+
108
80
  classes.keys.map do |name|
109
81
  cls = loader.load_class(name.tr('/', '.'))
110
- proxy = JavaUtilities.get_proxy_class(cls.name)
111
- @tmp_classes << "#{name}.class"
112
- proxy
82
+ JavaUtilities.get_proxy_class(cls.name)
113
83
  end
84
+ end
85
+
86
+ def compile(code, options = {})
87
+ name = options.delete :name
88
+ name ||= tmp_script_name
114
89
 
90
+ state = new_state
91
+ java_version = options.delete :java_version
92
+ if java_version
93
+ state.set_jvm_version java_version
94
+ end
95
+
96
+ generator = Mirah::Generator.new(state, compiler_type, false, false)
97
+ transformer = Mirah::Transform::Transformer.new(state, generator.typer)
98
+
99
+ ast = AST.parse(code, name, true, transformer)
100
+
101
+ scoper, typer = generator.infer_asts([ast], true)
102
+ compiler_results = generator.compiler.compile_asts([ast], scoper, typer)
103
+
104
+ generate_classes compiler_results
115
105
  end
116
-
117
- def compile_ast ast
118
- compiler = create_compiler
119
- compiler.compile(ast)
120
- compiler
106
+
107
+ def tmp_script_name
108
+ "script#{name.gsub(/\)|\(/,'_').capitalize}#{System.nano_time}"
121
109
  end
122
-
123
- def compile(code, name = tmp_script_name)
124
- clear_tmp_files
125
- reset_type_factory
126
-
127
- ast = parse_and_resolve_types name, code
128
-
129
- compiler = compile_ast ast
130
-
131
- generate_classes compiler
110
+ end
111
+
112
+
113
+ module CommonAssertions
114
+ import java.lang.System
115
+ import java.io.PrintStream
116
+
117
+ def assert_include(value, array, message=nil)
118
+ message = build_message message, '<?> does not include <?>', array, value
119
+ assert_block message do
120
+ array.include? value
121
+ end
132
122
  end
133
-
134
- def tmp_script_name
135
- "script" + System.nano_time.to_s
123
+
124
+ def capture_output
125
+ saved_output = System.out
126
+ output = StringIO.new
127
+ System.setOut(PrintStream.new(output.to_outputstream))
128
+ begin
129
+ yield
130
+ output.rewind
131
+ output.read
132
+ ensure
133
+ System.setOut(saved_output)
134
+ end
135
+ end
136
+
137
+ def assert_output(expected, &block)
138
+ assert_equal(expected, capture_output(&block))
139
+ end
140
+
141
+ def assert_raise_java(type, message=nil)
142
+ begin
143
+ yield
144
+ rescue Exception => e
145
+ ex = e
146
+ end
147
+ ex = ex.cause if ex.is_a? NativeException
148
+ assert_equal type, ex.class
149
+ if message
150
+ assert_equal message,
151
+ ex.message.to_s,
152
+ "expected error message to be '#{message}' but was '#{ex.message}'"
153
+ end
154
+ ex
136
155
  end
137
156
  end
138
157
 
139
158
  class Test::Unit::TestCase
140
159
  include JVMCompiler
141
-
160
+
142
161
  def setup
143
162
  @tmp_classes = []
144
163
  end
145
164
 
146
- def teardown
147
- reset_type_factory
148
- clear_tmp_files
165
+ def cleanup
166
+ clean_tmp_files
149
167
  end
150
168
  end