mirah 0.1.0.pre-java → 0.1.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +736 -0
- data/README.md +71 -0
- data/Rakefile +227 -73
- data/examples/Fib.class +0 -0
- data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +2 -3
- data/examples/simple_class.mirah +3 -3
- data/examples/{dynamic.mirah → simple_class.mirah~} +7 -12
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-builtins.jar +0 -0
- data/javalib/mirah-compiler.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/javalib/mirah-util.jar +0 -0
- data/lib/mirah.rb +8 -1
- data/lib/mirah/ast.rb +1 -1
- data/lib/mirah/ast/scope.rb +16 -0
- data/lib/mirah/commands/base.rb +1 -3
- data/lib/mirah/compiler.rb +17 -3
- data/lib/mirah/errors.rb +10 -10
- data/lib/mirah/generator.rb +21 -9
- data/lib/mirah/jvm/compiler.rb +17 -0
- data/lib/mirah/jvm/compiler/base.rb +24 -5
- data/lib/mirah/jvm/compiler/jvm_bytecode.rb +83 -20
- data/lib/mirah/jvm/method_lookup.rb +43 -22
- data/lib/mirah/jvm/types.rb +1 -2
- data/lib/mirah/jvm/types/array_type.rb +1 -6
- data/lib/mirah/jvm/types/ast_ext.rb +31 -0
- data/lib/mirah/jvm/types/basic_types.rb +1 -2
- data/lib/mirah/jvm/types/boolean.rb +11 -10
- data/lib/mirah/jvm/types/extensions.rb +14 -5
- data/lib/mirah/jvm/types/factory.rb +128 -43
- data/lib/mirah/jvm/types/floats.rb +8 -10
- data/lib/mirah/jvm/types/integers.rb +16 -9
- data/lib/mirah/jvm/types/intrinsics.rb +17 -69
- data/lib/mirah/jvm/types/meta_type.rb +5 -0
- data/lib/mirah/jvm/types/methods.rb +317 -151
- data/lib/mirah/jvm/types/methods.rb~ +973 -0
- data/lib/mirah/jvm/types/number.rb +29 -6
- data/lib/mirah/jvm/types/primitive_type.rb +35 -7
- data/lib/mirah/jvm/types/source_mirror.rb +11 -6
- data/lib/mirah/jvm/types/type.rb +52 -0
- data/lib/mirah/jvm/types/type_definition.rb +8 -2
- data/lib/mirah/transform/ast_ext.rb +9 -31
- data/lib/mirah/transform/transformer.rb +1 -1
- data/lib/mirah/typer.rb +2 -1
- data/lib/mirah/util/argument_processor.rb +10 -14
- data/lib/mirah/util/argument_processor.rb~ +146 -0
- data/lib/mirah/util/compilation_state.rb +15 -9
- data/lib/mirah/util/process_errors.rb +8 -2
- data/lib/mirah/version.rb +2 -2
- data/lib/mirah_task.rb +0 -7
- data/test/core/typer_test.rb +21 -13
- data/test/core/util/argument_processor_test.rb +19 -19
- data/test/core/util/class_loader_test.rb +19 -4
- data/test/core/util/compilation_state_test.rb +38 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
- data/test/jvm/blocks_test.rb +50 -29
- data/test/jvm/bytecode_test_helper.rb +71 -57
- data/test/jvm/cast_test.rb +162 -0
- data/test/jvm/constructors_test.rb +48 -0
- data/test/jvm/enumerable_test.rb +136 -7
- data/test/jvm/example_test.rb +39 -0
- data/test/jvm/factory_test.rb +6 -0
- data/test/jvm/generics_test.rb +0 -5
- data/test/jvm/import_test.rb +81 -0
- data/test/jvm/interface_test.rb +113 -0
- data/test/jvm/java_typer_test.rb +57 -11
- data/test/jvm/jvm_commands_test.rb +24 -0
- data/test/jvm/jvm_compiler_test.rb +186 -370
- data/test/jvm/macros_test.rb +67 -6
- data/test/jvm/main_method_test.rb +1 -1
- data/test/jvm/mirror_compilation_test_helper.rb +24 -0
- data/test/jvm/new_backend_test_helper.rb +25 -0
- data/test/jvm/rescue_test.rb +153 -18
- data/test/jvm/string_test.rb +41 -0
- data/test/jvm/varargs_test.rb +65 -0
- data/test/mirrors/base_type_test.rb +96 -0
- data/test/mirrors/bytecode_mirror_test.rb +86 -0
- data/test/mirrors/generics_test.rb +776 -0
- data/test/mirrors/member_test.rb +69 -0
- data/test/mirrors/method_lookup_test.rb +574 -0
- data/test/mirrors/mirrors_test.rb +562 -0
- data/test/mirrors/simple_async_mirror_loader_test.rb +110 -0
- data/test/mirrors/simple_mirror_loader_test.rb +104 -0
- data/test/test_helper.rb +2 -1
- metadata +244 -217
- data/README.txt +0 -59
- data/javalib/dynalink-0.2.jar +0 -0
- data/lib/mirah/jvm/typer.rb +0 -177
- data/lib/mirah/jvm/types/dynamic_type.rb +0 -45
- data/lib/mirah/jvm/types/unreachable_type.rb +0 -27
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Copyright (c) 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
|
+
|
|
16
|
+
class StringTest < Test::Unit::TestCase
|
|
17
|
+
|
|
18
|
+
def test_string_concat
|
|
19
|
+
cls, = compile("
|
|
20
|
+
def str_str; a = 'a'; b = 'b'; a + b; end
|
|
21
|
+
def str_boolean; a = 'a'; b = false; a + b; end
|
|
22
|
+
def str_float; a = 'a'; b = float(1.0); a + b; end
|
|
23
|
+
def str_double; a = 'a'; b = 1.0; a + b; end
|
|
24
|
+
def str_byte; a = 'a'; b = byte(1); a + b; end
|
|
25
|
+
def str_short; a = 'a'; b = short(1); a + b; end
|
|
26
|
+
def str_char; a = 'a'; b = char(123); a + b; end
|
|
27
|
+
def str_int; a = 'a'; b = 1; a + b; end
|
|
28
|
+
def str_long; a = 'a'; b = long(1); a + b; end
|
|
29
|
+
")
|
|
30
|
+
assert_equal("ab", cls.str_str)
|
|
31
|
+
assert_equal("afalse", cls.str_boolean)
|
|
32
|
+
assert_equal("a1.0", cls.str_float)
|
|
33
|
+
assert_equal("a1.0", cls.str_double)
|
|
34
|
+
assert_equal("a1", cls.str_byte)
|
|
35
|
+
assert_equal("a1", cls.str_short)
|
|
36
|
+
assert_equal("a{", cls.str_char)
|
|
37
|
+
assert_equal("a1", cls.str_int)
|
|
38
|
+
assert_equal("a1", cls.str_long)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
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 VarargsTest < Test::Unit::TestCase
|
|
17
|
+
|
|
18
|
+
def test_varargs_method_with_passed_varargs
|
|
19
|
+
cls, = compile(<<-EOF)
|
|
20
|
+
puts String.format("%s %s's", "rocking", "banana")
|
|
21
|
+
EOF
|
|
22
|
+
assert_output "rocking banana's\n" do
|
|
23
|
+
cls.main nil
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_varargs_method_with_passed_including_int_varargs
|
|
28
|
+
cls, = compile(<<-EOF)
|
|
29
|
+
puts String.format("%s %d's", "rocking", 3)
|
|
30
|
+
EOF
|
|
31
|
+
assert_output "rocking 3's\n" do
|
|
32
|
+
cls.main nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_varargs_method_with_passed_including_integer_varargs
|
|
37
|
+
cls, = compile(<<-EOF)
|
|
38
|
+
puts String.format("%s %d's", "rocking", Integer.valueOf(3))
|
|
39
|
+
EOF
|
|
40
|
+
assert_output "rocking 3's\n" do
|
|
41
|
+
cls.main nil
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_varargs_method_lookup_without_passed_varargs
|
|
46
|
+
cls, = compile(<<-EOF)
|
|
47
|
+
puts String.format("rocking with no args")
|
|
48
|
+
EOF
|
|
49
|
+
assert_output "rocking with no args\n" do
|
|
50
|
+
cls.main nil
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_varargs_method_lookup_when_passed_array
|
|
55
|
+
cls, = compile(<<-EOF)
|
|
56
|
+
args = String[1]
|
|
57
|
+
args[0] = "an array"
|
|
58
|
+
puts String.format("rocking with %s", args)
|
|
59
|
+
EOF
|
|
60
|
+
assert_output "rocking with an array\n" do
|
|
61
|
+
cls.main nil
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
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 BaseTypeTest < Test::Unit::TestCase
|
|
20
|
+
java_import 'org.jruby.org.objectweb.asm.Type'
|
|
21
|
+
java_import 'org.jruby.org.objectweb.asm.Opcodes'
|
|
22
|
+
java_import 'org.mirah.jvm.mirrors.BaseType'
|
|
23
|
+
java_import 'org.mirah.jvm.mirrors.Member'
|
|
24
|
+
java_import 'org.mirah.jvm.mirrors.MirrorTypeSystem'
|
|
25
|
+
java_import 'org.mirah.jvm.types.MemberKind'
|
|
26
|
+
java_import 'mirah.lang.ast.TypeRefImpl'
|
|
27
|
+
|
|
28
|
+
def setup
|
|
29
|
+
@types = MirrorTypeSystem.new
|
|
30
|
+
@type = BaseType.new(@types.context, Type.getType("LFooBar;"), 0, nil)
|
|
31
|
+
@void = BaseType.new(@types.context, Type.getType("V"), 0, nil)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def type(name)
|
|
35
|
+
@types.get(nil, TypeRefImpl.new(name, false, false, nil)).resolve
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_tostring
|
|
39
|
+
assert_equal("FooBar", @type.toString)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_assignableFrom
|
|
43
|
+
object = type('java.lang.Object')
|
|
44
|
+
map = type('java.util.Map')
|
|
45
|
+
hashmap = type('java.util.HashMap')
|
|
46
|
+
assert(object.assignableFrom(object))
|
|
47
|
+
assert(object.assignableFrom(map))
|
|
48
|
+
assert(object.assignableFrom(hashmap))
|
|
49
|
+
assert(!map.assignableFrom(object))
|
|
50
|
+
assert(map.assignableFrom(map))
|
|
51
|
+
assert(map.assignableFrom(hashmap))
|
|
52
|
+
assert(!hashmap.assignableFrom(object))
|
|
53
|
+
assert(!hashmap.assignableFrom(map))
|
|
54
|
+
assert(hashmap.assignableFrom(hashmap))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_primitive_widen
|
|
58
|
+
int = type('int')
|
|
59
|
+
long = type('long')
|
|
60
|
+
assert_equal(int, int.widen(int))
|
|
61
|
+
assert_equal(long, long.widen(long))
|
|
62
|
+
assert_equal(long, int.widen(long))
|
|
63
|
+
assert_equal(long, long.widen(int))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_object_widen
|
|
67
|
+
object = type('java.lang.Object')
|
|
68
|
+
map = type('java.util.Map')
|
|
69
|
+
hashmap = type('java.util.HashMap')
|
|
70
|
+
assert_equal(object, object.widen(object))
|
|
71
|
+
assert_equal(object, object.widen(map))
|
|
72
|
+
assert_equal(object, object.widen(hashmap))
|
|
73
|
+
assert_equal(object, map.widen(object))
|
|
74
|
+
assert_equal(map, map.widen(map))
|
|
75
|
+
assert_equal(map, map.widen(hashmap))
|
|
76
|
+
assert_equal(object, hashmap.widen(object))
|
|
77
|
+
assert_equal(map, hashmap.widen(map))
|
|
78
|
+
assert_equal(hashmap, hashmap.widen(hashmap))
|
|
79
|
+
|
|
80
|
+
# TODO: test more complex widening, eg LinkedList.widen(ArrayList)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_box_widen
|
|
84
|
+
object = type('java.lang.Object')
|
|
85
|
+
int = type('int')
|
|
86
|
+
map = type('java.util.Map')
|
|
87
|
+
assert_equal(object, int.widen(map))
|
|
88
|
+
assert_equal(object, map.widen(int))
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_widen_error
|
|
92
|
+
map = type('java.util.Map')
|
|
93
|
+
assert(@void.widen(map).isError)
|
|
94
|
+
assert(map.widen(@void).isError)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
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 BytecodeMirrorTest < Test::Unit::TestCase
|
|
20
|
+
java_import 'org.jruby.org.objectweb.asm.Type'
|
|
21
|
+
java_import 'org.mirah.jvm.mirrors.ClassPath'
|
|
22
|
+
java_import 'org.mirah.jvm.mirrors.MirrorTypeSystem'
|
|
23
|
+
java_import 'org.mirah.jvm.types.JVMTypeUtils'
|
|
24
|
+
|
|
25
|
+
def setup
|
|
26
|
+
types = MirrorTypeSystem.new
|
|
27
|
+
@loader = types.context.get(ClassPath).bytecode_loader
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_parent
|
|
31
|
+
mirror = @loader.loadMirror(Type.getType("I"))
|
|
32
|
+
assert_equal("I", mirror.asm_type.descriptor)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_classloading
|
|
36
|
+
mirror = @loader.loadMirror(Type.getType("Ljava/lang/Object;"))
|
|
37
|
+
assert(!mirror.isError)
|
|
38
|
+
assert_equal("java.lang.Object", mirror.name)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_inner_class
|
|
42
|
+
mirror = @loader.loadMirror(Type.getType("Ljava/util/Map/Entry;"))
|
|
43
|
+
assert(!mirror.isError)
|
|
44
|
+
assert_equal("java.util.Map$Entry", mirror.name)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_superclass
|
|
48
|
+
mirror = @loader.loadMirror(Type.getType("Ljava/lang/String;"))
|
|
49
|
+
assert(!mirror.isError)
|
|
50
|
+
assert_equal("java.lang.String", mirror.name)
|
|
51
|
+
|
|
52
|
+
superclass = mirror.superclass
|
|
53
|
+
assert(!superclass.isError)
|
|
54
|
+
assert_equal("java.lang.Object", superclass.name)
|
|
55
|
+
assert_nil(superclass.superclass)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_interfaces
|
|
59
|
+
mirror = @loader.loadMirror(Type.getType("Ljava/lang/String;"))
|
|
60
|
+
interfaces = mirror.interfaces.map {|t| t.resolve.name}
|
|
61
|
+
assert_equal(['java.io.Serializable', 'java.lang.Comparable', 'java.lang.CharSequence'], interfaces)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_declared_field
|
|
65
|
+
mirror = @loader.loadMirror(Type.getType("Ljava/lang/String;"))
|
|
66
|
+
field = mirror.getDeclaredField('hash')
|
|
67
|
+
assert_equal(mirror, field.declaringClass)
|
|
68
|
+
assert_equal('hash', field.name)
|
|
69
|
+
assert_equal([], field.argumentTypes.to_a)
|
|
70
|
+
assert_equal('I', field.returnType.asm_type.descriptor)
|
|
71
|
+
assert(!field.isVararg)
|
|
72
|
+
assert(!field.isAbstract)
|
|
73
|
+
assert_equal('FIELD_ACCESS', field.kind.name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_array
|
|
77
|
+
mirror = @loader.loadMirror(Type.getType("[Ljava/lang/Object;"))
|
|
78
|
+
assert(JVMTypeUtils.isArray(mirror))
|
|
79
|
+
assert_equal("Ljava/lang/Object;", mirror.getComponentType.asm_type.descriptor)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_retention
|
|
83
|
+
mirror = @loader.loadMirror(Type.getType("Ljava/lang/annotation/Retention;"))
|
|
84
|
+
assert_equal("RUNTIME", mirror.retention)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,776 @@
|
|
|
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 'java'
|
|
17
|
+
require 'test/unit'
|
|
18
|
+
require 'mirah'
|
|
19
|
+
|
|
20
|
+
class GenericsTest < Test::Unit::TestCase
|
|
21
|
+
java_import 'java.util.HashSet'
|
|
22
|
+
java_import 'org.mirah.jvm.mirrors.generics.Constraints'
|
|
23
|
+
java_import 'org.mirah.jvm.mirrors.generics.LubFinder'
|
|
24
|
+
java_import 'org.mirah.jvm.mirrors.generics.TypeParameterInference'
|
|
25
|
+
java_import 'org.mirah.jvm.mirrors.generics.TypeVariable'
|
|
26
|
+
java_import 'org.mirah.jvm.mirrors.generics.TypeInvocation'
|
|
27
|
+
java_import 'org.mirah.jvm.mirrors.generics.Wildcard'
|
|
28
|
+
java_import 'org.mirah.jvm.mirrors.BaseType'
|
|
29
|
+
java_import 'org.mirah.jvm.mirrors.NullType'
|
|
30
|
+
java_import 'org.mirah.jvm.mirrors.MirrorTypeSystem'
|
|
31
|
+
java_import 'org.mirah.jvm.model.Cycle'
|
|
32
|
+
java_import 'org.mirah.jvm.model.IntersectionType'
|
|
33
|
+
java_import 'org.mirah.typer.BaseTypeFuture'
|
|
34
|
+
java_import 'org.jruby.org.objectweb.asm.Type'
|
|
35
|
+
java_import 'javax.lang.model.util.Types'
|
|
36
|
+
|
|
37
|
+
def setup
|
|
38
|
+
@types = MirrorTypeSystem.new
|
|
39
|
+
@type_utils = @types.context.get(Types.java_class)
|
|
40
|
+
@tpi = TypeParameterInference.new(@type_utils)
|
|
41
|
+
@object = type('java.lang.Object')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def set(param)
|
|
45
|
+
g('java.util.Set', [param])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def type(name)
|
|
49
|
+
if name.kind_of?(String)
|
|
50
|
+
@types.loadNamedType(name).resolve
|
|
51
|
+
else
|
|
52
|
+
name
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def g(name, params)
|
|
57
|
+
klass = future(name)
|
|
58
|
+
params = params.map {|x| future(x)}
|
|
59
|
+
@types.parameterize(klass, params).resolve
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def future(x)
|
|
63
|
+
future = BaseTypeFuture.new
|
|
64
|
+
future.resolved(type(x))
|
|
65
|
+
future
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def typevar(name, bounds="java.lang.Object")
|
|
69
|
+
if bounds.kind_of?(String)
|
|
70
|
+
bounds = type(bounds)
|
|
71
|
+
end
|
|
72
|
+
TypeVariable.new(@types.context, name, bounds)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def assert_constraints(constraints, expected={})
|
|
76
|
+
expected_constraints = Constraints.new
|
|
77
|
+
if expected[:super]
|
|
78
|
+
expected[:super].each {|x| expected_constraints.addSuper(x)}
|
|
79
|
+
end
|
|
80
|
+
if expected[:equal]
|
|
81
|
+
expected[:equal].each {|x| expected_constraints.addEqual(x)}
|
|
82
|
+
end
|
|
83
|
+
if expected[:extends]
|
|
84
|
+
expected[:extends].each {|x| expected_constraints.addExtends(x)}
|
|
85
|
+
end
|
|
86
|
+
assert_equal(expected_constraints.toString, constraints.toString)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_null
|
|
90
|
+
a = NullType.new
|
|
91
|
+
f = typevar('S')
|
|
92
|
+
constraints = Constraints.new
|
|
93
|
+
map = {'S' => constraints}
|
|
94
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
95
|
+
assert_equal(0, constraints.size)
|
|
96
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
97
|
+
assert_equal(0, constraints.size)
|
|
98
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
99
|
+
assert_equal(0, constraints.size)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def test_extends_variable
|
|
103
|
+
a = @types.getStringType.resolve
|
|
104
|
+
f = typevar('S')
|
|
105
|
+
constraints = Constraints.new
|
|
106
|
+
map = {'S' => constraints}
|
|
107
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
108
|
+
assert_equal(1, constraints.size)
|
|
109
|
+
assert_equal(HashSet.new([a]), constraints.getSuper)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_extends_primitive
|
|
113
|
+
a = @types.getFixnumType(1).resolve
|
|
114
|
+
f = typevar('S')
|
|
115
|
+
constraints = Constraints.new
|
|
116
|
+
map = {'S' => constraints}
|
|
117
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
118
|
+
assert_equal(1, constraints.size)
|
|
119
|
+
c = constraints.getSuper.iterator.next
|
|
120
|
+
assert_equal 'java.lang.Integer', c.name
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def test_extends_array
|
|
124
|
+
a = @types.getArrayType(@types.getStringType.resolve)
|
|
125
|
+
s = typevar('S')
|
|
126
|
+
f = @types.getArrayType(s)
|
|
127
|
+
constraints = Constraints.new
|
|
128
|
+
map = {'S' => constraints}
|
|
129
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
130
|
+
assert_equal(1, constraints.size)
|
|
131
|
+
c = constraints.getSuper.iterator.next
|
|
132
|
+
assert_equal 'java.lang.String', c.name
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def test_extends_array_variable
|
|
136
|
+
a = typevar('T', @types.getArrayType(@types.getStringType.resolve))
|
|
137
|
+
s = typevar('S')
|
|
138
|
+
f = @types.getArrayType(s)
|
|
139
|
+
constraints = Constraints.new
|
|
140
|
+
map = {'S' => constraints}
|
|
141
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
142
|
+
assert_equal(1, constraints.size)
|
|
143
|
+
c = constraints.getSuper.iterator.next
|
|
144
|
+
assert_equal 'java.lang.String', c.name
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_extends_generic_no_wildcards
|
|
148
|
+
# A = Set<String[]>
|
|
149
|
+
a = set(@types.getArrayType(@types.getStringType.resolve))
|
|
150
|
+
|
|
151
|
+
# F = Set<S[]>
|
|
152
|
+
s = typevar('S')
|
|
153
|
+
constraints = Constraints.new
|
|
154
|
+
map = {'S' => constraints}
|
|
155
|
+
|
|
156
|
+
f = set(@types.getArrayType(s))
|
|
157
|
+
|
|
158
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
159
|
+
|
|
160
|
+
# S = String
|
|
161
|
+
assert_equal(1, constraints.size)
|
|
162
|
+
c = constraints.getEqual.iterator.next
|
|
163
|
+
assert_equal 'java.lang.String', c.name
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def test_extends_f_generic_with_extends_wildcard_a_not_wildcard
|
|
167
|
+
# A = Set<String>
|
|
168
|
+
a = set(@types.getStringType.resolve)
|
|
169
|
+
|
|
170
|
+
# F = Set<? extends S>
|
|
171
|
+
s = typevar('S')
|
|
172
|
+
constraints = Constraints.new
|
|
173
|
+
map = {'S' => constraints}
|
|
174
|
+
f = set(@type_utils.getWildcardType(s, nil))
|
|
175
|
+
|
|
176
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
177
|
+
# S <: String
|
|
178
|
+
assert_equal(1, constraints.size, constraints.toString)
|
|
179
|
+
c = constraints.getSuper.iterator.next
|
|
180
|
+
assert_equal 'java.lang.String', c.name
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
# A = Set<Regex[]>
|
|
184
|
+
a = set(@types.getArrayType((@types.getRegexType.resolve)))
|
|
185
|
+
|
|
186
|
+
constraints = Constraints.new
|
|
187
|
+
map = {'S' => constraints}
|
|
188
|
+
|
|
189
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
190
|
+
# S <: Regex[]
|
|
191
|
+
assert_equal(1, constraints.size)
|
|
192
|
+
c = constraints.getSuper.iterator.next
|
|
193
|
+
assert_equal 'java.util.regex.Pattern[]', c.name, c.java_class
|
|
194
|
+
|
|
195
|
+
# F = Set<? extends S[]>
|
|
196
|
+
f = set(@type_utils.getWildcardType(@types.getArrayType(s), nil))
|
|
197
|
+
constraints = Constraints.new
|
|
198
|
+
map = {'S' => constraints}
|
|
199
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
200
|
+
|
|
201
|
+
# S <: Regex
|
|
202
|
+
assert_equal(1, constraints.size)
|
|
203
|
+
c = constraints.getSuper.iterator.next
|
|
204
|
+
assert_equal 'java.util.regex.Pattern', c.name
|
|
205
|
+
|
|
206
|
+
# A has a supertype Set<Regex[]>
|
|
207
|
+
a = BaseType.new(nil, Type.getType('LFooBar;'), 0, a)
|
|
208
|
+
constraints = Constraints.new
|
|
209
|
+
map = {'S' => constraints}
|
|
210
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
211
|
+
|
|
212
|
+
# S <: Regex
|
|
213
|
+
assert_equal(1, constraints.size)
|
|
214
|
+
c = constraints.getSuper.iterator.next
|
|
215
|
+
assert_equal 'java.util.regex.Pattern', c.name
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def test_extends_f_and_a_are_generic_with_extends_wildcard
|
|
219
|
+
# A = Set<? extends String>
|
|
220
|
+
a = set(@type_utils.getWildcardType(@types.getStringType.resolve, nil))
|
|
221
|
+
|
|
222
|
+
# F = Set<? extends S>
|
|
223
|
+
s = typevar('S')
|
|
224
|
+
constraints = Constraints.new
|
|
225
|
+
map = {'S' => constraints}
|
|
226
|
+
f = set(@type_utils.getWildcardType(s, nil))
|
|
227
|
+
|
|
228
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
229
|
+
# S <: String
|
|
230
|
+
assert_equal(1, constraints.size, constraints.toString)
|
|
231
|
+
c = constraints.getSuper.iterator.next
|
|
232
|
+
assert_equal 'java.lang.String', c.name
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def test_extends_f_has_super_a_not_wildcard
|
|
236
|
+
# A has a supertype Set<String>
|
|
237
|
+
string = @types.getStringType.resolve
|
|
238
|
+
a = BaseType.new(nil, Type.getType('LFooBar;'), 0, set(string))
|
|
239
|
+
|
|
240
|
+
s = typevar('S')
|
|
241
|
+
constraints = Constraints.new
|
|
242
|
+
map = {'S' => constraints}
|
|
243
|
+
|
|
244
|
+
# F = Set<? super S>
|
|
245
|
+
f = set(@type_utils.getWildcardType(nil, s))
|
|
246
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
247
|
+
|
|
248
|
+
# S >: String
|
|
249
|
+
assert_constraints(constraints, :extends => [string])
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def test_extends_f_has_super_a_has_extends
|
|
253
|
+
# A has a supertype Set<? extends String>
|
|
254
|
+
string = @types.getStringType.resolve
|
|
255
|
+
a = BaseType.new(nil, Type.getType('LFooBar;'), 0, set(@type_utils.getWildcardType(string, nil)))
|
|
256
|
+
|
|
257
|
+
s = typevar('S')
|
|
258
|
+
constraints = Constraints.new
|
|
259
|
+
map = {'S' => constraints}
|
|
260
|
+
|
|
261
|
+
# F = Set<? super S>
|
|
262
|
+
f = set(@type_utils.getWildcardType(nil, s))
|
|
263
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
264
|
+
|
|
265
|
+
# no constraints
|
|
266
|
+
assert_constraints(constraints)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def test_extends_f_and_a_have_super
|
|
270
|
+
# A has a supertype Set<? super String>
|
|
271
|
+
string = @types.getStringType.resolve
|
|
272
|
+
a = BaseType.new(nil, Type.getType('LFooBar;'), 0, set(@type_utils.getWildcardType(nil, string)))
|
|
273
|
+
|
|
274
|
+
s = typevar('S')
|
|
275
|
+
constraints = Constraints.new
|
|
276
|
+
map = {'S' => constraints}
|
|
277
|
+
|
|
278
|
+
# F = Set<? super S>
|
|
279
|
+
f = set(@type_utils.getWildcardType(nil, s))
|
|
280
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
281
|
+
|
|
282
|
+
# S >: String
|
|
283
|
+
assert_constraints(constraints, :extends => [string])
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def test_null_type
|
|
287
|
+
assert_not_nil(@type_utils)
|
|
288
|
+
t = @type_utils.getNullType
|
|
289
|
+
assert_not_nil(t)
|
|
290
|
+
assert_equal 'NULL', t.getKind.name
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def test_directSupertypes
|
|
294
|
+
set = @types.loadNamedType('java.util.Set').resolve
|
|
295
|
+
assert_equal(['java.util.Collection'], @type_utils.directSupertypes(set).map {|x| x.name})
|
|
296
|
+
|
|
297
|
+
string = @types.loadNamedType('java.lang.String').resolve
|
|
298
|
+
assert_equal(
|
|
299
|
+
['java.lang.Object', 'java.io.Serializable', 'java.lang.Comparable', 'java.lang.CharSequence'],
|
|
300
|
+
@type_utils.directSupertypes(string).map {|x| x.name})
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def test_findMatchingSupertype
|
|
304
|
+
string = @types.loadNamedType('java.lang.String').resolve
|
|
305
|
+
assert_equal(string, @tpi.findMatchingSupertype(string, string))
|
|
306
|
+
cs = @types.loadNamedType('java.lang.CharSequence').resolve
|
|
307
|
+
assert_equal(cs, @tpi.findMatchingSupertype(string, cs))
|
|
308
|
+
abstract_list = @types.loadNamedType('java.util.AbstractList').resolve
|
|
309
|
+
assert_nil(@tpi.findMatchingSupertype(string, abstract_list))
|
|
310
|
+
|
|
311
|
+
array_list = @types.loadNamedType('java.util.ArrayList').resolve
|
|
312
|
+
assert_equal(abstract_list, @tpi.findMatchingSupertype(array_list, abstract_list))
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def test_equal_variable
|
|
316
|
+
a = @types.getStringType.resolve
|
|
317
|
+
f = typevar('S')
|
|
318
|
+
constraints = Constraints.new
|
|
319
|
+
map = {'S' => constraints}
|
|
320
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
321
|
+
assert_equal(1, constraints.size)
|
|
322
|
+
assert_equal(HashSet.new([a]), constraints.getEqual)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def test_equal_array
|
|
327
|
+
a = @types.getArrayType(@types.getStringType.resolve)
|
|
328
|
+
s = typevar('S')
|
|
329
|
+
f = @types.getArrayType(s)
|
|
330
|
+
constraints = Constraints.new
|
|
331
|
+
map = {'S' => constraints}
|
|
332
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
333
|
+
assert_equal(1, constraints.size)
|
|
334
|
+
c = constraints.getEqual.iterator.next
|
|
335
|
+
assert_equal 'java.lang.String', c.name
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def test_equal_array_variable
|
|
339
|
+
a = typevar('T', @types.getArrayType(@types.getStringType.resolve))
|
|
340
|
+
s = typevar('S')
|
|
341
|
+
f = @types.getArrayType(s)
|
|
342
|
+
constraints = Constraints.new
|
|
343
|
+
map = {'S' => constraints}
|
|
344
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
345
|
+
assert_equal(1, constraints.size)
|
|
346
|
+
c = constraints.getEqual.iterator.next
|
|
347
|
+
assert_equal 'java.lang.String', c.name
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def test_equal_generic_no_wildcards
|
|
351
|
+
# A = Set<String[]>
|
|
352
|
+
a = set(@types.getArrayType(@types.getStringType.resolve))
|
|
353
|
+
|
|
354
|
+
# F = Set<S[]>
|
|
355
|
+
s = typevar('S')
|
|
356
|
+
constraints = Constraints.new
|
|
357
|
+
map = {'S' => constraints}
|
|
358
|
+
|
|
359
|
+
f = set(@types.getArrayType(s))
|
|
360
|
+
|
|
361
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
362
|
+
|
|
363
|
+
# S = String
|
|
364
|
+
assert_equal(1, constraints.size)
|
|
365
|
+
c = constraints.getEqual.iterator.next
|
|
366
|
+
assert_equal 'java.lang.String', c.name
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def test_equal_f_and_a_are_generic_with_extends_wildcard
|
|
370
|
+
# A = Set<? extends String>
|
|
371
|
+
string = @types.getStringType.resolve
|
|
372
|
+
a = set(@type_utils.getWildcardType(string, nil))
|
|
373
|
+
|
|
374
|
+
# F = Set<? extends S>
|
|
375
|
+
s = typevar('S')
|
|
376
|
+
constraints = Constraints.new
|
|
377
|
+
map = {'S' => constraints}
|
|
378
|
+
f = set(@type_utils.getWildcardType(s, nil))
|
|
379
|
+
|
|
380
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
381
|
+
assert_constraints(constraints, :equal => [string])
|
|
382
|
+
assert_equal(1, constraints.size, constraints.toString)
|
|
383
|
+
c = constraints.getEqual.iterator.next
|
|
384
|
+
assert_equal 'java.lang.String', c.name
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
# A = Set<Regex[]>
|
|
388
|
+
re = @types.getRegexType.resolve
|
|
389
|
+
re_array = @types.getArrayType(re)
|
|
390
|
+
a = set(@type_utils.getWildcardType(re_array, nil))
|
|
391
|
+
|
|
392
|
+
constraints = Constraints.new
|
|
393
|
+
map = {'S' => constraints}
|
|
394
|
+
|
|
395
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
396
|
+
# S = Regex[]
|
|
397
|
+
assert_constraints(constraints, :equal => [re_array])
|
|
398
|
+
|
|
399
|
+
# F = Set<? extends S[]>
|
|
400
|
+
f = set(@type_utils.getWildcardType(@types.getArrayType(s), nil))
|
|
401
|
+
constraints = Constraints.new
|
|
402
|
+
map = {'S' => constraints}
|
|
403
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
404
|
+
|
|
405
|
+
# S = Regex
|
|
406
|
+
assert_constraints(constraints, :equal => [re])
|
|
407
|
+
|
|
408
|
+
# A has a supertype Set<Regex[]>
|
|
409
|
+
a = BaseType.new(nil, Type.getType('LFooBar;'), 0, a)
|
|
410
|
+
constraints = Constraints.new
|
|
411
|
+
map = {'S' => constraints}
|
|
412
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
413
|
+
|
|
414
|
+
# No constraint
|
|
415
|
+
assert_constraints(constraints)
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
def test_equal_f_generic_with_extends_wildcard_a_not_wildcard
|
|
419
|
+
# A = Set<String>
|
|
420
|
+
a = set(@types.getStringType.resolve)
|
|
421
|
+
|
|
422
|
+
# F = Set<? extends S>
|
|
423
|
+
s = typevar('S')
|
|
424
|
+
constraints = Constraints.new
|
|
425
|
+
map = {'S' => constraints}
|
|
426
|
+
f = set(@type_utils.getWildcardType(s, nil))
|
|
427
|
+
|
|
428
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
429
|
+
# No constraints
|
|
430
|
+
assert_constraints(constraints)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
def test_equal_f_generic_with_super
|
|
434
|
+
# A = Set<String>
|
|
435
|
+
a = set(@types.getStringType.resolve)
|
|
436
|
+
|
|
437
|
+
# F = Set<? super S>
|
|
438
|
+
s = typevar('S')
|
|
439
|
+
constraints = Constraints.new
|
|
440
|
+
map = {'S' => constraints}
|
|
441
|
+
f = set(@type_utils.getWildcardType(nil, s))
|
|
442
|
+
|
|
443
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
444
|
+
# No constraints
|
|
445
|
+
assert_constraints(constraints)
|
|
446
|
+
|
|
447
|
+
# A = Set<? super String>
|
|
448
|
+
string = @types.getStringType.resolve
|
|
449
|
+
a = set(@type_utils.getWildcardType(nil, string))
|
|
450
|
+
@tpi.processArgument(a, ?=.ord, f, map)
|
|
451
|
+
|
|
452
|
+
# S = String
|
|
453
|
+
assert_constraints(constraints, :equal => [string])
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
def test_super_variable
|
|
458
|
+
a = @types.getStringType.resolve
|
|
459
|
+
f = typevar('S')
|
|
460
|
+
constraints = Constraints.new
|
|
461
|
+
map = {'S' => constraints}
|
|
462
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
463
|
+
# T <: A
|
|
464
|
+
assert_constraints(constraints, :extends => [a])
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
def test_super_array
|
|
468
|
+
a = @types.getArrayType(@types.getStringType.resolve)
|
|
469
|
+
s = typevar('S')
|
|
470
|
+
f = @types.getArrayType(s)
|
|
471
|
+
constraints = Constraints.new
|
|
472
|
+
map = {'S' => constraints}
|
|
473
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
474
|
+
assert_constraints(constraints, :extends => [a.getComponentType])
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def test_super_array_variable
|
|
478
|
+
string = @types.getStringType.resolve
|
|
479
|
+
a = typevar('T', @types.getArrayType(string))
|
|
480
|
+
s = typevar('S')
|
|
481
|
+
f = @types.getArrayType(s)
|
|
482
|
+
constraints = Constraints.new
|
|
483
|
+
map = {'S' => constraints}
|
|
484
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
485
|
+
assert_constraints(constraints, :extends => [string])
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def test_super_generic_no_wildcards
|
|
489
|
+
# A = Set<String[]>
|
|
490
|
+
string = @types.getStringType.resolve
|
|
491
|
+
str_array = a = set(@types.getArrayType(string))
|
|
492
|
+
|
|
493
|
+
# F = Set<S[]>
|
|
494
|
+
s = typevar('S')
|
|
495
|
+
constraints = Constraints.new
|
|
496
|
+
map = {'S' => constraints}
|
|
497
|
+
|
|
498
|
+
f = set(@types.getArrayType(s))
|
|
499
|
+
|
|
500
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
501
|
+
|
|
502
|
+
# S = String
|
|
503
|
+
assert_constraints(constraints, :equal => [string])
|
|
504
|
+
|
|
505
|
+
# A = Set<? extends String>
|
|
506
|
+
a = set(@type_utils.getWildcardType(string, nil))
|
|
507
|
+
|
|
508
|
+
# F has supertype Set<String>
|
|
509
|
+
f = BaseType.new(nil, Type.getType("LFooBar;"), 0, set(s))
|
|
510
|
+
constraints = Constraints.new
|
|
511
|
+
map = {'S' => constraints}
|
|
512
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
513
|
+
assert_constraints(constraints, :extends => [string])
|
|
514
|
+
|
|
515
|
+
# A = Set<? super String>
|
|
516
|
+
a = set(@type_utils.getWildcardType(nil, string))
|
|
517
|
+
constraints = Constraints.new
|
|
518
|
+
map = {'S' => constraints}
|
|
519
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
520
|
+
assert_constraints(constraints, :super => [string])
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
def test_super_f_and_a_are_generic_with_extends_wildcard
|
|
524
|
+
# A = Set<? extends String>
|
|
525
|
+
string = @types.getStringType.resolve
|
|
526
|
+
a = set(@type_utils.getWildcardType(string, nil))
|
|
527
|
+
|
|
528
|
+
# F = Set<? extends S>
|
|
529
|
+
s = typevar('S')
|
|
530
|
+
constraints = Constraints.new
|
|
531
|
+
map = {'S' => constraints}
|
|
532
|
+
f = set(@type_utils.getWildcardType(s, nil))
|
|
533
|
+
|
|
534
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
535
|
+
assert_constraints(constraints, :extends => [string])
|
|
536
|
+
|
|
537
|
+
# A = Set<Regex[]>
|
|
538
|
+
re = @types.getRegexType.resolve
|
|
539
|
+
re_array = @types.getArrayType(re)
|
|
540
|
+
a = set(@type_utils.getWildcardType(re_array, nil))
|
|
541
|
+
|
|
542
|
+
constraints = Constraints.new
|
|
543
|
+
map = {'S' => constraints}
|
|
544
|
+
|
|
545
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
546
|
+
# S = Regex[]
|
|
547
|
+
assert_constraints(constraints, :extends => [re_array])
|
|
548
|
+
|
|
549
|
+
# F = Set<? extends S[]>
|
|
550
|
+
f = set(@type_utils.getWildcardType(@types.getArrayType(s), nil))
|
|
551
|
+
constraints = Constraints.new
|
|
552
|
+
map = {'S' => constraints}
|
|
553
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
554
|
+
|
|
555
|
+
# S = Regex
|
|
556
|
+
assert_constraints(constraints, :extends => [re])
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def test_super_f_generic_with_extends_wildcard_a_not_wildcard
|
|
560
|
+
# A = Set<String>
|
|
561
|
+
a = set(@types.getStringType.resolve)
|
|
562
|
+
|
|
563
|
+
# F = Set<? extends S>
|
|
564
|
+
s = typevar('S')
|
|
565
|
+
constraints = Constraints.new
|
|
566
|
+
map = {'S' => constraints}
|
|
567
|
+
f = set(@type_utils.getWildcardType(s, nil))
|
|
568
|
+
|
|
569
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
570
|
+
# No constraints
|
|
571
|
+
assert_constraints(constraints)
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
def test_super_f_generic_with_super
|
|
575
|
+
# A = Set<String>
|
|
576
|
+
a = set(@types.getStringType.resolve)
|
|
577
|
+
|
|
578
|
+
# F = Set<? super S>
|
|
579
|
+
s = typevar('S')
|
|
580
|
+
constraints = Constraints.new
|
|
581
|
+
map = {'S' => constraints}
|
|
582
|
+
f = set(@type_utils.getWildcardType(nil, s))
|
|
583
|
+
|
|
584
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
585
|
+
# No constraints
|
|
586
|
+
assert_constraints(constraints)
|
|
587
|
+
|
|
588
|
+
# A = Set<? super String>
|
|
589
|
+
string = @types.getStringType.resolve
|
|
590
|
+
a = set(@type_utils.getWildcardType(nil, string))
|
|
591
|
+
@tpi.processArgument(a, ?>.ord, f, map)
|
|
592
|
+
|
|
593
|
+
# S = String
|
|
594
|
+
assert_constraints(constraints, :super => [string])
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
def test_multi_generic
|
|
598
|
+
klass = BaseType.new(nil, Type.getType("LFooBar;"), 0, nil)
|
|
599
|
+
string = @types.getStringType
|
|
600
|
+
a = TypeInvocation.new(nil, klass, future(klass.superclass), klass.interfaces,
|
|
601
|
+
[string, string, string], {})
|
|
602
|
+
|
|
603
|
+
r = typevar('R')
|
|
604
|
+
s = typevar('S')
|
|
605
|
+
t = typevar('T')
|
|
606
|
+
|
|
607
|
+
f = TypeInvocation.new(nil, klass, future(klass.superclass), klass.interfaces,
|
|
608
|
+
[future(r), future(@type_utils.getWildcardType(s, nil)), future(@type_utils.getWildcardType(nil, t))], {})
|
|
609
|
+
rc = Constraints.new
|
|
610
|
+
sc = Constraints.new
|
|
611
|
+
tc = Constraints.new
|
|
612
|
+
map = {'R' => rc, 'S' => sc, 'T' => tc}
|
|
613
|
+
@tpi.processArgument(a, ?<.ord, f, map)
|
|
614
|
+
string = string.resolve
|
|
615
|
+
assert_constraints(rc, :equal => [string])
|
|
616
|
+
assert_constraints(sc, :super => [string])
|
|
617
|
+
assert_constraints(tc, :extends => [string])
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
def test_cycle
|
|
621
|
+
klass = BaseType.new(nil, Type.getType("LFooBar;"), 0, nil)
|
|
622
|
+
cycle = Cycle.new
|
|
623
|
+
a = TypeInvocation.new(nil, klass, future(klass.superclass), klass.interfaces, [future(cycle)], {})
|
|
624
|
+
cycle.target_set(a)
|
|
625
|
+
assert_equal("FooBar<FooBar<FooBar<...>>>", a.toString)
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
def test_erasure
|
|
629
|
+
t = @types.getFixnumType(0).resolve
|
|
630
|
+
assert_same(t, @type_utils.erasure(t))
|
|
631
|
+
t = @types.getStringType.resolve
|
|
632
|
+
assert_same(t, @type_utils.erasure(t))
|
|
633
|
+
t = @types.getArrayType(t)
|
|
634
|
+
assert_equal(t.toString, @type_utils.erasure(t).toString)
|
|
635
|
+
t = set(t)
|
|
636
|
+
assert_equal("java.util.Set<java.lang.String[]>", t.toString)
|
|
637
|
+
e = @type_utils.erasure(t)
|
|
638
|
+
assert_not_same(t, e)
|
|
639
|
+
assert_equal([], e.type_arguments.to_a)
|
|
640
|
+
assert_equal("java.util.Set", e.toString)
|
|
641
|
+
t = @type_utils.getArrayType(t)
|
|
642
|
+
assert_equal("java.util.Set<java.lang.String[]>[]", t.toString)
|
|
643
|
+
e = @type_utils.erasure(t)
|
|
644
|
+
assert_equal("java.util.Set[]", e.toString)
|
|
645
|
+
t = IntersectionType.new(@types.context,
|
|
646
|
+
[type('java.io.Serializable'),
|
|
647
|
+
type('java.lang.CharSequence')])
|
|
648
|
+
e = @type_utils.erasure(t)
|
|
649
|
+
assert_equal(type('java.io.Serializable'), e, e.toString)
|
|
650
|
+
t = IntersectionType.new(@types.context,
|
|
651
|
+
[type('java.io.Serializable'),
|
|
652
|
+
type('java.util.AbstractMap')])
|
|
653
|
+
e = @type_utils.erasure(t)
|
|
654
|
+
assert_equal(type('java.util.AbstractMap'), e)
|
|
655
|
+
t = typevar("S")
|
|
656
|
+
e = @type_utils.erasure(t)
|
|
657
|
+
assert_equal(type('java.lang.Object'), e, e.toString)
|
|
658
|
+
t = typevar("S", 'java.lang.Iterable')
|
|
659
|
+
e = @type_utils.erasure(t)
|
|
660
|
+
assert_equal(type('java.lang.Iterable'), e, e.toString)
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
def test_generic_array_supertype
|
|
664
|
+
s = set(type('java.lang.String'))
|
|
665
|
+
a = @types.getArrayType(s)
|
|
666
|
+
assert_equal('java.util.Set<java.lang.String>[]', a.toString)
|
|
667
|
+
supertypes = a.directSupertypes
|
|
668
|
+
assert_equal('[java.util.Set[], java.util.Collection<java.lang.String>[]]',
|
|
669
|
+
supertypes.toString)
|
|
670
|
+
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
def test_type_invocation
|
|
674
|
+
a = set(type('java.lang.String'))
|
|
675
|
+
b = type('java.util.Set')
|
|
676
|
+
assert(b.isSupertypeOf(a))
|
|
677
|
+
# Set<E> isn't really a supertype of Set, but we allow it to make unchecked conversion work.
|
|
678
|
+
# assert(!a.isSupertypeOf(b))
|
|
679
|
+
assert(b.isSupertypeOf(b))
|
|
680
|
+
assert(b.isSameType(b))
|
|
681
|
+
assert(!b.isSameType(a))
|
|
682
|
+
assert(!a.isSameType(b))
|
|
683
|
+
|
|
684
|
+
c = set(type('java.lang.CharSequence'))
|
|
685
|
+
assert(c.isSupertypeOf(a))
|
|
686
|
+
assert(!a.isSupertypeOf(c))
|
|
687
|
+
assert(!c.isSameType(a))
|
|
688
|
+
|
|
689
|
+
d = g('java.lang.Iterable', [type('java.lang.CharSequence')])
|
|
690
|
+
assert(d.isSupertypeOf(a))
|
|
691
|
+
assert(d.isSupertypeOf(c))
|
|
692
|
+
assert(!c.isSupertypeOf(d))
|
|
693
|
+
assert(!a.isSupertypeOf(d))
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
def test_erased_supertypes
|
|
697
|
+
lub = LubFinder.new(@types.context)
|
|
698
|
+
t = @types.getStringType.resolve
|
|
699
|
+
m = lub.erasedSupertypes(t)
|
|
700
|
+
assert_equal(
|
|
701
|
+
['java.lang.String', 'java.lang.Object',
|
|
702
|
+
'java.io.Serializable', 'java.lang.Comparable',
|
|
703
|
+
'java.lang.CharSequence'
|
|
704
|
+
], m.key_set.map{|x| x.toString})
|
|
705
|
+
|
|
706
|
+
t = set(t)
|
|
707
|
+
m = lub.erasedSupertypes(t)
|
|
708
|
+
assert_equal(
|
|
709
|
+
['java.util.Set', 'java.util.Collection',
|
|
710
|
+
'java.lang.Iterable', 'java.lang.Object'
|
|
711
|
+
], m.key_set.map{|x| x.toString})
|
|
712
|
+
assert_equal(
|
|
713
|
+
['[java.util.Set<java.lang.String>]',
|
|
714
|
+
'[java.util.Collection<java.lang.String>]',
|
|
715
|
+
'[java.lang.Iterable<java.lang.String>]',
|
|
716
|
+
'[java.lang.Object]'
|
|
717
|
+
], m.values.map{|x| x.toString})
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
def test_minimizeErasedCandidates
|
|
721
|
+
lub = LubFinder.new(@types.context)
|
|
722
|
+
t = set(@types.getStringType.resolve)
|
|
723
|
+
s = g('java.util.Collection', [type('java.lang.CharSequence')])
|
|
724
|
+
candidates = lub.erasedCandidateSet([t, s])
|
|
725
|
+
assert_equal(['java.util.Collection', 'java.lang.Iterable', 'java.lang.Object'],
|
|
726
|
+
candidates.key_set.map{|x| x.toString})
|
|
727
|
+
lub.minimizeErasedCandidates(candidates.key_set)
|
|
728
|
+
assert_equal(['java.util.Collection'],
|
|
729
|
+
candidates.key_set.map{|x| x.toString})
|
|
730
|
+
candidates = HashSet.new(candidates.values.iterator.next.map {|x| x.toString})
|
|
731
|
+
assert_equal(HashSet.new(
|
|
732
|
+
["java.util.Collection<java.lang.String>",
|
|
733
|
+
"java.util.Collection<java.lang.CharSequence>"
|
|
734
|
+
]), candidates)
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
def test_lub
|
|
738
|
+
finder = LubFinder.new(@types.context)
|
|
739
|
+
string = type('java.lang.String')
|
|
740
|
+
lub = finder.leastUpperBound([string])
|
|
741
|
+
assert_equal(string, lub, lub.toString)
|
|
742
|
+
|
|
743
|
+
cs = type('java.lang.CharSequence')
|
|
744
|
+
lub = finder.leastUpperBound([string, cs])
|
|
745
|
+
assert_equal(cs, lub, lub.toString)
|
|
746
|
+
|
|
747
|
+
a = set(string)
|
|
748
|
+
lub = finder.leastUpperBound([a, a])
|
|
749
|
+
assert_equal(a, lub, lub.toString)
|
|
750
|
+
|
|
751
|
+
b = g('java.lang.Iterable', [type('java.io.Serializable')])
|
|
752
|
+
lub = finder.leastUpperBound([a, b])
|
|
753
|
+
assert_equal('java.lang.Iterable<? extends java.io.Serializable>',
|
|
754
|
+
lub.toString)
|
|
755
|
+
|
|
756
|
+
c = set(a)
|
|
757
|
+
lub = finder.leastUpperBound([a, c])
|
|
758
|
+
assert_equal('java.util.Set<?>', lub.toString)
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
def test_lub_cycle
|
|
762
|
+
finder = LubFinder.new(@types.context)
|
|
763
|
+
string = type('java.lang.String')
|
|
764
|
+
integer = type('java.lang.Integer')
|
|
765
|
+
lub = finder.leastUpperBound([string, integer])
|
|
766
|
+
assert_match(/\? extends java\.lang\.Comparable<\? extends ...>/,
|
|
767
|
+
lub.toString)
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
def test_non_generic_type_with_generic_superclass
|
|
771
|
+
string = @types.getStringType.resolve
|
|
772
|
+
interfaces = string.interfaces.map {|x| x.resolve.toString}
|
|
773
|
+
assert_equal(["java.lang.Comparable<java.lang.String>"],
|
|
774
|
+
interfaces.grep(/Comparable/))
|
|
775
|
+
end
|
|
776
|
+
end
|