mirah 0.1.2-java → 0.1.3-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.
- checksums.yaml +4 -4
- data/History.txt +225 -0
- data/Rakefile +108 -315
- data/TODO.md +100 -0
- data/bin/bundler +16 -0
- data/bin/rake +16 -0
- data/dist/mirahc.jar +0 -0
- data/examples/appengine/Readme +0 -1
- data/examples/literals.mirah +17 -0
- data/examples/macros/string_each_char.mirah +1 -1
- data/lib/mirah.rb +11 -21
- data/lib/mirah/transform/transformer.rb +1 -2
- data/lib/mirah/util/class_loader.rb +1 -1
- data/lib/mirah/util/logging.rb +0 -63
- data/lib/mirah/util/process_errors.rb +1 -0
- data/lib/mirah/version.rb +1 -1
- data/{examples/simple_class.mirah~ → test/artifacts/jar_test.rb} +7 -11
- data/{lib/mirah/commands.rb → test/artifacts/jruby_test.rb} +8 -5
- data/test/core/typer_test.rb +29 -11
- data/test/core/util/argument_processor_test.rb +24 -23
- data/test/core/util/class_loader_test.rb +7 -4
- data/test/core/util/{compilation_state_test.rb → jvm_version_test.rb} +20 -16
- data/test/fixtures/org/foo/ImplicitClassRetAnno.java +4 -0
- data/test/fixtures/org/foo/IntAnno.java +9 -0
- data/test/jvm/annotations_test.rb +11 -11
- data/test/jvm/blocks_test.rb +16 -12
- data/test/jvm/constructors_test.rb +8 -8
- data/test/jvm/enumerable_test.rb +48 -24
- data/test/jvm/generics_test.rb +3 -7
- data/test/jvm/import_test.rb +14 -0
- data/test/jvm/interface_test.rb +9 -24
- data/test/jvm/jvm_commands_test.rb +22 -4
- data/test/jvm/jvm_compiler_test.rb +124 -79
- data/test/jvm/list_extensions_test.rb +1 -1
- data/test/jvm/macros_test.rb +67 -14
- data/test/jvm/main_method_test.rb +1 -1
- data/test/jvm/new_backend_test_helper.rb +100 -3
- data/{lib/mirah/jvm/types/bitescript_ext.rb → test/jvm/static_fields_test.rb} +22 -21
- data/test/mirrors/base_type_test.rb +4 -3
- data/test/mirrors/bytecode_mirror_test.rb +35 -15
- data/test/mirrors/generics_test.rb +14 -5
- data/test/mirrors/member_test.rb +2 -1
- data/test/mirrors/method_lookup_test.rb +18 -6
- data/test/mirrors/mirrors_test.rb +87 -20
- data/test/mirrors/simple_async_mirror_loader_test.rb +7 -3
- data/test/mirrors/simple_mirror_loader_test.rb +5 -5
- data/test/test_helper.rb +25 -1
- metadata +18 -78
- data/bin/mirahp +0 -27
- data/bin/mirahp.cmd +0 -16
- data/examples/Fib.class +0 -0
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-builtins.jar +0 -0
- data/javalib/mirah-compiler.jar +0 -0
- data/javalib/mirah-mirrors.jar +0 -0
- data/javalib/mirah-newast-transitional.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/javalib/mirah-util.jar +0 -0
- data/lib/mirah/ast.rb +0 -43
- data/lib/mirah/ast/scope.rb +0 -262
- data/lib/mirah/commands/base.rb +0 -59
- data/lib/mirah/commands/compile.rb +0 -39
- data/lib/mirah/commands/parse.rb +0 -36
- data/lib/mirah/commands/run.rb +0 -78
- data/lib/mirah/generator.rb +0 -150
- data/lib/mirah/jvm/compiler.rb +0 -50
- data/lib/mirah/jvm/compiler/base.rb +0 -421
- data/lib/mirah/jvm/compiler/jvm_bytecode.rb +0 -1194
- data/lib/mirah/jvm/method_lookup.rb +0 -307
- data/lib/mirah/jvm/types.rb +0 -45
- data/lib/mirah/jvm/types/array_type.rb +0 -60
- data/lib/mirah/jvm/types/ast_ext.rb +0 -31
- data/lib/mirah/jvm/types/basic_types.rb +0 -41
- data/lib/mirah/jvm/types/block_type.rb +0 -15
- data/lib/mirah/jvm/types/boolean.rb +0 -70
- data/lib/mirah/jvm/types/enumerable.rb +0 -80
- data/lib/mirah/jvm/types/extensions.rb +0 -110
- data/lib/mirah/jvm/types/factory.rb +0 -830
- data/lib/mirah/jvm/types/floats.rb +0 -99
- data/lib/mirah/jvm/types/generic_type.rb +0 -72
- data/lib/mirah/jvm/types/implicit_nil_type.rb +0 -29
- data/lib/mirah/jvm/types/integers.rb +0 -131
- data/lib/mirah/jvm/types/interface_definition.rb +0 -20
- data/lib/mirah/jvm/types/intrinsics.rb +0 -385
- data/lib/mirah/jvm/types/literals.rb +0 -89
- data/lib/mirah/jvm/types/meta_type.rb +0 -54
- data/lib/mirah/jvm/types/methods.rb +0 -946
- data/lib/mirah/jvm/types/null_type.rb +0 -39
- data/lib/mirah/jvm/types/number.rb +0 -184
- data/lib/mirah/jvm/types/primitive_type.rb +0 -76
- data/lib/mirah/jvm/types/source_mirror.rb +0 -274
- data/lib/mirah/jvm/types/type.rb +0 -311
- data/lib/mirah/jvm/types/type_definition.rb +0 -72
- data/lib/mirah/jvm/types/void_type.rb +0 -19
- data/lib/mirah/util/compilation_state.rb +0 -60
- data/test/core/commands_test.rb +0 -89
- data/test/core/generator_test.rb +0 -26
- data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
- data/test/jvm/bytecode_test_helper.rb +0 -193
- data/test/jvm/factory_test.rb +0 -28
- data/test/jvm/java_typer_test.rb +0 -283
data/test/core/commands_test.rb
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
require 'test_helper'
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class CommandsTest < Test::Unit::TestCase
|
|
19
|
-
class RaisesMirahErrorCommand < Mirah::Commands::Base
|
|
20
|
-
def execute
|
|
21
|
-
execute_base { raise Mirah::MirahError, "just an error" }
|
|
22
|
-
end
|
|
23
|
-
def command_name; :foo; end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
class MirahProcessesErrorCommand < Mirah::Commands::Base
|
|
27
|
-
include Mirah::Util::ProcessErrors
|
|
28
|
-
def execute
|
|
29
|
-
execute_base { process_errors [Mirah::NodeError.new("just an error")] }
|
|
30
|
-
end
|
|
31
|
-
def command_name; :foo; end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
class SuccessfulCommand < Mirah::Commands::Base
|
|
35
|
-
def execute
|
|
36
|
-
execute_base { "something" }
|
|
37
|
-
end
|
|
38
|
-
def command_name; :foo; end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def test_on_Mirah_error_has_non_zero_exit_code
|
|
42
|
-
assert_non_zero_exit do
|
|
43
|
-
RaisesMirahErrorCommand.new([]).execute
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def test_on_bad_argument_has_non_zero_exit_code
|
|
48
|
-
assert_non_zero_exit do
|
|
49
|
-
RaisesMirahErrorCommand.new(['-bad-argument']).execute
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def test_on_v_with_no_args_exits_without_running_command
|
|
54
|
-
assert_zero_exit do
|
|
55
|
-
RaisesMirahErrorCommand.new(['-v']).execute
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def test_on_j_option_when_command_is_not_compile_has_non_zero_exit_code
|
|
60
|
-
assert_non_zero_exit do
|
|
61
|
-
RaisesMirahErrorCommand.new(['-j']).execute
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def test_success_is_truthy
|
|
66
|
-
assert SuccessfulCommand.new([]).execute, "expected it to be truthy"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def test_process_errors_causes_a_non_zero_exit
|
|
70
|
-
assert_non_zero_exit do
|
|
71
|
-
MirahProcessesErrorCommand.new([]).execute
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def assert_non_zero_exit
|
|
76
|
-
ex = assert_raise SystemExit do
|
|
77
|
-
yield
|
|
78
|
-
end
|
|
79
|
-
assert_not_equal 0, ex.status
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def assert_zero_exit
|
|
83
|
-
ex = assert_raise SystemExit do
|
|
84
|
-
yield
|
|
85
|
-
end
|
|
86
|
-
assert_equal 0, ex.status
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
end
|
data/test/core/generator_test.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
require 'test_helper'
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class GeneratorTest < Test::Unit::TestCase
|
|
19
|
-
def test_generator_sets_classpath_bootclasspath_on_type_system
|
|
20
|
-
|
|
21
|
-
state = Mirah::Util::CompilationState.new
|
|
22
|
-
state.bootclasspath = "a:b"
|
|
23
|
-
generator = Mirah::Generator.new(state, Mirah::JVM::Compiler::JVMBytecode, false, false)
|
|
24
|
-
assert state.bootclasspath == generator.typer.type_system.bootclasspath
|
|
25
|
-
end
|
|
26
|
-
end
|
|
Binary file
|
|
Binary file
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
require 'test_helper'
|
|
16
|
-
require 'set'
|
|
17
|
-
|
|
18
|
-
module JVMCompiler
|
|
19
|
-
$CLASSPATH << TEST_DEST
|
|
20
|
-
|
|
21
|
-
java_import 'java.lang.System'
|
|
22
|
-
java_import 'java.io.PrintStream'
|
|
23
|
-
java_import 'java.net.URLClassLoader'
|
|
24
|
-
java_import 'org.jruby.javasupport.JavaClass'
|
|
25
|
-
|
|
26
|
-
include Mirah
|
|
27
|
-
|
|
28
|
-
def new_state
|
|
29
|
-
state = Mirah::Util::CompilationState.new
|
|
30
|
-
state.save_extensions = true
|
|
31
|
-
state.destination = TEST_DEST
|
|
32
|
-
state.classpath = Env.encode_paths [TEST_DEST, FIXTURE_TEST_DEST]
|
|
33
|
-
state.type_system = type_system if type_system
|
|
34
|
-
state
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def type_system
|
|
38
|
-
nil
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def clean_tmp_files
|
|
42
|
-
return unless @tmp_classes
|
|
43
|
-
File.unlink(*@tmp_classes)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def compiler_type
|
|
47
|
-
JVM::Compiler::JVMBytecode
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def compiler_name
|
|
51
|
-
"original"
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def parse name, code, transformer
|
|
55
|
-
AST.parse(code, name, true, transformer)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def infer_and_resolve_types ast, generator
|
|
59
|
-
scoper, typer = generator.infer_asts(ast, true)
|
|
60
|
-
ast
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def parse_and_resolve_types name, code
|
|
64
|
-
state = new_state
|
|
65
|
-
|
|
66
|
-
generator = Mirah::Generator.new(state, compiler_type, false, false)
|
|
67
|
-
transformer = Mirah::Transform::Transformer.new(state, generator.typer)
|
|
68
|
-
|
|
69
|
-
ast = [AST.parse(code, name, true, transformer)]
|
|
70
|
-
|
|
71
|
-
infer_and_resolve_types ast, generator
|
|
72
|
-
|
|
73
|
-
ast
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def generate_classes compiler_results, state
|
|
77
|
-
classes = {}
|
|
78
|
-
|
|
79
|
-
compiler_results.each do |result|
|
|
80
|
-
bytes = result.bytes
|
|
81
|
-
filename = "#{TEST_DEST}#{result.filename}"
|
|
82
|
-
FileUtils.mkdir_p(File.dirname(filename))
|
|
83
|
-
File.open(filename, 'wb') { |f| f.write(bytes) }
|
|
84
|
-
@tmp_classes << filename
|
|
85
|
-
classes[result.filename[0..-7]] = Mirah::Util::ClassLoader.binary_string bytes
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
loader = Mirah::Util::ClassLoader.new(
|
|
89
|
-
URLClassLoader.new(
|
|
90
|
-
Mirah::Env.make_urls(state.classpath),
|
|
91
|
-
JRuby.runtime.jruby_class_loader),
|
|
92
|
-
classes)
|
|
93
|
-
|
|
94
|
-
classes.keys.map do |name|
|
|
95
|
-
cls = loader.load_class(name.tr('/', '.'))
|
|
96
|
-
JavaUtilities.get_proxy_class(JavaClass.get(JRuby.runtime, cls))
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def compile(code, options = {})
|
|
101
|
-
name = options.delete :name
|
|
102
|
-
name ||= tmp_script_name
|
|
103
|
-
|
|
104
|
-
state = new_state
|
|
105
|
-
java_version = options.delete :java_version
|
|
106
|
-
if java_version
|
|
107
|
-
state.set_jvm_version java_version
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
generator = Mirah::Generator.new(state, compiler_type, false, false)
|
|
111
|
-
transformer = Mirah::Transform::Transformer.new(state, generator.typer)
|
|
112
|
-
|
|
113
|
-
ast = [AST.parse_ruby(nil, code, name)]
|
|
114
|
-
|
|
115
|
-
scoper, typer = generator.infer_asts(ast, true)
|
|
116
|
-
generator.do_transforms ast
|
|
117
|
-
compiler_results = generator.compiler.compile_asts(ast, scoper, typer)
|
|
118
|
-
|
|
119
|
-
generate_classes compiler_results, state
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def tmp_script_name
|
|
123
|
-
"script#{name.gsub(/\)|\(/,'_').capitalize}#{System.nano_time}"
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
module CommonAssertions
|
|
129
|
-
java_import 'java.lang.System'
|
|
130
|
-
java_import 'java.io.PrintStream'
|
|
131
|
-
|
|
132
|
-
def assert_include(value, array, message=nil)
|
|
133
|
-
message = build_message message, '<?> does not include <?>', array, value
|
|
134
|
-
assert_block message do
|
|
135
|
-
array.include? value
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def capture_output
|
|
140
|
-
saved_output = System.out
|
|
141
|
-
output = StringIO.new
|
|
142
|
-
System.setOut(PrintStream.new(output.to_outputstream))
|
|
143
|
-
begin
|
|
144
|
-
yield
|
|
145
|
-
output.rewind
|
|
146
|
-
output.read
|
|
147
|
-
ensure
|
|
148
|
-
System.setOut(saved_output)
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def assert_output(expected, &block)
|
|
153
|
-
assert_equal(expected, capture_output(&block))
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def assert_raise_java(type, message=nil)
|
|
157
|
-
begin
|
|
158
|
-
yield
|
|
159
|
-
rescue Exception => e
|
|
160
|
-
ex = e
|
|
161
|
-
end
|
|
162
|
-
ex = ex.cause if ex.is_a? NativeException
|
|
163
|
-
assert_equal type, ex.class
|
|
164
|
-
if message
|
|
165
|
-
assert_equal message,
|
|
166
|
-
ex.message.to_s,
|
|
167
|
-
"expected error message to be '#{message}' but was '#{ex.message}'"
|
|
168
|
-
end
|
|
169
|
-
ex
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
module DebuggingHelp
|
|
174
|
-
def with_finest_logging
|
|
175
|
-
Mirah::Logging::MirahLogger.level = Mirah::Logging::Level::FINEST
|
|
176
|
-
yield
|
|
177
|
-
ensure
|
|
178
|
-
Mirah::Logging::MirahLogger.level = Mirah::Logging::Level::INFO
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
class Test::Unit::TestCase
|
|
183
|
-
include JVMCompiler
|
|
184
|
-
include DebuggingHelp
|
|
185
|
-
|
|
186
|
-
def setup
|
|
187
|
-
@tmp_classes = Set.new
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def cleanup
|
|
191
|
-
clean_tmp_files
|
|
192
|
-
end
|
|
193
|
-
end
|
data/test/jvm/factory_test.rb
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
class FactoryTest < Test::Unit::TestCase
|
|
17
|
-
def test_bootclass_loader_can_find_things_on_bootclasspath
|
|
18
|
-
factory = Mirah::JVM::Types::TypeFactory.new
|
|
19
|
-
factory.bootclasspath = File.expand_path("#{__FILE__}/../../fixtures/") +"/"
|
|
20
|
-
assert factory.bootstrap_loader.get_resource 'org/foo/A.class'
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def test_nil_classpath_is_ok
|
|
24
|
-
factory = Mirah::JVM::Types::TypeFactory.new
|
|
25
|
-
factory.classpath = nil
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
end
|
data/test/jvm/java_typer_test.rb
DELETED
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
|
2
|
-
# All contributing project authors may be found in the NOTICE file.
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
|
|
16
|
-
require 'test/unit'
|
|
17
|
-
require 'mirah'
|
|
18
|
-
|
|
19
|
-
class JavaTyperTest < Test::Unit::TestCase
|
|
20
|
-
include Mirah
|
|
21
|
-
include Mirah::Util::ProcessErrors
|
|
22
|
-
|
|
23
|
-
java_import 'org.mirah.typer.simple.SimpleScoper'
|
|
24
|
-
java_import 'org.mirah.typer.BaseTypeFuture'
|
|
25
|
-
java_import 'org.mirah.typer.CallFuture'
|
|
26
|
-
java_import 'org.mirah.typer.TypeFuture'
|
|
27
|
-
|
|
28
|
-
def setup
|
|
29
|
-
@types = Mirah::JVM::Types::TypeFactory.new
|
|
30
|
-
@scopes = SimpleScoper.new {|scoper, node| Mirah::AST::StaticScope.new(node, scoper)}
|
|
31
|
-
@typer = Mirah::Typer::Typer.new(@types, @scopes, nil, nil)
|
|
32
|
-
@mirah = Mirah::Transform::Transformer.new(Mirah::Util::CompilationState.new, @typer)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def inferred_type(node, expression=false)
|
|
36
|
-
if node.kind_of? Java::MirahLangAst::Script
|
|
37
|
-
node = node.body
|
|
38
|
-
end
|
|
39
|
-
type = @typer.infer(node, expression).resolve
|
|
40
|
-
if type.name == ':error'
|
|
41
|
-
catch(:exit) do
|
|
42
|
-
process_errors([type])
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
type
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def assert_errors_including(message, ast)
|
|
49
|
-
@typer.infer(ast, false)
|
|
50
|
-
actual_errors = []
|
|
51
|
-
process_inference_errors(@typer, [ast]) do |errors|
|
|
52
|
-
actual_errors += errors.map {|e| e.message.map{|m| m[0]}.join("\n")}
|
|
53
|
-
end
|
|
54
|
-
fail("no errors") if actual_errors.empty?
|
|
55
|
-
assert actual_errors.any?{|error| error =~ message },
|
|
56
|
-
"no errors with message \"#{message}\" in #{actual_errors}"
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def method_type(target, name, args)
|
|
60
|
-
target = @types.cache_and_wrap(target)
|
|
61
|
-
args = args.map {|arg| @types.cache_and_wrap(arg) }
|
|
62
|
-
call = CallFuture.new(@types, nil, target, true, name, args, nil, nil)
|
|
63
|
-
@types.getMethodType(call).return_type
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def parse(text)
|
|
67
|
-
AST.parse(text, '-', false, @mirah)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def test_simple_overtyped_meta_method
|
|
71
|
-
string_meta = @types.type(nil, 'java.lang.String', false, true)
|
|
72
|
-
string = @types.type(nil, 'java.lang.String')
|
|
73
|
-
|
|
74
|
-
# integral types
|
|
75
|
-
['boolean', 'char', 'double', 'float', 'int', 'long'].each do |type_name|
|
|
76
|
-
type = @types.type(nil, type_name)
|
|
77
|
-
return_type = method_type(string_meta, 'valueOf', [type])
|
|
78
|
-
assert_equal(string, return_type.resolve, "valueOf(#{type}) should return #{string}")
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# char[]
|
|
82
|
-
type = @types.type(nil, 'char', true)
|
|
83
|
-
return_type = method_type(string_meta, 'valueOf', [type])
|
|
84
|
-
assert_equal(string, return_type.resolve)
|
|
85
|
-
|
|
86
|
-
# Object
|
|
87
|
-
type = @types.type(nil, 'java.lang.Object')
|
|
88
|
-
return_type = method_type(string_meta, 'valueOf', [type])
|
|
89
|
-
assert_equal(string, return_type.resolve)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def test_non_overtyped_method
|
|
93
|
-
string = @types.type(nil, 'java.lang.String')
|
|
94
|
-
|
|
95
|
-
int = @types.type(nil, 'int')
|
|
96
|
-
return_type = method_type(string, 'length', [])
|
|
97
|
-
assert_equal(int, return_type.resolve)
|
|
98
|
-
|
|
99
|
-
byte_array = @types.type(nil, 'byte', true)
|
|
100
|
-
return_type = method_type(string, 'getBytes', [])
|
|
101
|
-
assert_equal(byte_array, return_type.resolve)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def test_simple_overtyped_method
|
|
105
|
-
string_meta = @types.type(nil, 'java.lang.String', false, true)
|
|
106
|
-
string = @types.type(nil, 'java.lang.String')
|
|
107
|
-
|
|
108
|
-
return_type = method_type(string_meta, 'valueOf', [string])
|
|
109
|
-
assert_equal(string, return_type.resolve)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def test_primitive_conversion_method
|
|
113
|
-
string = @types.type(nil, 'java.lang.String')
|
|
114
|
-
byte = @types.type(nil, 'byte')
|
|
115
|
-
char = @types.type(nil, 'char')
|
|
116
|
-
long = @types.type(nil, 'long')
|
|
117
|
-
|
|
118
|
-
return_type = method_type(string, 'charAt', [byte])
|
|
119
|
-
assert_kind_of(TypeFuture, return_type)
|
|
120
|
-
assert_equal(char, return_type.resolve)
|
|
121
|
-
|
|
122
|
-
return_type = method_type(string, 'charAt', [long]).resolve
|
|
123
|
-
assert(return_type.isError)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
include Mirah::JVM::MethodLookup
|
|
127
|
-
|
|
128
|
-
def test_is_more_specific
|
|
129
|
-
object = @types.type(nil, 'java.lang.Object')
|
|
130
|
-
charseq = @types.type(nil, 'java.lang.CharSequence')
|
|
131
|
-
string = @types.type(nil, 'java.lang.String')
|
|
132
|
-
|
|
133
|
-
assert object.is_more_specific?([string], [object])
|
|
134
|
-
assert object.is_more_specific?([charseq], [object])
|
|
135
|
-
assert object.is_more_specific?([string], [charseq])
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def test_primitive_convertible
|
|
139
|
-
boolean = @types.type(nil, 'boolean')
|
|
140
|
-
byte = @types.type(nil, 'byte')
|
|
141
|
-
short = @types.type(nil, 'short')
|
|
142
|
-
char = @types.type(nil, 'char')
|
|
143
|
-
int = @types.type(nil, 'int')
|
|
144
|
-
long = @types.type(nil, 'long')
|
|
145
|
-
float = @types.type(nil, 'float')
|
|
146
|
-
double = @types.type(nil, 'double')
|
|
147
|
-
|
|
148
|
-
assert !primitive_convertible?(boolean, byte)
|
|
149
|
-
assert !primitive_convertible?(boolean, short)
|
|
150
|
-
assert !primitive_convertible?(boolean, char)
|
|
151
|
-
assert !primitive_convertible?(boolean, int)
|
|
152
|
-
assert !primitive_convertible?(boolean, long)
|
|
153
|
-
assert !primitive_convertible?(boolean, float)
|
|
154
|
-
assert !primitive_convertible?(boolean, double)
|
|
155
|
-
assert primitive_convertible?(boolean, boolean)
|
|
156
|
-
|
|
157
|
-
assert !primitive_convertible?(byte, boolean)
|
|
158
|
-
assert primitive_convertible?(byte, byte)
|
|
159
|
-
assert primitive_convertible?(byte, short)
|
|
160
|
-
assert !primitive_convertible?(byte, char)
|
|
161
|
-
assert primitive_convertible?(byte, int)
|
|
162
|
-
assert primitive_convertible?(byte, long)
|
|
163
|
-
assert primitive_convertible?(byte, float)
|
|
164
|
-
assert primitive_convertible?(byte, double)
|
|
165
|
-
|
|
166
|
-
assert !primitive_convertible?(short, boolean)
|
|
167
|
-
assert !primitive_convertible?(short, byte)
|
|
168
|
-
assert !primitive_convertible?(short, char)
|
|
169
|
-
assert primitive_convertible?(short, short)
|
|
170
|
-
assert primitive_convertible?(short, int)
|
|
171
|
-
assert primitive_convertible?(short, long)
|
|
172
|
-
assert primitive_convertible?(short, float)
|
|
173
|
-
assert primitive_convertible?(short, double)
|
|
174
|
-
|
|
175
|
-
assert !primitive_convertible?(char, boolean)
|
|
176
|
-
assert !primitive_convertible?(char, byte)
|
|
177
|
-
assert !primitive_convertible?(char, short)
|
|
178
|
-
assert primitive_convertible?(char, char)
|
|
179
|
-
assert primitive_convertible?(char, int)
|
|
180
|
-
assert primitive_convertible?(char, long)
|
|
181
|
-
assert primitive_convertible?(char, float)
|
|
182
|
-
assert primitive_convertible?(char, double)
|
|
183
|
-
|
|
184
|
-
assert !primitive_convertible?(int, boolean)
|
|
185
|
-
assert !primitive_convertible?(int, byte)
|
|
186
|
-
assert !primitive_convertible?(int, short)
|
|
187
|
-
assert !primitive_convertible?(int, char)
|
|
188
|
-
assert primitive_convertible?(int, int)
|
|
189
|
-
assert primitive_convertible?(int, long)
|
|
190
|
-
assert primitive_convertible?(int, float)
|
|
191
|
-
assert primitive_convertible?(int, double)
|
|
192
|
-
|
|
193
|
-
assert !primitive_convertible?(long, boolean)
|
|
194
|
-
assert !primitive_convertible?(long, byte)
|
|
195
|
-
assert !primitive_convertible?(long, short)
|
|
196
|
-
assert !primitive_convertible?(long, char)
|
|
197
|
-
assert !primitive_convertible?(long, int)
|
|
198
|
-
assert primitive_convertible?(long, long)
|
|
199
|
-
assert primitive_convertible?(long, float)
|
|
200
|
-
assert primitive_convertible?(long, double)
|
|
201
|
-
|
|
202
|
-
assert !primitive_convertible?(float, boolean)
|
|
203
|
-
assert !primitive_convertible?(float, byte)
|
|
204
|
-
assert !primitive_convertible?(float, short)
|
|
205
|
-
assert !primitive_convertible?(float, char)
|
|
206
|
-
assert !primitive_convertible?(float, int)
|
|
207
|
-
assert !primitive_convertible?(float, long)
|
|
208
|
-
assert primitive_convertible?(float, float)
|
|
209
|
-
assert primitive_convertible?(float, double)
|
|
210
|
-
|
|
211
|
-
assert !primitive_convertible?(double, boolean)
|
|
212
|
-
assert !primitive_convertible?(double, byte)
|
|
213
|
-
assert !primitive_convertible?(double, short)
|
|
214
|
-
assert !primitive_convertible?(double, char)
|
|
215
|
-
assert !primitive_convertible?(double, int)
|
|
216
|
-
assert !primitive_convertible?(double, long)
|
|
217
|
-
assert !primitive_convertible?(double, float)
|
|
218
|
-
assert primitive_convertible?(double, double)
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def test_primitive_array
|
|
222
|
-
ary = @types.type(nil, 'byte', true)
|
|
223
|
-
int = @types.type(nil, 'int')
|
|
224
|
-
|
|
225
|
-
# TODO fix intrinsics
|
|
226
|
-
assert_equal(@types.type(nil, 'byte'), method_type(ary, "[]", [int]).resolve)
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
def test_primitive_not_convertible_to_array_with_same_component_type
|
|
231
|
-
ary = @types.type(nil, 'byte', true)
|
|
232
|
-
byte = @types.type(nil, 'byte')
|
|
233
|
-
|
|
234
|
-
assert !primitive_convertible?(byte, ary)
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
def test_int
|
|
238
|
-
ast = parse("#{1 << 16}")
|
|
239
|
-
assert_equal(@types.type(nil, 'int'), inferred_type(ast))
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
def test_long
|
|
243
|
-
ast = parse("#{1 << 33}")
|
|
244
|
-
assert_equal(@types.type(nil, 'long'), inferred_type(ast))
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
def test_char
|
|
248
|
-
ast = parse("?a")
|
|
249
|
-
assert_equal(@types.type(nil, 'char'), inferred_type(ast))
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
def test_static_method
|
|
253
|
-
ast = parse("class Foo;def self.bar; 1; end; end; Foo.bar")
|
|
254
|
-
assert_equal(@types.type(nil, 'int'), inferred_type(ast))
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
def test_if_with_raise_has_non_raise_type
|
|
258
|
-
ast = parse("if true; 1; else; raise 'error'; end")
|
|
259
|
-
assert_equal(@types.type(nil, 'int'), inferred_type(ast))
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
def test_rescue_with_raise_in_rescue_has_body_type
|
|
263
|
-
ast = parse("1 + begin; 1; rescue; raise 'error'; end")
|
|
264
|
-
assert_equal(@types.type(nil, 'int'), inferred_type(ast))
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def test_rescue_with_else_and_raise_in_rescue_has_else_type
|
|
268
|
-
ast = parse("1 + begin; ''; rescue; raise 'error'; else 1 end")
|
|
269
|
-
assert_equal(@types.type(nil, 'int'), inferred_type(ast))
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
def test_type_cycle
|
|
273
|
-
ast = parse(<<-EOF)
|
|
274
|
-
def foo(a:String):Object
|
|
275
|
-
nil
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
a = "x"
|
|
279
|
-
a = foo(a)
|
|
280
|
-
EOF
|
|
281
|
-
assert_errors_including(/Cannot assign .*Object.* to .*String/, ast)
|
|
282
|
-
end
|
|
283
|
-
end
|