mirah 0.1.0.pre-java → 0.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/History.txt +736 -0
  2. data/README.md +71 -0
  3. data/Rakefile +227 -73
  4. data/examples/Fib.class +0 -0
  5. data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +2 -3
  6. data/examples/simple_class.mirah +3 -3
  7. data/examples/{dynamic.mirah → simple_class.mirah~} +7 -12
  8. data/javalib/mirah-bootstrap.jar +0 -0
  9. data/javalib/mirah-builtins.jar +0 -0
  10. data/javalib/mirah-compiler.jar +0 -0
  11. data/javalib/mirah-parser.jar +0 -0
  12. data/javalib/mirah-util.jar +0 -0
  13. data/lib/mirah.rb +8 -1
  14. data/lib/mirah/ast.rb +1 -1
  15. data/lib/mirah/ast/scope.rb +16 -0
  16. data/lib/mirah/commands/base.rb +1 -3
  17. data/lib/mirah/compiler.rb +17 -3
  18. data/lib/mirah/errors.rb +10 -10
  19. data/lib/mirah/generator.rb +21 -9
  20. data/lib/mirah/jvm/compiler.rb +17 -0
  21. data/lib/mirah/jvm/compiler/base.rb +24 -5
  22. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +83 -20
  23. data/lib/mirah/jvm/method_lookup.rb +43 -22
  24. data/lib/mirah/jvm/types.rb +1 -2
  25. data/lib/mirah/jvm/types/array_type.rb +1 -6
  26. data/lib/mirah/jvm/types/ast_ext.rb +31 -0
  27. data/lib/mirah/jvm/types/basic_types.rb +1 -2
  28. data/lib/mirah/jvm/types/boolean.rb +11 -10
  29. data/lib/mirah/jvm/types/extensions.rb +14 -5
  30. data/lib/mirah/jvm/types/factory.rb +128 -43
  31. data/lib/mirah/jvm/types/floats.rb +8 -10
  32. data/lib/mirah/jvm/types/integers.rb +16 -9
  33. data/lib/mirah/jvm/types/intrinsics.rb +17 -69
  34. data/lib/mirah/jvm/types/meta_type.rb +5 -0
  35. data/lib/mirah/jvm/types/methods.rb +317 -151
  36. data/lib/mirah/jvm/types/methods.rb~ +973 -0
  37. data/lib/mirah/jvm/types/number.rb +29 -6
  38. data/lib/mirah/jvm/types/primitive_type.rb +35 -7
  39. data/lib/mirah/jvm/types/source_mirror.rb +11 -6
  40. data/lib/mirah/jvm/types/type.rb +52 -0
  41. data/lib/mirah/jvm/types/type_definition.rb +8 -2
  42. data/lib/mirah/transform/ast_ext.rb +9 -31
  43. data/lib/mirah/transform/transformer.rb +1 -1
  44. data/lib/mirah/typer.rb +2 -1
  45. data/lib/mirah/util/argument_processor.rb +10 -14
  46. data/lib/mirah/util/argument_processor.rb~ +146 -0
  47. data/lib/mirah/util/compilation_state.rb +15 -9
  48. data/lib/mirah/util/process_errors.rb +8 -2
  49. data/lib/mirah/version.rb +2 -2
  50. data/lib/mirah_task.rb +0 -7
  51. data/test/core/typer_test.rb +21 -13
  52. data/test/core/util/argument_processor_test.rb +19 -19
  53. data/test/core/util/class_loader_test.rb +19 -4
  54. data/test/core/util/compilation_state_test.rb +38 -0
  55. data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
  56. data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
  57. data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
  58. data/test/jvm/blocks_test.rb +50 -29
  59. data/test/jvm/bytecode_test_helper.rb +71 -57
  60. data/test/jvm/cast_test.rb +162 -0
  61. data/test/jvm/constructors_test.rb +48 -0
  62. data/test/jvm/enumerable_test.rb +136 -7
  63. data/test/jvm/example_test.rb +39 -0
  64. data/test/jvm/factory_test.rb +6 -0
  65. data/test/jvm/generics_test.rb +0 -5
  66. data/test/jvm/import_test.rb +81 -0
  67. data/test/jvm/interface_test.rb +113 -0
  68. data/test/jvm/java_typer_test.rb +57 -11
  69. data/test/jvm/jvm_commands_test.rb +24 -0
  70. data/test/jvm/jvm_compiler_test.rb +186 -370
  71. data/test/jvm/macros_test.rb +67 -6
  72. data/test/jvm/main_method_test.rb +1 -1
  73. data/test/jvm/mirror_compilation_test_helper.rb +24 -0
  74. data/test/jvm/new_backend_test_helper.rb +25 -0
  75. data/test/jvm/rescue_test.rb +153 -18
  76. data/test/jvm/string_test.rb +41 -0
  77. data/test/jvm/varargs_test.rb +65 -0
  78. data/test/mirrors/base_type_test.rb +96 -0
  79. data/test/mirrors/bytecode_mirror_test.rb +86 -0
  80. data/test/mirrors/generics_test.rb +776 -0
  81. data/test/mirrors/member_test.rb +69 -0
  82. data/test/mirrors/method_lookup_test.rb +574 -0
  83. data/test/mirrors/mirrors_test.rb +562 -0
  84. data/test/mirrors/simple_async_mirror_loader_test.rb +110 -0
  85. data/test/mirrors/simple_mirror_loader_test.rb +104 -0
  86. data/test/test_helper.rb +2 -1
  87. metadata +244 -217
  88. data/README.txt +0 -59
  89. data/javalib/dynalink-0.2.jar +0 -0
  90. data/lib/mirah/jvm/typer.rb +0 -177
  91. data/lib/mirah/jvm/types/dynamic_type.rb +0 -45
  92. 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