import org.checkerframework.framework.test.*;
import testlib.util.*;
class MetaPostcondition {
String f1, f2, f3;
MetaPostcondition p;
/** *** normal postcondition ***** */
@EnsuresOdd("f1")
void oddF1() {
f1 = null;
}
@EnsuresOdd("p.f1")
void oddF1_1() {
p.f1 = null;
}
@EnsuresOdd("#1.f1")
void oddF1_2(final MetaPostcondition param) {
param.f1 = null;
}
@EnsuresOdd("f1")
//:: error: (contracts.postcondition.not.satisfied)
void oddF1_error() {}
@EnsuresOdd("---")
//:: error: (flowexpr.parse.error)
void error() {}
@EnsuresOdd("#1.#2")
//:: error: (flowexpr.parse.error)
void error2(final String p1, final String p2) {}
@EnsuresOdd("f1")
void exception() {
throw new RuntimeException();
}
@EnsuresOdd("#1")
void param1(final @Odd String f) {}
@EnsuresOdd({"#1", "#2"})
//:: error: (flowexpr.parameter.not.final)
void param2(@Odd String f, @Odd String g) {
f = g;
}
@EnsuresOdd("#1")
//:: error: (flowexpr.parse.index.too.big)
void param3() {}
// basic postcondition test
void t1(@Odd String p1, String p2) {
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
oddF1();
@Odd String l2 = f1;
//:: error: (flowexpr.parse.error)
error();
}
// test parameter syntax
void t2(@Odd String p1, String p2) {
//:: error: (flowexpr.parse.index.too.big)
param3();
}
// postcondition with more complex flow expression
void tn1(boolean b) {
//:: error: (assignment.type.incompatible)
@Odd String l1 = p.f1;
oddF1_1();
@Odd String l2 = p.f1;
}
// postcondition with more complex flow expression
void tn2(boolean b) {
MetaPostcondition param = null;
//:: error: (assignment.type.incompatible)
@Odd String l1 = param.f1;
oddF1_2(param);
@Odd String l2 = param.f1;
}
// basic postcondition test
void tnm1(@Odd String p1, @Value String p2) {
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
//:: error: (assignment.type.incompatible)
@Value String l2 = f2;
//:: error: (flowexpr.parse.error)
error2(p1, p2);
}
/** *** conditional postcondition ***** */
@EnsuresOddIf(result = true, expression = "f1")
boolean condOddF1(boolean b) {
if (b) {
f1 = null;
return true;
}
return false;
}
@EnsuresOddIf(result = false, expression = "f1")
boolean condOddF1False(boolean b) {
if (b) {
return true;
}
f1 = null;
return false;
}
@EnsuresOddIf(result = false, expression = "f1")
boolean condOddF1Invalid(boolean b) {
if (b) {
f1 = null;
return true;
}
//:: error: (contracts.conditional.postcondition.not.satisfied)
return false;
}
@EnsuresOddIf(result = false, expression = "f1")
//:: error: (contracts.conditional.postcondition.invalid.returntype)
void wrongReturnType() {}
@EnsuresOddIf(result = false, expression = "f1")
//:: error: (contracts.conditional.postcondition.invalid.returntype)
String wrongReturnType2() {
f1 = null;
return "";
}
// basic conditional postcondition test
void t3(@Odd String p1, String p2) {
condOddF1(true);
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
if (condOddF1(false)) {
@Odd String l2 = f1;
}
//:: error: (assignment.type.incompatible)
@Odd String l3 = f1;
}
// basic conditional postcondition test (inverted)
void t4(@Odd String p1, String p2) {
condOddF1False(true);
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
if (!condOddF1False(false)) {
@Odd String l2 = f1;
}
//:: error: (assignment.type.incompatible)
@Odd String l3 = f1;
}
// basic conditional postcondition test 2
void t5(boolean b) {
condOddF1(true);
if (b) {
//:: error: (assignment.type.incompatible)
@Odd String l2 = f1;
}
}
}