package chapter;
import org.checkerframework.checker.lock.qual.GuardSatisfied;
import org.checkerframework.checker.lock.qual.GuardedBy;
import org.checkerframework.checker.lock.qual.GuardedByBottom;
import org.checkerframework.checker.lock.qual.GuardedByUnknown;
public class Strings {
final Object lock = new Object();
// Tests that @GuardedBy({}) is @ImplicitFor(typeNames = { java.lang.String.class })
void StringIsGBnothing(
@GuardedByUnknown Object o1,
@GuardedBy("lock") Object o2,
@GuardSatisfied Object o3,
@GuardedByBottom Object o4) {
//:: error: (assignment.type.incompatible)
String s1 = (String) o1;
//:: error: (assignment.type.incompatible)
String s2 = (String) o2;
//:: error: (assignment.type.incompatible)
String s3 = (String) o3;
String s4 = (String) o4; // OK
}
// Tests that the resulting type of string concatenation is always @GuardedBy({})
// (and not @GuardedByUnknown, which is the LUB of @GuardedBy({}) (the type of the
// string literal "a") and @GuardedBy("lock") (the type of param))
void StringConcat(@GuardedBy("lock") MyClass param) {
{
String s1a = "a" + "a";
//:: error: (lock.not.held)
String s1b = "a" + param;
//:: error: (lock.not.held)
String s1c = param + "a";
//:: error: (lock.not.held)
String s1d = param.toString();
String s2 = "a";
//:: error: (lock.not.held)
s2 += param;
String s3 = "a";
// In addition to testing whether "lock" is held, tests that the result of a string concatenation has type @GuardedBy({}).
//:: error: (lock.not.held)
String s4 = s3 += param;
}
synchronized (lock) {
String s1a = "a" + "a";
String s1b = "a" + param;
String s1c = param + "a";
String s1d = param.toString();
String s2 = "a";
s2 += param;
String s3 = "a";
// In addition to testing whether "lock" is held, tests that the result of a string concatenation has type @GuardedBy({}).
String s4 = s3 += param;
}
}
class MyClass {
Object field = new Object();
}
}