mirah 0.0.10-java → 0.0.11-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/History.txt +44 -0
  2. data/README.txt +12 -7
  3. data/Rakefile +13 -12
  4. data/examples/SortClosure$__xform_tmp_1.class +0 -0
  5. data/examples/SortClosure$__xform_tmp_2.class +0 -0
  6. data/examples/SortClosure.class +0 -0
  7. data/examples/macros/StringEachChar$Extension1.class +0 -0
  8. data/javalib/mirah-bootstrap.jar +0 -0
  9. data/lib/mirah/appengine_tasks.rb +8 -6
  10. data/lib/mirah/ast/flow.rb +3 -3
  11. data/lib/mirah/ast/structure.rb +23 -2
  12. data/lib/mirah/commands/base.rb +5 -2
  13. data/lib/mirah/commands/base.rb~ +57 -0
  14. data/lib/mirah/commands/run.rb +15 -8
  15. data/lib/mirah/jvm/compiler/java_source.rb +15 -11
  16. data/lib/mirah/jvm/method_lookup.rb~ +247 -0
  17. data/lib/mirah/jvm/types/bitescript_ext.rb +41 -0
  18. data/lib/mirah/jvm/types/boolean.rb +33 -0
  19. data/lib/mirah/jvm/types/factory.rb +43 -3
  20. data/lib/mirah/jvm/types/integers.rb +1 -14
  21. data/lib/mirah/jvm/types/intrinsics.rb +1 -14
  22. data/lib/mirah/jvm/types/source_mirror.rb +6 -3
  23. data/lib/mirah/parser.rb +2 -6
  24. data/lib/mirah/transform/transformer.rb +2 -0
  25. data/lib/mirah/util/argument_processor.rb +33 -12
  26. data/lib/mirah/util/class_loader.rb +7 -2
  27. data/lib/mirah/util/compilation_state.rb +8 -0
  28. data/lib/mirah/version.rb +1 -1
  29. data/lib/mirah/version.rb~ +18 -0
  30. data/test/core/{test_ast.rb → ast_test.rb} +5 -1
  31. data/test/core/{test_commands.rb → commands_test.rb} +29 -2
  32. data/test/core/{test_compilation.rb → compilation_test.rb} +2 -2
  33. data/test/core/{test_env.rb → env_test.rb} +2 -2
  34. data/test/core/{test_macros.rb → macros_test.rb} +2 -2
  35. data/test/core/{test_typer.rb → typer_test.rb} +1 -1
  36. data/test/core/util/argument_processor_test.rb +64 -0
  37. data/test/core/util/class_loader_test.rb +31 -0
  38. data/test/fixtures/my.properties +0 -0
  39. data/test/fixtures/org/foo/A.class +0 -0
  40. data/test/jvm/{test_annotations.rb → annotations_test.rb} +2 -2
  41. data/test/jvm/blocks_test.rb +262 -0
  42. data/test/jvm/bytecode_test_helper.rb +1 -33
  43. data/test/jvm/constructors_test.rb +110 -0
  44. data/test/jvm/{test_enumerable.rb → enumerable_test.rb} +2 -2
  45. data/test/jvm/factory_test.rb +22 -0
  46. data/test/jvm/{test_java_typer.rb → java_typer_test.rb} +1 -1
  47. data/test/jvm/jvm_compiler_test.rb +2162 -0
  48. data/test/jvm/{test_jvm_compiler.rb → jvm_compiler_test.rb~} +43 -220
  49. data/test/jvm/{test_macros.rb → macros_test.rb} +2 -2
  50. data/test/jvm/{test_main_method.rb → main_method_test.rb} +2 -2
  51. data/test/jvm/{test_rescue.rb → rescue_test.rb} +33 -2
  52. data/test/plugins/{test_gwt.rb → gwt_test.rb} +2 -2
  53. data/test/test_helper.rb +40 -0
  54. metadata +33 -33
  55. data/test/jvm/test_blocks.rb +0 -62
data/lib/mirah/parser.rb CHANGED
@@ -46,7 +46,7 @@ module Mirah
46
46
  end
47
47
  end
48
48
  raise 'nothing to parse? ' + files_or_scripts.inspect unless nodes.length > 0
49
- nodes
49
+ nodes.compact
50
50
  end
51
51
 
52
52
  def parse_inline(source)
@@ -60,12 +60,8 @@ module Mirah
60
60
  end
61
61
 
62
62
  def parse_and_transform(filename, src)
63
- parser_ast = Mirah::AST.parse_ruby(src, filename)
64
-
65
- transformer.filename = filename
66
- mirah_ast = transformer.transform(parser_ast, nil)
63
+ mirah_ast = AST.parse src, filename, false, transformer
67
64
  process_errors(transformer.errors)
68
-
69
65
  mirah_ast
70
66
  end
71
67
 
@@ -76,6 +76,8 @@ module Mirah
76
76
  begin
77
77
  top = @extra_body.nil?
78
78
  if top
79
+ return nil if !node.children.empty? && node.children.all?(&:nil?)
80
+
79
81
  @extra_body = Mirah::AST::Body.new(nil, position(node))
80
82
  end
81
83
  method = "transform_#{camelize(node[0])}"
@@ -21,7 +21,9 @@ module Mirah
21
21
  @args = args
22
22
  end
23
23
 
24
- attr_accessor :state, :args
24
+ attr_accessor :state, :args, :exit_status_code
25
+
26
+ alias exit? exit_status_code
25
27
 
26
28
  def process
27
29
  state.args = args
@@ -29,7 +31,10 @@ module Mirah
29
31
  case args[0]
30
32
  when '--classpath', '-c'
31
33
  args.shift
32
- Mirah::Env.decode_paths(args.shift, $CLASSPATH)
34
+ state.classpath = args.shift
35
+ when '--bootclasspath'
36
+ args.shift
37
+ state.bootclasspath = args.shift
33
38
  when '--cd'
34
39
  args.shift
35
40
  Dir.chdir(args.shift)
@@ -42,17 +47,21 @@ module Mirah
42
47
  args.shift
43
48
  Mirah::AST::Script.explicit_packages = true
44
49
  when '--help', '-h'
50
+ args.shift
45
51
  print_help
46
- throw :exit
52
+
53
+ self.exit_status_code = 0
54
+ break
47
55
  when '--java', '-j'
48
56
  if state.command == :compile
49
57
  require 'mirah/jvm/compiler/java_source'
50
58
  state.compiler_class = Mirah::JVM::Compiler::JavaSource
51
59
  args.shift
52
60
  else
53
- puts "-j/--java flag only applies to \"compile\" mode."
54
- print_help
55
- throw :exit, 1
61
+ $stderr.puts "-j/--java flag only applies to \"compile\" mode."
62
+
63
+ self.exit_status_code = 1
64
+ break
56
65
  end
57
66
  when '--jvm'
58
67
  args.shift
@@ -73,22 +82,35 @@ module Mirah
73
82
  when '--version', '-v'
74
83
  args.shift
75
84
  print_version
85
+
86
+ self.exit_status_code = 0 if args.empty?
87
+ break
76
88
  when '--no-save-extensions'
77
89
  args.shift
78
90
  state.save_extensions = false
79
91
  else
80
- puts "unrecognized flag: " + args[0]
81
- print_help
82
- throw :exit, 1
92
+ $stderr.puts "unrecognized flag: " + args[0]
93
+
94
+ self.exit_status_code = 1
95
+ break
83
96
  end
84
97
  end
98
+
99
+ return if exit?
100
+
85
101
  state.destination ||= File.join(File.expand_path('.'), '')
86
102
  state.compiler_class ||= Mirah::JVM::Compiler::JVMBytecode
87
103
  end
88
104
 
89
105
  def print_help
90
- puts "#{$0} [flags] <files or -e SCRIPT>
106
+ puts help_message
107
+ state.help_printed = true
108
+ end
109
+
110
+ def help_message
111
+ "#{$0} [flags] <files or -e SCRIPT>
91
112
  -c, --classpath PATH\tAdd PATH to the Java classpath for compilation
113
+ --bootclasspath PATH\tSet the Java bootclasspath to PATH for compilation
92
114
  --cd DIR\t\tSwitch to the specified DIR befor compilation
93
115
  -d, --dir DIR\t\tUse DIR as the base dir for compilation, packages
94
116
  -e CODE\t\tCompile or run the inline script following -e
@@ -102,7 +124,6 @@ module Mirah
102
124
  -p, --plugin PLUGIN\trequire 'mirah/plugin/PLUGIN' before running
103
125
  -v, --version\t\tPrint the version of Mirah to the console
104
126
  -V, --verbose\t\tVerbose logging"
105
- state.help_printed = true
106
127
  end
107
128
 
108
129
  def print_version
@@ -111,4 +132,4 @@ module Mirah
111
132
  end
112
133
  end
113
134
  end
114
- end
135
+ end
@@ -2,8 +2,13 @@ module Mirah
2
2
  module Util
3
3
 
4
4
  ClassLoader = Java::OrgMirah::MirahClassLoader
5
+
6
+ # converts string to a java string w/ binary encoding
7
+ # might be able to avoid this in 1.9 mode
5
8
  def ClassLoader.binary_string string
6
9
  java.lang.String.new string.to_java_bytes, "ISO-8859-1"
7
- end
10
+ end
11
+
12
+ IsolatedResourceLoader = Java::OrgMirah::IsolatedResourceLoader
8
13
  end
9
- end
14
+ end
@@ -32,6 +32,14 @@ module Mirah
32
32
  attr_accessor :args
33
33
  attr_accessor :command
34
34
 
35
+ def classpath=(classpath)
36
+ Mirah::AST.type_factory.classpath = classpath
37
+ end
38
+
39
+ def bootclasspath=(classpath)
40
+ Mirah::AST.type_factory.bootclasspath = classpath
41
+ end
42
+
35
43
  def set_jvm_version(ver_str)
36
44
  case ver_str
37
45
  when '1.4'
data/lib/mirah/version.rb CHANGED
@@ -14,5 +14,5 @@
14
14
  # limitations under the License.
15
15
 
16
16
  module Mirah
17
- VERSION = "0.0.10"
17
+ VERSION = "0.0.11"
18
18
  end
@@ -0,0 +1,18 @@
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
+ module Mirah
17
+ VERSION = "0.0.9"
18
+ end
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
  require 'test_helper'
16
16
 
17
- class TestAst < Test::Unit::TestCase
17
+ class AstTest < Test::Unit::TestCase
18
18
  include Mirah
19
19
 
20
20
  def test_args
@@ -375,4 +375,8 @@ class TestAst < Test::Unit::TestCase
375
375
  AST.parse("puts( 'aoue'")
376
376
  end
377
377
  end
378
+
379
+ def test_parsing_empty_string_raises_no_error
380
+ AST.parse("")
381
+ end
378
382
  end
@@ -15,7 +15,7 @@
15
15
  require 'test_helper'
16
16
 
17
17
 
18
- class TestCommands < Test::Unit::TestCase
18
+ class CommandsTest < Test::Unit::TestCase
19
19
  def teardown
20
20
  Mirah::AST.type_factory = nil
21
21
  end
@@ -54,6 +54,12 @@ class TestCommands < Test::Unit::TestCase
54
54
  end
55
55
  end
56
56
 
57
+ def test_on_v_with_no_args_exits_without_running_command
58
+ assert_zero_exit do
59
+ RaisesMirahErrorCommand.new(['-v']).execute
60
+ end
61
+ end
62
+
57
63
  def test_on_j_option_when_command_is_not_compile_has_non_zero_exit_code
58
64
  assert_non_zero_exit do
59
65
  RaisesMirahErrorCommand.new(['-j']).execute
@@ -70,6 +76,20 @@ class TestCommands < Test::Unit::TestCase
70
76
  end
71
77
  end
72
78
 
79
+ def test_run_says_no_main_and_exits_with_non_zero_with_no_main
80
+ cmd = Mirah::Commands::Run.new([])
81
+
82
+ #stub class generation, loading, return nil main
83
+ def cmd.load_classes_and_find_main *args;nil;end
84
+ def cmd.generate_class_map;end
85
+
86
+ assert_non_zero_exit do
87
+ assert_output "No main found\n" do
88
+ cmd.execute
89
+ end
90
+ end
91
+ end
92
+
73
93
  def assert_non_zero_exit
74
94
  ex = assert_raise SystemExit do
75
95
  yield
@@ -77,4 +97,11 @@ class TestCommands < Test::Unit::TestCase
77
97
  assert_not_equal 0, ex.status
78
98
  end
79
99
 
80
- end
100
+ def assert_zero_exit
101
+ ex = assert_raise SystemExit do
102
+ yield
103
+ end
104
+ assert_equal 0, ex.status
105
+ end
106
+
107
+ end
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
  require 'test_helper'
16
16
 
17
- class TestCompilation < Test::Unit::TestCase
17
+ class CompilationTest < Test::Unit::TestCase
18
18
  include Mirah
19
19
 
20
20
  class MockCompiler
@@ -127,4 +127,4 @@ class TestCompilation < Test::Unit::TestCase
127
127
 
128
128
  assert_equal([:array, a(Mirah::AST::Array), true], @compiler.calls.first)
129
129
  end
130
- end
130
+ end
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
  require 'test_helper'
16
16
 
17
- class TestEnv < Test::Unit::TestCase
17
+ class EnvTest < Test::Unit::TestCase
18
18
  include Mirah
19
19
 
20
20
  def test_use_file_path_separator
@@ -51,4 +51,4 @@ class TestEnv < Test::Unit::TestCase
51
51
  assert_equal(['a'], Mirah::Env.decode_paths('a'))
52
52
  end
53
53
 
54
- end
54
+ end
@@ -15,7 +15,7 @@
15
15
  # TODO refactor this and test_jvm_compiler to use mirah.rb
16
16
  require 'test_helper'
17
17
 
18
- class TestMacros < Test::Unit::TestCase
18
+ class MacrosTest < Test::Unit::TestCase
19
19
  java_import 'java.lang.System'
20
20
 
21
21
  def parse(code)
@@ -58,4 +58,4 @@ class TestMacros < Test::Unit::TestCase
58
58
  EOF
59
59
  end
60
60
 
61
- end
61
+ end
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
  require 'test_helper'
16
16
 
17
- class TestTyper < Test::Unit::TestCase
17
+ class TyperTest < Test::Unit::TestCase
18
18
  include Mirah
19
19
 
20
20
  def test_fixnum
@@ -0,0 +1,64 @@
1
+ require 'test_helper'
2
+
3
+ class ArgumentProcessorTest < Test::Unit::TestCase
4
+
5
+ def test_arg_dash_v_prints_version_and_has_exit_0
6
+ state = Mirah::Util::CompilationState.new
7
+ processor = Mirah::Util::ArgumentProcessor.new state, ["-v"]
8
+
9
+ assert_output "Mirah v#{Mirah::VERSION}\n" do
10
+ processor.process
11
+ end
12
+
13
+ assert processor.exit?
14
+ assert_equal 0, processor.exit_status_code
15
+ end
16
+
17
+
18
+ def test_on_invalid_arg_prints_error_and_exits_1
19
+ state = Mirah::Util::CompilationState.new
20
+ processor = Mirah::Util::ArgumentProcessor.new state, ["--some-arg"]
21
+
22
+ assert_output "unrecognized flag: --some-arg\n" do
23
+ processor.process
24
+ end
25
+
26
+ assert processor.exit?
27
+ assert_equal 1, processor.exit_status_code
28
+ end
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
40
+
41
+ def test_dash_j_fails_when_not_compiling
42
+ state = Mirah::Util::CompilationState.new
43
+ processor = Mirah::Util::ArgumentProcessor.new state, ["-j"]
44
+
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
51
+ end
52
+
53
+ def test_dash_h_prints_help_and_exits
54
+ state = Mirah::Util::CompilationState.new
55
+ processor = Mirah::Util::ArgumentProcessor.new state, ["-h"]
56
+
57
+ assert_output processor.help_message + "\n" do
58
+ processor.process
59
+ end
60
+
61
+ assert processor.exit?
62
+ assert_equal 0, processor.exit_status_code
63
+ end
64
+ end
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ class ClassLoaderTest < Test::Unit::TestCase
4
+ FIXTURES = File.expand_path("#{__FILE__}/../../../fixtures/") +"/"
5
+ A_CLASS = "#{FIXTURES}org/foo/A.class"
6
+
7
+ def test_mirah_class_loader_find_class_in_map_successful
8
+ class_map = {
9
+ 'org.foo.A' => Mirah::Util::ClassLoader.binary_string(File.open(A_CLASS, 'rb') {|f| f.read })
10
+ }
11
+ class_loader = Mirah::Util::ClassLoader.new nil, class_map
12
+ cls = class_loader.load_class 'org.foo.A'
13
+ assert_equal 'org.foo.A', cls.name
14
+ end
15
+
16
+ def test_mirah_class_loader_w_missing_class_raises_class_not_found
17
+ class_loader = Mirah::Util::ClassLoader.new nil, {}
18
+
19
+ ex = assert_raise NativeException do
20
+ class_loader.find_class 'org.doesnt.exist.Class'
21
+ end
22
+ assert_equal java.lang.ClassNotFoundException, ex.cause.class
23
+ end
24
+
25
+
26
+ def test_isolated_resource_loader_only_finds_resources_given_to_it
27
+ loader = Mirah::Util::IsolatedResourceLoader.new [java.net.URL.new("file:#{FIXTURES}")]
28
+ url = loader.get_resource "my.properties"
29
+ assert_not_nil url
30
+ end
31
+ end
File without changes
Binary file
@@ -1,4 +1,4 @@
1
- class TestAnnotations < Test::Unit::TestCase
1
+ class AnnotationsTest < Test::Unit::TestCase
2
2
  def deprecated
3
3
  @deprecated ||= java.lang.Deprecated.java_class
4
4
  end
@@ -55,4 +55,4 @@ class TestAnnotations < Test::Unit::TestCase
55
55
  assert_equal 1, method_annotation.optional
56
56
  end
57
57
 
58
- end
58
+ end
@@ -0,0 +1,262 @@
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 BlocksTest < Test::Unit::TestCase
17
+
18
+ def setup
19
+ super
20
+ clear_tmp_files
21
+ reset_type_factory
22
+ end
23
+
24
+ def parse_and_type code, name=tmp_script_name
25
+ parse_and_resolve_types name, code
26
+ end
27
+
28
+ #this should probably be a core test
29
+ def test_empty_block_parses_and_types_without_error
30
+ assert_nothing_raised do
31
+ parse_and_type(<<-CODE)
32
+ interface Bar do;def run:void;end;end
33
+
34
+ class Foo
35
+ def foo(a:Bar)
36
+ 1
37
+ end
38
+ end
39
+ Foo.new.foo do
40
+ end
41
+ CODE
42
+ end
43
+ end
44
+
45
+ def test_non_empty_block_parses_and_types_without_error
46
+ assert_nothing_raised do
47
+ 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
57
+ end
58
+ CODE
59
+ end
60
+ end
61
+
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
+ class Foo
72
+ def foo(a:Bar)
73
+ 1
74
+ end
75
+ end
76
+ Foo.new.foo do
77
+ 1
78
+ end
79
+ CODE
80
+ end
81
+ end
82
+
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
+
121
+ def test_block
122
+ cls, = compile(<<-EOF)
123
+ thread = Thread.new do
124
+ puts "Hello"
125
+ end
126
+ begin
127
+ thread.run
128
+ thread.join
129
+ rescue
130
+ puts "Uh Oh!"
131
+ end
132
+ EOF
133
+ assert_output("Hello\n") do
134
+ cls.main([].to_java :string)
135
+ end
136
+
137
+ script, cls = compile(<<-EOF)
138
+ import java.util.Observable
139
+ class MyObservable < Observable
140
+ def initialize
141
+ super
142
+ setChanged
143
+ end
144
+ end
145
+
146
+ o = MyObservable.new
147
+ o.addObserver {|x, a| puts a}
148
+ o.notifyObservers("Hello Observer")
149
+ EOF
150
+ assert_output("Hello Observer\n") do
151
+ script.main([].to_java :string)
152
+ end
153
+
154
+ cls, = compile(<<-EOF)
155
+ def foo
156
+ a = "Hello"
157
+ thread = Thread.new do
158
+ puts a
159
+ end
160
+ begin
161
+ a = a + " Closures"
162
+ thread.run
163
+ thread.join
164
+ rescue
165
+ puts "Uh Oh!"
166
+ end
167
+ return
168
+ end
169
+ EOF
170
+ assert_output("Hello Closures\n") do
171
+ cls.foo
172
+ end
173
+
174
+ cls, = compile(<<-EOF)
175
+ def run(x:Runnable)
176
+ x.run
177
+ end
178
+ def foo
179
+ a = 1
180
+ run {a += 1}
181
+ a
182
+ end
183
+ EOF
184
+ assert_equal(2, cls.foo)
185
+ end
186
+
187
+ def test_block_with_method_def
188
+ cls, = compile(<<-EOF)
189
+ import java.util.ArrayList
190
+ import java.util.Collections
191
+ list = ArrayList.new(["a", "ABC", "Cats", "b"])
192
+ Collections.sort(list) do
193
+ def equals(a:Object, b:Object)
194
+ String(a).equalsIgnoreCase(String(b))
195
+ end
196
+ def compare(a:Object, b:Object)
197
+ String(a).compareToIgnoreCase(String(b))
198
+ end
199
+ end
200
+ list.each {|x| puts x}
201
+ EOF
202
+
203
+ assert_output("a\nABC\nb\nCats\n") do
204
+ cls.main(nil)
205
+ end
206
+ end
207
+
208
+ def test_block_with_abstract_from_object
209
+ # Comparator interface also defines equals(Object) as abstract,
210
+ # but it can be inherited from Object. We test that here.
211
+ cls, = compile(<<-EOF)
212
+ import java.util.ArrayList
213
+ 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))
217
+ end
218
+ list.each {|x| puts x}
219
+ EOF
220
+
221
+ assert_output("a\nABC\nb\nCats\n") do
222
+ cls.main(nil)
223
+ end
224
+ end
225
+
226
+ def test_block_with_no_arguments_and_return_value
227
+ cls, = compile(<<-EOF)
228
+ import java.util.concurrent.Callable
229
+ def foo c:Callable
230
+ throws Exception
231
+ puts c.call
232
+ end
233
+ begin
234
+ foo do
235
+ "an object"
236
+ end
237
+ rescue
238
+ puts "never get here"
239
+ end
240
+ EOF
241
+ assert_output("an object\n") do
242
+ cls.main(nil)
243
+ end
244
+ end
245
+
246
+ def test_closure_in_closure_doesnt_raise_error
247
+ parse_and_type(<<-CODE)
248
+ interface Bar do;def run:void;end;end
249
+
250
+ class Foo
251
+ def foo(a:Bar)
252
+ 1
253
+ end
254
+ end
255
+ Foo.new.foo do
256
+ Foo.new.foo do
257
+ 1
258
+ end
259
+ end
260
+ CODE
261
+ end
262
+ end