1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
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();
}
}
|