import java.util.Map;
import org.checkerframework.checker.nullness.qual.*;
public class ParameterExpression {
public void m1(
@Nullable Object o, @Nullable Object o1, @Nullable Object o2, @Nullable Object o3) {
//:: error: (flowexpr.parse.error)
m2(o);
//:: error: (dereference.of.nullable)
o.toString();
m3(o);
o.toString();
m4(o1, o2, o3);
//:: error: (dereference.of.nullable)
o1.toString();
//:: error: (dereference.of.nullable)
o2.toString();
o3.toString();
}
@SuppressWarnings("assert.postcondition.not.satisfied")
// "#0" is illegal syntax; it should be "#1"
@EnsuresNonNull("#0")
//:: error: (flowexpr.parse.error)
public void m2(final @Nullable Object o) {}
@SuppressWarnings("contracts.postcondition.not.satisfied")
@EnsuresNonNull("#1")
public void m3(final @Nullable Object o) {}
@SuppressWarnings("contracts.postcondition.not.satisfied")
@EnsuresNonNull("#3")
public void m4(@Nullable Object x1, @Nullable Object x2, final @Nullable Object x3) {}
// Formal parameter names should not be used on pre/postcondition, conditional postcondition
// and formal parameter annotations in the same method declaration as the formal parameter
// being referred. In this case, "#paramNum" should be used. This is because
// the parameter names are not saved in bytecode.
@Nullable Object field = null;
// Postconditions
@EnsuresNonNull("field") // OK
public void m5() {
field = new Object();
}
@EnsuresNonNull("param")
//:: error: (flowexpr.parse.error) :: warning: (contracts.postcondition.expression.parameter.name)
public void m6(Object param) {
param = new Object();
}
// Warning issued. 'field' is a field, but in this case what matters is that it is the name of a formal parameter.
@EnsuresNonNull("field")
// The user can write "#1" if they meant the formal parameter, and "this.field" if they meant the field.
//:: error: (contracts.postcondition.not.satisfied) :: warning: (contracts.postcondition.expression.parameter.name)
public void m7(Object field) {
field = new Object();
}
// Preconditions
@RequiresNonNull("field") // OK
public void m8() {}
@RequiresNonNull("param")
//:: error: (flowexpr.parse.error) :: warning: (contracts.precondition.expression.parameter.name)
public void m9(Object param) {}
// Warning issued. 'field' is a field, but in this case what matters is that it is the name of a formal parameter.
@RequiresNonNull("field")
// The user can write "#1" if they meant the formal parameter, and "this.field" if they meant the field.
//:: warning: (contracts.precondition.expression.parameter.name)
public void m10(Object field) {}
// Conditional postconditions
@EnsuresNonNullIf(result = true, expression = "field") // OK
public boolean m11() {
field = new Object();
return true;
}
@EnsuresNonNullIf(result = true, expression = "param")
//:: error: (flowexpr.parse.error) :: warning: (contracts.conditional.postcondition.expression.parameter.name)
public boolean m12(Object param) {
param = new Object();
return true;
}
// Warning issued. 'field' is a field, but in this case what matters is that it is the name of a formal parameter.
@EnsuresNonNullIf(result = true, expression = "field")
// The user can write "#1" if they meant the formal parameter, and "this.field" if they meant the field.
//:: warning: (contracts.conditional.postcondition.expression.parameter.name)
public boolean m13(Object field) {
field = new Object();
//:: error: (contracts.conditional.postcondition.not.satisfied)
return true;
}
// Annotations on formal parameters referring to a formal parameter of the same method.
//:: error: (expression.unparsable.type.invalid)
public void m14(@KeyFor("param2") Object param1, Map<Object, Object> param2) {}
}