blob: c692e188dd072bfdc1186af96ee5457f8a9f16d3 [file] [log] [blame]
package gls.generics.vm5
class GenericsTest extends GenericsTestBase {
public void testClassWithoutParameterExtendsClassWithFixedParameter() {
createClassInfo """
class B extends ArrayList<Long> {}
"""
assert signatures==[
"class" : "Ljava/util/ArrayList<Ljava/lang/Long;>;Lgroovy/lang/GroovyObject;",
]
}
public void testMultipleImplementsWithParameter() {
createClassInfo """
abstract class B<T> implements Runnable,List<T> {}
"""
assert signatures == ["class":"<T:Ljava/lang/Object;>Ljava/lang/Object;Ljava/lang/Runnable;Ljava/util/List<TT;>;Lgroovy/lang/GroovyObject;"]
}
public void testImplementsWithParameter() {
createClassInfo """
abstract class B<T> implements List<T> {}
"""
assert signatures==["class":"<T:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/List<TT;>;Lgroovy/lang/GroovyObject;"]
}
public void testExtendsWithParameter() {
createClassInfo """
class B<T> extends ArrayList<T> {}
"""
assert signatures==["class":"<T:Ljava/lang/Object;>Ljava/util/ArrayList<TT;>;Lgroovy/lang/GroovyObject;"]
}
public void testNestedExtendsWithParameter() {
createClassInfo """
class B<T> extends HashMap<T,List<T>> {}
"""
assert signatures == ["class":"<T:Ljava/lang/Object;>Ljava/util/HashMap<TT;Ljava/util/List<TT;>;>;Lgroovy/lang/GroovyObject;"]
}
public void testBoundInterface() {
createClassInfo """
class B<T extends List> {}
"""
assert signatures == ["class":"<T::Ljava/util/List;>Ljava/lang/Object;Lgroovy/lang/GroovyObject;"]
}
public void testNestedReuseOfParameter() {
createClassInfo """
class B<Y,T extends Map<String,Map<Y,Integer>>> {}
"""
assert signatures == ["class":"<Y:Ljava/lang/Object;T::Ljava/util/Map<Ljava/lang/String;Ljava/util/Map<TY;Ljava/lang/Integer;>;>;>Ljava/lang/Object;Lgroovy/lang/GroovyObject;"]
}
public void testFieldWithParameter() {
createClassInfo """
class B { public Collection<Integer> books }
"""
assert signatures == [books : "Ljava/util/Collection<Ljava/lang/Integer;>;"]
}
public void testFieldReusedParameter() {
createClassInfo """
class B<T> { public Collection<T> collection }
"""
assert signatures == ["class" : "<T:Ljava/lang/Object;>Ljava/lang/Object;Lgroovy/lang/GroovyObject;",
collection : "Ljava/util/Collection<TT;>;"]
}
public void testParameterAsReturnType() {
createClassInfo """
class B {
static <T> T foo() {return null}
}
"""
assert signatures == ["foo()Ljava/lang/Object;":"<T:Ljava/lang/Object;>()TT;"]
}
public void testParameterAsReturnTypeAndParameter() {
createClassInfo """
class B {
static <T> T foo(T t) {return null}
}
"""
assert signatures == ["foo(Ljava/lang/Object;)Ljava/lang/Object;":"<T:Ljava/lang/Object;>(TT;)TT;"]
}
public void testParameterAsMethodParameter() {
createClassInfo """
class B<T> {
void foo(T t){}
}
"""
assert signatures == ["class" : "<T:Ljava/lang/Object;>Ljava/lang/Object;Lgroovy/lang/GroovyObject;",
"foo(Ljava/lang/Object;)V":"(TT;)V"]
}
public void testParameterAsNestedMethodParameter() {
createClassInfo """
class B<T> {
void foo(List<T> t){}
}
"""
assert signatures == ["class" : "<T:Ljava/lang/Object;>Ljava/lang/Object;Lgroovy/lang/GroovyObject;",
"foo(Ljava/util/List;)V":"(Ljava/util/List<TT;>;)V"]
}
public void testParameterAsNestedMethodParameterReturningInterface() {
createClassInfo """
class B<T> {
Cloneable foo(List<T> t){}
}
"""
assert signatures == ["class" : "<T:Ljava/lang/Object;>Ljava/lang/Object;Lgroovy/lang/GroovyObject;",
"foo(Ljava/util/List;)Ljava/lang/Cloneable;":"(Ljava/util/List<TT;>;)Ljava/lang/Cloneable;"]
}
public void testMultipleBounds() {
createClassInfo """
class Pair< A extends Comparable<A> & Cloneable ,
B extends Cloneable & Comparable<B> >
{
A foo(){}
B bar(){}
}
"""
assert signatures ==
["class" : "<A::Ljava/lang/Comparable<TA;>;:Ljava/lang/Cloneable;B::Ljava/lang/Cloneable;:Ljava/lang/Comparable<TB;>;>Ljava/lang/Object;Lgroovy/lang/GroovyObject;",
"foo()Ljava/lang/Comparable;" : "()TA;",
"bar()Ljava/lang/Cloneable;" : "()TB;"]
}
public void testWildCard() {
createClassInfo """
class B {
private Collection<?> f1
private List<? extends Number> f2
private Comparator<? super String> f3
private Map<String,?> f4
}
"""
assert signatures==[
f1 : "Ljava/util/Collection<*>;",
f2 : "Ljava/util/List<+Ljava/lang/Number;>;",
f3 : "Ljava/util/Comparator<-Ljava/lang/String;>;",
f4 : "Ljava/util/Map<Ljava/lang/String;*>;"
]
}
public void testParameterAsParameterForReturnTypeAndFieldClass() {
createClassInfo """
public class B<T> {
private T owner;
public Class<T> getOwnerClass(){}
}
"""
assert signatures==[
"class" : "<T:Ljava/lang/Object;>Ljava/lang/Object;Lgroovy/lang/GroovyObject;",
"owner" : "TT;",
"getOwnerClass()Ljava/lang/Class;" : "()Ljava/lang/Class<TT;>;"
]
}
public void testInterfaceWithParameter() {
createClassInfo """
interface B<T> {}
"""
assert signatures == ["class" : "<T:Ljava/lang/Object;>Ljava/lang/Object;"]
}
public void testInvalidParameterUsage() {
shouldNotCompile """
abstract class B<T> implements Map<T>{}
"""
shouldNotCompile """
class A<T,V> extends ArrayList<T,V>{}
"""
shouldNotCompile """
class A<T extends Number> {}
class B<T> extends A<T>{}
"""
shouldNotCompile """
class B<T> extends ArrayList<?>{}
"""
}
void testCovariantReturn() {
shouldNotCompile """
class A<T> {
T foo(T t) {1}
}
class B extends A<Long>{
String foo(Long l){"2"}
}
"""
assertScript """
class A<T> {
T foo(T t) {1}
}
class B extends A<Long>{
Long foo(Long l){2}
}
def b = new B();
try {
b.foo(new Object())
assert false
} catch (ClassCastException cce) {
assert true
}
assert b.foo((Long) 1) == 2
"""
}
void testCovariantReturnWithInterface() {
assertScript """
import java.util.concurrent.*
class CallableTask implements Callable<String> {
public String call() { "x" }
}
def task = new CallableTask()
assert task.call() == "x"
"""
}
}