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.
- data/History.txt +372 -0
- data/README.txt +4 -5
- data/Rakefile +178 -55
- data/examples/appengine/Readme +3 -3
- data/examples/appengine/src/org/mirah/MirahApp.mirah +1 -1
- data/examples/appengine/src/org/mirah/list.dhtml +1 -1
- data/examples/bintrees.mirah +1 -1
- data/examples/edb.mirah +1 -1
- data/examples/fib.mirah +1 -1
- data/examples/interfaces.mirah +1 -1
- data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +4 -5
- data/examples/maven/README.txt +1 -1
- data/examples/maven/src/main/mirah/hello_mirah.mirah +1 -1
- data/examples/plugins/appengine/Rakefile +1 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +1 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +1 -1
- data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +1 -1
- data/examples/rosettacode/100-doors.mirah +6 -6
- data/examples/rosettacode/README.txt +3 -3
- data/examples/rosettacode/boolean-values.mirah +1 -1
- data/examples/rosettacode/comments.mirah +1 -1
- data/examples/rosettacode/count-occurrences-of-a-substring.mirah +1 -1
- data/examples/rosettacode/factorial.mirah +1 -1
- data/examples/rosettacode/fibonacci.mirah +1 -1
- data/examples/rosettacode/fizz-buzz.mirah +2 -2
- data/examples/rosettacode/flatten-a-list.mirah +4 -4
- data/examples/rosettacode/guess-the-number.mirah +2 -2
- data/examples/rosettacode/hamming-numbers.mirah +4 -4
- data/examples/rosettacode/is-string-numeric.mirah +22 -22
- data/examples/rosettacode/palindrome.mirah +2 -2
- data/examples/rosettacode/random-numbers.mirah +1 -1
- data/examples/rosettacode/repeat-a-string.mirah +1 -1
- data/examples/rosettacode/reverse-a-string.mirah +1 -1
- data/examples/rosettacode/rot-13.mirah +5 -5
- data/examples/rosettacode/secure-temporary-file.mirah +2 -2
- data/examples/rosettacode/sleep.mirah +1 -1
- data/examples/rosettacode/string-length.mirah +5 -5
- data/examples/swing.mirah +1 -1
- data/examples/test.edb +1 -1
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-builtins.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/javalib/mirah-util.jar +0 -0
- data/lib/duby.rb +1 -1
- data/lib/mirah.rb +50 -28
- data/lib/mirah/ast.rb +15 -605
- data/lib/mirah/ast/scope.rb +98 -69
- data/lib/mirah/commands.rb +1 -1
- data/lib/mirah/commands/base.rb +7 -7
- data/lib/mirah/commands/compile.rb +3 -3
- data/lib/mirah/commands/parse.rb +7 -5
- data/lib/mirah/commands/run.rb +12 -19
- data/lib/mirah/compiler.rb +15 -23
- data/lib/mirah/errors.rb +16 -1
- data/lib/mirah/generator.rb +79 -39
- data/lib/mirah/jvm/compiler.rb +1 -19
- data/lib/mirah/jvm/compiler/base.rb +233 -90
- data/lib/mirah/jvm/compiler/jvm_bytecode.rb +675 -363
- data/lib/mirah/jvm/method_lookup.rb +134 -65
- data/lib/mirah/jvm/typer.rb +10 -5
- data/lib/mirah/jvm/types.rb +10 -2
- data/lib/mirah/jvm/types/array_type.rb +10 -12
- data/lib/mirah/{compiler/type.rb → jvm/types/ast_ext.rb} +12 -8
- data/lib/mirah/jvm/types/basic_types.rb +26 -33
- data/lib/mirah/jvm/types/bitescript_ext.rb +1 -1
- data/lib/mirah/jvm/types/block_type.rb +15 -0
- data/lib/mirah/jvm/types/boolean.rb +8 -4
- data/lib/mirah/jvm/types/dynamic_type.rb +12 -13
- data/lib/mirah/jvm/types/enumerable.rb +7 -7
- data/lib/mirah/jvm/types/extensions.rb +11 -6
- data/lib/mirah/jvm/types/factory.rb +624 -94
- data/lib/mirah/jvm/types/floats.rb +21 -15
- data/lib/mirah/jvm/types/generic_type.rb +72 -0
- data/lib/mirah/jvm/types/implicit_nil_type.rb +29 -0
- data/lib/mirah/jvm/types/integers.rb +26 -71
- data/lib/mirah/jvm/types/interface_definition.rb +3 -3
- data/lib/mirah/jvm/types/intrinsics.rb +203 -168
- data/lib/mirah/jvm/types/literals.rb +6 -6
- data/lib/mirah/jvm/types/meta_type.rb +13 -4
- data/lib/mirah/jvm/types/methods.rb +281 -93
- data/lib/mirah/jvm/types/null_type.rb +17 -5
- data/lib/mirah/jvm/types/number.rb +10 -7
- data/lib/mirah/jvm/types/primitive_type.rb +17 -6
- data/lib/mirah/jvm/types/source_mirror.rb +12 -7
- data/lib/mirah/jvm/types/type.rb +107 -23
- data/lib/mirah/jvm/types/type_definition.rb +25 -10
- data/lib/mirah/jvm/types/unreachable_type.rb +1 -1
- data/lib/mirah/jvm/types/void_type.rb +3 -3
- data/lib/mirah/parser.rb +154 -16
- data/lib/mirah/plugin/edb.rb +1 -1
- data/lib/mirah/transform.rb +1 -2
- data/lib/mirah/transform/ast_ext.rb +24 -43
- data/lib/mirah/transform/transformer.rb +29 -224
- data/lib/mirah/typer.rb +2 -16
- data/lib/mirah/util/argument_processor.rb +25 -10
- data/lib/mirah/util/class_loader.rb +1 -1
- data/lib/mirah/util/compilation_state.rb +16 -17
- data/lib/mirah/util/delegate.rb +2 -2
- data/lib/mirah/util/logging.rb +110 -0
- data/lib/mirah/util/process_errors.rb +69 -11
- data/lib/mirah/version.rb +1 -1
- data/test/core/commands_test.rb +6 -24
- data/test/core/env_test.rb +5 -5
- data/{lib/mirah/jvm/source_generator/typer.rb → test/core/generator_test.rb} +9 -9
- data/test/core/typer_test.rb +196 -158
- data/test/core/util/argument_processor_test.rb +10 -10
- data/test/core/util/class_loader_test.rb +6 -5
- data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
- data/test/jvm/annotations_test.rb +5 -5
- data/test/jvm/blocks_test.rb +140 -88
- data/test/jvm/bytecode_test_helper.rb +112 -94
- data/test/jvm/cast_test.rb +162 -0
- data/test/jvm/constructors_test.rb +18 -8
- data/test/jvm/enumerable_test.rb +77 -44
- data/test/jvm/example_test.rb +53 -0
- data/test/jvm/factory_test.rb +7 -1
- data/test/jvm/generics_test.rb +57 -0
- data/test/jvm/hash_test.rb +106 -0
- data/test/jvm/import_test.rb +81 -0
- data/test/jvm/interface_test.rb +73 -0
- data/test/jvm/java_typer_test.rb +92 -66
- data/{lib/mirah/typer/base.rb → test/jvm/jvm_commands_test.rb} +6 -10
- data/test/jvm/jvm_compiler_test.rb +170 -604
- data/test/jvm/list_extensions_test.rb +23 -0
- data/test/jvm/macros_test.rb +197 -32
- data/test/jvm/main_method_test.rb +4 -4
- data/test/jvm/numeric_extensions_test.rb +13 -0
- data/test/jvm/rescue_test.rb +73 -16
- data/test/jvm/varargs_test.rb +65 -0
- data/test/test_helper.rb +1 -2
- metadata +234 -251
- data/examples/SortClosure$__xform_tmp_1.class +0 -0
- data/examples/SortClosure$__xform_tmp_2.class +0 -0
- data/examples/SortClosure.class +0 -0
- data/examples/macros/StringEachChar$Extension1.class +0 -0
- data/lib/mirah/ast/call.rb +0 -345
- data/lib/mirah/ast/class.rb +0 -359
- data/lib/mirah/ast/flow.rb +0 -381
- data/lib/mirah/ast/intrinsics.rb +0 -563
- data/lib/mirah/ast/literal.rb +0 -178
- data/lib/mirah/ast/local.rb +0 -112
- data/lib/mirah/ast/method.rb +0 -408
- data/lib/mirah/ast/structure.rb +0 -387
- data/lib/mirah/ast/type.rb +0 -146
- data/lib/mirah/commands/base.rb~ +0 -57
- data/lib/mirah/compiler/call.rb +0 -45
- data/lib/mirah/compiler/class.rb +0 -81
- data/lib/mirah/compiler/flow.rb +0 -109
- data/lib/mirah/compiler/literal.rb +0 -130
- data/lib/mirah/compiler/local.rb +0 -59
- data/lib/mirah/compiler/method.rb +0 -44
- data/lib/mirah/compiler/structure.rb +0 -65
- data/lib/mirah/jvm/compiler/java_source.rb +0 -787
- data/lib/mirah/jvm/method_lookup.rb~ +0 -247
- data/lib/mirah/jvm/source_generator/builder.rb +0 -468
- data/lib/mirah/jvm/source_generator/loops.rb +0 -131
- data/lib/mirah/jvm/source_generator/precompile.rb +0 -210
- data/lib/mirah/plugin/gwt.rb +0 -189
- data/lib/mirah/plugin/java.rb +0 -70
- data/lib/mirah/transform/error.rb +0 -13
- data/lib/mirah/transform/helper.rb +0 -765
- data/lib/mirah/typer/simple.rb +0 -384
- data/lib/mirah/version.rb~ +0 -18
- data/test/core/ast_test.rb +0 -382
- data/test/core/compilation_test.rb +0 -130
- data/test/core/macros_test.rb +0 -61
- data/test/jvm/javac_test_helper.rb +0 -89
- data/test/jvm/jvm_compiler_test.rb~ +0 -2181
- 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
|
-
|
|
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"
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
-
|
|
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
|
data/test/jvm/blocks_test.rb
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
61
|
+
def test_simple_block
|
|
122
62
|
cls, = compile(<<-EOF)
|
|
123
63
|
thread = Thread.new do
|
|
124
|
-
|
|
64
|
+
System.out.println "Hello"
|
|
125
65
|
end
|
|
126
66
|
begin
|
|
127
67
|
thread.run
|
|
128
68
|
thread.join
|
|
129
69
|
rescue
|
|
130
|
-
|
|
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|
|
|
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
|
-
|
|
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
|
-
|
|
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|
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
26
|
+
|
|
27
|
+
def new_state
|
|
51
28
|
state = Mirah::Util::CompilationState.new
|
|
52
|
-
state.save_extensions =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
|
64
|
-
|
|
65
|
-
|
|
34
|
+
|
|
35
|
+
def clean_tmp_files
|
|
36
|
+
return unless @tmp_classes
|
|
37
|
+
File.unlink(*@tmp_classes.uniq)
|
|
66
38
|
end
|
|
67
|
-
|
|
68
|
-
def
|
|
69
|
-
JVM::Compiler::JVMBytecode
|
|
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,
|
|
77
|
-
typer =
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
99
|
-
bytes =
|
|
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(
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
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
|
|
118
|
-
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
|
135
|
-
|
|
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
|
|
147
|
-
|
|
148
|
-
clear_tmp_files
|
|
165
|
+
def cleanup
|
|
166
|
+
clean_tmp_files
|
|
149
167
|
end
|
|
150
168
|
end
|