mirah 0.0.10-java → 0.0.11-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 (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