duby 0.0.2-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 +8 -0
- data/README.txt +39 -0
- data/Rakefile +13 -0
- data/bin/duby +9 -0
- data/bin/dubyc +9 -0
- data/bin/dubyp +9 -0
- data/examples/README +16 -0
- data/examples/appengine/Rakefile +72 -0
- data/examples/appengine/Readme +27 -0
- data/examples/appengine/config.ru +7 -0
- data/examples/appengine/lib/duby/plugin/datastore.rb +171 -0
- data/examples/appengine/src/com/google/appengine/ext/duby/db/Model.duby +132 -0
- data/examples/appengine/src/com/ribrdb/DubyApp.duby +28 -0
- data/examples/appengine/src/com/ribrdb/list.dhtml +15 -0
- data/examples/construction.duby +8 -0
- data/examples/edb.duby +3 -0
- data/examples/fib.duby +24 -0
- data/examples/fields.duby +22 -0
- data/examples/fractal.duby +57 -0
- data/examples/java_thing.duby +13 -0
- data/examples/simple_class.duby +12 -0
- data/examples/swing.duby +20 -0
- data/examples/tak.duby +15 -0
- data/examples/test.edb +9 -0
- data/javalib/JRubyParser.jar +0 -0
- data/lib/duby.rb +168 -0
- data/lib/duby/ast.rb +386 -0
- data/lib/duby/ast/call.rb +145 -0
- data/lib/duby/ast/class.rb +154 -0
- data/lib/duby/ast/flow.rb +332 -0
- data/lib/duby/ast/intrinsics.rb +56 -0
- data/lib/duby/ast/literal.rb +97 -0
- data/lib/duby/ast/local.rb +92 -0
- data/lib/duby/ast/method.rb +244 -0
- data/lib/duby/ast/structure.rb +62 -0
- data/lib/duby/ast/type.rb +93 -0
- data/lib/duby/c/compiler.rb +134 -0
- data/lib/duby/compiler.rb +282 -0
- data/lib/duby/jvm/compiler.rb +766 -0
- data/lib/duby/jvm/method_lookup.rb +193 -0
- data/lib/duby/jvm/source_compiler.rb +605 -0
- data/lib/duby/jvm/source_generator/builder.rb +387 -0
- data/lib/duby/jvm/source_generator/loops.rb +110 -0
- data/lib/duby/jvm/source_generator/precompile.rb +170 -0
- data/lib/duby/jvm/source_generator/typer.rb +11 -0
- data/lib/duby/jvm/typer.rb +131 -0
- data/lib/duby/jvm/types.rb +331 -0
- data/lib/duby/jvm/types/basic_types.rb +19 -0
- data/lib/duby/jvm/types/boolean.rb +11 -0
- data/lib/duby/jvm/types/enumerable.rb +63 -0
- data/lib/duby/jvm/types/factory.rb +155 -0
- data/lib/duby/jvm/types/floats.rb +70 -0
- data/lib/duby/jvm/types/integers.rb +110 -0
- data/lib/duby/jvm/types/intrinsics.rb +230 -0
- data/lib/duby/jvm/types/literals.rb +82 -0
- data/lib/duby/jvm/types/methods.rb +381 -0
- data/lib/duby/jvm/types/number.rb +92 -0
- data/lib/duby/nbcompiler.rb +29 -0
- data/lib/duby/old/compiler_old.rb +845 -0
- data/lib/duby/old/declaration.rb +72 -0
- data/lib/duby/old/mapper.rb +72 -0
- data/lib/duby/old/signature.rb +52 -0
- data/lib/duby/old/typer_old.rb +163 -0
- data/lib/duby/plugin/edb.rb +25 -0
- data/lib/duby/plugin/java.rb +42 -0
- data/lib/duby/plugin/math.rb +84 -0
- data/lib/duby/transform.rb +1028 -0
- data/lib/duby/typer.rb +369 -0
- data/test/TestUser.class +0 -0
- data/test/test_ast.rb +391 -0
- data/test/test_compilation.rb +98 -0
- data/test/test_java_typer.rb +199 -0
- data/test/test_javac_compiler.rb +58 -0
- data/test/test_jvm_compiler.rb +1770 -0
- data/test/test_math_plugin.rb +87 -0
- data/test/test_typer.rb +246 -0
- metadata +156 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'duby'
|
2
|
+
require 'duby/compiler'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'jruby'
|
5
|
+
|
6
|
+
class TestAst < Test::Unit::TestCase
|
7
|
+
include Duby
|
8
|
+
|
9
|
+
class MockCompiler
|
10
|
+
attr_accessor :calls
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@calls = []
|
14
|
+
end
|
15
|
+
def compile(ast)
|
16
|
+
ast.compile(self, true)
|
17
|
+
end
|
18
|
+
|
19
|
+
def line(num)
|
20
|
+
# ignore newlines
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(sym, *args, &block)
|
24
|
+
calls << [sym, *args]
|
25
|
+
block.call if block
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup
|
30
|
+
@compiler = MockCompiler.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_fixnum
|
34
|
+
new_ast = AST.parse("1").body
|
35
|
+
|
36
|
+
new_ast.compile(@compiler, true)
|
37
|
+
|
38
|
+
assert_equal([[:fixnum, 1]], @compiler.calls)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_string
|
42
|
+
new_ast = AST.parse("'foo'").body
|
43
|
+
|
44
|
+
new_ast.compile(@compiler, true)
|
45
|
+
|
46
|
+
assert_equal([[:string, "foo"]], @compiler.calls)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_float
|
50
|
+
new_ast = AST.parse("1.0").body
|
51
|
+
|
52
|
+
new_ast.compile(@compiler, true)
|
53
|
+
|
54
|
+
assert_equal([[:float, 1.0]], @compiler.calls)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_boolean
|
58
|
+
new_ast = AST.parse("true").body
|
59
|
+
|
60
|
+
new_ast.compile(@compiler, true)
|
61
|
+
|
62
|
+
assert_equal([[:boolean, true]], @compiler.calls)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_local
|
66
|
+
new_ast = AST.parse("a = 1").body
|
67
|
+
|
68
|
+
new_ast.compile(@compiler, true)
|
69
|
+
|
70
|
+
assert_equal([[:local_assign, "a", nil, true, AST.fixnum(nil, nil, 1)]], @compiler.calls)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_local_typed
|
74
|
+
new_ast = AST.parse("a = 1").body
|
75
|
+
typer = Typer::Simple.new(:bar)
|
76
|
+
new_ast.infer(typer)
|
77
|
+
new_ast.compile(@compiler, true)
|
78
|
+
|
79
|
+
assert_equal([[:local_assign, "a", AST.type(:fixnum), true, AST.fixnum(nil, nil, 1)]], @compiler.calls)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_return
|
83
|
+
new_ast = AST.parse("return 1").body
|
84
|
+
new_ast.compile(@compiler, true)
|
85
|
+
|
86
|
+
assert_equal([[:return, new_ast]], @compiler.calls)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_empty_array
|
90
|
+
new_ast = AST.parse("int[5]").body
|
91
|
+
new_ast.compile(@compiler, true)
|
92
|
+
|
93
|
+
assert_equal(1, @compiler.calls.size)
|
94
|
+
size = @compiler.calls[0].pop
|
95
|
+
assert_equal([[:empty_array, AST.type(:int)]], @compiler.calls)
|
96
|
+
assert_equal(5, size.literal)
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'duby/typer'
|
5
|
+
require 'duby/plugin/java'
|
6
|
+
require 'duby/jvm/compiler'
|
7
|
+
require 'duby/jvm/typer'
|
8
|
+
|
9
|
+
class TestJavaTyper < Test::Unit::TestCase
|
10
|
+
include Duby
|
11
|
+
|
12
|
+
def setup
|
13
|
+
AST.type_factory = Duby::JVM::Types::TypeFactory.new
|
14
|
+
@typer = Typer::JVM.new('foobar', nil)
|
15
|
+
compiler = Duby::Compiler::JVM.new('foobar')
|
16
|
+
|
17
|
+
@java_typer = Typer::JavaTyper.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
AST.type_factory = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_simple_overtyped_meta_method
|
25
|
+
string_meta = AST::type('java.lang.String', false, true)
|
26
|
+
string = AST::type('java.lang.String')
|
27
|
+
|
28
|
+
# integral types
|
29
|
+
['boolean', 'char', 'double', 'float', 'int', 'long'].each do |type_name|
|
30
|
+
type = AST::type(type_name)
|
31
|
+
return_type = @java_typer.method_type(@typer, string_meta, 'valueOf', [type])
|
32
|
+
assert_equal(string, return_type, "valueOf(#{type}) should return #{string}")
|
33
|
+
end
|
34
|
+
|
35
|
+
# char[]
|
36
|
+
type = AST::type('char', true)
|
37
|
+
return_type = @java_typer.method_type(@typer, string_meta, 'valueOf', [type])
|
38
|
+
assert_equal(string, return_type)
|
39
|
+
|
40
|
+
# Object
|
41
|
+
type = AST::type('java.lang.Object')
|
42
|
+
return_type = @java_typer.method_type(@typer, string_meta, 'valueOf', [type])
|
43
|
+
assert_equal(string, return_type)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_non_overtyped_method
|
47
|
+
string = AST::type('java.lang.String')
|
48
|
+
|
49
|
+
int = AST::type('int')
|
50
|
+
return_type = @java_typer.method_type(@typer, string, 'length', [])
|
51
|
+
assert_equal(int, return_type)
|
52
|
+
|
53
|
+
byte_array = AST::type('byte', true)
|
54
|
+
return_type = @java_typer.method_type(@typer, string, 'getBytes', [])
|
55
|
+
assert_equal(byte_array, return_type)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_simple_overtyped_method
|
59
|
+
string_meta = AST::type('java.lang.String', false, true)
|
60
|
+
string = AST::type('java.lang.String')
|
61
|
+
|
62
|
+
return_type = @java_typer.method_type(@typer, string_meta, 'valueOf', [string])
|
63
|
+
assert_equal(string, return_type)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_primitive_conversion_method
|
67
|
+
string = AST::type('java.lang.String')
|
68
|
+
byte = AST::type('byte')
|
69
|
+
char = AST::type('char')
|
70
|
+
long = AST::type('long')
|
71
|
+
|
72
|
+
return_type = @java_typer.method_type(@typer, string, 'charAt', [byte])
|
73
|
+
assert_equal(char, return_type)
|
74
|
+
|
75
|
+
assert_raise NoMethodError do
|
76
|
+
@java_typer.method_type(@typer, string, 'charAt', [long])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
include Duby::JVM::MethodLookup
|
81
|
+
|
82
|
+
def test_complex_overtyped_method
|
83
|
+
printstream = java.io.PrintStream.java_class
|
84
|
+
object = java.lang.Object.java_class
|
85
|
+
string = java.lang.String.java_class
|
86
|
+
|
87
|
+
# best match is Object
|
88
|
+
method = find_method(printstream, "println", [object], false)
|
89
|
+
assert_match('println(java.lang.Object)', method.to_s)
|
90
|
+
# best match is String
|
91
|
+
method = find_method(printstream, "println", [string], false)
|
92
|
+
assert_match('println(java.lang.String)', method.to_s)
|
93
|
+
# only match is Object
|
94
|
+
method = find_method(printstream, "println", [printstream], false)
|
95
|
+
assert_match('println(java.lang.Object)', method.to_s)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_is_more_specific
|
99
|
+
object = java.lang.Object.java_class
|
100
|
+
charseq = java.lang.CharSequence.java_class
|
101
|
+
string = java.lang.String.java_class
|
102
|
+
|
103
|
+
assert @java_typer.is_more_specific?([string], [object])
|
104
|
+
assert @java_typer.is_more_specific?([charseq], [object])
|
105
|
+
assert @java_typer.is_more_specific?([string], [charseq])
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_primitive_convertible
|
109
|
+
boolean = Java::boolean.java_class
|
110
|
+
byte = Java::byte.java_class
|
111
|
+
short = Java::short.java_class
|
112
|
+
char = Java::char.java_class
|
113
|
+
int = Java::int.java_class
|
114
|
+
long = Java::long.java_class
|
115
|
+
float = Java::float.java_class
|
116
|
+
double = Java::double.java_class
|
117
|
+
|
118
|
+
assert !primitive_convertible?(boolean, byte)
|
119
|
+
assert !primitive_convertible?(boolean, short)
|
120
|
+
assert !primitive_convertible?(boolean, char)
|
121
|
+
assert !primitive_convertible?(boolean, int)
|
122
|
+
assert !primitive_convertible?(boolean, long)
|
123
|
+
assert !primitive_convertible?(boolean, float)
|
124
|
+
assert !primitive_convertible?(boolean, double)
|
125
|
+
assert primitive_convertible?(boolean, boolean)
|
126
|
+
|
127
|
+
assert !primitive_convertible?(byte, boolean)
|
128
|
+
assert primitive_convertible?(byte, byte)
|
129
|
+
assert primitive_convertible?(byte, short)
|
130
|
+
assert primitive_convertible?(byte, char)
|
131
|
+
assert primitive_convertible?(byte, int)
|
132
|
+
assert primitive_convertible?(byte, long)
|
133
|
+
assert primitive_convertible?(byte, float)
|
134
|
+
assert primitive_convertible?(byte, double)
|
135
|
+
|
136
|
+
assert !primitive_convertible?(short, boolean)
|
137
|
+
assert !primitive_convertible?(short, byte)
|
138
|
+
assert !primitive_convertible?(short, char)
|
139
|
+
assert primitive_convertible?(short, short)
|
140
|
+
assert primitive_convertible?(short, int)
|
141
|
+
assert primitive_convertible?(short, long)
|
142
|
+
assert primitive_convertible?(short, float)
|
143
|
+
assert primitive_convertible?(short, double)
|
144
|
+
|
145
|
+
assert !primitive_convertible?(char, boolean)
|
146
|
+
assert !primitive_convertible?(char, byte)
|
147
|
+
assert !primitive_convertible?(char, short)
|
148
|
+
assert primitive_convertible?(char, char)
|
149
|
+
assert primitive_convertible?(char, int)
|
150
|
+
assert primitive_convertible?(char, long)
|
151
|
+
assert primitive_convertible?(char, float)
|
152
|
+
assert primitive_convertible?(char, double)
|
153
|
+
|
154
|
+
assert !primitive_convertible?(int, boolean)
|
155
|
+
assert !primitive_convertible?(int, byte)
|
156
|
+
assert !primitive_convertible?(int, short)
|
157
|
+
assert !primitive_convertible?(int, char)
|
158
|
+
assert primitive_convertible?(int, int)
|
159
|
+
assert primitive_convertible?(int, long)
|
160
|
+
assert primitive_convertible?(int, float)
|
161
|
+
assert primitive_convertible?(int, double)
|
162
|
+
|
163
|
+
assert !primitive_convertible?(long, boolean)
|
164
|
+
assert !primitive_convertible?(long, byte)
|
165
|
+
assert !primitive_convertible?(long, short)
|
166
|
+
assert !primitive_convertible?(long, char)
|
167
|
+
assert !primitive_convertible?(long, int)
|
168
|
+
assert primitive_convertible?(long, long)
|
169
|
+
assert !primitive_convertible?(long, float)
|
170
|
+
assert primitive_convertible?(long, double)
|
171
|
+
|
172
|
+
assert !primitive_convertible?(float, boolean)
|
173
|
+
assert !primitive_convertible?(float, byte)
|
174
|
+
assert !primitive_convertible?(float, short)
|
175
|
+
assert !primitive_convertible?(float, char)
|
176
|
+
assert !primitive_convertible?(float, int)
|
177
|
+
assert !primitive_convertible?(float, long)
|
178
|
+
assert primitive_convertible?(float, float)
|
179
|
+
assert primitive_convertible?(float, double)
|
180
|
+
|
181
|
+
assert !primitive_convertible?(double, boolean)
|
182
|
+
assert !primitive_convertible?(double, byte)
|
183
|
+
assert !primitive_convertible?(double, short)
|
184
|
+
assert !primitive_convertible?(double, char)
|
185
|
+
assert !primitive_convertible?(double, int)
|
186
|
+
assert !primitive_convertible?(double, long)
|
187
|
+
assert !primitive_convertible?(double, float)
|
188
|
+
assert primitive_convertible?(double, double)
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_primitive_array
|
192
|
+
ary = AST.type('byte', true)
|
193
|
+
int = AST.type('int')
|
194
|
+
|
195
|
+
java_typer = Typer::JavaTyper.new
|
196
|
+
|
197
|
+
assert_equal(AST.type('byte'), java_typer.method_type(nil, ary, "[]", [int]))
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'duby'
|
5
|
+
require 'duby/jvm/source_compiler'
|
6
|
+
require 'jruby'
|
7
|
+
require 'stringio'
|
8
|
+
require File.join(File.dirname(__FILE__), 'test_jvm_compiler')
|
9
|
+
|
10
|
+
class TestJavacCompiler < TestJVMCompiler
|
11
|
+
import javax.tools.ToolProvider
|
12
|
+
import java.util.Arrays
|
13
|
+
def javac(files)
|
14
|
+
compiler = ToolProvider.system_java_compiler
|
15
|
+
fm = compiler.get_standard_file_manager(nil, nil, nil)
|
16
|
+
units = fm.get_java_file_objects_from_strings(Arrays.as_list(files.to_java :string))
|
17
|
+
unless compiler.get_task(nil, fm, nil, nil, nil, units).call
|
18
|
+
raise "Compilation error"
|
19
|
+
end
|
20
|
+
loader = org.jruby.util.ClassCache::OneShotClassLoader.new(
|
21
|
+
JRuby.runtime.jruby_class_loader)
|
22
|
+
classes = []
|
23
|
+
files.each do |name|
|
24
|
+
classfile = name.sub /java$/, 'class'
|
25
|
+
if File.exist? classfile
|
26
|
+
bytecode = IO.read(classfile)
|
27
|
+
cls = loader.define_class(name[0..-6], bytecode.to_java_bytes)
|
28
|
+
classes << JavaUtilities.get_proxy_class(cls.name)
|
29
|
+
@tmp_classes << name
|
30
|
+
@tmp_classes << classfile
|
31
|
+
end
|
32
|
+
end
|
33
|
+
classes
|
34
|
+
end
|
35
|
+
|
36
|
+
def compile(code)
|
37
|
+
File.unlink(*@tmp_classes)
|
38
|
+
@tmp_classes.clear
|
39
|
+
AST.type_factory = Duby::JVM::Types::TypeFactory.new
|
40
|
+
transformer = Duby::Transform::Transformer.new
|
41
|
+
ast = AST.parse(code, name, true, transformer)
|
42
|
+
name = "script" + System.nano_time.to_s
|
43
|
+
typer = Typer::JVM.new(name, transformer)
|
44
|
+
ast.infer(typer)
|
45
|
+
typer.resolve(true)
|
46
|
+
compiler = Compiler::JavaSource.new(name)
|
47
|
+
ast.compile(compiler, false)
|
48
|
+
java_files = []
|
49
|
+
compiler.generate do |name, builder|
|
50
|
+
bytes = builder.generate
|
51
|
+
open("#{name}", "w") do |f|
|
52
|
+
f << bytes
|
53
|
+
end
|
54
|
+
java_files << name
|
55
|
+
end
|
56
|
+
classes = javac(java_files)
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,1770 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'duby'
|
5
|
+
require 'jruby'
|
6
|
+
require 'stringio'
|
7
|
+
|
8
|
+
unless Duby::AST.macro "__gloop__"
|
9
|
+
Duby::AST.defmacro "__gloop__" do |transformer, fcall, parent|
|
10
|
+
Duby::AST::Loop.new(parent, parent.position, true, false) do |loop|
|
11
|
+
init, condition, check_first, pre, post = fcall.args_node.child_nodes.to_a
|
12
|
+
loop.check_first = check_first.kind_of?(Duby::AST::JRubyAst::TrueNode)
|
13
|
+
|
14
|
+
nil_t = Duby::AST::JRubyAst::NilNode
|
15
|
+
loop.init = transformer.transform(init, loop) unless init.kind_of?(nil_t)
|
16
|
+
loop.pre = transformer.transform(pre, loop) unless pre.kind_of?(nil_t)
|
17
|
+
loop.post = transformer.transform(post, loop) unless post.kind_of?(nil_t)
|
18
|
+
|
19
|
+
body = transformer.transform(fcall.iter_node, loop).body
|
20
|
+
body.parent = loop
|
21
|
+
[
|
22
|
+
Duby::AST::Condition.new(loop, parent.position) do |c|
|
23
|
+
[transformer.transform(condition, c)]
|
24
|
+
end,
|
25
|
+
body
|
26
|
+
]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TestJVMCompiler < Test::Unit::TestCase
|
32
|
+
include Duby
|
33
|
+
import java.lang.System
|
34
|
+
import java.io.PrintStream
|
35
|
+
|
36
|
+
def setup
|
37
|
+
@tmp_classes = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def teardown
|
41
|
+
AST.type_factory = nil
|
42
|
+
File.unlink(*@tmp_classes)
|
43
|
+
end
|
44
|
+
|
45
|
+
def assert_include(value, array, message=nil)
|
46
|
+
message = build_message message, '<?> does not include <?>', array, value
|
47
|
+
assert_block message do
|
48
|
+
array.include? value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def compile(code)
|
53
|
+
File.unlink(*@tmp_classes)
|
54
|
+
@tmp_classes.clear
|
55
|
+
AST.type_factory = Duby::JVM::Types::TypeFactory.new
|
56
|
+
name = "script" + System.nano_time.to_s
|
57
|
+
transformer = Duby::Transform::Transformer.new
|
58
|
+
ast = AST.parse(code, name, true, transformer)
|
59
|
+
typer = Typer::JVM.new(name, transformer)
|
60
|
+
ast.infer(typer)
|
61
|
+
typer.resolve(true)
|
62
|
+
compiler = Compiler::JVM.new(name)
|
63
|
+
compiler.compile(ast)
|
64
|
+
classes = []
|
65
|
+
loader = org.jruby.util.JRubyClassLoader.new(
|
66
|
+
JRuby.runtime.jruby_class_loader)
|
67
|
+
compiler.generate do |name, builder|
|
68
|
+
bytes = builder.generate
|
69
|
+
open("#{name}", "w") do |f|
|
70
|
+
f << bytes
|
71
|
+
end
|
72
|
+
cls = loader.define_class(name[0..-7], bytes.to_java_bytes)
|
73
|
+
classes << JavaUtilities.get_proxy_class(cls.name)
|
74
|
+
@tmp_classes << "#{name}"
|
75
|
+
end
|
76
|
+
|
77
|
+
classes
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_local
|
81
|
+
cls, = compile("def foo; a = 1; a; end")
|
82
|
+
assert_equal(1, cls.foo)
|
83
|
+
|
84
|
+
cls, = compile("def foo; a = 1.0; a; end")
|
85
|
+
assert_equal(1.0, cls.foo)
|
86
|
+
|
87
|
+
cls, = compile("def foo; a = 'bar'; a; end")
|
88
|
+
assert_equal('bar', cls.foo)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_addition
|
92
|
+
cls, = compile("def foo; a = 1; b = 2; a + b; end")
|
93
|
+
assert_equal(3, cls.foo)
|
94
|
+
|
95
|
+
cls, = compile("def foo; a = 1.0; b = 2.0; a + b; end")
|
96
|
+
assert_equal(3.0, cls.foo)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_subtraction
|
100
|
+
cls, = compile("def foo; a = 3; b = 2; a - b; end")
|
101
|
+
assert_equal(1, cls.foo)
|
102
|
+
|
103
|
+
cls, = compile("def foo; a = 3.0; b = 2.0; a - b; end")
|
104
|
+
assert_equal(1.0, cls.foo)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_multiplication
|
108
|
+
cls, = compile("def foo; a = 2; b = 3; a * b; end")
|
109
|
+
assert_equal(6, cls.foo)
|
110
|
+
|
111
|
+
cls, = compile("def foo; a = 2.0; b = 3.0; a * b; end")
|
112
|
+
assert_equal(6.0, cls.foo)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_division
|
116
|
+
cls, = compile("def foo; a = 6; b = 3; a / b; end")
|
117
|
+
assert_equal(2, cls.foo)
|
118
|
+
|
119
|
+
cls, = compile("def foo; a = 6.0; b = 3.0; a / b; end")
|
120
|
+
assert_equal(2.0, cls.foo)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_rem
|
124
|
+
cls, = compile("def foo; a = 7; b = 3; a % b; end")
|
125
|
+
assert_equal(1, cls.foo)
|
126
|
+
|
127
|
+
cls, = compile("def foo; a = 8.0; b = 3.0; a % b; end")
|
128
|
+
assert_equal(2.0, cls.foo)
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_shift_left
|
132
|
+
cls, = compile("def foo; a = 1; b = 3; a << b; end")
|
133
|
+
assert_equal(8, cls.foo)
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_shift_right
|
137
|
+
cls, = compile("def foo; a = 7; b = 2; a >> b; end")
|
138
|
+
assert_equal(1, cls.foo)
|
139
|
+
|
140
|
+
cls, = compile("def foo; a = -1; b = 1; a >> b; end")
|
141
|
+
assert_equal(-1, cls.foo)
|
142
|
+
end
|
143
|
+
|
144
|
+
# TODO the parser doesn't like >>>
|
145
|
+
|
146
|
+
# def test_unsigned_shift_right
|
147
|
+
# cls, = compile("def foo; a = -1; b = 31; a >>> b; end")
|
148
|
+
# assert_equal(1, cls.foo)
|
149
|
+
# end
|
150
|
+
|
151
|
+
def test_binary_and
|
152
|
+
cls, = compile("def foo; a = 7; b = 3; a & b; end")
|
153
|
+
assert_equal(3, cls.foo)
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_binary_or
|
157
|
+
cls, = compile("def foo; a = 4; b = 3; a | b; end")
|
158
|
+
assert_equal(7, cls.foo)
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_binary_xor
|
162
|
+
cls, = compile("def foo; a = 5; b = 3; a ^ b; end")
|
163
|
+
assert_equal(6, cls.foo)
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_return
|
167
|
+
cls, = compile("def foo; return 1; end")
|
168
|
+
assert_equal(1, cls.foo)
|
169
|
+
|
170
|
+
cls, = compile("def foo; return 1.0; end")
|
171
|
+
assert_equal(1.0, cls.foo)
|
172
|
+
|
173
|
+
cls, = compile("def foo; return 'bar'; end")
|
174
|
+
assert_equal('bar', cls.foo)
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_primitive_array
|
178
|
+
cls, = compile("def foo; a = boolean[2]; a; end")
|
179
|
+
assert_equal(Java::boolean[].java_class, cls.foo.class.java_class)
|
180
|
+
assert_equal([false,false], cls.foo.to_a)
|
181
|
+
cls, = compile("def foo; a = boolean[2]; a[0] = true; a[0]; end")
|
182
|
+
assert_equal(TrueClass, cls.foo.class)
|
183
|
+
assert_equal(true, cls.foo)
|
184
|
+
cls, = compile("def foo; a = boolean[2]; a.length; end")
|
185
|
+
assert_equal(Fixnum, cls.foo.class)
|
186
|
+
assert_equal(2, cls.foo)
|
187
|
+
|
188
|
+
cls, = compile("def foo; a = byte[2]; a; end")
|
189
|
+
assert_equal(Java::byte[].java_class, cls.foo.class.java_class)
|
190
|
+
assert_equal([0,0], cls.foo.to_a)
|
191
|
+
cls, = compile("def foo; a = byte[2]; a[0] = 1; a[0]; end")
|
192
|
+
assert_equal(Fixnum, cls.foo.class)
|
193
|
+
assert_equal(1, cls.foo)
|
194
|
+
|
195
|
+
cls, = compile("def foo; a = short[2]; a; end")
|
196
|
+
assert_equal(Java::short[].java_class, cls.foo.class.java_class)
|
197
|
+
assert_equal([0,0], cls.foo.to_a)
|
198
|
+
cls, = compile("def foo; a = short[2]; a[0] = 1; a[0]; end")
|
199
|
+
assert_equal(Fixnum, cls.foo.class)
|
200
|
+
assert_equal(1, cls.foo)
|
201
|
+
|
202
|
+
cls, = compile("def foo; a = char[2]; a; end")
|
203
|
+
assert_equal(Java::char[].java_class, cls.foo.class.java_class)
|
204
|
+
assert_equal([0,0], cls.foo.to_a)
|
205
|
+
# Pending char constants or casts
|
206
|
+
# cls, = compile("def foo; a = char[2]; a[0] = 1; a[0]; end")
|
207
|
+
# assert_equal(Fixnum, cls.foo.class)
|
208
|
+
# assert_equal(1, cls.foo)
|
209
|
+
|
210
|
+
cls, = compile("def foo; a = int[2]; a; end")
|
211
|
+
assert_equal(Java::int[].java_class, cls.foo.class.java_class)
|
212
|
+
assert_equal([0,0], cls.foo.to_a)
|
213
|
+
cls, = compile("def foo; a = int[2]; a[0] = 1; a[0]; end")
|
214
|
+
assert_equal(Fixnum, cls.foo.class)
|
215
|
+
assert_equal(1, cls.foo)
|
216
|
+
|
217
|
+
cls, = compile("def foo; a = long[2]; a; end")
|
218
|
+
assert_equal(Java::long[].java_class, cls.foo.class.java_class)
|
219
|
+
assert_equal([0,0], cls.foo.to_a)
|
220
|
+
cls, = compile(<<-EOF)
|
221
|
+
def foo
|
222
|
+
a = long[2]
|
223
|
+
a[0] = 1
|
224
|
+
a[0]
|
225
|
+
end
|
226
|
+
EOF
|
227
|
+
assert_equal(Fixnum, cls.foo.class)
|
228
|
+
assert_equal(1, cls.foo)
|
229
|
+
|
230
|
+
cls, = compile("def foo; a = float[2]; a; end")
|
231
|
+
assert_equal(Java::float[].java_class, cls.foo.class.java_class)
|
232
|
+
assert_equal([0.0,0.0], cls.foo.to_a)
|
233
|
+
cls, = compile("def foo; a = float[2]; a[0] = 1.0; a[0]; end")
|
234
|
+
assert_equal(Float, cls.foo.class)
|
235
|
+
assert_equal(1.0, cls.foo)
|
236
|
+
|
237
|
+
cls, = compile("def foo; a = double[2]; a; end")
|
238
|
+
assert_equal(Java::double[].java_class, cls.foo.class.java_class)
|
239
|
+
assert_equal([0.0,0.0], cls.foo.to_a)
|
240
|
+
cls, = compile(<<-EOF)
|
241
|
+
def foo
|
242
|
+
a = double[2]
|
243
|
+
# awaiting implicit F2D
|
244
|
+
# a[0] = 1.0
|
245
|
+
a[0]
|
246
|
+
end
|
247
|
+
EOF
|
248
|
+
assert_equal(Float, cls.foo.class)
|
249
|
+
assert_equal(0.0, cls.foo)
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_array_with_dynamic_size
|
253
|
+
cls, = compile("def foo(size => :int); a = int[size + 1];end")
|
254
|
+
array = cls.foo(3)
|
255
|
+
assert_equal(Java::int[].java_class, array.class.java_class)
|
256
|
+
assert_equal([0,0,0,0], array.to_a)
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_object_array
|
260
|
+
cls, = compile("import java.lang.Object;def foo; a = Object[2];end")
|
261
|
+
assert_equal(Java::JavaLang::Object[].java_class, cls.foo.class.java_class)
|
262
|
+
assert_equal([nil, nil], cls.foo.to_a)
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_string_concat
|
266
|
+
cls, = compile("def foo; a = 'a'; b = 'b'; a + b; end")
|
267
|
+
assert_equal("ab", cls.foo)
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_void_selfcall
|
271
|
+
cls, = compile("import 'System', 'java.lang.System'; def foo; System.gc; end; foo")
|
272
|
+
assert_nothing_raised {cls.foo}
|
273
|
+
end
|
274
|
+
|
275
|
+
def test_import
|
276
|
+
cls, = compile("import 'AL', 'java.util.ArrayList'; def foo; AL.new; end; foo")
|
277
|
+
assert_equal java.util.ArrayList.java_class, cls.foo.java_class
|
278
|
+
|
279
|
+
cls, = compile("import 'java.util.ArrayList'; def foo; ArrayList.new; end; foo")
|
280
|
+
assert_equal java.util.ArrayList.java_class, cls.foo.java_class
|
281
|
+
end
|
282
|
+
|
283
|
+
def test_no_quote_import
|
284
|
+
cls, = compile("import java.util.ArrayList as AL; def foo; AL.new; end; foo")
|
285
|
+
assert_equal java.util.ArrayList.java_class, cls.foo.java_class
|
286
|
+
|
287
|
+
cls, = compile("import java.util.ArrayList; def foo; ArrayList.new; end; foo")
|
288
|
+
assert_equal java.util.ArrayList.java_class, cls.foo.java_class
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_imported_decl
|
292
|
+
cls, = compile("import 'java.util.ArrayList'; def foo(a => ArrayList); a.size; end")
|
293
|
+
assert_equal 0, cls.foo(java.util.ArrayList.new)
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_interface
|
297
|
+
cls, = compile(<<-EOF)
|
298
|
+
import 'java.util.concurrent.Callable'
|
299
|
+
def foo(a => Callable)
|
300
|
+
throws Exception
|
301
|
+
a.call
|
302
|
+
end
|
303
|
+
EOF
|
304
|
+
result = cls.foo {0}
|
305
|
+
assert_equal 0, result
|
306
|
+
m = cls.java_class.java_method 'foo', java.util.concurrent.Callable
|
307
|
+
assert_equal([java.lang.Exception.java_class], m.exception_types)
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
def test_class_decl
|
312
|
+
foo, = compile("class ClassDeclTest;end")
|
313
|
+
assert_equal('ClassDeclTest', foo.java_class.name)
|
314
|
+
end
|
315
|
+
|
316
|
+
def capture_output
|
317
|
+
saved_output = System.out
|
318
|
+
output = StringIO.new
|
319
|
+
System.setOut(PrintStream.new(output.to_outputstream))
|
320
|
+
begin
|
321
|
+
yield
|
322
|
+
output.rewind
|
323
|
+
output.read
|
324
|
+
ensure
|
325
|
+
System.setOut(saved_output)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def assert_output(expected, &block)
|
330
|
+
assert_equal(expected, capture_output(&block))
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_puts
|
334
|
+
cls, = compile("def foo;puts 'Hello World!';end")
|
335
|
+
output = capture_output do
|
336
|
+
cls.foo
|
337
|
+
end
|
338
|
+
assert_equal("Hello World!\n", output)
|
339
|
+
end
|
340
|
+
|
341
|
+
def test_constructor
|
342
|
+
cls, = compile(
|
343
|
+
"class InitializeTest;def initialize;puts 'Constructed';end;end")
|
344
|
+
assert_output("Constructed\n") do
|
345
|
+
cls.new
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def test_method
|
350
|
+
# TODO auto generate a constructor
|
351
|
+
cls, = compile(
|
352
|
+
"class MethodTest; def initialize; ''; end; def foo; 'foo';end;end")
|
353
|
+
instance = cls.new
|
354
|
+
assert_equal(cls, instance.class)
|
355
|
+
assert_equal('foo', instance.foo)
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_unless_fixnum
|
359
|
+
cls, = compile(<<-EOF)
|
360
|
+
def foo(a => :fixnum)
|
361
|
+
values = boolean[5]
|
362
|
+
values[0] = true unless a < 0
|
363
|
+
values[1] = true unless a <= 0
|
364
|
+
values[2] = true unless a == 0
|
365
|
+
values[3] = true unless a >= 0
|
366
|
+
values[4] = true unless a > 0
|
367
|
+
values
|
368
|
+
end
|
369
|
+
EOF
|
370
|
+
assert_equal [true, true, true, false, false], cls.foo(1).to_a
|
371
|
+
assert_equal [true, false, false, false, true], cls.foo(0).to_a
|
372
|
+
assert_equal [false, false, true, true, true], cls.foo(-1).to_a
|
373
|
+
end
|
374
|
+
|
375
|
+
def test_unless_float
|
376
|
+
cls, = compile(<<-EOF)
|
377
|
+
def foo(a => :float)
|
378
|
+
values = boolean[5]
|
379
|
+
values[0] = true unless a < 0.0
|
380
|
+
values[1] = true unless a <= 0.0
|
381
|
+
values[2] = true unless a == 0.0
|
382
|
+
values[3] = true unless a >= 0.0
|
383
|
+
values[4] = true unless a > 0.0
|
384
|
+
values
|
385
|
+
end
|
386
|
+
EOF
|
387
|
+
assert_equal [true, true, true, false, false], cls.foo(1.0).to_a
|
388
|
+
assert_equal [true, false, false, false, true], cls.foo(0.0).to_a
|
389
|
+
assert_equal [false, false, true, true, true], cls.foo(-1.0).to_a
|
390
|
+
end
|
391
|
+
|
392
|
+
def test_if_fixnum
|
393
|
+
cls, = compile(<<-EOF)
|
394
|
+
def foo(a => :fixnum)
|
395
|
+
if a < -5
|
396
|
+
-6
|
397
|
+
elsif a <= 0
|
398
|
+
0
|
399
|
+
elsif a == 1
|
400
|
+
1
|
401
|
+
elsif a > 4
|
402
|
+
5
|
403
|
+
elsif a >= 3
|
404
|
+
3
|
405
|
+
else
|
406
|
+
2
|
407
|
+
end
|
408
|
+
end
|
409
|
+
EOF
|
410
|
+
assert_equal(-6, cls.foo(-6))
|
411
|
+
assert_equal(0, cls.foo(-5))
|
412
|
+
assert_equal(0, cls.foo(0))
|
413
|
+
assert_equal(1, cls.foo(1))
|
414
|
+
assert_equal(2, cls.foo(2))
|
415
|
+
assert_equal(3, cls.foo(3))
|
416
|
+
assert_equal(3, cls.foo(4))
|
417
|
+
assert_equal(5, cls.foo(5))
|
418
|
+
end
|
419
|
+
|
420
|
+
def test_if_float
|
421
|
+
cls, = compile(<<-EOF)
|
422
|
+
def foo(a => :float)
|
423
|
+
if a < -5.0
|
424
|
+
-6
|
425
|
+
elsif a <= 0.0
|
426
|
+
0
|
427
|
+
elsif a == 1.0
|
428
|
+
1
|
429
|
+
elsif a > 4.0
|
430
|
+
5
|
431
|
+
elsif a >= 3.0
|
432
|
+
3
|
433
|
+
else
|
434
|
+
2
|
435
|
+
end
|
436
|
+
end
|
437
|
+
EOF
|
438
|
+
assert_equal(-6, cls.foo(-5.1))
|
439
|
+
assert_equal(0, cls.foo(-5.0))
|
440
|
+
assert_equal(0, cls.foo(0.0))
|
441
|
+
assert_equal(1, cls.foo(1.0))
|
442
|
+
assert_equal(2, cls.foo(2.5))
|
443
|
+
assert_equal(3, cls.foo(3.0))
|
444
|
+
assert_equal(3, cls.foo(3.5))
|
445
|
+
assert_equal(5, cls.foo(4.1))
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_if_boolean
|
449
|
+
cls, = compile(<<-EOF)
|
450
|
+
def foo(a => :boolean)
|
451
|
+
if a
|
452
|
+
'true'
|
453
|
+
else
|
454
|
+
'false'
|
455
|
+
end
|
456
|
+
end
|
457
|
+
EOF
|
458
|
+
assert_equal('true', cls.foo(true))
|
459
|
+
assert_equal('false', cls.foo(false))
|
460
|
+
end
|
461
|
+
|
462
|
+
def test_if_int
|
463
|
+
# conditions don't work with :int
|
464
|
+
# cls, = compile("def foo(a => :int); if a < 0; -a; else; a; end; end")
|
465
|
+
# assert_equal 1, cls.foo(-1)
|
466
|
+
# assert_equal 3, cls.foo(3)
|
467
|
+
end
|
468
|
+
|
469
|
+
def test_trailing_conditions
|
470
|
+
cls, = compile(<<-EOF)
|
471
|
+
def foo(a => :fixnum)
|
472
|
+
return '+' if a > 0
|
473
|
+
return '0' unless a < 0
|
474
|
+
'-'
|
475
|
+
end
|
476
|
+
EOF
|
477
|
+
assert_equal '+', cls.foo(3)
|
478
|
+
assert_equal '0', cls.foo(0)
|
479
|
+
assert_equal '-', cls.foo(-1)
|
480
|
+
end
|
481
|
+
|
482
|
+
|
483
|
+
def test_local_decl
|
484
|
+
cls, = compile(<<-EOF)
|
485
|
+
import 'java.lang.String'
|
486
|
+
a = :fixnum
|
487
|
+
b = :int
|
488
|
+
c = :long
|
489
|
+
d = :float
|
490
|
+
e = :string
|
491
|
+
f = String
|
492
|
+
puts a
|
493
|
+
puts b
|
494
|
+
puts c
|
495
|
+
puts d
|
496
|
+
puts e
|
497
|
+
puts f
|
498
|
+
EOF
|
499
|
+
output = capture_output do
|
500
|
+
cls.main([].to_java(:string))
|
501
|
+
end
|
502
|
+
assert_equal("0\n0\n0\n0.0\nnull\nnull\n", output)
|
503
|
+
end
|
504
|
+
|
505
|
+
def test_multi_assign
|
506
|
+
cls, = compile(<<-EOF)
|
507
|
+
def foo
|
508
|
+
array = int[2]
|
509
|
+
a = b = 2
|
510
|
+
array[0] = a
|
511
|
+
array[1] = b
|
512
|
+
array
|
513
|
+
end
|
514
|
+
EOF
|
515
|
+
assert_equal([2, 2], cls.foo.to_a)
|
516
|
+
|
517
|
+
end
|
518
|
+
|
519
|
+
def test_loop
|
520
|
+
cls, = compile(
|
521
|
+
'def foo(a => :fixnum);while a > 0; a -= 1; puts ".";end;end')
|
522
|
+
assert_equal('', capture_output{cls.foo(0)})
|
523
|
+
assert_equal(".\n", capture_output{cls.foo(1)})
|
524
|
+
assert_equal(".\n.\n", capture_output{cls.foo(2)})
|
525
|
+
|
526
|
+
cls, = compile(
|
527
|
+
'def foo(a => :fixnum);begin;a -= 1; puts ".";end while a > 0;end')
|
528
|
+
assert_equal(".\n", capture_output{cls.foo(0)})
|
529
|
+
assert_equal(".\n", capture_output{cls.foo(1)})
|
530
|
+
assert_equal(".\n.\n", capture_output{cls.foo(2)})
|
531
|
+
|
532
|
+
cls, = compile(
|
533
|
+
'def foo(a => :fixnum);until a <= 0; a -= 1; puts ".";end;end')
|
534
|
+
assert_equal('', capture_output{cls.foo(0)})
|
535
|
+
assert_equal(".\n", capture_output{cls.foo(1)})
|
536
|
+
assert_equal(".\n.\n", capture_output{cls.foo(2)})
|
537
|
+
|
538
|
+
cls, = compile(
|
539
|
+
'def foo(a => :fixnum);begin;a -= 1; puts ".";end until a <= 0;end')
|
540
|
+
assert_equal(".\n", capture_output{cls.foo(0)})
|
541
|
+
assert_equal(".\n", capture_output{cls.foo(1)})
|
542
|
+
assert_equal(".\n.\n", capture_output{cls.foo(2)})
|
543
|
+
|
544
|
+
cls, = compile(
|
545
|
+
'def foo; a = 0; while a < 2; a+=1; end; end')
|
546
|
+
assert_equal(nil, cls.foo)
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_break
|
550
|
+
cls, = compile <<-EOF
|
551
|
+
def foo
|
552
|
+
count = 0
|
553
|
+
while count < 5
|
554
|
+
count += 1
|
555
|
+
break if count == 1
|
556
|
+
end
|
557
|
+
count
|
558
|
+
end
|
559
|
+
EOF
|
560
|
+
assert_equal(1, cls.foo)
|
561
|
+
|
562
|
+
cls, = compile <<-EOF
|
563
|
+
def foo
|
564
|
+
a = 0
|
565
|
+
b = 0
|
566
|
+
while a < 2
|
567
|
+
a += 1
|
568
|
+
while b < 5
|
569
|
+
b += 1
|
570
|
+
break if b > 0
|
571
|
+
end
|
572
|
+
break if a == 1
|
573
|
+
end
|
574
|
+
a * 100 + b
|
575
|
+
end
|
576
|
+
EOF
|
577
|
+
assert_equal(101, cls.foo)
|
578
|
+
|
579
|
+
cls, = compile <<-EOF
|
580
|
+
def foo
|
581
|
+
count = 0
|
582
|
+
begin
|
583
|
+
count += 1
|
584
|
+
break if count == 1
|
585
|
+
end while count < 5
|
586
|
+
count
|
587
|
+
end
|
588
|
+
EOF
|
589
|
+
assert_equal(1, cls.foo)
|
590
|
+
end
|
591
|
+
|
592
|
+
def test_next
|
593
|
+
cls, = compile <<-EOF
|
594
|
+
def foo
|
595
|
+
values = int[3]
|
596
|
+
i = 0
|
597
|
+
while i < 3
|
598
|
+
i += 1
|
599
|
+
next if i == 2
|
600
|
+
values[i - 1] = i
|
601
|
+
end
|
602
|
+
values
|
603
|
+
end
|
604
|
+
EOF
|
605
|
+
assert_equal([1, 0, 3], cls.foo.to_a)
|
606
|
+
|
607
|
+
cls, = compile <<-EOF
|
608
|
+
def foo
|
609
|
+
i = 0
|
610
|
+
while i < 5
|
611
|
+
i += 1
|
612
|
+
next if i == 5
|
613
|
+
end
|
614
|
+
i
|
615
|
+
end
|
616
|
+
EOF
|
617
|
+
assert_equal(5, cls.foo)
|
618
|
+
|
619
|
+
cls, = compile <<-EOF
|
620
|
+
def foo
|
621
|
+
values = int[3]
|
622
|
+
a = 0
|
623
|
+
b = 0
|
624
|
+
while a < 3
|
625
|
+
b = 0
|
626
|
+
while b < 5
|
627
|
+
b += 1
|
628
|
+
next if b == a + 1
|
629
|
+
# values[a] += b # TODO
|
630
|
+
values[a] = values[a] + b
|
631
|
+
end
|
632
|
+
a += 1
|
633
|
+
next if a == 2
|
634
|
+
values[a - 1] = values[a - 1] + a * 100
|
635
|
+
end
|
636
|
+
values
|
637
|
+
end
|
638
|
+
EOF
|
639
|
+
assert_equal([114, 13, 312], cls.foo.to_a)
|
640
|
+
|
641
|
+
cls, = compile <<-EOF
|
642
|
+
def foo
|
643
|
+
count = 0
|
644
|
+
sum = 0
|
645
|
+
begin
|
646
|
+
count += 1
|
647
|
+
next if count == 2
|
648
|
+
sum += count
|
649
|
+
next if count == 5
|
650
|
+
end while count < 5
|
651
|
+
count * 100 + sum
|
652
|
+
end
|
653
|
+
EOF
|
654
|
+
assert_equal(513, cls.foo)
|
655
|
+
end
|
656
|
+
|
657
|
+
def test_redo
|
658
|
+
cls, = compile <<-EOF
|
659
|
+
def foo
|
660
|
+
i = 0
|
661
|
+
while i < 5
|
662
|
+
i += 1
|
663
|
+
redo if i == 5
|
664
|
+
end
|
665
|
+
i
|
666
|
+
end
|
667
|
+
EOF
|
668
|
+
assert_equal(6, cls.foo)
|
669
|
+
|
670
|
+
cls, = compile <<-EOF
|
671
|
+
def foo
|
672
|
+
values = int[4]
|
673
|
+
a = 0
|
674
|
+
b = 0
|
675
|
+
while a < 3
|
676
|
+
b = a
|
677
|
+
while b < 5
|
678
|
+
b += 1
|
679
|
+
redo if b == 5
|
680
|
+
values[a] = values[a] + b
|
681
|
+
end
|
682
|
+
a += 1
|
683
|
+
values[a - 1] = values[a - 1] + a * 100
|
684
|
+
redo if a == 3
|
685
|
+
end
|
686
|
+
values
|
687
|
+
end
|
688
|
+
EOF
|
689
|
+
assert_equal([116, 215, 313, 410], cls.foo.to_a)
|
690
|
+
|
691
|
+
cls, = compile <<-EOF
|
692
|
+
def foo
|
693
|
+
i = 0
|
694
|
+
begin
|
695
|
+
i += 1
|
696
|
+
redo if i == 5
|
697
|
+
end while i < 5
|
698
|
+
i
|
699
|
+
end
|
700
|
+
EOF
|
701
|
+
assert_equal(6, cls.foo)
|
702
|
+
end
|
703
|
+
|
704
|
+
def test_fields
|
705
|
+
cls, = compile(<<-EOF)
|
706
|
+
class FieldTest
|
707
|
+
def initialize(a => :fixnum)
|
708
|
+
@a = a
|
709
|
+
end
|
710
|
+
|
711
|
+
def a
|
712
|
+
@a
|
713
|
+
end
|
714
|
+
end
|
715
|
+
EOF
|
716
|
+
first = cls.new(1)
|
717
|
+
assert_equal(1, first.a)
|
718
|
+
|
719
|
+
second = cls.new(2)
|
720
|
+
assert_equal(1, first.a)
|
721
|
+
assert_equal(2, second.a)
|
722
|
+
end
|
723
|
+
|
724
|
+
def test_object_intrinsics
|
725
|
+
cls, = compile(<<-EOF)
|
726
|
+
import 'java.lang.Object'
|
727
|
+
def nil(a => :Object)
|
728
|
+
a.nil?
|
729
|
+
end
|
730
|
+
|
731
|
+
def equal(a => Object, b => Object)
|
732
|
+
a == b
|
733
|
+
end
|
734
|
+
EOF
|
735
|
+
|
736
|
+
assert(cls.nil(nil))
|
737
|
+
assert(!cls.nil("abc"))
|
738
|
+
|
739
|
+
a = "foobar".to_java_string
|
740
|
+
b = java.lang.Object.new
|
741
|
+
assert(cls.equal(a, a))
|
742
|
+
assert(cls.equal(b, b))
|
743
|
+
assert(!cls.equal(a, b))
|
744
|
+
end
|
745
|
+
|
746
|
+
def test_implements
|
747
|
+
script, cls = compile(<<-EOF)
|
748
|
+
import java.lang.Iterable
|
749
|
+
class Foo; implements Iterable
|
750
|
+
def iterator
|
751
|
+
nil
|
752
|
+
end
|
753
|
+
end
|
754
|
+
EOF
|
755
|
+
|
756
|
+
assert_include java.lang.Iterable.java_class, cls.java_class.interfaces
|
757
|
+
end
|
758
|
+
|
759
|
+
def test_argument_widening
|
760
|
+
cls, = compile(<<-EOF)
|
761
|
+
def Byte(a => :byte)
|
762
|
+
Short(a)
|
763
|
+
end
|
764
|
+
|
765
|
+
def Short(a => :short)
|
766
|
+
Int(a)
|
767
|
+
end
|
768
|
+
|
769
|
+
def Int(a => :int)
|
770
|
+
Long(a)
|
771
|
+
end
|
772
|
+
|
773
|
+
def Long(a => :long)
|
774
|
+
Float(a)
|
775
|
+
end
|
776
|
+
|
777
|
+
def Float(a => :float)
|
778
|
+
Double(a)
|
779
|
+
end
|
780
|
+
|
781
|
+
def Double(a => :double)
|
782
|
+
a
|
783
|
+
end
|
784
|
+
EOF
|
785
|
+
|
786
|
+
assert_equal(1.0, cls.Byte(1))
|
787
|
+
assert_equal(127.0, cls.Byte(127))
|
788
|
+
assert_equal(128.0, cls.Short(128))
|
789
|
+
assert_equal(32767.0, cls.Short(32767))
|
790
|
+
assert_equal(32768.0, cls.Int(32768))
|
791
|
+
assert_equal(2147483648.0, cls.Long(2147483648))
|
792
|
+
end
|
793
|
+
|
794
|
+
def test_interface_declaration
|
795
|
+
script, interface = compile('interface A do; end')
|
796
|
+
assert(interface.java_class.interface?)
|
797
|
+
assert_equal('A', interface.java_class.name)
|
798
|
+
|
799
|
+
script, a, b = compile('interface A do; end; interface B < A do; end')
|
800
|
+
assert_include(a, b.ancestors)
|
801
|
+
assert_equal('A', a.java_class.name)
|
802
|
+
assert_equal('B', b.java_class.name)
|
803
|
+
|
804
|
+
script, a, b, c = compile(<<-EOF)
|
805
|
+
interface A do
|
806
|
+
end
|
807
|
+
|
808
|
+
interface B do
|
809
|
+
end
|
810
|
+
|
811
|
+
interface C < A, B do
|
812
|
+
end
|
813
|
+
EOF
|
814
|
+
|
815
|
+
assert_include(a, c.ancestors)
|
816
|
+
assert_include(b, c.ancestors)
|
817
|
+
assert_equal('A', a.java_class.name)
|
818
|
+
assert_equal('B', b.java_class.name)
|
819
|
+
assert_equal('C', c.java_class.name)
|
820
|
+
|
821
|
+
assert_raise Duby::Typer::InferenceError do
|
822
|
+
compile(<<-EOF)
|
823
|
+
interface A do
|
824
|
+
def a
|
825
|
+
returns :int
|
826
|
+
end
|
827
|
+
end
|
828
|
+
|
829
|
+
class Impl; implements A
|
830
|
+
def a
|
831
|
+
"foo"
|
832
|
+
end
|
833
|
+
end
|
834
|
+
EOF
|
835
|
+
end
|
836
|
+
end
|
837
|
+
|
838
|
+
def assert_throw(type, message=nil)
|
839
|
+
ex = assert_raise(NativeException) do
|
840
|
+
yield
|
841
|
+
end
|
842
|
+
assert_equal type, ex.cause.class
|
843
|
+
assert_equal message, ex.cause.message
|
844
|
+
end
|
845
|
+
|
846
|
+
def test_raise
|
847
|
+
cls, = compile(<<-EOF)
|
848
|
+
def foo
|
849
|
+
raise
|
850
|
+
end
|
851
|
+
EOF
|
852
|
+
assert_throw(java.lang.RuntimeException) do
|
853
|
+
cls.foo
|
854
|
+
end
|
855
|
+
|
856
|
+
cls, = compile(<<-EOF)
|
857
|
+
def foo
|
858
|
+
raise "Oh no!"
|
859
|
+
end
|
860
|
+
EOF
|
861
|
+
ex = assert_throw(java.lang.RuntimeException, 'Oh no!') do
|
862
|
+
cls.foo
|
863
|
+
end
|
864
|
+
|
865
|
+
cls, = compile(<<-EOF)
|
866
|
+
def foo
|
867
|
+
raise IllegalArgumentException
|
868
|
+
end
|
869
|
+
EOF
|
870
|
+
ex = assert_throw(java.lang.IllegalArgumentException) do
|
871
|
+
cls.foo
|
872
|
+
end
|
873
|
+
|
874
|
+
cls, = compile(<<-EOF)
|
875
|
+
def foo
|
876
|
+
throws Exception
|
877
|
+
raise Exception, "oops"
|
878
|
+
end
|
879
|
+
EOF
|
880
|
+
ex = assert_throw(java.lang.Exception, "oops") do
|
881
|
+
cls.foo
|
882
|
+
end
|
883
|
+
|
884
|
+
cls, = compile(<<-EOF)
|
885
|
+
def foo
|
886
|
+
throws Throwable
|
887
|
+
raise Throwable.new("darn")
|
888
|
+
end
|
889
|
+
EOF
|
890
|
+
ex = assert_throw(java.lang.Throwable, "darn") do
|
891
|
+
cls.foo
|
892
|
+
end
|
893
|
+
end
|
894
|
+
|
895
|
+
def test_rescue
|
896
|
+
cls, = compile(<<-EOF)
|
897
|
+
def foo
|
898
|
+
begin
|
899
|
+
puts "body"
|
900
|
+
rescue
|
901
|
+
puts "rescue"
|
902
|
+
end
|
903
|
+
end
|
904
|
+
EOF
|
905
|
+
|
906
|
+
output = capture_output do
|
907
|
+
cls.foo
|
908
|
+
end
|
909
|
+
assert_equal("body\n", output)
|
910
|
+
|
911
|
+
cls, = compile(<<-EOF)
|
912
|
+
def foo
|
913
|
+
begin
|
914
|
+
puts "body"
|
915
|
+
raise
|
916
|
+
rescue
|
917
|
+
puts "rescue"
|
918
|
+
end
|
919
|
+
end
|
920
|
+
EOF
|
921
|
+
|
922
|
+
output = capture_output do
|
923
|
+
cls.foo
|
924
|
+
end
|
925
|
+
assert_equal("body\nrescue\n", output)
|
926
|
+
|
927
|
+
cls, = compile(<<-EOF)
|
928
|
+
def foo(a:int)
|
929
|
+
begin
|
930
|
+
puts "body"
|
931
|
+
if a == 0
|
932
|
+
raise IllegalArgumentException
|
933
|
+
else
|
934
|
+
raise
|
935
|
+
end
|
936
|
+
rescue IllegalArgumentException
|
937
|
+
puts "IllegalArgumentException"
|
938
|
+
rescue
|
939
|
+
puts "rescue"
|
940
|
+
end
|
941
|
+
end
|
942
|
+
EOF
|
943
|
+
|
944
|
+
output = capture_output do
|
945
|
+
cls.foo(1)
|
946
|
+
cls.foo(0)
|
947
|
+
end
|
948
|
+
assert_equal("body\nrescue\nbody\nIllegalArgumentException\n", output)
|
949
|
+
|
950
|
+
cls, = compile(<<-EOF)
|
951
|
+
def foo(a:int)
|
952
|
+
begin
|
953
|
+
puts "body"
|
954
|
+
if a == 0
|
955
|
+
raise IllegalArgumentException
|
956
|
+
elsif a == 1
|
957
|
+
raise Throwable
|
958
|
+
else
|
959
|
+
raise
|
960
|
+
end
|
961
|
+
rescue IllegalArgumentException, RuntimeException
|
962
|
+
puts "multi"
|
963
|
+
rescue Throwable
|
964
|
+
puts "other"
|
965
|
+
end
|
966
|
+
end
|
967
|
+
EOF
|
968
|
+
|
969
|
+
output = capture_output do
|
970
|
+
cls.foo(0)
|
971
|
+
cls.foo(1)
|
972
|
+
cls.foo(2)
|
973
|
+
end
|
974
|
+
assert_equal("body\nmulti\nbody\nother\nbody\nmulti\n", output)
|
975
|
+
|
976
|
+
cls, = compile(<<-EOF)
|
977
|
+
def foo
|
978
|
+
begin
|
979
|
+
raise "foo"
|
980
|
+
rescue => ex
|
981
|
+
puts ex.getMessage
|
982
|
+
end
|
983
|
+
end
|
984
|
+
EOF
|
985
|
+
|
986
|
+
output = capture_output do
|
987
|
+
cls.foo
|
988
|
+
end
|
989
|
+
assert_equal("foo\n", output)
|
990
|
+
end
|
991
|
+
|
992
|
+
def test_ensure
|
993
|
+
cls, = compile(<<-EOF)
|
994
|
+
def foo
|
995
|
+
1
|
996
|
+
ensure
|
997
|
+
puts "Hi"
|
998
|
+
end
|
999
|
+
EOF
|
1000
|
+
output = capture_output do
|
1001
|
+
assert_equal(1, cls.foo)
|
1002
|
+
end
|
1003
|
+
assert_equal "Hi\n", output
|
1004
|
+
|
1005
|
+
cls, = compile(<<-EOF)
|
1006
|
+
def foo
|
1007
|
+
return 1
|
1008
|
+
ensure
|
1009
|
+
puts "Hi"
|
1010
|
+
end
|
1011
|
+
EOF
|
1012
|
+
output = capture_output do
|
1013
|
+
assert_equal(1, cls.foo)
|
1014
|
+
end
|
1015
|
+
assert_equal "Hi\n", output
|
1016
|
+
|
1017
|
+
cls, = compile(<<-EOF)
|
1018
|
+
def foo
|
1019
|
+
begin
|
1020
|
+
break
|
1021
|
+
ensure
|
1022
|
+
puts "Hi"
|
1023
|
+
end while false
|
1024
|
+
end
|
1025
|
+
EOF
|
1026
|
+
output = capture_output do
|
1027
|
+
cls.foo
|
1028
|
+
end
|
1029
|
+
assert_equal "Hi\n", output
|
1030
|
+
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
def test_cast
|
1034
|
+
cls, = compile(<<-EOF)
|
1035
|
+
def f2b; byte(1.0); end
|
1036
|
+
def f2s; short(1.0); end
|
1037
|
+
def f2c; char(1.0); end
|
1038
|
+
def f2i; int(1.0); end
|
1039
|
+
def f2l; long(1.0); end
|
1040
|
+
def f2d; int(1.0); end
|
1041
|
+
|
1042
|
+
def i2b; byte(1); end
|
1043
|
+
def i2s; short(1); end
|
1044
|
+
def i2c; char(1); end
|
1045
|
+
def i2l; long(1); end
|
1046
|
+
def i2f; float(1); end
|
1047
|
+
def i2d; int(1); end
|
1048
|
+
|
1049
|
+
def b2s; short(byte(1)); end
|
1050
|
+
def b2c; char(byte(1)); end
|
1051
|
+
def b2i; int(byte(1)); end
|
1052
|
+
def b2l; long(byte(1)); end
|
1053
|
+
def b2f; float(byte(1)); end
|
1054
|
+
def b2d; double(byte(1)); end
|
1055
|
+
|
1056
|
+
def s2b; byte(short(1)); end
|
1057
|
+
def s2c; char(short(1)); end
|
1058
|
+
def s2i; int(short(1)); end
|
1059
|
+
def s2l; long(short(1)); end
|
1060
|
+
def s2f; float(short(1)); end
|
1061
|
+
def s2d; double(short(1)); end
|
1062
|
+
|
1063
|
+
def c2b; byte(char(1)); end
|
1064
|
+
def c2s; short(char(1)); end
|
1065
|
+
def c2i; int(char(1)); end
|
1066
|
+
def c2l; long(char(1)); end
|
1067
|
+
def c2f; float(char(1)); end
|
1068
|
+
def c2d; double(char(1)); end
|
1069
|
+
|
1070
|
+
def l2b; byte(long(1)); end
|
1071
|
+
def l2c; char(long(1)); end
|
1072
|
+
def l2i; int(long(1)); end
|
1073
|
+
def l2l; long(long(1)); end
|
1074
|
+
def l2f; float(long(1)); end
|
1075
|
+
def l2d; double(long(1)); end
|
1076
|
+
|
1077
|
+
def d2b; byte(1.0); end
|
1078
|
+
def d2s; short(1.0); end
|
1079
|
+
def d2c; char(1.0); end
|
1080
|
+
def d2i; int(1.0); end
|
1081
|
+
def d2l; long(1.0); end
|
1082
|
+
def d2f; float(1.0); end
|
1083
|
+
|
1084
|
+
def hard_i2f(a:int)
|
1085
|
+
float(if a < 0
|
1086
|
+
a *= -1
|
1087
|
+
a * 2
|
1088
|
+
else
|
1089
|
+
a * 2
|
1090
|
+
end)
|
1091
|
+
end
|
1092
|
+
EOF
|
1093
|
+
|
1094
|
+
assert_equal 1, cls.b2s
|
1095
|
+
assert_equal 1, cls.b2c
|
1096
|
+
assert_equal 1, cls.b2i
|
1097
|
+
assert_equal 1, cls.b2l
|
1098
|
+
assert_equal 1.0, cls.b2f
|
1099
|
+
assert_equal 1.0, cls.b2d
|
1100
|
+
|
1101
|
+
assert_equal 1, cls.s2b
|
1102
|
+
assert_equal 1, cls.s2c
|
1103
|
+
assert_equal 1, cls.s2i
|
1104
|
+
assert_equal 1, cls.s2l
|
1105
|
+
assert_equal 1.0, cls.s2f
|
1106
|
+
assert_equal 1.0, cls.s2d
|
1107
|
+
|
1108
|
+
assert_equal 1, cls.c2b
|
1109
|
+
assert_equal 1, cls.c2s
|
1110
|
+
assert_equal 1, cls.c2i
|
1111
|
+
assert_equal 1, cls.c2l
|
1112
|
+
assert_equal 1.0, cls.c2f
|
1113
|
+
assert_equal 1.0, cls.c2d
|
1114
|
+
|
1115
|
+
assert_equal 1, cls.i2b
|
1116
|
+
assert_equal 1, cls.i2s
|
1117
|
+
assert_equal 1, cls.i2c
|
1118
|
+
assert_equal 1, cls.i2l
|
1119
|
+
assert_equal 1.0, cls.i2f
|
1120
|
+
assert_equal 1.0, cls.i2d
|
1121
|
+
|
1122
|
+
assert_equal 1, cls.f2b
|
1123
|
+
assert_equal 1, cls.f2s
|
1124
|
+
assert_equal 1, cls.f2c
|
1125
|
+
assert_equal 1, cls.f2i
|
1126
|
+
assert_equal 1, cls.f2l
|
1127
|
+
assert_equal 1.0, cls.f2d
|
1128
|
+
|
1129
|
+
assert_equal 1, cls.d2b
|
1130
|
+
assert_equal 1, cls.d2s
|
1131
|
+
assert_equal 1, cls.d2c
|
1132
|
+
assert_equal 1, cls.d2i
|
1133
|
+
assert_equal 1, cls.d2l
|
1134
|
+
assert_equal 1.0, cls.d2f
|
1135
|
+
|
1136
|
+
assert_equal 2.0, cls.hard_i2f(1)
|
1137
|
+
assert_equal 4.0, cls.hard_i2f(-2)
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
def test_set
|
1141
|
+
cls, = compile(<<-EOF)
|
1142
|
+
def foo
|
1143
|
+
@foo
|
1144
|
+
end
|
1145
|
+
|
1146
|
+
def foo=(foo:int)
|
1147
|
+
@foo = foo
|
1148
|
+
end
|
1149
|
+
EOF
|
1150
|
+
|
1151
|
+
assert_equal(0, cls.foo)
|
1152
|
+
assert_equal(2, cls.foo_set(2))
|
1153
|
+
assert_equal(2, cls.foo)
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
def test_null_is_false
|
1157
|
+
cls, = compile("def foo(a:String);if a;true;else;false;end;end")
|
1158
|
+
assert_equal(true, cls.foo("a"))
|
1159
|
+
assert_equal(false, cls.foo(nil))
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
def test_for
|
1163
|
+
cls, = compile(<<-EOF)
|
1164
|
+
def foo
|
1165
|
+
a = int[3]
|
1166
|
+
count = 0
|
1167
|
+
for x in a
|
1168
|
+
count += 1
|
1169
|
+
end
|
1170
|
+
count
|
1171
|
+
end
|
1172
|
+
EOF
|
1173
|
+
|
1174
|
+
cls, = compile(<<-EOF)
|
1175
|
+
def foo(a:int[])
|
1176
|
+
count = 0
|
1177
|
+
for x in a
|
1178
|
+
count += x
|
1179
|
+
end
|
1180
|
+
count
|
1181
|
+
end
|
1182
|
+
EOF
|
1183
|
+
|
1184
|
+
assert_equal(9, cls.foo([2, 3, 4].to_java(:int)))
|
1185
|
+
|
1186
|
+
cls, = compile(<<-EOF)
|
1187
|
+
def foo(a:Iterable)
|
1188
|
+
a.each do |x|
|
1189
|
+
puts x
|
1190
|
+
end
|
1191
|
+
end
|
1192
|
+
EOF
|
1193
|
+
|
1194
|
+
assert_output("1\n2\n3\n") do
|
1195
|
+
list = java.util.ArrayList.new
|
1196
|
+
list << "1"
|
1197
|
+
list << "2"
|
1198
|
+
list << "3"
|
1199
|
+
cls.foo(list)
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
cls, = compile(<<-EOF)
|
1203
|
+
import java.util.ArrayList
|
1204
|
+
def foo(a:ArrayList)
|
1205
|
+
a.each do |x|
|
1206
|
+
puts x
|
1207
|
+
end
|
1208
|
+
end
|
1209
|
+
EOF
|
1210
|
+
|
1211
|
+
assert_output("1\n2\n3\n") do
|
1212
|
+
list = java.util.ArrayList.new
|
1213
|
+
list << "1"
|
1214
|
+
list << "2"
|
1215
|
+
list << "3"
|
1216
|
+
cls.foo(list)
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
cls, = compile(<<-EOF)
|
1220
|
+
def foo(a:int[])
|
1221
|
+
a.each {|x| x += 1;puts x; redo if x == 2}
|
1222
|
+
end
|
1223
|
+
EOF
|
1224
|
+
|
1225
|
+
assert_output("2\n3\n3\n4\n") do
|
1226
|
+
cls.foo([1,2,3].to_java(:int))
|
1227
|
+
end
|
1228
|
+
end
|
1229
|
+
|
1230
|
+
def test_all
|
1231
|
+
cls, = compile(<<-EOF)
|
1232
|
+
def foo(a:int[])
|
1233
|
+
a.all? {|x| x % 2 == 0}
|
1234
|
+
end
|
1235
|
+
EOF
|
1236
|
+
|
1237
|
+
assert_equal(false, cls.foo([2, 3, 4].to_java(:int)))
|
1238
|
+
assert_equal(true, cls.foo([2, 0, 4].to_java(:int)))
|
1239
|
+
|
1240
|
+
cls, = compile(<<-EOF)
|
1241
|
+
def foo(a:String[])
|
1242
|
+
a.all?
|
1243
|
+
end
|
1244
|
+
EOF
|
1245
|
+
|
1246
|
+
assert_equal(true, cls.foo(["a", "", "b"].to_java(:string)))
|
1247
|
+
assert_equal(false, cls.foo(["a", nil, "b"].to_java(:string)))
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
def test_general_loop
|
1251
|
+
cls, = compile(<<-EOF)
|
1252
|
+
def foo(x:boolean)
|
1253
|
+
a = ""
|
1254
|
+
__gloop__(nil, x, true, nil, nil) {a += "<body>"}
|
1255
|
+
a
|
1256
|
+
end
|
1257
|
+
EOF
|
1258
|
+
assert_equal("", cls.foo(false))
|
1259
|
+
|
1260
|
+
cls, = compile(<<-EOF)
|
1261
|
+
def foo
|
1262
|
+
a = ""
|
1263
|
+
__gloop__(nil, false, false, nil, nil) {a += "<body>"}
|
1264
|
+
a
|
1265
|
+
end
|
1266
|
+
EOF
|
1267
|
+
assert_equal("<body>", cls.foo)
|
1268
|
+
|
1269
|
+
cls, = compile(<<-EOF)
|
1270
|
+
def foo(x:boolean)
|
1271
|
+
a = ""
|
1272
|
+
__gloop__(a += "<init>", x, true, a += "<pre>", a += "<post>") do
|
1273
|
+
a += "<body>"
|
1274
|
+
end
|
1275
|
+
a
|
1276
|
+
end
|
1277
|
+
EOF
|
1278
|
+
assert_equal("<init>", cls.foo(false))
|
1279
|
+
|
1280
|
+
cls, = compile(<<-EOF)
|
1281
|
+
def foo
|
1282
|
+
a = ""
|
1283
|
+
__gloop__(a += "<init>", false, false, a += "<pre>", a += "<post>") do
|
1284
|
+
a += "<body>"
|
1285
|
+
end
|
1286
|
+
a
|
1287
|
+
end
|
1288
|
+
EOF
|
1289
|
+
assert_equal("<init><pre><body><post>", cls.foo)
|
1290
|
+
|
1291
|
+
cls, = compile(<<-EOF)
|
1292
|
+
def foo
|
1293
|
+
a = ""
|
1294
|
+
__gloop__(a += "<init>", false, false, a += "<pre>", a += "<post>") do
|
1295
|
+
a += "<body>"
|
1296
|
+
redo if a.length < 20
|
1297
|
+
end
|
1298
|
+
a
|
1299
|
+
end
|
1300
|
+
EOF
|
1301
|
+
assert_equal( "<init><pre><body><body><post>", cls.foo)
|
1302
|
+
|
1303
|
+
cls, = compile(<<-EOF)
|
1304
|
+
def foo
|
1305
|
+
a = ""
|
1306
|
+
__gloop__(a += "<init>", a.length < 20, true, a += "<pre>", a += "<post>") do
|
1307
|
+
next if a.length < 17
|
1308
|
+
a += "<body>"
|
1309
|
+
end
|
1310
|
+
a
|
1311
|
+
end
|
1312
|
+
EOF
|
1313
|
+
assert_equal("<init><pre><post><pre><body><post>", cls.foo)
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
def test_if_expr
|
1317
|
+
cls, = compile(<<-EOF)
|
1318
|
+
def foo(a:int)
|
1319
|
+
return 1 if a == 1
|
1320
|
+
end
|
1321
|
+
|
1322
|
+
def bar(a:int)
|
1323
|
+
return 1 unless a == 1
|
1324
|
+
end
|
1325
|
+
EOF
|
1326
|
+
|
1327
|
+
assert_equal(0, cls.foo(0))
|
1328
|
+
assert_equal(1, cls.foo(1))
|
1329
|
+
assert_equal(1, cls.bar(0))
|
1330
|
+
assert_equal(0, cls.bar(1))
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
def test_and
|
1334
|
+
cls, = compile(<<-EOF)
|
1335
|
+
def bool(n:String, x:boolean)
|
1336
|
+
puts n
|
1337
|
+
x
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
def foo(a:boolean, b:boolean)
|
1341
|
+
return bool('a', a) && bool('b', b)
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
def str(n:String, x:String)
|
1345
|
+
puts n
|
1346
|
+
x
|
1347
|
+
end
|
1348
|
+
|
1349
|
+
def bar(a:String, b:String)
|
1350
|
+
return str('a', a) && str('b', b)
|
1351
|
+
end
|
1352
|
+
EOF
|
1353
|
+
|
1354
|
+
assert_output("a\n") { assert_equal(false, cls.foo(false, true)) }
|
1355
|
+
assert_output("a\nb\n") { assert_equal(false, cls.foo(true, false)) }
|
1356
|
+
assert_output("a\nb\n") { assert_equal(true, cls.foo(true, true)) }
|
1357
|
+
|
1358
|
+
assert_output("a\n") { assert_equal(nil, cls.bar(nil, "B")) }
|
1359
|
+
assert_output("a\nb\n") { assert_equal(nil, cls.bar("A", nil)) }
|
1360
|
+
assert_output("a\nb\n") { assert_equal("B", cls.bar("A", "B")) }
|
1361
|
+
|
1362
|
+
cls, = compile(<<-EOF)
|
1363
|
+
def s
|
1364
|
+
@s
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
def s=(s:String)
|
1368
|
+
@s = s
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
def b
|
1372
|
+
@b
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
def b=(b:boolean)
|
1376
|
+
@b = b
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
def foo(x:boolean)
|
1380
|
+
@b &&= x
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
def bar(x:String)
|
1384
|
+
@s &&= x
|
1385
|
+
end
|
1386
|
+
EOF
|
1387
|
+
|
1388
|
+
cls.b_set(false)
|
1389
|
+
assert_equal(false, cls.foo(false))
|
1390
|
+
assert_equal(false, cls.b)
|
1391
|
+
|
1392
|
+
cls.b_set(true)
|
1393
|
+
assert_equal(false, cls.foo(false))
|
1394
|
+
assert_equal(false, cls.b)
|
1395
|
+
|
1396
|
+
cls.b_set(true)
|
1397
|
+
assert_equal(true, cls.foo(true))
|
1398
|
+
assert_equal(true, cls.b)
|
1399
|
+
|
1400
|
+
cls.s_set(nil)
|
1401
|
+
assert_equal(nil, cls.bar(nil))
|
1402
|
+
assert_equal(nil, cls.s)
|
1403
|
+
|
1404
|
+
cls.s_set("S")
|
1405
|
+
assert_equal(nil, cls.bar(nil))
|
1406
|
+
assert_equal(nil, cls.s)
|
1407
|
+
|
1408
|
+
cls.s_set("S")
|
1409
|
+
assert_equal("x", cls.bar("x"))
|
1410
|
+
assert_equal("x", cls.s)
|
1411
|
+
|
1412
|
+
foo, = compile(<<-EOF)
|
1413
|
+
class Foo2
|
1414
|
+
def initialize
|
1415
|
+
@count = 0
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
def count
|
1419
|
+
@count
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
def a
|
1423
|
+
@a
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
def a=(a:String)
|
1427
|
+
@count += 1
|
1428
|
+
@a = a
|
1429
|
+
end
|
1430
|
+
|
1431
|
+
def foo(f:Foo2, x:String)
|
1432
|
+
f.a &&= x
|
1433
|
+
end
|
1434
|
+
end
|
1435
|
+
EOF
|
1436
|
+
|
1437
|
+
f = foo.new
|
1438
|
+
assert_equal(nil, f.foo(f, 'x'))
|
1439
|
+
assert_equal(0, f.count)
|
1440
|
+
|
1441
|
+
f = foo.new
|
1442
|
+
f.a_set("A")
|
1443
|
+
assert_equal(nil, f.foo(f, nil))
|
1444
|
+
assert_equal(2, f.count)
|
1445
|
+
|
1446
|
+
f = foo.new
|
1447
|
+
f.a_set("A")
|
1448
|
+
assert_equal('x', f.foo(f, 'x'))
|
1449
|
+
assert_equal(2, f.count)
|
1450
|
+
end
|
1451
|
+
|
1452
|
+
def test_or
|
1453
|
+
cls, = compile(<<-EOF)
|
1454
|
+
def bool(n:String, x:boolean)
|
1455
|
+
puts n
|
1456
|
+
x
|
1457
|
+
end
|
1458
|
+
|
1459
|
+
def foo(a:boolean, b:boolean)
|
1460
|
+
return bool('a', a) || bool('b', b)
|
1461
|
+
end
|
1462
|
+
|
1463
|
+
def str(n:String, x:String)
|
1464
|
+
puts n
|
1465
|
+
x
|
1466
|
+
end
|
1467
|
+
|
1468
|
+
def bar(a:String, b:String)
|
1469
|
+
return str('a', a) || str('b', b)
|
1470
|
+
end
|
1471
|
+
EOF
|
1472
|
+
|
1473
|
+
assert_output("a\n") { assert_equal(true, cls.foo(true, false)) }
|
1474
|
+
assert_output("a\nb\n") { assert_equal(false, cls.foo(false, false)) }
|
1475
|
+
assert_output("a\nb\n") { assert_equal(true, cls.foo(false, true)) }
|
1476
|
+
|
1477
|
+
assert_output("a\n") { assert_equal("A", cls.bar("A", nil)) }
|
1478
|
+
assert_output("a\nb\n") { assert_equal(nil, cls.bar(nil, nil)) }
|
1479
|
+
assert_output("a\nb\n") { assert_equal("B", cls.bar(nil, "B")) }
|
1480
|
+
|
1481
|
+
cls, = compile(<<-EOF)
|
1482
|
+
def s
|
1483
|
+
@s
|
1484
|
+
end
|
1485
|
+
|
1486
|
+
def s=(s:String)
|
1487
|
+
@s = s
|
1488
|
+
end
|
1489
|
+
|
1490
|
+
def b
|
1491
|
+
@b
|
1492
|
+
end
|
1493
|
+
|
1494
|
+
def b=(b:boolean)
|
1495
|
+
@b = b
|
1496
|
+
end
|
1497
|
+
|
1498
|
+
def foo(x:boolean)
|
1499
|
+
@b ||= x
|
1500
|
+
end
|
1501
|
+
|
1502
|
+
def bar(x:String)
|
1503
|
+
@s ||= x
|
1504
|
+
end
|
1505
|
+
EOF
|
1506
|
+
|
1507
|
+
cls.b_set(false)
|
1508
|
+
assert_equal(false, cls.foo(false))
|
1509
|
+
assert_equal(false, cls.b)
|
1510
|
+
|
1511
|
+
cls.b_set(false)
|
1512
|
+
assert_equal(true, cls.foo(true))
|
1513
|
+
assert_equal(true, cls.b)
|
1514
|
+
|
1515
|
+
cls.b_set(true)
|
1516
|
+
assert_equal(true, cls.foo(false))
|
1517
|
+
assert_equal(true, cls.b)
|
1518
|
+
|
1519
|
+
cls.s_set(nil)
|
1520
|
+
assert_equal(nil, cls.bar(nil))
|
1521
|
+
assert_equal(nil, cls.s)
|
1522
|
+
|
1523
|
+
cls.s_set(nil)
|
1524
|
+
assert_equal("x", cls.bar("x"))
|
1525
|
+
assert_equal("x", cls.s)
|
1526
|
+
|
1527
|
+
cls.s_set("S")
|
1528
|
+
assert_equal("S", cls.bar("x"))
|
1529
|
+
assert_equal("S", cls.s)
|
1530
|
+
|
1531
|
+
foo, = compile(<<-EOF)
|
1532
|
+
class Foo3
|
1533
|
+
def initialize
|
1534
|
+
@count = 0
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
def count
|
1538
|
+
@count
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
def a
|
1542
|
+
@a
|
1543
|
+
end
|
1544
|
+
|
1545
|
+
def a=(a:String)
|
1546
|
+
@count += 1
|
1547
|
+
@a = a
|
1548
|
+
end
|
1549
|
+
|
1550
|
+
def foo(f:Foo3, x:String)
|
1551
|
+
f.a ||= x
|
1552
|
+
end
|
1553
|
+
end
|
1554
|
+
EOF
|
1555
|
+
|
1556
|
+
f = foo.new
|
1557
|
+
assert_equal('x', f.foo(f, 'x'))
|
1558
|
+
assert_equal(1, f.count)
|
1559
|
+
|
1560
|
+
f = foo.new
|
1561
|
+
assert_equal(nil, f.foo(f, nil))
|
1562
|
+
assert_equal(1, f.count)
|
1563
|
+
|
1564
|
+
f = foo.new
|
1565
|
+
f.a_set("A")
|
1566
|
+
assert_equal("A", f.foo(f, nil))
|
1567
|
+
assert_equal(1, f.count)
|
1568
|
+
|
1569
|
+
f = foo.new
|
1570
|
+
f.a_set("A")
|
1571
|
+
assert_equal("A", f.foo(f, 'X'))
|
1572
|
+
assert_equal(1, f.count)
|
1573
|
+
end
|
1574
|
+
|
1575
|
+
def test_op_elem_assign
|
1576
|
+
foo, = compile(<<-EOF)
|
1577
|
+
class Foo4
|
1578
|
+
def initialize
|
1579
|
+
@i = -1
|
1580
|
+
end
|
1581
|
+
|
1582
|
+
def i
|
1583
|
+
@i += 1
|
1584
|
+
end
|
1585
|
+
|
1586
|
+
def a
|
1587
|
+
@a
|
1588
|
+
end
|
1589
|
+
|
1590
|
+
def a=(a:String[])
|
1591
|
+
@a = a
|
1592
|
+
end
|
1593
|
+
|
1594
|
+
def foo(x:String)
|
1595
|
+
a[i] ||= x
|
1596
|
+
end
|
1597
|
+
|
1598
|
+
def bar(x:String)
|
1599
|
+
a[i] &&= x
|
1600
|
+
end
|
1601
|
+
end
|
1602
|
+
EOF
|
1603
|
+
|
1604
|
+
f = foo.new
|
1605
|
+
f.a_set([nil, nil, nil].to_java(:string))
|
1606
|
+
assert_equal(nil, f.bar("x"))
|
1607
|
+
assert_equal([nil, nil, nil], f.a.to_a)
|
1608
|
+
assert_equal("x", f.foo("x"))
|
1609
|
+
assert_equal([nil, "x", nil], f.a.to_a)
|
1610
|
+
end
|
1611
|
+
|
1612
|
+
def test_constructor_chaining
|
1613
|
+
foo, = compile(<<-EOF)
|
1614
|
+
class Foo5
|
1615
|
+
def initialize(s:String)
|
1616
|
+
initialize(s, "foo")
|
1617
|
+
end
|
1618
|
+
|
1619
|
+
def initialize(s:String, f:String)
|
1620
|
+
@s = s
|
1621
|
+
@f = f
|
1622
|
+
end
|
1623
|
+
|
1624
|
+
def f
|
1625
|
+
@f
|
1626
|
+
end
|
1627
|
+
|
1628
|
+
def s
|
1629
|
+
@s
|
1630
|
+
end
|
1631
|
+
end
|
1632
|
+
EOF
|
1633
|
+
|
1634
|
+
instance = foo.new("S")
|
1635
|
+
assert_equal("S", instance.s)
|
1636
|
+
assert_equal("foo", instance.f)
|
1637
|
+
|
1638
|
+
instance = foo.new("foo", "bar")
|
1639
|
+
assert_equal("foo", instance.s)
|
1640
|
+
assert_equal("bar", instance.f)
|
1641
|
+
end
|
1642
|
+
|
1643
|
+
def test_super_constructor
|
1644
|
+
cls, a, b = compile(<<-EOF)
|
1645
|
+
class SC_A
|
1646
|
+
def initialize(a:int)
|
1647
|
+
puts "A"
|
1648
|
+
end
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
class SC_B < SC_A
|
1652
|
+
def initialize
|
1653
|
+
super(0)
|
1654
|
+
puts "B"
|
1655
|
+
end
|
1656
|
+
end
|
1657
|
+
EOF
|
1658
|
+
|
1659
|
+
assert_output("A\nB\n") do
|
1660
|
+
b.new
|
1661
|
+
end
|
1662
|
+
end
|
1663
|
+
|
1664
|
+
def test_literal_array
|
1665
|
+
cls, = compile(<<-EOF)
|
1666
|
+
def foo; puts "hello"; nil; end
|
1667
|
+
def expr
|
1668
|
+
[foo]
|
1669
|
+
end
|
1670
|
+
def nonexpr
|
1671
|
+
[foo]
|
1672
|
+
nil
|
1673
|
+
end
|
1674
|
+
EOF
|
1675
|
+
|
1676
|
+
assert_output("hello\nhello\n") do
|
1677
|
+
val = cls.expr
|
1678
|
+
assert val
|
1679
|
+
|
1680
|
+
val = cls.nonexpr
|
1681
|
+
assert !val
|
1682
|
+
end
|
1683
|
+
end
|
1684
|
+
|
1685
|
+
def test_empty_constructor
|
1686
|
+
foo, = compile(<<-EOF)
|
1687
|
+
class Foo6
|
1688
|
+
def initialize; end
|
1689
|
+
end
|
1690
|
+
EOF
|
1691
|
+
foo.new
|
1692
|
+
end
|
1693
|
+
|
1694
|
+
def test_same_field_name
|
1695
|
+
cls, = compile(<<-EOF)
|
1696
|
+
class A1
|
1697
|
+
def initialize; end
|
1698
|
+
def foo(bar:String)
|
1699
|
+
@bar = bar
|
1700
|
+
end
|
1701
|
+
end
|
1702
|
+
|
1703
|
+
class B1
|
1704
|
+
def initialize; end
|
1705
|
+
def foo(bar:String)
|
1706
|
+
@bar = bar
|
1707
|
+
end
|
1708
|
+
end
|
1709
|
+
|
1710
|
+
puts A1.new.foo("Hi")
|
1711
|
+
puts B1.new.foo("There")
|
1712
|
+
EOF
|
1713
|
+
|
1714
|
+
assert_output("Hi\nThere\n") do
|
1715
|
+
cls.main(nil)
|
1716
|
+
end
|
1717
|
+
end
|
1718
|
+
|
1719
|
+
def test_annotations
|
1720
|
+
deprecated = java.lang.Deprecated.java_class
|
1721
|
+
cls, = compile(<<-EOF)
|
1722
|
+
$Deprecated
|
1723
|
+
def foo
|
1724
|
+
'foo'
|
1725
|
+
end
|
1726
|
+
EOF
|
1727
|
+
|
1728
|
+
assert_not_nil cls.java_class.java_method('foo').annotation(deprecated)
|
1729
|
+
assert_nil cls.java_class.annotation(deprecated)
|
1730
|
+
|
1731
|
+
script, cls = compile(<<-EOF)
|
1732
|
+
$Deprecated
|
1733
|
+
class Annotated
|
1734
|
+
end
|
1735
|
+
EOF
|
1736
|
+
assert_not_nil cls.java_class.annotation(deprecated)
|
1737
|
+
|
1738
|
+
cls, = compile(<<-EOF)
|
1739
|
+
class AnnotatedField
|
1740
|
+
def initialize
|
1741
|
+
$Deprecated
|
1742
|
+
@foo = 1
|
1743
|
+
end
|
1744
|
+
end
|
1745
|
+
EOF
|
1746
|
+
|
1747
|
+
assert_not_nil cls.java_class.declared_fields[0].annotation(deprecated)
|
1748
|
+
end
|
1749
|
+
|
1750
|
+
def test_super
|
1751
|
+
cls, = compile(<<-EOF)
|
1752
|
+
class Foo
|
1753
|
+
def initialize; end
|
1754
|
+
def equals(other:Object); super(other); end
|
1755
|
+
end
|
1756
|
+
EOF
|
1757
|
+
|
1758
|
+
obj = cls.new
|
1759
|
+
assert obj.equals(obj)
|
1760
|
+
assert !obj.equals(cls.new)
|
1761
|
+
end
|
1762
|
+
def test_inexact_constructor
|
1763
|
+
# FIXME: this is a stupid test
|
1764
|
+
cls, = compile(
|
1765
|
+
"class EmptyEmpty; def self.empty_empty; t = Thread.new(Thread.new); t.start; begin; t.join; rescue InterruptedException; end; puts 'ok'; end; end")
|
1766
|
+
assert_output("ok\n") do
|
1767
|
+
cls.empty_empty
|
1768
|
+
end
|
1769
|
+
end
|
1770
|
+
end
|