mirah 0.0.4-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. data/History.txt +15 -0
  2. data/README.txt +51 -0
  3. data/Rakefile +86 -0
  4. data/bin/duby +10 -0
  5. data/bin/dubyc +10 -0
  6. data/bin/dubyp +10 -0
  7. data/bin/jrubyp +36 -0
  8. data/bin/mirah +9 -0
  9. data/bin/mirah.cmd +1 -0
  10. data/bin/mirahc +9 -0
  11. data/bin/mirahc.cmd +1 -0
  12. data/bin/mirahp +9 -0
  13. data/bin/mirahp.cmd +1 -0
  14. data/examples/ant/example-build.xml +7 -0
  15. data/examples/appengine/Rakefile +19 -0
  16. data/examples/appengine/Readme +29 -0
  17. data/examples/appengine/src/org/mirah/MirahApp.mirah +57 -0
  18. data/examples/appengine/src/org/mirah/list.dhtml +15 -0
  19. data/examples/appengine/war/WEB-INF/lib/dubydatastore.jar +0 -0
  20. data/examples/bintrees.mirah +66 -0
  21. data/examples/construction.mirah +8 -0
  22. data/examples/dynamic.mirah +17 -0
  23. data/examples/edb.mirah +3 -0
  24. data/examples/fib.mirah +16 -0
  25. data/examples/fields.mirah +22 -0
  26. data/examples/fractal.mirah +55 -0
  27. data/examples/java_thing.mirah +13 -0
  28. data/examples/plugins/appengine/Rakefile +55 -0
  29. data/examples/plugins/appengine/lib/com/google/appengine/ext/duby/db/datastore.rb +375 -0
  30. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +336 -0
  31. data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +113 -0
  32. data/examples/simple_class.mirah +12 -0
  33. data/examples/sort_closure.mirah +7 -0
  34. data/examples/swing.mirah +20 -0
  35. data/examples/tak.mirah +15 -0
  36. data/examples/test.edb +9 -0
  37. data/examples/wiki/Rakefile +18 -0
  38. data/examples/wiki/src/org/mirah/wiki/MirahWiki.duby +324 -0
  39. data/examples/wiki/src/org/mirah/wiki/edit.eduby.html +42 -0
  40. data/examples/wiki/src/org/mirah/wiki/error.eduby.html +2 -0
  41. data/examples/wiki/src/org/mirah/wiki/layout.eduby.html +69 -0
  42. data/examples/wiki/src/org/mirah/wiki/parser.eduby.html +7 -0
  43. data/examples/wiki/src/org/mirah/wiki/view.eduby.html +15 -0
  44. data/examples/wiki/war/WEB-INF/classes/test/HeredocContext.class +0 -0
  45. data/examples/wiki/war/WEB-INF/classes/test/MirahParser.class +0 -0
  46. data/examples/wiki/war/WEB-INF/lib/appengine-api.jar +0 -0
  47. data/examples/wiki/war/WEB-INF/lib/dubydatastore.jar +0 -0
  48. data/examples/wiki/war/WEB-INF/lib/jmeta-runtime.jar +0 -0
  49. data/examples/wiki/war/WEB-INF/lib/pegdown-stubs.jar +0 -0
  50. data/examples/wiki/war/WEB-INF/pegdown.jar +0 -0
  51. data/examples/wiki/war/app.yaml +21 -0
  52. data/examples/wiki/war/public/favicon.ico +0 -0
  53. data/examples/wiki/war/public/images/appengine_duby.png +0 -0
  54. data/examples/wiki/war/public/images/back.gif +0 -0
  55. data/examples/wiki/war/public/images/dir.gif +0 -0
  56. data/examples/wiki/war/public/images/file.gif +0 -0
  57. data/examples/wiki/war/public/javascripts/prettify.js +61 -0
  58. data/examples/wiki/war/public/robots.txt +0 -0
  59. data/examples/wiki/war/public/stylesheets/main.css +156 -0
  60. data/examples/wiki/war/public/stylesheets/prettify.css +1 -0
  61. data/examples/wiki/war/public/stylesheets/sh_style.css +66 -0
  62. data/examples/wiki/war/public/stylesheets/source.css +21 -0
  63. data/examples/wiki/war/public/wmd/images/bg-fill.png +0 -0
  64. data/examples/wiki/war/public/wmd/images/bg.png +0 -0
  65. data/examples/wiki/war/public/wmd/images/blockquote.png +0 -0
  66. data/examples/wiki/war/public/wmd/images/bold.png +0 -0
  67. data/examples/wiki/war/public/wmd/images/code.png +0 -0
  68. data/examples/wiki/war/public/wmd/images/h1.png +0 -0
  69. data/examples/wiki/war/public/wmd/images/hr.png +0 -0
  70. data/examples/wiki/war/public/wmd/images/img.png +0 -0
  71. data/examples/wiki/war/public/wmd/images/italic.png +0 -0
  72. data/examples/wiki/war/public/wmd/images/link.png +0 -0
  73. data/examples/wiki/war/public/wmd/images/ol.png +0 -0
  74. data/examples/wiki/war/public/wmd/images/redo.png +0 -0
  75. data/examples/wiki/war/public/wmd/images/separator.png +0 -0
  76. data/examples/wiki/war/public/wmd/images/ul.png +0 -0
  77. data/examples/wiki/war/public/wmd/images/undo.png +0 -0
  78. data/examples/wiki/war/public/wmd/images/wmd-on.png +0 -0
  79. data/examples/wiki/war/public/wmd/images/wmd.png +0 -0
  80. data/examples/wiki/war/public/wmd/showdown.js +421 -0
  81. data/examples/wiki/war/public/wmd/wmd-base.js +1799 -0
  82. data/examples/wiki/war/public/wmd/wmd-plus.js +311 -0
  83. data/examples/wiki/war/public/wmd/wmd.js +73 -0
  84. data/javalib/JRubyParser.jar +0 -0
  85. data/javalib/dynalang-invoke-0.1.jar +0 -0
  86. data/javalib/mirah-bootstrap.jar +0 -0
  87. data/javalib/mirah-parser.jar +0 -0
  88. data/lib/duby.rb +2 -0
  89. data/lib/mirah.rb +338 -0
  90. data/lib/mirah/appengine_tasks.rb +146 -0
  91. data/lib/mirah/ast.rb +615 -0
  92. data/lib/mirah/ast/call.rb +307 -0
  93. data/lib/mirah/ast/class.rb +311 -0
  94. data/lib/mirah/ast/flow.rb +364 -0
  95. data/lib/mirah/ast/intrinsics.rb +470 -0
  96. data/lib/mirah/ast/literal.rb +154 -0
  97. data/lib/mirah/ast/local.rb +89 -0
  98. data/lib/mirah/ast/method.rb +360 -0
  99. data/lib/mirah/ast/scope.rb +208 -0
  100. data/lib/mirah/ast/structure.rb +226 -0
  101. data/lib/mirah/ast/type.rb +130 -0
  102. data/lib/mirah/compiler.rb +341 -0
  103. data/lib/mirah/env.rb +33 -0
  104. data/lib/mirah/jvm/base.rb +258 -0
  105. data/lib/mirah/jvm/compiler.rb +885 -0
  106. data/lib/mirah/jvm/method_lookup.rb +203 -0
  107. data/lib/mirah/jvm/source_compiler.rb +737 -0
  108. data/lib/mirah/jvm/source_generator/builder.rb +444 -0
  109. data/lib/mirah/jvm/source_generator/loops.rb +110 -0
  110. data/lib/mirah/jvm/source_generator/precompile.rb +188 -0
  111. data/lib/mirah/jvm/source_generator/typer.rb +11 -0
  112. data/lib/mirah/jvm/typer.rb +151 -0
  113. data/lib/mirah/jvm/types.rb +416 -0
  114. data/lib/mirah/jvm/types/basic_types.rb +33 -0
  115. data/lib/mirah/jvm/types/boolean.rb +17 -0
  116. data/lib/mirah/jvm/types/enumerable.rb +65 -0
  117. data/lib/mirah/jvm/types/extensions.rb +86 -0
  118. data/lib/mirah/jvm/types/factory.rb +186 -0
  119. data/lib/mirah/jvm/types/floats.rb +86 -0
  120. data/lib/mirah/jvm/types/integers.rb +171 -0
  121. data/lib/mirah/jvm/types/intrinsics.rb +376 -0
  122. data/lib/mirah/jvm/types/literals.rb +74 -0
  123. data/lib/mirah/jvm/types/methods.rb +614 -0
  124. data/lib/mirah/jvm/types/number.rb +143 -0
  125. data/lib/mirah/nbcompiler.rb +29 -0
  126. data/lib/mirah/plugin/edb.rb +29 -0
  127. data/lib/mirah/plugin/gwt.rb +173 -0
  128. data/lib/mirah/plugin/java.rb +55 -0
  129. data/lib/mirah/transform.rb +266 -0
  130. data/lib/mirah/transform2.rb +728 -0
  131. data/lib/mirah/typer.rb +407 -0
  132. data/lib/mirah_task.rb +107 -0
  133. data/test/test_ast.rb +359 -0
  134. data/test/test_compilation.rb +112 -0
  135. data/test/test_env.rb +42 -0
  136. data/test/test_gwt.rb +58 -0
  137. data/test/test_java_typer.rb +183 -0
  138. data/test/test_javac_compiler.rb +63 -0
  139. data/test/test_jvm_compiler.rb +2607 -0
  140. data/test/test_typer.rb +221 -0
  141. metadata +235 -0
@@ -0,0 +1,42 @@
1
+ require 'test/unit'
2
+ require 'mirah'
3
+
4
+ class TestEnv < Test::Unit::TestCase
5
+ include Duby
6
+
7
+ def test_path_seperator
8
+ # Check that env var PATH_SEPERATOR is used
9
+ RbConfig::CONFIG['PATH_SEPARATOR'] = '*'
10
+ assert_equal('*', Duby::Env.path_seperator)
11
+
12
+ # Check that : (colon) is returned if no PATH_SEPERATOR env var set
13
+ RbConfig::CONFIG['PATH_SEPARATOR'] = ''
14
+ assert_equal(':', Duby::Env.path_seperator)
15
+ end
16
+
17
+ def test_encode_paths
18
+ RbConfig::CONFIG['PATH_SEPARATOR'] = ':'
19
+
20
+ assert_equal('a:b:c', Duby::Env.encode_paths(['a','b','c']))
21
+ assert_equal('a', Duby::Env.encode_paths(['a']))
22
+ assert_equal('', Duby::Env.encode_paths([]))
23
+
24
+ RbConfig::CONFIG['PATH_SEPARATOR'] = ';'
25
+
26
+ assert_equal('a;b;c', Duby::Env.encode_paths(['a','b','c']))
27
+ end
28
+
29
+ def test_decode_paths
30
+ RbConfig::CONFIG['PATH_SEPARATOR'] = ':'
31
+
32
+ path_array = ['1','2']
33
+ assert_equal(['1','2','a','b','c','d'], Duby::Env.decode_paths('a:b:c:d', path_array))
34
+ assert_equal(['1','2','a','b','c','d'], path_array)
35
+
36
+ assert_equal(['a','b','c','d'], Duby::Env.decode_paths('a:b:c:d'))
37
+ assert_equal(['a'], Duby::Env.decode_paths('a'))
38
+
39
+ RbConfig::CONFIG['PATH_SEPARATOR'] = ';'
40
+ assert_equal(['a','b','c','d'], Duby::Env.decode_paths('a;b;c;d'))
41
+ end
42
+ end
@@ -0,0 +1,58 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'test/unit'
4
+ require 'mirah'
5
+ require 'jruby'
6
+
7
+ class TestGWT < Test::Unit::TestCase
8
+ include Duby::AST
9
+
10
+ def test_jsni_static
11
+ new_ast = parse("def_jsni void, _log(), 'hi'").body[0]
12
+ # True after JsniMethodDefinition infer is called.
13
+ assert(!new_ast.static?)
14
+
15
+ new_ast = parse("def_jsni void, self._log(), 'hi'").body[0]
16
+ assert_equal(new_ast.static?, true)
17
+
18
+ new_ast = parse(<<-'S').body[0].body[0]
19
+ class Log
20
+ def_jsni void, _log(), 'hi'
21
+ end
22
+ S
23
+ assert(!new_ast.static?)
24
+ end
25
+
26
+ def test_jsni_no_arg
27
+ new_ast = parse("def_jsni void, _log(), 'hi'").body[0]
28
+
29
+ name = new_ast.name
30
+ assert_equal(name, '_log')
31
+
32
+ body = new_ast.body.literal
33
+ assert_equal(body, 'hi')
34
+
35
+ signature = new_ast.signature
36
+ return_type = signature[:return] == Duby::AST::TypeReference.new('void')
37
+ assert_equal(return_type, true)
38
+
39
+ has_arguments = new_ast.arguments.args
40
+ assert_equal(has_arguments, [])
41
+ end
42
+
43
+ def test_jsni_one_arg
44
+ new_ast = parse("def_jsni void, _log(message:Object), 'hi'").body[0]
45
+
46
+ message_type = new_ast.signature[:message] == Duby::AST::TypeReference.new('Object')
47
+ assert_equal(message_type, true)
48
+
49
+ arg_size = new_ast.arguments.args.size
50
+ assert_equal(arg_size, 1)
51
+ end
52
+
53
+ def test_jsni_two_args
54
+ new_ast = parse("def_jsni void, _log(message:Object,message2:Object), 'hi'").body[0]
55
+ arg_size = new_ast.arguments.args.size
56
+ assert_equal(arg_size, 2)
57
+ end
58
+ end
@@ -0,0 +1,183 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'test/unit'
4
+ require 'mirah/typer'
5
+ require 'mirah/plugin/java'
6
+ require 'mirah/jvm/compiler'
7
+ require 'mirah/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(nil)
15
+ compiler = Duby::Compiler::JVM.new
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(nil, 'java.lang.String', false, true)
26
+ string = AST.type(nil, 'java.lang.String')
27
+
28
+ # integral types
29
+ ['boolean', 'char', 'double', 'float', 'int', 'long'].each do |type_name|
30
+ type = AST.type(nil, 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(nil, '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(nil, '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(nil, 'java.lang.String')
48
+
49
+ int = AST.type(nil, 'int')
50
+ return_type = @java_typer.method_type(@typer, string, 'length', [])
51
+ assert_equal(int, return_type)
52
+
53
+ byte_array = AST.type(nil, '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(nil, 'java.lang.String', false, true)
60
+ string = AST.type(nil, '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(nil, 'java.lang.String')
68
+ byte = AST.type(nil, 'byte')
69
+ char = AST.type(nil, 'char')
70
+ long = AST.type(nil, '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_is_more_specific
83
+ object = java.lang.Object.java_class
84
+ charseq = java.lang.CharSequence.java_class
85
+ string = java.lang.String.java_class
86
+
87
+ assert @java_typer.is_more_specific?([string], [object])
88
+ assert @java_typer.is_more_specific?([charseq], [object])
89
+ assert @java_typer.is_more_specific?([string], [charseq])
90
+ end
91
+
92
+ def test_primitive_convertible
93
+ boolean = Duby::JVM::Types::Boolean
94
+ byte = Duby::JVM::Types::Byte
95
+ short = Duby::JVM::Types::Short
96
+ char = Duby::JVM::Types::Char
97
+ int = Duby::JVM::Types::Int
98
+ long = Duby::JVM::Types::Long
99
+ float = Duby::JVM::Types::Float
100
+ double = Duby::JVM::Types::Double
101
+
102
+ assert !primitive_convertible?(boolean, byte)
103
+ assert !primitive_convertible?(boolean, short)
104
+ assert !primitive_convertible?(boolean, char)
105
+ assert !primitive_convertible?(boolean, int)
106
+ assert !primitive_convertible?(boolean, long)
107
+ assert !primitive_convertible?(boolean, float)
108
+ assert !primitive_convertible?(boolean, double)
109
+ assert primitive_convertible?(boolean, boolean)
110
+
111
+ assert !primitive_convertible?(byte, boolean)
112
+ assert primitive_convertible?(byte, byte)
113
+ assert primitive_convertible?(byte, short)
114
+ assert !primitive_convertible?(byte, char)
115
+ assert primitive_convertible?(byte, int)
116
+ assert primitive_convertible?(byte, long)
117
+ assert primitive_convertible?(byte, float)
118
+ assert primitive_convertible?(byte, double)
119
+
120
+ assert !primitive_convertible?(short, boolean)
121
+ assert !primitive_convertible?(short, byte)
122
+ assert !primitive_convertible?(short, char)
123
+ assert primitive_convertible?(short, short)
124
+ assert primitive_convertible?(short, int)
125
+ assert primitive_convertible?(short, long)
126
+ assert primitive_convertible?(short, float)
127
+ assert primitive_convertible?(short, double)
128
+
129
+ assert !primitive_convertible?(char, boolean)
130
+ assert !primitive_convertible?(char, byte)
131
+ assert !primitive_convertible?(char, short)
132
+ assert primitive_convertible?(char, char)
133
+ assert primitive_convertible?(char, int)
134
+ assert primitive_convertible?(char, long)
135
+ assert primitive_convertible?(char, float)
136
+ assert primitive_convertible?(char, double)
137
+
138
+ assert !primitive_convertible?(int, boolean)
139
+ assert !primitive_convertible?(int, byte)
140
+ assert !primitive_convertible?(int, short)
141
+ assert !primitive_convertible?(int, char)
142
+ assert primitive_convertible?(int, int)
143
+ assert primitive_convertible?(int, long)
144
+ assert primitive_convertible?(int, float)
145
+ assert primitive_convertible?(int, double)
146
+
147
+ assert !primitive_convertible?(long, boolean)
148
+ assert !primitive_convertible?(long, byte)
149
+ assert !primitive_convertible?(long, short)
150
+ assert !primitive_convertible?(long, char)
151
+ assert !primitive_convertible?(long, int)
152
+ assert primitive_convertible?(long, long)
153
+ assert primitive_convertible?(long, float)
154
+ assert primitive_convertible?(long, double)
155
+
156
+ assert !primitive_convertible?(float, boolean)
157
+ assert !primitive_convertible?(float, byte)
158
+ assert !primitive_convertible?(float, short)
159
+ assert !primitive_convertible?(float, char)
160
+ assert !primitive_convertible?(float, int)
161
+ assert !primitive_convertible?(float, long)
162
+ assert primitive_convertible?(float, float)
163
+ assert primitive_convertible?(float, double)
164
+
165
+ assert !primitive_convertible?(double, boolean)
166
+ assert !primitive_convertible?(double, byte)
167
+ assert !primitive_convertible?(double, short)
168
+ assert !primitive_convertible?(double, char)
169
+ assert !primitive_convertible?(double, int)
170
+ assert !primitive_convertible?(double, long)
171
+ assert !primitive_convertible?(double, float)
172
+ assert primitive_convertible?(double, double)
173
+ end
174
+
175
+ def test_primitive_array
176
+ ary = AST.type(nil, 'byte', true)
177
+ int = AST.type(nil, 'int')
178
+
179
+ java_typer = Typer::JavaTyper.new
180
+
181
+ assert_equal(AST.type(nil, 'byte'), java_typer.method_type(nil, ary, "[]", [int]))
182
+ end
183
+ end
@@ -0,0 +1,63 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'test/unit'
4
+ require 'mirah'
5
+ require 'mirah/jvm/source_compiler'
6
+ require 'jruby'
7
+ require 'stringio'
8
+ require File.join(File.dirname(__FILE__), 'test_jvm_compiler')
9
+
10
+ # make sure . is in CLASSPATH
11
+ $CLASSPATH << '.'
12
+
13
+ class TestJavacCompiler < TestJVMCompiler
14
+ import javax.tools.ToolProvider
15
+ import java.util.Arrays
16
+ def javac(files)
17
+ compiler = ToolProvider.system_java_compiler
18
+ fm = compiler.get_standard_file_manager(nil, nil, nil)
19
+ units = fm.get_java_file_objects_from_strings(Arrays.as_list(files.to_java :string))
20
+ unless compiler.get_task(nil, fm, nil, nil, nil, units).call
21
+ raise "Compilation error"
22
+ end
23
+ loader = org.jruby.util.ClassCache::OneShotClassLoader.new(
24
+ JRuby.runtime.jruby_class_loader)
25
+ classes = []
26
+ files.each do |name|
27
+ classfile = name.sub /java$/, 'class'
28
+ if File.exist? classfile
29
+ bytecode = IO.read(classfile)
30
+ cls = loader.define_class(name[0..-6].tr('/', '.'), bytecode.to_java_bytes)
31
+ classes << JavaUtilities.get_proxy_class(cls.name)
32
+ @tmp_classes << name
33
+ @tmp_classes << classfile
34
+ end
35
+ end
36
+ classes
37
+ end
38
+
39
+ def compile(code)
40
+ File.unlink(*@tmp_classes)
41
+ @tmp_classes.clear
42
+ AST.type_factory = Duby::JVM::Types::TypeFactory.new
43
+ transformer = Duby::Transform::Transformer.new(Duby::CompilationState.new)
44
+ Java::MirahImpl::Builtin.initialize_builtins(transformer)
45
+ name = "script" + System.nano_time.to_s
46
+ ast = AST.parse(code, name, true, transformer)
47
+ typer = Typer::JVM.new(transformer)
48
+ ast.infer(typer)
49
+ typer.resolve(true)
50
+ compiler = Compiler::JavaSource.new
51
+ ast.compile(compiler, false)
52
+ java_files = []
53
+ compiler.generate do |name, builder|
54
+ bytes = builder.generate
55
+ FileUtils.mkdir_p(File.dirname(name))
56
+ open("#{name}", "w") do |f|
57
+ f << bytes
58
+ end
59
+ java_files << name
60
+ end
61
+ classes = javac(java_files)
62
+ end
63
+ end
@@ -0,0 +1,2607 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'test/unit'
4
+ require 'mirah'
5
+ require 'jruby'
6
+ require 'stringio'
7
+ require 'fileutils'
8
+
9
+ unless Duby::AST.macro "__gloop__"
10
+ Duby::AST.defmacro "__gloop__" do |transformer, fcall, parent|
11
+ Duby::AST::Loop.new(parent, parent.position, true, false) do |loop|
12
+ init, condition, check_first, pre, post = fcall.parameters
13
+ loop.check_first = check_first.literal
14
+
15
+ nil_t = Duby::AST::Null
16
+ loop.init = init
17
+ loop.pre = pre
18
+ loop.post = post
19
+
20
+ body = fcall.block.body
21
+ body.parent = loop
22
+ [
23
+ Duby::AST::Condition.new(loop, parent.position) do |c|
24
+ condition.parent = c
25
+ [condition]
26
+ end,
27
+ body
28
+ ]
29
+ end
30
+ end
31
+ end
32
+
33
+ class TestJVMCompiler < Test::Unit::TestCase
34
+ include Duby
35
+ import java.lang.System
36
+ import java.io.PrintStream
37
+
38
+ def setup
39
+ @tmp_classes = []
40
+ end
41
+
42
+ def teardown
43
+ AST.type_factory = nil
44
+ File.unlink(*@tmp_classes)
45
+ end
46
+
47
+ def assert_include(value, array, message=nil)
48
+ message = build_message message, '<?> does not include <?>', array, value
49
+ assert_block message do
50
+ array.include? value
51
+ end
52
+ end
53
+
54
+ def compile(code)
55
+ File.unlink(*@tmp_classes)
56
+ @tmp_classes.clear
57
+ AST.type_factory = Duby::JVM::Types::TypeFactory.new
58
+ name = "script" + System.nano_time.to_s
59
+ transformer = Duby::Transform::Transformer.new(Duby::CompilationState.new)
60
+ Java::MirahImpl::Builtin.initialize_builtins(transformer)
61
+ ast = AST.parse(code, name, true, transformer)
62
+ typer = Typer::JVM.new(transformer)
63
+ ast.infer(typer)
64
+ typer.resolve(true)
65
+ compiler = Compiler::JVM.new
66
+ compiler.compile(ast)
67
+ classes = {}
68
+ loader = DubyClassLoader.new(JRuby.runtime.jruby_class_loader, classes)
69
+ compiler.generate do |name, builder|
70
+ bytes = builder.generate
71
+ FileUtils.mkdir_p(File.dirname(name))
72
+ open("#{name}", "wb") do |f|
73
+ f << bytes
74
+ end
75
+ classes[name[0..-7]] = bytes
76
+ end
77
+
78
+ classes.keys.map do |name|
79
+ cls = loader.load_class(name.tr('/', '.'))
80
+ proxy = JavaUtilities.get_proxy_class(cls.name)
81
+ @tmp_classes << "#{name}.class"
82
+ proxy
83
+ end
84
+ end
85
+
86
+ def test_local
87
+ cls, = compile("def foo; a = 1; a; end")
88
+ assert_equal(1, cls.foo)
89
+
90
+ cls, = compile("def foo; a = 1.0; a; end")
91
+ assert_equal(1.0, cls.foo)
92
+
93
+ cls, = compile("def foo; a = 'bar'; a; end")
94
+ assert_equal('bar', cls.foo)
95
+ end
96
+
97
+ def test_addition
98
+ cls, = compile("def foo; a = 1; b = 2; a + b; end")
99
+ assert_equal(3, cls.foo)
100
+
101
+ cls, = compile("def foo; a = 1.0; b = 2.0; a + b; end")
102
+ assert_equal(3.0, cls.foo)
103
+ end
104
+
105
+ def test_subtraction
106
+ cls, = compile("def foo; a = 3; b = 2; a - b; end")
107
+ assert_equal(1, cls.foo)
108
+
109
+ cls, = compile("def foo; a = 3.0; b = 2.0; a - b; end")
110
+ assert_equal(1.0, cls.foo)
111
+ end
112
+
113
+ def test_multiplication
114
+ cls, = compile("def foo; a = 2; b = 3; a * b; end")
115
+ assert_equal(6, cls.foo)
116
+
117
+ cls, = compile("def foo; a = 2.0; b = 3.0; a * b; end")
118
+ assert_equal(6.0, cls.foo)
119
+ end
120
+
121
+ def test_division
122
+ cls, = compile("def foo; a = 6; b = 3; a / b; end")
123
+ assert_equal(2, cls.foo)
124
+
125
+ cls, = compile("def foo; a = 6.0; b = 3.0; a / b; end")
126
+ assert_equal(2.0, cls.foo)
127
+ end
128
+
129
+ def test_rem
130
+ cls, = compile("def foo; a = 7; b = 3; a % b; end")
131
+ assert_equal(1, cls.foo)
132
+
133
+ cls, = compile("def foo; a = 8.0; b = 3.0; a % b; end")
134
+ assert_equal(2.0, cls.foo)
135
+ end
136
+
137
+ def test_shift_left
138
+ cls, = compile("def foo; a = 1; b = 3; a << b; end")
139
+ assert_equal(8, cls.foo)
140
+ end
141
+
142
+ def test_shift_right
143
+ cls, = compile("def foo; a = 7; b = 2; a >> b; end")
144
+ assert_equal(1, cls.foo)
145
+
146
+ cls, = compile("def foo; a = -1; b = 1; a >> b; end")
147
+ assert_equal(-1, cls.foo)
148
+ end
149
+
150
+ # TODO the parser doesn't like >>>
151
+
152
+ # def test_unsigned_shift_right
153
+ # cls, = compile("def foo; a = -1; b = 31; a >>> b; end")
154
+ # assert_equal(1, cls.foo)
155
+ # end
156
+
157
+ def test_binary_and
158
+ cls, = compile("def foo; a = 7; b = 3; a & b; end")
159
+ assert_equal(3, cls.foo)
160
+ end
161
+
162
+ def test_binary_or
163
+ cls, = compile("def foo; a = 4; b = 3; a | b; end")
164
+ assert_equal(7, cls.foo)
165
+ end
166
+
167
+ def test_binary_xor
168
+ cls, = compile("def foo; a = 5; b = 3; a ^ b; end")
169
+ assert_equal(6, cls.foo)
170
+ end
171
+
172
+ def test_return
173
+ cls, = compile("def foo; return 1; end")
174
+ assert_equal(1, cls.foo)
175
+
176
+ cls, = compile("def foo; return 1.0; end")
177
+ assert_equal(1.0, cls.foo)
178
+
179
+ cls, = compile("def foo; return 'bar'; end")
180
+ assert_equal('bar', cls.foo)
181
+ end
182
+
183
+ def test_primitive_array
184
+ cls, = compile("def foo; a = boolean[2]; a; end")
185
+ assert_equal(Java::boolean[].java_class, cls.foo.class.java_class)
186
+ assert_equal([false,false], cls.foo.to_a)
187
+ cls, = compile("def foo; a = boolean[2]; a[0] = true; a[0]; end")
188
+ assert_equal(TrueClass, cls.foo.class)
189
+ assert_equal(true, cls.foo)
190
+ cls, = compile("def foo; a = boolean[2]; a.length; end")
191
+ assert_equal(Fixnum, cls.foo.class)
192
+ assert_equal(2, cls.foo)
193
+
194
+ cls, = compile("def foo; a = byte[2]; a; end")
195
+ assert_equal(Java::byte[].java_class, cls.foo.class.java_class)
196
+ assert_equal([0,0], cls.foo.to_a)
197
+ cls, = compile("def foo; a = byte[2]; a[0] = 1; a[0]; end")
198
+ assert_equal(Fixnum, cls.foo.class)
199
+ assert_equal(1, cls.foo)
200
+
201
+ cls, = compile("def foo; a = short[2]; a; end")
202
+ assert_equal(Java::short[].java_class, cls.foo.class.java_class)
203
+ assert_equal([0,0], cls.foo.to_a)
204
+ cls, = compile("def foo; a = short[2]; a[0] = 1; a[0]; end")
205
+ assert_equal(Fixnum, cls.foo.class)
206
+ assert_equal(1, cls.foo)
207
+
208
+ cls, = compile("def foo; a = char[2]; a; end")
209
+ assert_equal(Java::char[].java_class, cls.foo.class.java_class)
210
+ assert_equal([0,0], cls.foo.to_a)
211
+ # Pending char constants or casts
212
+ # cls, = compile("def foo; a = char[2]; a[0] = 1; a[0]; end")
213
+ # assert_equal(Fixnum, cls.foo.class)
214
+ # assert_equal(1, cls.foo)
215
+
216
+ cls, = compile("def foo; a = int[2]; a; end")
217
+ assert_equal(Java::int[].java_class, cls.foo.class.java_class)
218
+ assert_equal([0,0], cls.foo.to_a)
219
+ cls, = compile("def foo; a = int[2]; a[0] = 1; a[0]; end")
220
+ assert_equal(Fixnum, cls.foo.class)
221
+ assert_equal(1, cls.foo)
222
+
223
+ cls, = compile("def foo; a = long[2]; a; end")
224
+ assert_equal(Java::long[].java_class, cls.foo.class.java_class)
225
+ assert_equal([0,0], cls.foo.to_a)
226
+ cls, = compile(<<-EOF)
227
+ def foo
228
+ a = long[2]
229
+ a[0] = 1
230
+ a[0]
231
+ end
232
+ EOF
233
+ assert_equal(Fixnum, cls.foo.class)
234
+ assert_equal(1, cls.foo)
235
+
236
+ cls, = compile("def foo; a = float[2]; a; end")
237
+ assert_equal(Java::float[].java_class, cls.foo.class.java_class)
238
+ assert_equal([0.0,0.0], cls.foo.to_a)
239
+ cls, = compile("def foo; a = float[2]; a[0] = float(1.0); a[0]; end")
240
+ assert_equal(Float, cls.foo.class)
241
+ assert_equal(1.0, cls.foo)
242
+
243
+ cls, = compile("def foo; a = double[2]; a; end")
244
+ assert_equal(Java::double[].java_class, cls.foo.class.java_class)
245
+ assert_equal([0.0,0.0], cls.foo.to_a)
246
+ cls, = compile(<<-EOF)
247
+ def foo
248
+ a = double[2]
249
+ a[0] = 1.0
250
+ a[0]
251
+ end
252
+ EOF
253
+ assert_equal(Float, cls.foo.class)
254
+ assert_equal(1.0, cls.foo)
255
+ end
256
+
257
+ def test_array_with_dynamic_size
258
+ cls, = compile("def foo(size:int); a = int[size + 1];end")
259
+ array = cls.foo(3)
260
+ assert_equal(Java::int[].java_class, array.class.java_class)
261
+ assert_equal([0,0,0,0], array.to_a)
262
+ end
263
+
264
+ def test_object_array
265
+ cls, = compile("import java.lang.Object;def foo; a = Object[2];end")
266
+ assert_equal(Java::JavaLang::Object[].java_class, cls.foo.class.java_class)
267
+ assert_equal([nil, nil], cls.foo.to_a)
268
+ end
269
+
270
+ def test_string_concat
271
+ cls, = compile("
272
+ def str_str; a = 'a'; b = 'b'; a + b; end
273
+ def str_boolean; a = 'a'; b = false; a + b; end
274
+ def str_float; a = 'a'; b = float(1.0); a + b; end
275
+ def str_double; a = 'a'; b = 1.0; a + b; end
276
+ def str_byte; a = 'a'; b = byte(1); a + b; end
277
+ def str_short; a = 'a'; b = short(1); a + b; end
278
+ def str_char; a = 'a'; b = char(123); a + b; end
279
+ def str_int; a = 'a'; b = 1; a + b; end
280
+ def str_long; a = 'a'; b = long(1); a + b; end
281
+ ")
282
+ assert_equal("ab", cls.str_str)
283
+ assert_equal("afalse", cls.str_boolean)
284
+ assert_equal("a1.0", cls.str_float)
285
+ assert_equal("a1.0", cls.str_double)
286
+ assert_equal("a1", cls.str_byte)
287
+ assert_equal("a1", cls.str_short)
288
+ assert_equal("a{", cls.str_char)
289
+ assert_equal("a1", cls.str_int)
290
+ assert_equal("a1", cls.str_long)
291
+ end
292
+
293
+ def test_void_selfcall
294
+ cls, = compile("import 'System', 'java.lang.System'; def foo; System.gc; end; foo")
295
+ assert_nothing_raised {cls.foo}
296
+ end
297
+
298
+ def test_void_chain
299
+ cls, = compile(<<-EOF)
300
+ import java.io.*
301
+ def foo
302
+ throws IOException
303
+ OutputStreamWriter.new(
304
+ System.out).write("Hello ").write("there\n").flush
305
+ end
306
+ EOF
307
+
308
+ assert_output("Hello there\n") { cls.foo }
309
+
310
+ script, a, b = compile(<<-EOF)
311
+ class VoidBase
312
+ def foo
313
+ returns void
314
+ puts "foo"
315
+ end
316
+ end
317
+ class VoidChain < VoidBase
318
+ def bar
319
+ returns void
320
+ puts "bar"
321
+ end
322
+
323
+ def self.foobar
324
+ VoidChain.new.foo.bar
325
+ end
326
+ end
327
+ EOF
328
+
329
+ assert_output("foo\nbar\n") { b.foobar }
330
+
331
+ end
332
+
333
+ def test_import
334
+ cls, = compile("import 'AL', 'java.util.ArrayList'; def foo; AL.new; end; foo")
335
+ assert_equal java.util.ArrayList.java_class, cls.foo.java_class
336
+
337
+ cls, = compile("import 'java.util.ArrayList'; def foo; ArrayList.new; end; foo")
338
+ assert_equal java.util.ArrayList.java_class, cls.foo.java_class
339
+ end
340
+
341
+ def test_no_quote_import
342
+ cls, = compile("import java.util.ArrayList as AL; def foo; AL.new; end; foo")
343
+ assert_equal java.util.ArrayList.java_class, cls.foo.java_class
344
+
345
+ cls, = compile("import java.util.ArrayList; def foo; ArrayList.new; end; foo")
346
+ assert_equal java.util.ArrayList.java_class, cls.foo.java_class
347
+ end
348
+
349
+ def test_imported_decl
350
+ cls, = compile("import 'java.util.ArrayList'; def foo(a:ArrayList); a.size; end")
351
+ assert_equal 0, cls.foo(java.util.ArrayList.new)
352
+ end
353
+
354
+ def test_import_package
355
+ cls, = compile(<<-EOF)
356
+ import java.util.*
357
+ def foo
358
+ ArrayList.new
359
+ end
360
+ EOF
361
+ assert_equal java.util.ArrayList.java_class, cls.foo.java_class
362
+ end
363
+
364
+ def test_interface
365
+ cls, = compile(<<-EOF)
366
+ import 'java.util.concurrent.Callable'
367
+ def foo(a:Callable)
368
+ throws Exception
369
+ a.call
370
+ end
371
+ EOF
372
+ result = cls.foo {0}
373
+ assert_equal 0, result
374
+ m = cls.java_class.java_method 'foo', java.util.concurrent.Callable
375
+ assert_equal([java.lang.Exception.java_class], m.exception_types)
376
+
377
+ end
378
+
379
+ def test_class_decl
380
+ foo, = compile("class ClassDeclTest;end")
381
+ assert_equal('ClassDeclTest', foo.java_class.name)
382
+ end
383
+
384
+ def capture_output
385
+ saved_output = System.out
386
+ output = StringIO.new
387
+ System.setOut(PrintStream.new(output.to_outputstream))
388
+ begin
389
+ yield
390
+ output.rewind
391
+ output.read
392
+ ensure
393
+ System.setOut(saved_output)
394
+ end
395
+ end
396
+
397
+ def assert_output(expected, &block)
398
+ assert_equal(expected, capture_output(&block))
399
+ end
400
+
401
+ def test_puts
402
+ cls, = compile("def foo;puts 'Hello World!';end")
403
+ output = capture_output do
404
+ cls.foo
405
+ end
406
+ assert_equal("Hello World!\n", output)
407
+ end
408
+
409
+ def test_print
410
+ cls, = compile("def foo;print 'Hello World!';end")
411
+ output = capture_output do
412
+ cls.foo
413
+ end
414
+ assert_equal("Hello World!", output)
415
+ end
416
+
417
+ def test_constructor
418
+ cls, = compile(
419
+ "class InitializeTest;def initialize;puts 'Constructed';end;end")
420
+ assert_output("Constructed\n") do
421
+ cls.new
422
+ end
423
+ end
424
+
425
+ def test_method
426
+ # TODO auto generate a constructor
427
+ cls, = compile(
428
+ "class MethodTest; def foo; 'foo';end;end")
429
+ instance = cls.new
430
+ assert_equal(cls, instance.class)
431
+ assert_equal('foo', instance.foo)
432
+ end
433
+
434
+ def test_unless_fixnum
435
+ cls, = compile(<<-EOF)
436
+ def foo(a:fixnum)
437
+ values = boolean[5]
438
+ values[0] = true unless a < 0
439
+ values[1] = true unless a <= 0
440
+ values[2] = true unless a == 0
441
+ values[3] = true unless a >= 0
442
+ values[4] = true unless a > 0
443
+ values
444
+ end
445
+ EOF
446
+ assert_equal [true, true, true, false, false], cls.foo(1).to_a
447
+ assert_equal [true, false, false, false, true], cls.foo(0).to_a
448
+ assert_equal [false, false, true, true, true], cls.foo(-1).to_a
449
+ end
450
+
451
+ def test_unless_float
452
+ cls, = compile(<<-EOF)
453
+ def foo(a:float)
454
+ values = boolean[5]
455
+ values[0] = true unless a < 0.0
456
+ values[1] = true unless a <= 0.0
457
+ values[2] = true unless a == 0.0
458
+ values[3] = true unless a >= 0.0
459
+ values[4] = true unless a > 0.0
460
+ values
461
+ end
462
+ EOF
463
+ assert_equal [true, true, true, false, false], cls.foo(1.0).to_a
464
+ assert_equal [true, false, false, false, true], cls.foo(0.0).to_a
465
+ assert_equal [false, false, true, true, true], cls.foo(-1.0).to_a
466
+ end
467
+
468
+ def test_if_fixnum
469
+ cls, = compile(<<-EOF)
470
+ def foo(a:fixnum)
471
+ if a < -5
472
+ -6
473
+ elsif a <= 0
474
+ 0
475
+ elsif a == 1
476
+ 1
477
+ elsif a > 4
478
+ 5
479
+ elsif a >= 3
480
+ 3
481
+ else
482
+ 2
483
+ end
484
+ end
485
+ EOF
486
+ assert_equal(-6, cls.foo(-6))
487
+ assert_equal(0, cls.foo(-5))
488
+ assert_equal(0, cls.foo(0))
489
+ assert_equal(1, cls.foo(1))
490
+ assert_equal(2, cls.foo(2))
491
+ assert_equal(3, cls.foo(3))
492
+ assert_equal(3, cls.foo(4))
493
+ assert_equal(5, cls.foo(5))
494
+ end
495
+
496
+ def test_if_float
497
+ cls, = compile(<<-EOF)
498
+ def foo(a:float)
499
+ if a < -5.0
500
+ -6
501
+ elsif a <= 0.0
502
+ 0
503
+ elsif a == 1.0
504
+ 1
505
+ elsif a > 4.0
506
+ 5
507
+ elsif a >= 3.0
508
+ 3
509
+ else
510
+ 2
511
+ end
512
+ end
513
+ EOF
514
+ assert_equal(-6, cls.foo(-5.1))
515
+ assert_equal(0, cls.foo(-5.0))
516
+ assert_equal(0, cls.foo(0.0))
517
+ assert_equal(1, cls.foo(1.0))
518
+ assert_equal(2, cls.foo(2.5))
519
+ assert_equal(3, cls.foo(3.0))
520
+ assert_equal(3, cls.foo(3.5))
521
+ assert_equal(5, cls.foo(4.1))
522
+ end
523
+
524
+ def test_if_boolean
525
+ cls, = compile(<<-EOF)
526
+ def foo(a:boolean)
527
+ if a
528
+ 'true'
529
+ else
530
+ 'false'
531
+ end
532
+ end
533
+ EOF
534
+ assert_equal('true', cls.foo(true))
535
+ assert_equal('false', cls.foo(false))
536
+ end
537
+
538
+ def test_if_int
539
+ # conditions don't work with :int
540
+ # cls, = compile("def foo(a:int); if a < 0; -a; else; a; end; end")
541
+ # assert_equal 1, cls.foo(-1)
542
+ # assert_equal 3, cls.foo(3)
543
+ end
544
+
545
+ def test_trailing_conditions
546
+ cls, = compile(<<-EOF)
547
+ def foo(a:fixnum)
548
+ return '+' if a > 0
549
+ return '0' unless a < 0
550
+ '-'
551
+ end
552
+ EOF
553
+ assert_equal '+', cls.foo(3)
554
+ assert_equal '0', cls.foo(0)
555
+ assert_equal '-', cls.foo(-1)
556
+ end
557
+
558
+
559
+ def test_local_decl
560
+ cls, = compile(<<-EOF)
561
+ import 'java.lang.String'
562
+ a = :fixnum
563
+ b = :int
564
+ c = :long
565
+ d = :float
566
+ e = :string
567
+ f = String
568
+ puts a
569
+ puts b
570
+ puts c
571
+ puts d
572
+ puts e
573
+ puts f
574
+ EOF
575
+ output = capture_output do
576
+ cls.main([].to_java(:string))
577
+ end
578
+ assert_equal("0\n0\n0\n0.0\nnull\nnull\n", output)
579
+ end
580
+
581
+ def test_multi_assign
582
+ cls, = compile(<<-EOF)
583
+ def foo
584
+ array = int[2]
585
+ a = b = 2
586
+ array[0] = a
587
+ array[1] = b
588
+ array
589
+ end
590
+ EOF
591
+ assert_equal([2, 2], cls.foo.to_a)
592
+
593
+ end
594
+
595
+ def test_loop
596
+ cls, = compile(
597
+ 'def foo(a:fixnum);while a > 0; a -= 1; puts ".";end;end')
598
+ assert_equal('', capture_output{cls.foo(0)})
599
+ assert_equal(".\n", capture_output{cls.foo(1)})
600
+ assert_equal(".\n.\n", capture_output{cls.foo(2)})
601
+
602
+ cls, = compile(
603
+ 'def foo(a:fixnum);begin;a -= 1; puts ".";end while a > 0;end')
604
+ assert_equal(".\n", capture_output{cls.foo(0)})
605
+ assert_equal(".\n", capture_output{cls.foo(1)})
606
+ assert_equal(".\n.\n", capture_output{cls.foo(2)})
607
+
608
+ cls, = compile(
609
+ 'def foo(a:fixnum);until a <= 0; a -= 1; puts ".";end;end')
610
+ assert_equal('', capture_output{cls.foo(0)})
611
+ assert_equal(".\n", capture_output{cls.foo(1)})
612
+ assert_equal(".\n.\n", capture_output{cls.foo(2)})
613
+
614
+ cls, = compile(
615
+ 'def foo(a:fixnum);begin;a -= 1; puts ".";end until a <= 0;end')
616
+ assert_equal(".\n", capture_output{cls.foo(0)})
617
+ assert_equal(".\n", capture_output{cls.foo(1)})
618
+ assert_equal(".\n.\n", capture_output{cls.foo(2)})
619
+
620
+ cls, = compile(
621
+ 'def foo; a = 0; while a < 2; a+=1; end; end')
622
+ assert_equal(nil, cls.foo)
623
+ end
624
+
625
+ def test_break
626
+ cls, = compile <<-EOF
627
+ def foo
628
+ count = 0
629
+ while count < 5
630
+ count += 1
631
+ break if count == 1
632
+ end
633
+ count
634
+ end
635
+ EOF
636
+ assert_equal(1, cls.foo)
637
+
638
+ cls, = compile <<-EOF
639
+ def foo
640
+ a = 0
641
+ b = 0
642
+ while a < 2
643
+ a += 1
644
+ while b < 5
645
+ b += 1
646
+ break if b > 0
647
+ end
648
+ break if a == 1
649
+ end
650
+ a * 100 + b
651
+ end
652
+ EOF
653
+ assert_equal(101, cls.foo)
654
+
655
+ cls, = compile <<-EOF
656
+ def foo
657
+ count = 0
658
+ begin
659
+ count += 1
660
+ break if count == 1
661
+ end while count < 5
662
+ count
663
+ end
664
+ EOF
665
+ assert_equal(1, cls.foo)
666
+ end
667
+
668
+ def test_next
669
+ cls, = compile <<-EOF
670
+ def foo
671
+ values = int[3]
672
+ i = 0
673
+ while i < 3
674
+ i += 1
675
+ next if i == 2
676
+ values[i - 1] = i
677
+ end
678
+ values
679
+ end
680
+ EOF
681
+ assert_equal([1, 0, 3], cls.foo.to_a)
682
+
683
+ cls, = compile <<-EOF
684
+ def foo
685
+ i = 0
686
+ while i < 5
687
+ i += 1
688
+ next if i == 5
689
+ end
690
+ i
691
+ end
692
+ EOF
693
+ assert_equal(5, cls.foo)
694
+
695
+ cls, = compile <<-EOF
696
+ def foo
697
+ values = int[3]
698
+ a = 0
699
+ b = 0
700
+ while a < 3
701
+ b = 0
702
+ while b < 5
703
+ b += 1
704
+ next if b == a + 1
705
+ # values[a] += b # TODO
706
+ values[a] = values[a] + b
707
+ end
708
+ a += 1
709
+ next if a == 2
710
+ values[a - 1] = values[a - 1] + a * 100
711
+ end
712
+ values
713
+ end
714
+ EOF
715
+ assert_equal([114, 13, 312], cls.foo.to_a)
716
+
717
+ cls, = compile <<-EOF
718
+ def foo
719
+ count = 0
720
+ sum = 0
721
+ begin
722
+ count += 1
723
+ next if count == 2
724
+ sum += count
725
+ next if count == 5
726
+ end while count < 5
727
+ count * 100 + sum
728
+ end
729
+ EOF
730
+ assert_equal(513, cls.foo)
731
+ end
732
+
733
+ def test_redo
734
+ cls, = compile <<-EOF
735
+ def foo
736
+ i = 0
737
+ while i < 5
738
+ i += 1
739
+ redo if i == 5
740
+ end
741
+ i
742
+ end
743
+ EOF
744
+ assert_equal(6, cls.foo)
745
+
746
+ cls, = compile <<-EOF
747
+ def foo
748
+ values = int[4]
749
+ a = 0
750
+ b = 0
751
+ while a < 3
752
+ b = a
753
+ while b < 5
754
+ b += 1
755
+ redo if b == 5
756
+ values[a] = values[a] + b
757
+ end
758
+ a += 1
759
+ values[a - 1] = values[a - 1] + a * 100
760
+ redo if a == 3
761
+ end
762
+ values
763
+ end
764
+ EOF
765
+ assert_equal([116, 215, 313, 410], cls.foo.to_a)
766
+
767
+ cls, = compile <<-EOF
768
+ def foo
769
+ i = 0
770
+ begin
771
+ i += 1
772
+ redo if i == 5
773
+ end while i < 5
774
+ i
775
+ end
776
+ EOF
777
+ assert_equal(6, cls.foo)
778
+ end
779
+
780
+ def test_fields
781
+ cls, = compile(<<-EOF)
782
+ class FieldTest
783
+ def initialize(a:fixnum)
784
+ @a = a
785
+ end
786
+
787
+ def a
788
+ @a
789
+ end
790
+ end
791
+ EOF
792
+ first = cls.new(1)
793
+ assert_equal(1, first.a)
794
+
795
+ second = cls.new(2)
796
+ assert_equal(1, first.a)
797
+ assert_equal(2, second.a)
798
+ end
799
+
800
+ def test_object_intrinsics
801
+ cls, = compile(<<-EOF)
802
+ import 'java.lang.Object'
803
+ def nil(a:Object)
804
+ a.nil?
805
+ end
806
+
807
+ def equal(a:Object, b:Object)
808
+ a == b
809
+ end
810
+ EOF
811
+
812
+ assert(cls.nil(nil))
813
+ assert(!cls.nil("abc"))
814
+
815
+ a = "foobar".to_java_string
816
+ b = java.lang.Object.new
817
+ assert(cls.equal(a, a))
818
+ assert(cls.equal(b, b))
819
+ assert(!cls.equal(a, b))
820
+ end
821
+
822
+ def test_implements
823
+ script, cls = compile(<<-EOF)
824
+ import java.lang.Iterable
825
+ class Foo; implements Iterable
826
+ def iterator
827
+ nil
828
+ end
829
+ end
830
+ EOF
831
+
832
+ assert_include java.lang.Iterable.java_class, cls.java_class.interfaces
833
+ end
834
+
835
+ def test_argument_widening
836
+ cls, = compile(<<-EOF)
837
+ def _Byte(a:byte)
838
+ _Short(a)
839
+ end
840
+
841
+ def _Short(a:short)
842
+ _Int(a)
843
+ end
844
+
845
+ def _Int(a:int)
846
+ _Long(a)
847
+ end
848
+
849
+ def _Long(a:long)
850
+ _Float(a)
851
+ end
852
+
853
+ def _Float(a:float)
854
+ _Double(a)
855
+ end
856
+
857
+ def _Double(a:double)
858
+ a
859
+ end
860
+ EOF
861
+
862
+ assert_equal(1.0, cls._Byte(1))
863
+ assert_equal(127.0, cls._Byte(127))
864
+ assert_equal(128.0, cls._Short(128))
865
+ assert_equal(32767.0, cls._Short(32767))
866
+ assert_equal(32768.0, cls._Int(32768))
867
+ assert_equal(2147483648.0, cls._Long(2147483648))
868
+ end
869
+
870
+ def test_interface_declaration
871
+ script, interface = compile('interface A do; end')
872
+ assert(interface.java_class.interface?)
873
+ assert_equal('A', interface.java_class.name)
874
+
875
+ script, a, b = compile('interface A do; end; interface B < A do; end')
876
+ assert_include(a, b.ancestors)
877
+ assert_equal('A', a.java_class.name)
878
+ assert_equal('B', b.java_class.name)
879
+
880
+ script, a, b, c = compile(<<-EOF)
881
+ interface A do
882
+ end
883
+
884
+ interface B do
885
+ end
886
+
887
+ interface C < A, B do
888
+ end
889
+ EOF
890
+
891
+ assert_include(a, c.ancestors)
892
+ assert_include(b, c.ancestors)
893
+ assert_equal('A', a.java_class.name)
894
+ assert_equal('B', b.java_class.name)
895
+ assert_equal('C', c.java_class.name)
896
+
897
+ assert_raise Duby::Typer::InferenceError do
898
+ compile(<<-EOF)
899
+ interface A do
900
+ def a
901
+ returns :int
902
+ end
903
+ end
904
+
905
+ class Impl; implements A
906
+ def a
907
+ "foo"
908
+ end
909
+ end
910
+ EOF
911
+ end
912
+ end
913
+
914
+ def assert_throw(type, message=nil)
915
+ ex = assert_raise(NativeException) do
916
+ yield
917
+ end
918
+ assert_equal type, ex.cause.class
919
+ assert_equal message, ex.cause.message
920
+ end
921
+
922
+ def test_raise
923
+ cls, = compile(<<-EOF)
924
+ def foo
925
+ raise
926
+ end
927
+ EOF
928
+ assert_throw(java.lang.RuntimeException) do
929
+ cls.foo
930
+ end
931
+
932
+ cls, = compile(<<-EOF)
933
+ def foo
934
+ raise "Oh no!"
935
+ end
936
+ EOF
937
+ ex = assert_throw(java.lang.RuntimeException, 'Oh no!') do
938
+ cls.foo
939
+ end
940
+
941
+ cls, = compile(<<-EOF)
942
+ def foo
943
+ raise IllegalArgumentException
944
+ end
945
+ EOF
946
+ ex = assert_throw(java.lang.IllegalArgumentException) do
947
+ cls.foo
948
+ end
949
+
950
+ cls, = compile(<<-EOF)
951
+ def foo
952
+ throws Exception
953
+ raise Exception, "oops"
954
+ end
955
+ EOF
956
+ ex = assert_throw(java.lang.Exception, "oops") do
957
+ cls.foo
958
+ end
959
+
960
+ cls, = compile(<<-EOF)
961
+ def foo
962
+ throws Throwable
963
+ raise Throwable.new("darn")
964
+ end
965
+ EOF
966
+ ex = assert_throw(java.lang.Throwable, "darn") do
967
+ cls.foo
968
+ end
969
+ end
970
+
971
+ def test_rescue
972
+ cls, = compile(<<-EOF)
973
+ def foo
974
+ begin
975
+ puts "body"
976
+ rescue
977
+ puts "rescue"
978
+ end
979
+ end
980
+ EOF
981
+
982
+ output = capture_output do
983
+ cls.foo
984
+ end
985
+ assert_equal("body\n", output)
986
+
987
+ cls, = compile(<<-EOF)
988
+ def foo
989
+ begin
990
+ puts "body"
991
+ raise
992
+ rescue
993
+ puts "rescue"
994
+ end
995
+ end
996
+ EOF
997
+
998
+ output = capture_output do
999
+ cls.foo
1000
+ end
1001
+ assert_equal("body\nrescue\n", output)
1002
+
1003
+ cls, = compile(<<-EOF)
1004
+ def foo(a:int)
1005
+ begin
1006
+ puts "body"
1007
+ if a == 0
1008
+ raise IllegalArgumentException
1009
+ else
1010
+ raise
1011
+ end
1012
+ rescue IllegalArgumentException
1013
+ puts "IllegalArgumentException"
1014
+ rescue
1015
+ puts "rescue"
1016
+ end
1017
+ end
1018
+ EOF
1019
+
1020
+ output = capture_output do
1021
+ cls.foo(1)
1022
+ cls.foo(0)
1023
+ end
1024
+ assert_equal("body\nrescue\nbody\nIllegalArgumentException\n", output)
1025
+
1026
+ cls, = compile(<<-EOF)
1027
+ def foo(a:int)
1028
+ begin
1029
+ puts "body"
1030
+ if a == 0
1031
+ raise IllegalArgumentException
1032
+ elsif a == 1
1033
+ raise Throwable
1034
+ else
1035
+ raise
1036
+ end
1037
+ rescue IllegalArgumentException, RuntimeException
1038
+ puts "multi"
1039
+ rescue Throwable
1040
+ puts "other"
1041
+ end
1042
+ end
1043
+ EOF
1044
+
1045
+ output = capture_output do
1046
+ cls.foo(0)
1047
+ cls.foo(1)
1048
+ cls.foo(2)
1049
+ end
1050
+ assert_equal("body\nmulti\nbody\nother\nbody\nmulti\n", output)
1051
+
1052
+ cls, = compile(<<-EOF)
1053
+ def foo
1054
+ begin
1055
+ raise "foo"
1056
+ rescue => ex
1057
+ puts ex.getMessage
1058
+ end
1059
+ end
1060
+ EOF
1061
+
1062
+ output = capture_output do
1063
+ cls.foo
1064
+ end
1065
+ assert_equal("foo\n", output)
1066
+ end
1067
+
1068
+ def test_ensure
1069
+ cls, = compile(<<-EOF)
1070
+ def foo
1071
+ 1
1072
+ ensure
1073
+ puts "Hi"
1074
+ end
1075
+ EOF
1076
+ output = capture_output do
1077
+ assert_equal(1, cls.foo)
1078
+ end
1079
+ assert_equal "Hi\n", output
1080
+
1081
+ cls, = compile(<<-EOF)
1082
+ def foo
1083
+ return 1
1084
+ ensure
1085
+ puts "Hi"
1086
+ end
1087
+ EOF
1088
+ output = capture_output do
1089
+ assert_equal(1, cls.foo)
1090
+ end
1091
+ assert_equal "Hi\n", output
1092
+
1093
+ cls, = compile(<<-EOF)
1094
+ def foo
1095
+ begin
1096
+ break
1097
+ ensure
1098
+ puts "Hi"
1099
+ end while false
1100
+ end
1101
+ EOF
1102
+ output = capture_output do
1103
+ cls.foo
1104
+ end
1105
+ assert_equal "Hi\n", output
1106
+
1107
+ end
1108
+
1109
+ def test_cast
1110
+ cls, = compile(<<-EOF)
1111
+ def f2b; byte(1.0); end
1112
+ def f2s; short(1.0); end
1113
+ def f2c; char(1.0); end
1114
+ def f2i; int(1.0); end
1115
+ def f2l; long(1.0); end
1116
+ def f2d; int(1.0); end
1117
+
1118
+ def i2b; byte(1); end
1119
+ def i2s; short(1); end
1120
+ def i2c; char(1); end
1121
+ def i2l; long(1); end
1122
+ def i2f; float(1); end
1123
+ def i2d; int(1); end
1124
+
1125
+ def b2s; short(byte(1)); end
1126
+ def b2c; char(byte(1)); end
1127
+ def b2i; int(byte(1)); end
1128
+ def b2l; long(byte(1)); end
1129
+ def b2f; float(byte(1)); end
1130
+ def b2d; double(byte(1)); end
1131
+
1132
+ def s2b; byte(short(1)); end
1133
+ def s2c; char(short(1)); end
1134
+ def s2i; int(short(1)); end
1135
+ def s2l; long(short(1)); end
1136
+ def s2f; float(short(1)); end
1137
+ def s2d; double(short(1)); end
1138
+
1139
+ def c2b; byte(char(1)); end
1140
+ def c2s; short(char(1)); end
1141
+ def c2i; int(char(1)); end
1142
+ def c2l; long(char(1)); end
1143
+ def c2f; float(char(1)); end
1144
+ def c2d; double(char(1)); end
1145
+
1146
+ def l2b; byte(long(1)); end
1147
+ def l2c; char(long(1)); end
1148
+ def l2i; int(long(1)); end
1149
+ def l2l; long(long(1)); end
1150
+ def l2f; float(long(1)); end
1151
+ def l2d; double(long(1)); end
1152
+
1153
+ def d2b; byte(1.0); end
1154
+ def d2s; short(1.0); end
1155
+ def d2c; char(1.0); end
1156
+ def d2i; int(1.0); end
1157
+ def d2l; long(1.0); end
1158
+ def d2f; float(1.0); end
1159
+
1160
+ def hard_i2f(a:int)
1161
+ float(if a < 0
1162
+ a *= -1
1163
+ a * 2
1164
+ else
1165
+ a * 2
1166
+ end)
1167
+ end
1168
+ EOF
1169
+
1170
+ assert_equal 1, cls.b2s
1171
+ assert_equal 1, cls.b2c
1172
+ assert_equal 1, cls.b2i
1173
+ assert_equal 1, cls.b2l
1174
+ assert_equal 1.0, cls.b2f
1175
+ assert_equal 1.0, cls.b2d
1176
+
1177
+ assert_equal 1, cls.s2b
1178
+ assert_equal 1, cls.s2c
1179
+ assert_equal 1, cls.s2i
1180
+ assert_equal 1, cls.s2l
1181
+ assert_equal 1.0, cls.s2f
1182
+ assert_equal 1.0, cls.s2d
1183
+
1184
+ assert_equal 1, cls.c2b
1185
+ assert_equal 1, cls.c2s
1186
+ assert_equal 1, cls.c2i
1187
+ assert_equal 1, cls.c2l
1188
+ assert_equal 1.0, cls.c2f
1189
+ assert_equal 1.0, cls.c2d
1190
+
1191
+ assert_equal 1, cls.i2b
1192
+ assert_equal 1, cls.i2s
1193
+ assert_equal 1, cls.i2c
1194
+ assert_equal 1, cls.i2l
1195
+ assert_equal 1.0, cls.i2f
1196
+ assert_equal 1.0, cls.i2d
1197
+
1198
+ assert_equal 1, cls.f2b
1199
+ assert_equal 1, cls.f2s
1200
+ assert_equal 1, cls.f2c
1201
+ assert_equal 1, cls.f2i
1202
+ assert_equal 1, cls.f2l
1203
+ assert_equal 1.0, cls.f2d
1204
+
1205
+ assert_equal 1, cls.d2b
1206
+ assert_equal 1, cls.d2s
1207
+ assert_equal 1, cls.d2c
1208
+ assert_equal 1, cls.d2i
1209
+ assert_equal 1, cls.d2l
1210
+ assert_equal 1.0, cls.d2f
1211
+
1212
+ assert_equal 2.0, cls.hard_i2f(1)
1213
+ assert_equal 4.0, cls.hard_i2f(-2)
1214
+ end
1215
+
1216
+ def test_set
1217
+ cls, = compile(<<-EOF)
1218
+ def foo
1219
+ @foo
1220
+ end
1221
+
1222
+ def foo=(foo:int)
1223
+ @foo = foo
1224
+ end
1225
+ EOF
1226
+
1227
+ assert_equal(0, cls.foo)
1228
+ assert_equal(2, cls.foo_set(2))
1229
+ assert_equal(2, cls.foo)
1230
+ end
1231
+
1232
+ def test_null_is_false
1233
+ cls, = compile("def foo(a:String);if a;true;else;false;end;end")
1234
+ assert_equal(true, cls.foo("a"))
1235
+ assert_equal(false, cls.foo(nil))
1236
+ end
1237
+
1238
+ def test_for
1239
+ cls, = compile(<<-EOF)
1240
+ def foo
1241
+ a = int[3]
1242
+ count = 0
1243
+ for x in a
1244
+ count += 1
1245
+ end
1246
+ count
1247
+ end
1248
+ EOF
1249
+
1250
+ cls, = compile(<<-EOF)
1251
+ def foo(a:int[])
1252
+ count = 0
1253
+ for x in a
1254
+ count += x
1255
+ end
1256
+ count
1257
+ end
1258
+ EOF
1259
+
1260
+ assert_equal(9, cls.foo([2, 3, 4].to_java(:int)))
1261
+
1262
+ cls, = compile(<<-EOF)
1263
+ def foo(a:Iterable)
1264
+ a.each do |x|
1265
+ puts x
1266
+ end
1267
+ end
1268
+ EOF
1269
+
1270
+ assert_output("1\n2\n3\n") do
1271
+ list = java.util.ArrayList.new
1272
+ list << "1"
1273
+ list << "2"
1274
+ list << "3"
1275
+ cls.foo(list)
1276
+ end
1277
+
1278
+ cls, = compile(<<-EOF)
1279
+ import java.util.ArrayList
1280
+ def foo(a:ArrayList)
1281
+ a.each do |x|
1282
+ puts x
1283
+ end
1284
+ end
1285
+ EOF
1286
+
1287
+ assert_output("1\n2\n3\n") do
1288
+ list = java.util.ArrayList.new
1289
+ list << "1"
1290
+ list << "2"
1291
+ list << "3"
1292
+ cls.foo(list)
1293
+ end
1294
+
1295
+ cls, = compile(<<-EOF)
1296
+ def foo(a:int[])
1297
+ a.each {|x| x += 1;puts x; redo if x == 2}
1298
+ end
1299
+ EOF
1300
+
1301
+ assert_output("2\n3\n3\n4\n") do
1302
+ cls.foo([1,2,3].to_java(:int))
1303
+ end
1304
+ end
1305
+
1306
+ def test_all
1307
+ cls, = compile(<<-EOF)
1308
+ def foo(a:int[])
1309
+ a.all? {|x| x % 2 == 0}
1310
+ end
1311
+ EOF
1312
+
1313
+ assert_equal(false, cls.foo([2, 3, 4].to_java(:int)))
1314
+ assert_equal(true, cls.foo([2, 0, 4].to_java(:int)))
1315
+
1316
+ cls, = compile(<<-EOF)
1317
+ def foo(a:String[])
1318
+ a.all?
1319
+ end
1320
+ EOF
1321
+
1322
+ assert_equal(true, cls.foo(["a", "", "b"].to_java(:string)))
1323
+ assert_equal(false, cls.foo(["a", nil, "b"].to_java(:string)))
1324
+ end
1325
+
1326
+ def test_downto
1327
+ cls, = compile(<<-EOF)
1328
+ def foo(i:int)
1329
+ i.downto(1) {|x| puts x }
1330
+ end
1331
+ EOF
1332
+
1333
+ assert_output("3\n2\n1\n") do
1334
+ cls.foo(3)
1335
+ end
1336
+ end
1337
+
1338
+ def test_upto
1339
+ cls, = compile(<<-EOF)
1340
+ def foo(i:int)
1341
+ i.upto(3) {|x| puts x }
1342
+ end
1343
+ EOF
1344
+
1345
+ assert_output("1\n2\n3\n") do
1346
+ cls.foo(1)
1347
+ end
1348
+ end
1349
+
1350
+ def test_times
1351
+ cls, = compile(<<-EOF)
1352
+ def foo(i:int)
1353
+ i.times {|x| puts x }
1354
+ end
1355
+ EOF
1356
+
1357
+ assert_output("0\n1\n2\n") do
1358
+ cls.foo(3)
1359
+ end
1360
+
1361
+ cls, = compile(<<-EOF)
1362
+ def foo(i:int)
1363
+ i.times { puts "Hi" }
1364
+ end
1365
+ EOF
1366
+
1367
+ assert_output("Hi\nHi\nHi\n") do
1368
+ cls.foo(3)
1369
+ end
1370
+ end
1371
+
1372
+ def test_general_loop
1373
+ cls, = compile(<<-EOF)
1374
+ def foo(x:boolean)
1375
+ a = ""
1376
+ __gloop__(nil, x, true, nil, nil) {a += "<body>"}
1377
+ a
1378
+ end
1379
+ EOF
1380
+ assert_equal("", cls.foo(false))
1381
+
1382
+ cls, = compile(<<-EOF)
1383
+ def foo
1384
+ a = ""
1385
+ __gloop__(nil, false, false, nil, nil) {a += "<body>"}
1386
+ a
1387
+ end
1388
+ EOF
1389
+ assert_equal("<body>", cls.foo)
1390
+
1391
+ cls, = compile(<<-EOF)
1392
+ def foo(x:boolean)
1393
+ a = ""
1394
+ __gloop__(a += "<init>", x, true, a += "<pre>", a += "<post>") do
1395
+ a += "<body>"
1396
+ end
1397
+ a
1398
+ end
1399
+ EOF
1400
+ assert_equal("<init>", cls.foo(false))
1401
+
1402
+ cls, = compile(<<-EOF)
1403
+ def foo
1404
+ a = ""
1405
+ __gloop__(a += "<init>", false, false, a += "<pre>", a += "<post>") do
1406
+ a += "<body>"
1407
+ end
1408
+ a
1409
+ end
1410
+ EOF
1411
+ assert_equal("<init><pre><body><post>", cls.foo)
1412
+
1413
+ cls, = compile(<<-EOF)
1414
+ def foo
1415
+ a = ""
1416
+ __gloop__(a += "<init>", false, false, a += "<pre>", a += "<post>") do
1417
+ a += "<body>"
1418
+ redo if a.length < 20
1419
+ end
1420
+ a
1421
+ end
1422
+ EOF
1423
+ assert_equal( "<init><pre><body><body><post>", cls.foo)
1424
+
1425
+ cls, = compile(<<-EOF)
1426
+ def foo
1427
+ a = ""
1428
+ __gloop__(a += "<init>", a.length < 20, true, a += "<pre>", a += "<post>") do
1429
+ next if a.length < 17
1430
+ a += "<body>"
1431
+ end
1432
+ a
1433
+ end
1434
+ EOF
1435
+ assert_equal("<init><pre><post><pre><body><post>", cls.foo)
1436
+ end
1437
+
1438
+ def test_if_expr
1439
+ cls, = compile(<<-EOF)
1440
+ def foo(a:int)
1441
+ return 1 if a == 1
1442
+ end
1443
+
1444
+ def bar(a:int)
1445
+ return 1 unless a == 1
1446
+ end
1447
+ EOF
1448
+
1449
+ assert_equal(0, cls.foo(0))
1450
+ assert_equal(1, cls.foo(1))
1451
+ assert_equal(1, cls.bar(0))
1452
+ assert_equal(0, cls.bar(1))
1453
+ end
1454
+
1455
+ def test_and
1456
+ cls, = compile(<<-EOF)
1457
+ def bool(n:String, x:boolean)
1458
+ puts n
1459
+ x
1460
+ end
1461
+
1462
+ def foo(a:boolean, b:boolean)
1463
+ return bool('a', a) && bool('b', b)
1464
+ end
1465
+
1466
+ def str(n:String, x:String)
1467
+ puts n
1468
+ x
1469
+ end
1470
+
1471
+ def bar(a:String, b:String)
1472
+ return str('a', a) && str('b', b)
1473
+ end
1474
+ EOF
1475
+
1476
+ assert_output("a\n") { assert_equal(false, cls.foo(false, true)) }
1477
+ assert_output("a\nb\n") { assert_equal(false, cls.foo(true, false)) }
1478
+ assert_output("a\nb\n") { assert_equal(true, cls.foo(true, true)) }
1479
+
1480
+ assert_output("a\n") { assert_equal(nil, cls.bar(nil, "B")) }
1481
+ assert_output("a\nb\n") { assert_equal(nil, cls.bar("A", nil)) }
1482
+ assert_output("a\nb\n") { assert_equal("B", cls.bar("A", "B")) }
1483
+
1484
+ cls, = compile(<<-EOF)
1485
+ def s
1486
+ @s
1487
+ end
1488
+
1489
+ def s=(s:String)
1490
+ @s = s
1491
+ end
1492
+
1493
+ def b
1494
+ @b
1495
+ end
1496
+
1497
+ def b=(b:boolean)
1498
+ @b = b
1499
+ end
1500
+
1501
+ def foo(x:boolean)
1502
+ @b &&= x
1503
+ end
1504
+
1505
+ def bar(x:String)
1506
+ @s &&= x
1507
+ end
1508
+ EOF
1509
+
1510
+ cls.b_set(false)
1511
+ assert_equal(false, cls.foo(false))
1512
+ assert_equal(false, cls.b)
1513
+
1514
+ cls.b_set(true)
1515
+ assert_equal(false, cls.foo(false))
1516
+ assert_equal(false, cls.b)
1517
+
1518
+ cls.b_set(true)
1519
+ assert_equal(true, cls.foo(true))
1520
+ assert_equal(true, cls.b)
1521
+
1522
+ cls.s_set(nil)
1523
+ assert_equal(nil, cls.bar(nil))
1524
+ assert_equal(nil, cls.s)
1525
+
1526
+ cls.s_set("S")
1527
+ assert_equal(nil, cls.bar(nil))
1528
+ assert_equal(nil, cls.s)
1529
+
1530
+ cls.s_set("S")
1531
+ assert_equal("x", cls.bar("x"))
1532
+ assert_equal("x", cls.s)
1533
+
1534
+ foo, = compile(<<-EOF)
1535
+ class Foo2
1536
+ def initialize
1537
+ @count = 0
1538
+ end
1539
+
1540
+ def count
1541
+ @count
1542
+ end
1543
+
1544
+ def a
1545
+ @a
1546
+ end
1547
+
1548
+ def a=(a:String)
1549
+ @count += 1
1550
+ @a = a
1551
+ end
1552
+
1553
+ def foo(f:Foo2, x:String)
1554
+ f.a &&= x
1555
+ end
1556
+ end
1557
+ EOF
1558
+
1559
+ f = foo.new
1560
+ assert_equal(nil, f.foo(f, 'x'))
1561
+ assert_equal(0, f.count)
1562
+
1563
+ f = foo.new
1564
+ f.a_set("A")
1565
+ assert_equal(nil, f.foo(f, nil))
1566
+ assert_equal(2, f.count)
1567
+
1568
+ f = foo.new
1569
+ f.a_set("A")
1570
+ assert_equal('x', f.foo(f, 'x'))
1571
+ assert_equal(2, f.count)
1572
+ end
1573
+
1574
+ def test_or
1575
+ cls, = compile(<<-EOF)
1576
+ def bool(n:String, x:boolean)
1577
+ puts n
1578
+ x
1579
+ end
1580
+
1581
+ def foo(a:boolean, b:boolean)
1582
+ return bool('a', a) || bool('b', b)
1583
+ end
1584
+
1585
+ def str(n:String, x:String)
1586
+ puts n
1587
+ x
1588
+ end
1589
+
1590
+ def bar(a:String, b:String)
1591
+ return str('a', a) || str('b', b)
1592
+ end
1593
+ EOF
1594
+
1595
+ assert_output("a\n") { assert_equal(true, cls.foo(true, false)) }
1596
+ assert_output("a\nb\n") { assert_equal(false, cls.foo(false, false)) }
1597
+ assert_output("a\nb\n") { assert_equal(true, cls.foo(false, true)) }
1598
+
1599
+ assert_output("a\n") { assert_equal("A", cls.bar("A", nil)) }
1600
+ assert_output("a\nb\n") { assert_equal(nil, cls.bar(nil, nil)) }
1601
+ assert_output("a\nb\n") { assert_equal("B", cls.bar(nil, "B")) }
1602
+
1603
+ cls, = compile(<<-EOF)
1604
+ def s
1605
+ @s
1606
+ end
1607
+
1608
+ def s=(s:String)
1609
+ @s = s
1610
+ end
1611
+
1612
+ def b
1613
+ @b
1614
+ end
1615
+
1616
+ def b=(b:boolean)
1617
+ @b = b
1618
+ end
1619
+
1620
+ def foo(x:boolean)
1621
+ @b ||= x
1622
+ end
1623
+
1624
+ def bar(x:String)
1625
+ @s ||= x
1626
+ end
1627
+ EOF
1628
+
1629
+ cls.b_set(false)
1630
+ assert_equal(false, cls.foo(false))
1631
+ assert_equal(false, cls.b)
1632
+
1633
+ cls.b_set(false)
1634
+ assert_equal(true, cls.foo(true))
1635
+ assert_equal(true, cls.b)
1636
+
1637
+ cls.b_set(true)
1638
+ assert_equal(true, cls.foo(false))
1639
+ assert_equal(true, cls.b)
1640
+
1641
+ cls.s_set(nil)
1642
+ assert_equal(nil, cls.bar(nil))
1643
+ assert_equal(nil, cls.s)
1644
+
1645
+ cls.s_set(nil)
1646
+ assert_equal("x", cls.bar("x"))
1647
+ assert_equal("x", cls.s)
1648
+
1649
+ cls.s_set("S")
1650
+ assert_equal("S", cls.bar("x"))
1651
+ assert_equal("S", cls.s)
1652
+
1653
+ foo, = compile(<<-EOF)
1654
+ class Foo3
1655
+ def initialize
1656
+ @count = 0
1657
+ end
1658
+
1659
+ def count
1660
+ @count
1661
+ end
1662
+
1663
+ def a
1664
+ @a
1665
+ end
1666
+
1667
+ def a=(a:String)
1668
+ @count += 1
1669
+ @a = a
1670
+ end
1671
+
1672
+ def foo(f:Foo3, x:String)
1673
+ f.a ||= x
1674
+ end
1675
+ end
1676
+ EOF
1677
+
1678
+ f = foo.new
1679
+ assert_equal('x', f.foo(f, 'x'))
1680
+ assert_equal(1, f.count)
1681
+
1682
+ f = foo.new
1683
+ assert_equal(nil, f.foo(f, nil))
1684
+ assert_equal(1, f.count)
1685
+
1686
+ f = foo.new
1687
+ f.a_set("A")
1688
+ assert_equal("A", f.foo(f, nil))
1689
+ assert_equal(1, f.count)
1690
+
1691
+ f = foo.new
1692
+ f.a_set("A")
1693
+ assert_equal("A", f.foo(f, 'X'))
1694
+ assert_equal(1, f.count)
1695
+ end
1696
+
1697
+ def test_op_elem_assign
1698
+ foo, = compile(<<-EOF)
1699
+ class Foo4
1700
+ def initialize
1701
+ @i = -1
1702
+ end
1703
+
1704
+ def i
1705
+ @i += 1
1706
+ end
1707
+
1708
+ def a
1709
+ @a
1710
+ end
1711
+
1712
+ def a=(a:String[])
1713
+ @a = a
1714
+ end
1715
+
1716
+ def foo(x:String)
1717
+ a[i] ||= x
1718
+ end
1719
+
1720
+ def bar(x:String)
1721
+ a[i] &&= x
1722
+ end
1723
+ end
1724
+ EOF
1725
+
1726
+ f = foo.new
1727
+ f.a_set([nil, nil, nil].to_java(:string))
1728
+ assert_equal(nil, f.bar("x"))
1729
+ assert_equal([nil, nil, nil], f.a.to_a)
1730
+ assert_equal("x", f.foo("x"))
1731
+ assert_equal([nil, "x", nil], f.a.to_a)
1732
+ end
1733
+
1734
+ def test_constructor_chaining
1735
+ foo, = compile(<<-EOF)
1736
+ class Foo5
1737
+ def initialize(s:String)
1738
+ initialize(s, "foo")
1739
+ end
1740
+
1741
+ def initialize(s:String, f:String)
1742
+ @s = s
1743
+ @f = f
1744
+ end
1745
+
1746
+ def f
1747
+ @f
1748
+ end
1749
+
1750
+ def s
1751
+ @s
1752
+ end
1753
+ end
1754
+ EOF
1755
+
1756
+ instance = foo.new("S")
1757
+ assert_equal("S", instance.s)
1758
+ assert_equal("foo", instance.f)
1759
+
1760
+ instance = foo.new("foo", "bar")
1761
+ assert_equal("foo", instance.s)
1762
+ assert_equal("bar", instance.f)
1763
+ end
1764
+
1765
+ def test_super_constructor
1766
+ cls, a, b = compile(<<-EOF)
1767
+ class SC_A
1768
+ def initialize(a:int)
1769
+ puts "A"
1770
+ end
1771
+ end
1772
+
1773
+ class SC_B < SC_A
1774
+ def initialize
1775
+ super(0)
1776
+ puts "B"
1777
+ end
1778
+ end
1779
+ EOF
1780
+
1781
+ assert_output("A\nB\n") do
1782
+ b.new
1783
+ end
1784
+ end
1785
+
1786
+ def test_literal_array
1787
+ cls, = compile(<<-EOF)
1788
+ def foo; puts "hello"; nil; end
1789
+ def expr
1790
+ [foo]
1791
+ end
1792
+ def nonexpr
1793
+ [foo]
1794
+ nil
1795
+ end
1796
+ EOF
1797
+
1798
+ assert_output("hello\nhello\n") do
1799
+ val = cls.expr
1800
+ assert val
1801
+
1802
+ val = cls.nonexpr
1803
+ assert !val
1804
+ end
1805
+ end
1806
+
1807
+ def test_literal_regexp
1808
+ cls, = compile(<<-EOF)
1809
+ def expr
1810
+ /foo/
1811
+ end
1812
+ def matches
1813
+ expr.matcher('barfoobaz').find
1814
+ end
1815
+ EOF
1816
+
1817
+ val = cls.expr
1818
+ assert_equal java.util.regex.Pattern, val.class
1819
+ assert_equal 'foo', val.to_s
1820
+
1821
+ assert cls.matches
1822
+ end
1823
+
1824
+ def test_array_return_type
1825
+ cls, = compile(<<-EOF)
1826
+ def split
1827
+ /foo/.split('barfoobaz')
1828
+ end
1829
+ def puts
1830
+ puts split
1831
+ end
1832
+ EOF
1833
+
1834
+ assert_nothing_raised do
1835
+ result = capture_output {cls.puts}
1836
+ assert result =~ /\[Ljava\.lang\.String;@[a-f0-9]+/
1837
+ end
1838
+ assert_equal java.lang.String.java_class.array_class, cls.split.class.java_class
1839
+ end
1840
+
1841
+ def test_empty_constructor
1842
+ foo, = compile(<<-EOF)
1843
+ class Foo6
1844
+ def initialize; end
1845
+ end
1846
+ EOF
1847
+ foo.new
1848
+ end
1849
+
1850
+ def test_same_field_name
1851
+ cls, = compile(<<-EOF)
1852
+ class A1
1853
+ def foo(bar:String)
1854
+ @bar = bar
1855
+ end
1856
+ end
1857
+
1858
+ class B1
1859
+ def foo(bar:String)
1860
+ @bar = bar
1861
+ end
1862
+ end
1863
+
1864
+ puts A1.new.foo("Hi")
1865
+ puts B1.new.foo("There")
1866
+ EOF
1867
+
1868
+ assert_output("Hi\nThere\n") do
1869
+ cls.main(nil)
1870
+ end
1871
+ end
1872
+
1873
+ def test_annotations
1874
+ deprecated = java.lang.Deprecated.java_class
1875
+ cls, = compile(<<-EOF)
1876
+ $Deprecated
1877
+ def foo
1878
+ 'foo'
1879
+ end
1880
+ EOF
1881
+
1882
+ assert_not_nil cls.java_class.java_method('foo').annotation(deprecated)
1883
+ assert_nil cls.java_class.annotation(deprecated)
1884
+
1885
+ script, cls = compile(<<-EOF)
1886
+ $Deprecated
1887
+ class Annotated
1888
+ end
1889
+ EOF
1890
+ assert_not_nil cls.java_class.annotation(deprecated)
1891
+
1892
+ cls, = compile(<<-EOF)
1893
+ class AnnotatedField
1894
+ def initialize
1895
+ $Deprecated
1896
+ @foo = 1
1897
+ end
1898
+ end
1899
+ EOF
1900
+
1901
+ assert_not_nil cls.java_class.declared_fields[0].annotation(deprecated)
1902
+ end
1903
+
1904
+ def test_super
1905
+ cls, = compile(<<-EOF)
1906
+ class Foo
1907
+ def equals(other:Object); super(other); end
1908
+ end
1909
+ EOF
1910
+
1911
+ obj = cls.new
1912
+ assert obj.equals(obj)
1913
+ assert !obj.equals(cls.new)
1914
+ end
1915
+
1916
+ def test_inexact_constructor
1917
+ # FIXME: this is a stupid test
1918
+ cls, = compile(
1919
+ "class EmptyEmpty; def self.empty_empty; t = Thread.new(Thread.new); t.start; begin; t.join; rescue InterruptedException; end; puts 'ok'; end; end")
1920
+ assert_output("ok\n") do
1921
+ cls.empty_empty
1922
+ end
1923
+ end
1924
+
1925
+ def test_method_lookup_with_overrides
1926
+ cls, = compile(<<-EOF)
1927
+ class Bar; implements Runnable
1928
+ def foo(x:Bar)
1929
+ Thread.new(x)
1930
+ end
1931
+ def run
1932
+ end
1933
+ end
1934
+ EOF
1935
+
1936
+ # Just make sure this compiles.
1937
+ # It shouldn't get confused by the Thread(String) constructor.
1938
+ end
1939
+
1940
+ def test_block
1941
+ cls, = compile(<<-EOF)
1942
+ thread = Thread.new do
1943
+ puts "Hello"
1944
+ end
1945
+ begin
1946
+ thread.run
1947
+ thread.join
1948
+ rescue
1949
+ puts "Uh Oh!"
1950
+ end
1951
+ EOF
1952
+ assert_output("Hello\n") do
1953
+ cls.main([].to_java :string)
1954
+ end
1955
+
1956
+ script, cls = compile(<<-EOF)
1957
+ import java.util.Observable
1958
+ class MyObservable < Observable
1959
+ def initialize
1960
+ super
1961
+ setChanged
1962
+ end
1963
+ end
1964
+
1965
+ o = MyObservable.new
1966
+ o.addObserver {|x, a| puts a}
1967
+ o.notifyObservers("Hello Observer")
1968
+ EOF
1969
+ assert_output("Hello Observer\n") do
1970
+ script.main([].to_java :string)
1971
+ end
1972
+
1973
+ cls, = compile(<<-EOF)
1974
+ def foo
1975
+ a = "Hello"
1976
+ thread = Thread.new do
1977
+ puts a
1978
+ end
1979
+ begin
1980
+ a = a + " Closures"
1981
+ thread.run
1982
+ thread.join
1983
+ rescue
1984
+ puts "Uh Oh!"
1985
+ end
1986
+ return
1987
+ end
1988
+ EOF
1989
+ assert_output("Hello Closures\n") do
1990
+ cls.foo
1991
+ end
1992
+
1993
+ cls, = compile(<<-EOF)
1994
+ def run(x:Runnable)
1995
+ x.run
1996
+ end
1997
+ def foo
1998
+ a = 1
1999
+ run {a += 1}
2000
+ a
2001
+ end
2002
+ EOF
2003
+ assert_equal(2, cls.foo)
2004
+ end
2005
+
2006
+ def test_block_with_method_def
2007
+ cls, = compile(<<-EOF)
2008
+ import java.util.ArrayList
2009
+ import java.util.Collections
2010
+ list = ArrayList.new(["a", "ABC", "Cats", "b"])
2011
+ Collections.sort(list) do
2012
+ def equals(a:Object, b:Object)
2013
+ String(a).equalsIgnoreCase(String(b))
2014
+ end
2015
+ def compare(a:Object, b:Object)
2016
+ String(a).compareToIgnoreCase(String(b))
2017
+ end
2018
+ end
2019
+ list.each {|x| puts x}
2020
+ EOF
2021
+
2022
+ assert_output("a\nABC\nb\nCats\n") do
2023
+ cls.main(nil)
2024
+ end
2025
+ end
2026
+
2027
+ def test_each
2028
+ cls, = compile(<<-EOF)
2029
+ def foo
2030
+ [1,2,3].each {|x| puts x}
2031
+ end
2032
+ EOF
2033
+ assert_output("1\n2\n3\n") do
2034
+ cls.foo
2035
+ end
2036
+ end
2037
+
2038
+ def test_any
2039
+ cls, = compile(<<-EOF)
2040
+ import java.lang.Integer
2041
+ def foo
2042
+ puts [1,2,3].any?
2043
+ puts [1,2,3].any? {|x| Integer(x).intValue > 3}
2044
+ end
2045
+ EOF
2046
+ assert_output("true\nfalse\n") do
2047
+ cls.foo
2048
+ end
2049
+ end
2050
+
2051
+ def test_all
2052
+ cls, = compile(<<-EOF)
2053
+ import java.lang.Integer
2054
+ def foo
2055
+ puts [1,2,3].all?
2056
+ puts [1,2,3].all? {|x| Integer(x).intValue > 3}
2057
+ end
2058
+ EOF
2059
+ assert_output("true\nfalse\n") do
2060
+ cls.foo
2061
+ end
2062
+ end
2063
+
2064
+ def test_optional_args
2065
+ cls, = compile(<<-EOF)
2066
+ def foo(a:int, b:int = 1, c:int = 2)
2067
+ puts a; puts b; puts c
2068
+ end
2069
+ foo(0)
2070
+ foo(0,0)
2071
+ foo(0,0,0)
2072
+ EOF
2073
+ assert_output("0\n1\n2\n0\n0\n2\n0\n0\n0\n") do
2074
+ cls.main([].to_java :string)
2075
+ end
2076
+ end
2077
+
2078
+ def test_field_read
2079
+ cls, = compile(<<-EOF)
2080
+ puts System.out.getClass.getName
2081
+ EOF
2082
+ assert_output("java.io.PrintStream\n") do
2083
+ cls.main([].to_java :String)
2084
+ end
2085
+ end
2086
+
2087
+ def test_array_arguments
2088
+ cls, = compile(<<-EOF)
2089
+ class ArrayArg
2090
+ def initialize(foo:byte[]); end
2091
+
2092
+ def self.make_one(foo:byte[])
2093
+ ArrayArg.new(foo)
2094
+ end
2095
+ end
2096
+ EOF
2097
+ cls.make_one(nil)
2098
+ end
2099
+
2100
+ def test_block_with_duby_interface
2101
+ cls, interface = compile(<<-EOF)
2102
+ interface MyProc do
2103
+ def call; returns :void; end
2104
+ end
2105
+ def foo(b:MyProc)
2106
+ b.call
2107
+ end
2108
+ def bar
2109
+ foo {puts "Hi"}
2110
+ end
2111
+ EOF
2112
+ assert_output("Hi\n") do
2113
+ cls.bar
2114
+ end
2115
+ end
2116
+
2117
+ def test_duby_iterable
2118
+ script, cls = compile(<<-EOF)
2119
+ import java.util.Iterator
2120
+ class MyIterator; implements Iterable, Iterator
2121
+ def initialize(x:Object)
2122
+ @next = x
2123
+ end
2124
+
2125
+ def hasNext
2126
+ @next != nil
2127
+ end
2128
+
2129
+ def next
2130
+ result = @next
2131
+ @next = nil
2132
+ result
2133
+ end
2134
+
2135
+ def iterator
2136
+ self
2137
+ end
2138
+
2139
+ def remove
2140
+ raise UnsupportedOperationException
2141
+ end
2142
+
2143
+ def self.test(x:String)
2144
+ MyIterator.new(x).each {|y| puts y}
2145
+ end
2146
+ end
2147
+ EOF
2148
+ assert_output("Hi\n") do
2149
+ cls.test("Hi")
2150
+ end
2151
+ end
2152
+
2153
+ def test_java_lang_cast
2154
+ cls, = compile(<<-EOF)
2155
+ def foo(a:Object)
2156
+ Integer(a).intValue
2157
+ end
2158
+ EOF
2159
+
2160
+ assert_equal(2, cls.foo(java.lang.Integer.new(2)))
2161
+ end
2162
+
2163
+ def test_array_cast
2164
+ cls, = compile(<<-EOF)
2165
+ def foo(a:Object)
2166
+ bar(String[].cast(a))
2167
+ end
2168
+
2169
+ def bar(a:String[])
2170
+ a[0]
2171
+ end
2172
+ EOF
2173
+
2174
+ assert_equal("foo", cls.foo(["foo", "bar"].to_java(:string)))
2175
+
2176
+ cls, = compile(<<-EOF)
2177
+ def foo(a:Object)
2178
+ bar(int[].cast(a))
2179
+ end
2180
+
2181
+ def bar(a:int[])
2182
+ a[0]
2183
+ end
2184
+ EOF
2185
+
2186
+ assert_equal(2, cls.foo([2, 3].to_java(:int)))
2187
+
2188
+ end
2189
+
2190
+ def test_string_interpolation
2191
+ cls, = compile(<<-EOF)
2192
+ def foo(name:String)
2193
+ print "Hello \#{name}."
2194
+ end
2195
+ EOF
2196
+
2197
+ assert_output("Hello Fred.") do
2198
+ cls.foo "Fred"
2199
+ end
2200
+
2201
+ cls, = compile(<<-EOF)
2202
+ def foo(x:int)
2203
+ print "\#{x += 1}"
2204
+ x
2205
+ end
2206
+ EOF
2207
+
2208
+ assert_output("2") do
2209
+ assert_equal(2, cls.foo(1))
2210
+ end
2211
+
2212
+ cls, = compile(<<-EOF)
2213
+ def foo(a:int)
2214
+ "\#{a += 1}"
2215
+ a
2216
+ end
2217
+ EOF
2218
+ assert_equal(2, cls.foo(1))
2219
+ end
2220
+
2221
+ def test_self_dot_static_methods
2222
+ cls, = compile(<<-EOF)
2223
+ class ClassWithStatics
2224
+ def self.a
2225
+ b
2226
+ end
2227
+ def self.b
2228
+ print "b"
2229
+ end
2230
+ end
2231
+ EOF
2232
+
2233
+ assert_output("b") do
2234
+ cls.a
2235
+ end
2236
+ end
2237
+
2238
+ def test_evaluation_order
2239
+ cls, = compile(<<-EOF)
2240
+ def call(a:int, b:int, c:int)
2241
+ print "\#{a}, \#{b}, \#{c}"
2242
+ end
2243
+
2244
+ def test_call(a:int)
2245
+ call(a, if a < 10;a+=1;a;else;a;end, a)
2246
+ end
2247
+
2248
+ def test_string(a:int)
2249
+ "\#{a}, \#{if a < 10;a += 1;a;else;a;end}, \#{a}"
2250
+ end
2251
+ EOF
2252
+
2253
+ assert_output("1, 2, 2") do
2254
+ cls.test_call(1)
2255
+ end
2256
+
2257
+ assert_equal("2, 3, 3", cls.test_string(2))
2258
+ end
2259
+
2260
+ def test_inner_class
2261
+ cls, = compile(<<-EOF)
2262
+ def foo
2263
+ Character.UnicodeBlock.ARROWS
2264
+ end
2265
+ EOF
2266
+
2267
+ subset = cls.foo
2268
+ assert_equal("java.lang.Character$UnicodeBlock", subset.java_class.name)
2269
+ end
2270
+
2271
+ def test_defmacro
2272
+ cls, = compile(<<-EOF)
2273
+ defmacro bar(x) do
2274
+ x
2275
+ end
2276
+
2277
+ def foo
2278
+ bar("bar")
2279
+ end
2280
+ EOF
2281
+
2282
+ assert_equal("bar", cls.foo)
2283
+ assert(!cls.respond_to?(:bar))
2284
+ end
2285
+
2286
+ def test_default_constructor
2287
+ script, cls = compile(<<-EOF)
2288
+ class DefaultConstructable
2289
+ def foo
2290
+ "foo"
2291
+ end
2292
+ end
2293
+
2294
+ print DefaultConstructable.new.foo
2295
+ EOF
2296
+
2297
+ assert_output("foo") do
2298
+ script.main(nil)
2299
+ end
2300
+ end
2301
+
2302
+ def test_class_literal
2303
+ cls, = compile(<<-EOF)
2304
+ def foo
2305
+ String.class.getName
2306
+ end
2307
+ EOF
2308
+
2309
+ assert_equal("java.lang.String", cls.foo)
2310
+ end
2311
+
2312
+ def test_instanceof
2313
+ cls, = compile(<<-EOF)
2314
+ def string(x:Object)
2315
+ x.kind_of?(String)
2316
+ end
2317
+
2318
+ def dynamic(c:Class, o:Object)
2319
+ o.kind_of?(c)
2320
+ end
2321
+ EOF
2322
+
2323
+ assert_equal(true, cls.string("foo"))
2324
+ assert_equal(false, cls.string(2))
2325
+ assert_equal(true, cls.dynamic(java.lang.String, "foo"))
2326
+ assert_equal(true, cls.dynamic(java.lang.Object, "foo"))
2327
+ assert_equal(false, cls.dynamic(java.lang.Object, nil))
2328
+ end
2329
+
2330
+ def test_instance_macro
2331
+ # TODO fix annotation output and create a duby.anno.Extensions annotation.
2332
+ return if self.class.name == 'TestJavacCompiler'
2333
+ script, cls = compile(<<-EOF)
2334
+ class InstanceMacros
2335
+ def foobar
2336
+ "foobar"
2337
+ end
2338
+
2339
+ macro def macro_foobar
2340
+ quote {foobar}
2341
+ end
2342
+
2343
+ def call_foobar
2344
+ macro_foobar
2345
+ end
2346
+ end
2347
+
2348
+ def macro
2349
+ InstanceMacros.new.macro_foobar
2350
+ end
2351
+
2352
+ def function
2353
+ InstanceMacros.new.call_foobar
2354
+ end
2355
+ EOF
2356
+
2357
+ assert_equal("foobar", script.function)
2358
+ assert_equal("foobar", script.macro)
2359
+ end
2360
+
2361
+ def test_unquote
2362
+ # TODO fix annotation output and create a duby.anno.Extensions annotation.
2363
+ return if self.class.name == 'TestJavacCompiler'
2364
+ # TODO figure out why this fails to compile in the unittests but works
2365
+ # otherwise.
2366
+ return
2367
+ script, cls = compile(<<-EOF)
2368
+ import duby.lang.compiler.StringNode
2369
+ class UnquoteMacros
2370
+ macro def make_attr(name_node, type)
2371
+ name = StringNode(name_node).literal()
2372
+ quote do
2373
+ def `name`
2374
+ @`name`
2375
+ end
2376
+ def `"#{name}_set"`(`name`:`type`)
2377
+ @`name` = `name`
2378
+ end
2379
+ end
2380
+ end
2381
+
2382
+ make_attr :foo, :int
2383
+ end
2384
+
2385
+ x = UnquoteMacros.new
2386
+ puts x.foo
2387
+ x.foo = 3
2388
+ puts x.foo
2389
+ EOF
2390
+ assert_output("1\n3\n") {script.main(nil)}
2391
+ end
2392
+
2393
+ def test_static_import
2394
+ cls, = compile(<<-EOF)
2395
+ import java.util.Arrays
2396
+ include Arrays
2397
+ def list(x:Object[])
2398
+ asList(x)
2399
+ end
2400
+ EOF
2401
+
2402
+ o = ["1", "2", "3"].to_java(:object)
2403
+ list = cls.list(o)
2404
+ assert_kind_of(Java::JavaUtil::List, list)
2405
+ assert_equal(["1", "2", "3"], list.to_a)
2406
+
2407
+ scripe, cls = compile(<<-EOF)
2408
+ import java.util.Arrays
2409
+ class StaticImports
2410
+ include Arrays
2411
+ def list(x:Object[])
2412
+ asList(x)
2413
+ end
2414
+ end
2415
+ EOF
2416
+
2417
+ list = cls.new.list(o)
2418
+ assert_kind_of(Java::JavaUtil::List, list)
2419
+ assert_equal(["1", "2", "3"], list.to_a)
2420
+ end
2421
+
2422
+ # TODO: need a writable field somewhere...
2423
+ # def test_field_write
2424
+ # cls, = compile(<<-EOF)
2425
+ # old_pi = Math.PI
2426
+ # Math.PI = 3.0
2427
+ # puts Math.PI
2428
+ # Math.PI = old_pi
2429
+ # puts Math.PI
2430
+ # EOF
2431
+ # raise
2432
+ # cls.main([].to_java :string)
2433
+ # assert_output("3.0\n") do
2434
+ # cls.main([].to_java :string)
2435
+ # end
2436
+ # end
2437
+
2438
+ def test_class_append_self
2439
+ cls, = compile(<<-EOF)
2440
+ class Append
2441
+ class << self
2442
+ def hi
2443
+ print 'Static Hello'
2444
+ end
2445
+ end
2446
+ end
2447
+ EOF
2448
+
2449
+ output = capture_output do
2450
+ cls.hi
2451
+ end
2452
+
2453
+ assert_equal('Static Hello', output)
2454
+ end
2455
+
2456
+ def test_hashes
2457
+ cls, = compile(<<-EOF)
2458
+ def foo1
2459
+ {a:"A", b:"B"}
2460
+ end
2461
+ def foo2
2462
+ return {a:"A", b:"B"}
2463
+ end
2464
+ EOF
2465
+
2466
+ map = cls.foo1
2467
+ assert_equal("A", map["a"])
2468
+ assert_equal("B", map["b"])
2469
+ map = cls.foo2
2470
+ assert_equal("A", map["a"])
2471
+ assert_equal("B", map["b"])
2472
+ end
2473
+
2474
+ def test_loop_in_ensure
2475
+ cls, = compile(<<-EOF)
2476
+ begin
2477
+ puts "a"
2478
+ begin
2479
+ puts "b"
2480
+ break
2481
+ end while false
2482
+ puts "c"
2483
+ ensure
2484
+ puts "ensure"
2485
+ end
2486
+ EOF
2487
+
2488
+ assert_output("a\nb\nc\nensure\n") { cls.main(nil) }
2489
+ end
2490
+
2491
+ def test_return_type
2492
+ assert_raise Duby::Typer::InferenceError do
2493
+ compile(<<-EOF)
2494
+ class ReturnsA
2495
+ def a:int
2496
+ :foo
2497
+ end
2498
+ end
2499
+ EOF
2500
+ end
2501
+
2502
+ assert_raise Duby::Typer::InferenceError do
2503
+ compile(<<-EOF)
2504
+ class ReturnsB
2505
+ def self.a:String
2506
+ 2
2507
+ end
2508
+ end
2509
+ EOF
2510
+ end
2511
+ end
2512
+
2513
+ def test_abstract
2514
+ script, cls1, cls2 = compile(<<-EOF)
2515
+ abstract class Abstract
2516
+ abstract def foo:void; end
2517
+ def bar; puts "bar"; end
2518
+ end
2519
+ class Concrete < Abstract
2520
+ def foo; puts :foo; end
2521
+ end
2522
+ EOF
2523
+
2524
+ assert_output("foo\nbar\n") do
2525
+ a = cls2.new
2526
+ a.foo
2527
+ a.bar
2528
+ end
2529
+ begin
2530
+ cls1.new
2531
+ fail "Expected InstantiationException"
2532
+ rescue java.lang.InstantiationException
2533
+ # expected
2534
+ end
2535
+ end
2536
+
2537
+ def test_return_void
2538
+ script, = compile(<<-EOF)
2539
+ def foo:void
2540
+ puts :hi
2541
+ return
2542
+ end
2543
+ EOF
2544
+
2545
+ assert_output("hi\n") { script.foo }
2546
+ end
2547
+
2548
+ def test_package
2549
+ script, cls = compile(<<-EOF)
2550
+ package foo
2551
+
2552
+ # package foo.bar {
2553
+ # class PackagedBar
2554
+ # def self.dosomething
2555
+ # "bar"
2556
+ # end
2557
+ # end
2558
+ # }
2559
+
2560
+ def dosomething
2561
+ "foo"
2562
+ end
2563
+ EOF
2564
+
2565
+ package = script.java_class.name.split('.')[0]
2566
+ assert_equal('foo', package)
2567
+ assert_equal('foo', script.dosomething)
2568
+
2569
+ # TODO move package to the parser so we can support blocks
2570
+ # assert_equal('bar', cls.dosomething)
2571
+ # assert_equal("foo.bar.PackagedBar", cls.java_class.name)
2572
+ end
2573
+
2574
+ def test_not
2575
+ cls, = compile(<<-EOF)
2576
+ def foo(x:boolean)
2577
+ !x
2578
+ end
2579
+ def bar(x:Object)
2580
+ !x
2581
+ end
2582
+ EOF
2583
+ assert_equal(true, cls.foo(false))
2584
+ assert_equal(false, cls.foo(true))
2585
+ assert_equal(true, cls.bar(nil))
2586
+ assert_equal(false, cls.bar(""))
2587
+ end
2588
+
2589
+ def test_rescue_scope
2590
+ cls, = compile(<<-EOF)
2591
+ def foo
2592
+ a = 1
2593
+ b = 2
2594
+ begin
2595
+ raise "Foo"
2596
+ rescue => b
2597
+ puts a
2598
+ puts b.getMessage
2599
+ end
2600
+ puts b
2601
+ end
2602
+ EOF
2603
+
2604
+ assert_output("1\nFoo\n2\n") { cls.foo }
2605
+ end
2606
+
2607
+ end