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
@@ -20,6 +20,7 @@ module Mirah
20
20
  class CompilationState
21
21
  def initialize
22
22
  @save_extensions = true
23
+ set_jvm_version ENV_JAVA['java.specification.version']
23
24
  end
24
25
 
25
26
  attr_accessor :verbose, :destination
@@ -32,22 +33,27 @@ module Mirah
32
33
  attr_accessor :args
33
34
  attr_accessor :command
34
35
  attr_accessor :loggers
36
+ attr_accessor :type_system
35
37
 
36
38
  attr_accessor :classpath, :bootclasspath
39
+ attr_reader :target_jvm_version, :bytecode_version
37
40
 
38
41
  def set_jvm_version(ver_str)
39
- case ver_str
40
- when '1.4'
41
- BiteScript.bytecode_version = BiteScript::JAVA1_4
42
- when '1.5'
43
- BiteScript.bytecode_version = BiteScript::JAVA1_5
44
- when '1.6'
45
- BiteScript.bytecode_version = BiteScript::JAVA1_6
46
- when '1.7'
47
- BiteScript.bytecode_version = BiteScript::JAVA1_7
42
+ @target_jvm_version = ver_str
43
+ @bytecode_version = case ver_str
44
+ when '1.4' then BiteScript::JAVA1_4
45
+ when '1.5' then BiteScript::JAVA1_5
46
+ when '1.6' then BiteScript::JAVA1_6
47
+ when '1.7' then BiteScript::JAVA1_7
48
+ when '1.8' then BiteScript::JAVA1_8
48
49
  else
49
50
  $stderr.puts "invalid bytecode version specified: #{ver_str}"
50
51
  end
52
+ BiteScript.bytecode_version = @bytecode_version
53
+ end
54
+
55
+ def supports_invokedynamic?
56
+ @bytecode_version == BiteScript::JAVA1_7
51
57
  end
52
58
  end
53
59
  end
@@ -55,9 +55,15 @@ module Mirah
55
55
  type = type.resolve if type
56
56
  if (type && type.isError)
57
57
  @errors[type] ||= begin
58
- if type.message.size == 1 && type.message[0].size == 1
58
+ if type.message.size == 1
59
59
  m = type.message[0]
60
- m << node rescue nil
60
+ if m.size == 1
61
+ m << node rescue nil
62
+ elsif m.size == 2 && m[1] == nil
63
+ m[1] = node.position rescue nil
64
+ end
65
+ elsif type.message.size == 0
66
+ type.message << ["Error", node.position]
61
67
  end
62
68
  type
63
69
  end
data/lib/mirah/version.rb CHANGED
@@ -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");
@@ -14,5 +14,5 @@
14
14
  # limitations under the License.
15
15
 
16
16
  module Mirah
17
- VERSION = "0.1.0.pre"
17
+ VERSION = "0.1.1"
18
18
  end
data/lib/mirah_task.rb CHANGED
@@ -109,13 +109,6 @@ def mirahc(*files)
109
109
  end
110
110
  end
111
111
 
112
- rule '.java' => [proc {|n| Mirah.dest_to_source_path(n)}] do |t|
113
- mirahc(t.source,
114
- :dir=>Mirah.find_source(t.source),
115
- :dest=>Mirah.find_dest(t.name),
116
- :options=>['-java'])
117
- end
118
-
119
112
  rule '.class' => [proc {|n| Mirah.dest_to_source_path(n)}] do |t|
120
113
  mirahc(t.source,
121
114
  :dir=>Mirah.find_source(t.source),
@@ -32,8 +32,7 @@ class TyperTest < Test::Unit::TestCase
32
32
 
33
33
  def setup
34
34
  @scopes = SimpleScoper.new
35
- @types = SimpleTypes.new('bar')
36
- new_typer('bar')
35
+ new_typer('Bar')
37
36
  end
38
37
 
39
38
  def parse(text)
@@ -42,7 +41,7 @@ class TyperTest < Test::Unit::TestCase
42
41
 
43
42
  def new_typer(n)
44
43
  @types = SimpleTypes.new(n.to_s)
45
- @typer = Mirah::Typer::Typer.new(@types, @scopes, nil)
44
+ @typer = Mirah::Typer::Typer.new(@types, @scopes, nil, nil)
46
45
  @mirah = Transform::Transformer.new(Mirah::Util::CompilationState.new, @typer)
47
46
  @typer
48
47
  end
@@ -75,9 +74,18 @@ class TyperTest < Test::Unit::TestCase
75
74
 
76
75
  def infer(ast, expression=true)
77
76
  new_typer(:bar).infer(ast, expression)
77
+ if ast.kind_of? Java::MirahLangAst::Script
78
+ ast = ast.body
79
+ end
78
80
  inferred_type(ast)
79
81
  end
80
82
 
83
+ def test_script_is_void
84
+ ast = parse("x='a script'")
85
+ infer(ast)
86
+ assert_equal(@types.getVoidType, inferred_type(ast))
87
+ end
88
+
81
89
  def test_fixnum
82
90
  ast = parse("1")
83
91
  assert_equal(@types.getFixnumType(1), infer(ast))
@@ -155,7 +163,7 @@ class TyperTest < Test::Unit::TestCase
155
163
 
156
164
  # assert_equal(@types.getNullType, @types.getMethodType(type, 'foo', [@types.getStringType.resolve]).resolve)
157
165
  assert_equal(@types.getStringType, @types.getLocalType(inner_scope, 'a', nil).resolve)
158
- assert_equal(@types.getNullType, inferred_type(mdef))
166
+ assert_equal(@types.getNullType, inferred_type(mdef).returnType)
159
167
  assert_equal(@types.getStringType, inferred_type(mdef.arguments.required.get(0)))
160
168
 
161
169
  ast1 = parse("#{def_foo}(a:String); a; end")
@@ -166,7 +174,7 @@ class TyperTest < Test::Unit::TestCase
166
174
 
167
175
  # assert_equal(@types.getStringType, @types.getMethodType(type, 'foo', [@types.getStringType.resolve]).resolve)
168
176
  assert_equal(@types.getStringType, @types.getLocalType(inner_scope, 'a', nil).resolve)
169
- assert_equal(@types.getStringType, inferred_type(mdef))
177
+ assert_equal(@types.getStringType, inferred_type(mdef).returnType)
170
178
  assert_equal(@types.getStringType, inferred_type(mdef.arguments.required.get(0)))
171
179
  end
172
180
 
@@ -180,8 +188,8 @@ class TyperTest < Test::Unit::TestCase
180
188
  infer(ast)
181
189
  ast = ast.body
182
190
  self_type = @scopes.getScope(ast.get(0)).selfType
183
- assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(0)))
184
- assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(1)))
191
+ assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(0)).returnType)
192
+ assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(1)).returnType)
185
193
 
186
194
  # Reverse the order, ensure deferred inference succeeds
187
195
  ast = parse("def baz; bar(1, 'x'); end; def bar(a:Int, b:String); 1.0; end")
@@ -192,8 +200,8 @@ class TyperTest < Test::Unit::TestCase
192
200
 
193
201
  assert_no_errors(typer, ast)
194
202
 
195
- assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(0)))
196
- assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(1)))
203
+ assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(0)).returnType)
204
+ assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(1)).returnType)
197
205
 
198
206
  # modify bar call to have bogus types, ensure resolution fails
199
207
  ast = parse("def baz; bar(1, 1); end; def bar(a:Int, b:String); 1.0; end")
@@ -203,7 +211,7 @@ class TyperTest < Test::Unit::TestCase
203
211
  ast = ast.body
204
212
 
205
213
  assert_equal(":error", inferred_type(ast.get(0)).name)
206
- assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(1)))
214
+ assert_equal(@types.getFloatType(1.0), inferred_type(ast.get(1)).returnType)
207
215
  end
208
216
 
209
217
  def test_if
@@ -220,7 +228,7 @@ class TyperTest < Test::Unit::TestCase
220
228
  assert_equal(@types.getFloatType(1.0), inferred_type(ast.body))
221
229
  assert_equal(@types.getFloatType(1.0), inferred_type(ast.elseBody))
222
230
 
223
- typer = new_typer(:bar)
231
+ typer = new_typer(:Bar)
224
232
 
225
233
  ast = parse("if foo; bar; else; baz; end").body.get(0)
226
234
  typer.infer(ast.parent.parent, true)
@@ -239,7 +247,7 @@ class TyperTest < Test::Unit::TestCase
239
247
  ast2 = parse("def baz; 2.0; end")
240
248
  typer.infer(ast2, true)
241
249
 
242
- assert_equal(@types.getFloatType(1.0), inferred_type(ast2.body))
250
+ assert_equal(@types.getFloatType(1.0), inferred_type(ast2.body).returnType)
243
251
 
244
252
  assert_equal(@types.getFloatType(1.0), inferred_type(ast))
245
253
  assert_equal(@types.getFloatType(1.0), inferred_type(ast.elseBody))
@@ -282,7 +290,7 @@ class TyperTest < Test::Unit::TestCase
282
290
  end
283
291
 
284
292
  def test_vcall
285
- ast = parse("foo = 1; def bar; end; foo; bar")
293
+ ast = parse("foo = 1; def squeak; nil; end; foo; squeak")
286
294
  assert_kind_of(VCall, ast.body(2))
287
295
  assert_kind_of(VCall, ast.body(3))
288
296
  infer(ast)
@@ -1,3 +1,17 @@
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.
1
15
  require 'test_helper'
2
16
 
3
17
  class ArgumentProcessorTest < Test::Unit::TestCase
@@ -27,27 +41,13 @@ class ArgumentProcessorTest < Test::Unit::TestCase
27
41
  assert_equal 1, processor.exit_status_code
28
42
  end
29
43
 
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
-
41
- def test_dash_j_fails_when_not_compiling
44
+ def test_arg_bootclasspath_sets_bootclasspath_on_compilation_state
45
+ path = "class:path"
42
46
  state = Mirah::Util::CompilationState.new
43
- processor = Mirah::Util::ArgumentProcessor.new state, ["-j"]
47
+ processor = Mirah::Util::ArgumentProcessor.new state, ["--bootclasspath", path]
48
+ processor.process
44
49
 
45
- assert_output "-j/--java flag only applies to \"compile\" mode.\n" do
46
- processor.process
47
- end
48
-
49
- assert processor.exit?
50
- assert_equal 1, processor.exit_status_code
50
+ assert_equal path, state.bootclasspath
51
51
  end
52
52
 
53
53
  def test_dash_h_prints_help_and_exits
@@ -1,3 +1,17 @@
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.
1
15
  require 'test_helper'
2
16
 
3
17
  class ClassLoaderTest < Test::Unit::TestCase
@@ -16,13 +30,14 @@ class ClassLoaderTest < Test::Unit::TestCase
16
30
  def test_mirah_class_loader_w_missing_class_raises_class_not_found
17
31
  class_loader = Mirah::Util::ClassLoader.new nil, {}
18
32
 
19
- ex = assert_raise NativeException do
20
- class_loader.find_class 'org.doesnt.exist.Class'
33
+ begin
34
+ klass = class_loader.find_class 'org.doesnt.exist.Class'
35
+ fail 'Expected ClassNotFoundException'
36
+ rescue java.lang.ClassNotFoundException
37
+ # expected
21
38
  end
22
- assert_equal java.lang.ClassNotFoundException, ex.cause.class
23
39
  end
24
40
 
25
-
26
41
  def test_isolated_resource_loader_only_finds_resources_given_to_it
27
42
  loader = Mirah::Util::IsolatedResourceLoader.new [java.net.URL.new("file:#{FIXTURES}")]
28
43
  url = loader.get_resource "my.properties"
@@ -0,0 +1,38 @@
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
+ require 'test_helper'
16
+
17
+ class CampilationStateTest < Test::Unit::TestCase
18
+ include Mirah::Util
19
+ def test_defaults_to_current_java
20
+ state = CompilationState.new
21
+ spec_version = ENV_JAVA['java.specification.version']
22
+ assert_equal spec_version, state.target_jvm_version
23
+ assert_equal bitescript_const(spec_version), state.bytecode_version
24
+ end
25
+
26
+ %w[1.4 1.5 1.6 1.7 1.8].each do |version|
27
+ define_method "test_setting_version_to_#{version.tr '.', '_'}" do
28
+ state = CompilationState.new
29
+ state.set_jvm_version version
30
+ assert_equal version, state.target_jvm_version
31
+ assert_equal bitescript_const(version), state.bytecode_version
32
+ end
33
+ end
34
+
35
+ def bitescript_const version
36
+ BiteScript.const_get("JAVA#{version.gsub('.', '_')}")
37
+ end
38
+ end
@@ -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
+ }
@@ -12,14 +12,10 @@
12
12
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
+ require 'test_helper'
15
16
 
16
17
  class BlocksTest < Test::Unit::TestCase
17
18
 
18
- def setup
19
- super
20
- clear_tmp_files
21
- end
22
-
23
19
  def parse_and_type code, name=tmp_script_name
24
20
  parse_and_resolve_types name, code
25
21
  end
@@ -30,13 +26,13 @@ class BlocksTest < Test::Unit::TestCase
30
26
  parse_and_type(<<-CODE)
31
27
  interface Bar do;def run:void;end;end
32
28
 
33
- class Foo
29
+ class BarOner
34
30
  def initialize; end
35
31
  def foo(a:Bar)
36
32
  1
37
33
  end
38
34
  end
39
- Foo.new.foo do
35
+ BarOner.new.foo do
40
36
  end
41
37
  CODE
42
38
  end
@@ -49,13 +45,13 @@ class BlocksTest < Test::Unit::TestCase
49
45
  def run:void; end
50
46
  end
51
47
 
52
- class Foo
48
+ class NotEmptyAccepter
53
49
  def initialize; end
54
50
  def foo(a:Bar)
55
51
  1
56
52
  end
57
53
  end
58
- Foo.new.foo do
54
+ NotEmptyAccepter.new.foo do
59
55
  1
60
56
  end
61
57
  CODE
@@ -244,17 +240,17 @@ class BlocksTest < Test::Unit::TestCase
244
240
  def test_block_impling_interface_w_multiple_methods
245
241
  assert_jraise java.lang.UnsupportedOperationException do
246
242
  parse_and_type(<<-CODE)
247
- interface Bar do
243
+ interface RunOrRun2 do
248
244
  def run:void;end
249
245
  def run2:void;end;
250
246
  end
251
247
 
252
- class Foo
253
- def foo(a:Bar)
248
+ class RunOrRun2Fooer
249
+ def foo(a:RunOrRun2)
254
250
  1
255
251
  end
256
252
  end
257
- Foo.new.foo do
253
+ RunOrRun2Fooer.new.foo do
258
254
  1
259
255
  end
260
256
  CODE
@@ -264,15 +260,15 @@ class BlocksTest < Test::Unit::TestCase
264
260
  def test_block_with_missing_params
265
261
  cls, = compile(<<-CODE)
266
262
  interface Bar do
267
- def run(a:string):void;end
263
+ def run(a:String):void;end
268
264
  end
269
265
 
270
- class Foo
266
+ class TakesABar
271
267
  def foo(a:Bar)
272
268
  a.run("x")
273
269
  end
274
270
  end
275
- Foo.new.foo do
271
+ TakesABar.new.foo do
276
272
  puts "hi"
277
273
  end
278
274
  CODE
@@ -284,16 +280,16 @@ class BlocksTest < Test::Unit::TestCase
284
280
  def test_block_with_too_many_params
285
281
  assert_raises Mirah::MirahError do
286
282
  parse_and_type(<<-CODE)
287
- interface Bar do
288
- def run(a:string):void;end
283
+ interface SingleArgMethod do
284
+ def run(a:String):void;end
289
285
  end
290
286
 
291
- class Foo
292
- def foo(a:Bar)
287
+ class ExpectsSingleArgMethod
288
+ def foo(a:SingleArgMethod)
293
289
  1
294
290
  end
295
291
  end
296
- Foo.new.foo do |a, b|
292
+ ExpectsSingleArgMethod.new.foo do |a, b|
297
293
  1
298
294
  end
299
295
  CODE
@@ -301,20 +297,24 @@ class BlocksTest < Test::Unit::TestCase
301
297
  end
302
298
 
303
299
  def test_closure_in_closure_doesnt_raise_error
304
- parse_and_type(<<-CODE)
305
- interface Bar do;def run:void;end;end
300
+ cls, = compile(<<-CODE)
301
+ interface BarRunner do;def run:void;end;end
306
302
 
307
- class Foo
308
- def foo(a:Bar)
309
- 1
303
+ class Nestable
304
+ def foo(a:BarRunner)
305
+ a.run
310
306
  end
311
307
  end
312
- Foo.new.foo do
313
- Foo.new.foo do
314
- 1
308
+ Nestable.new.foo do
309
+ puts "first closure"
310
+ Nestable.new.foo do
311
+ puts "second closure"
315
312
  end
316
313
  end
317
314
  CODE
315
+ assert_output "first closure\nsecond closure\n" do
316
+ cls.main(nil)
317
+ end
318
318
  end
319
319
 
320
320
  def test_method_requiring_subclass_of_abstract_class_finds_abstract_method
@@ -332,4 +332,25 @@ class BlocksTest < Test::Unit::TestCase
332
332
  cls.main(nil)
333
333
  end
334
334
  end
335
+
336
+ def test_block_with_interface_method_with_2_arguments
337
+ cls, = compile(<<-EOF)
338
+ interface DoubleArgMethod do
339
+ def run(a: String, b: int):void;end
340
+ end
341
+
342
+ class ExpectsDoubleArgMethod
343
+ def foo(a:DoubleArgMethod)
344
+ a.run "hello", 1243
345
+ end
346
+ end
347
+ ExpectsDoubleArgMethod.new.foo do |a, b|
348
+ puts a
349
+ puts b
350
+ end
351
+ EOF
352
+ assert_output "hello\n1243\n" do
353
+ cls.main(nil)
354
+ end
355
+ end
335
356
  end