package org.jmlspecs.openjmltest.testcases;
import org.jmlspecs.openjmltest.TCBase;
import org.junit.Assert;
import org.junit.Test;
/** These tests do typechecking on all the aspects of JML types.
* <BR> \TYPE - the type of types in JML, somewhat like, but not equivalent to Class<?>
* <BR> \type - (type \TYPE) type literal in JML, similar to T.class
* <BR> \typeof - (type \TYPE) dynamic type in JML, similar to getClass()
* <BR> \elemtype - element type of array type
* <BR> <: - is subtype of - similar to isAssignableFrom
* @author David R. Cok
*
*/
public class jmltypes extends TCBase {
@Override
public void setUp() throws Exception {
// noCollectDiagnostics = true;
// jmldebug = true;
useSystemSpecs = true; // Needed for JML.erasure
super.setUp();
}
@Test
public void testUninitGhost() {
helpTCF("A.java",
"import java.util.Vector; public class A { \n" +
" void m() {\n" +
" Class<?> c = Object.class; Object o = c; \n" +
" //@ ghost \\TYPE t;\n" +
" //@ ghost \\TYPE tt = \\type(Object);\n" +
" //@ set tt = \\type(int);\n" +
" //@ set tt = \\type(Vector<Integer>);\n" +
" //@ ghost \\TYPE ttt = \\typeof(o);\n" +
" //@ ghost boolean b = \\type(Object) == tt;\n" +
" //@ set b = \\typeof(o) == tt;\n" +
" //@ set b = (\\TYPE)c == t; \n" + // Casts allowed
" //@ set t = \\elemtype(t); \n" + // Allow elemtype on TYPE, returning TYPE
" //@ set c = \\elemtype(c); \n" + // Allow elemtype on Class, returning Class
" //@ set b = tt <: ttt;\n" +
" }\n" +
"}\n"
,"/A.java:11: variable t might not have been initialized",27
);
}
@Test
public void testOK1() {
helpTCF("A.java",
"public class A { \n" +
" void m() {\n" +
" Class<?> c = Object.class; Object o = c; \n" +
" //@ ghost boolean b = JML.erasure(\\typeof(o)) == Object.class;\n" +
" //@ set b = JML.typeargs(\\typeof(o)).length == 0;\n" +
" //@ set b = JML.typeargs(\\typeof(o))[0] != \\typeof(o);\n" +
" //@ set b = JML.isArray(\\typeof(o));\n" +
" boolean jb = c.isArray();\n" +
" }\n" +
"}\n"
);
}
@Test
public void testOK2() {
helpTCF("A.java",
"public class A { \n" +
" void m() {\n" +
" Class<?> c = Object.class; Object o = c; \n" +
" //@ ghost \\TYPE t;\n" +
" //@ ghost boolean b = JML.typeargs(\\type(Object)).length == 0;\n" +
" //@ set b = JML.typeargs(\\elemtype(t)).length == 0;\n" +
" }\n" +
"}\n"
);
}
@Test
public void testOK3() {
helpTCF("A.java",
"class B<T> {}\n" +
"public class A<T> { \n" +
" void m() {\n" +
" Class<?> c = Object.class; Object o = c; \n" +
" //@ ghost \\TYPE w = \\type(B<Integer>);\n" +
" //@ ghost \\TYPE t = \\type(B<T>);\n" +
" //@ ghost \\TYPE v = \\type(T);\n" +
" }\n" +
"}\n"
);
}
@Test
public void testBad() {
helpTCF("A.java",
"public class A { \n" +
" void m() {\n" +
" Class<?> c = Object.class; Object o = c; \n" +
" //@ ghost \\TYPE t = Object.class;\n" + // NO mixing
" //@ ghost Class<?> cc = t;\n" + // NO mixing
" //@ ghost boolean b = \\type(Object) == Object.class;\n" + // No mixing
" //@ ghost Object oo = \\type(Object);\n" + // \TYPE will box
" //@ set b = t <: Object.class;\n" + // No mixing
" //@ set b = Object.class <: t;\n" + // No mixing
" //@ set b = c instanceof \\type(Object);\n" + // No mixing
" //@ set b = t instanceof Object;\n" + // \Type is a primitive
" //@ set t = (\\TYPE)0;\n" + // No casts of ints
" //@ set t = (\\TYPE)o;\n" + // No casts of Object
"}}\n"
,"/A.java:4: incompatible types: java.lang.Class<java.lang.Object> cannot be converted to \\TYPE",29
,"/A.java:5: incompatible types: \\TYPE cannot be converted to java.lang.Class<?>",27
,"/A.java:6: incomparable types: \\TYPE and java.lang.Class<java.lang.Object>",39
,"/A.java:8: The arguments to <: must both be \\TYPE or both be Class",26
,"/A.java:9: The arguments to <: must both be \\TYPE or both be Class",31
,"/A.java:10: unexpected type\n required: class\n found: value",33
,"/A.java:11: unexpected type\n required: reference\n found: \\TYPE",15
,"/A.java:12: A cast to \\TYPE may be applied only to expressions of type Class, not int",22
,"/A.java:13: A cast to \\TYPE may be applied only to expressions of type Class, not java.lang.Object",22
);
}
@Test
public void testBadJava() {
helpTCF("A.java",
"public class A<T extends java.io.File> { \n" +
" void m() {\n" +
" Class<?> c = T.class; \n" +
"}}\n"
,"/A.java:3: cannot select from a type variable",17
);
}
@Test
public void testBadJava2() {
helpTCF("A.java",
"public class A<T extends java.io.File> { \n" +
" void m() {\n" +
" Class<?> c = A<T>.class; \n" +
"}}\n"
,"/A.java:3: <identifier> expected",21
);
}
}