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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Vector;
import org.checkerframework.checker.interning.qual.InternMethod;
import org.checkerframework.checker.interning.qual.Interned;
import org.checkerframework.checker.interning.qual.UnknownInterned;
// The @Interned annotation indicates that much like an enum, all variables
// declared of this type are interned (except the constructor return value).
public @Interned class InternedClass {
int value;
InternedClass factory(int i) {
return new InternedClass(i).intern();
}
// Private constructor
private InternedClass(int i) {
value = i;
// "this" in the constructor is not interned.
// :: error: (assignment.type.incompatible)
@Interned InternedClass that = this;
}
// Overriding method
@org.checkerframework.dataflow.qual.Pure
public String toString() {
@Interned InternedClass c = this;
return Integer.valueOf(value).toString();
}
// Factory method
private InternedClass(InternedClass ic) {
value = ic.value;
}
// Equals method (used only by interning; clients should use ==)
@org.checkerframework.dataflow.qual.Pure
public boolean equals(Object other) {
if (!(other instanceof InternedClass)) {
return false;
}
return value == ((InternedClass) other).value;
}
// Interning method
@SuppressWarnings("type.invalid.annotations.on.use")
private static Map<@UnknownInterned InternedClass, @Interned InternedClass> pool =
new HashMap<>();
@InternMethod
public @Interned InternedClass intern() {
if (!pool.containsKey(this)) {
pool.put(this, (@Interned InternedClass) this);
}
return pool.get(this);
}
public void myMethod(InternedClass ic, InternedClass[] ica) {
boolean b1 = (this == ic); // valid
boolean b2 = (this == returnInternedObject()); // valid
boolean b3 = (this == ica[0]); // valid
InternedClass ic2 = returnArray()[0]; // valid
// :: error: (interned.object.creation)
ica[0] = new InternedClass(22);
InternedClass[] arr1 = returnArray(); // valid
InternedClass[] arr2 = new InternedClass[22]; // valid
InternedClass[] arr3 = new InternedClass[] {}; // valid
Map<InternedClass, Integer> map = new LinkedHashMap<>();
for (Map.Entry<InternedClass, Integer> e : map.entrySet()) {
InternedClass ic3 = e.getKey(); // valid
}
}
public InternedClass returnInternedObject() {
return this;
}
public InternedClass[] returnArray() {
return new InternedClass[] {};
}
public void internedVarargs(String name, InternedClass... args) {
InternedClass arg = args[0]; // valid
}
public void internedVarargs2(String name, @Interned String... args) {
@Interned String arg = args[0]; // valid
}
public static InternedClass[] arrayclone_simple(InternedClass[] a_old) {
int len = a_old.length;
InternedClass[] a_new = new InternedClass[len];
for (int i = 0; i < len; i++) {
// :: error: (interned.object.creation)
a_new[i] = new InternedClass(a_old[i]);
}
return a_new;
}
public @Interned class Subclass extends InternedClass {
// Private constructor
private Subclass(int i) {
super(i);
}
}
public static void castFromInternedClass(InternedClass ic) {
Subclass s = (Subclass) ic;
}
public static void castToInternedClass(Object o) {
InternedClass ic = (InternedClass) o;
}
// Default implementation
@org.checkerframework.dataflow.qual.Pure
public InternedClass clone() throws CloneNotSupportedException {
return (InternedClass) super.clone();
}
// java.lang.Class should be considered interned
public static void classTest() {
Integer i = 5;
assert i.getClass() == Integer.class;
}
// java.lang.Class is interned
public static void arrayOfClass() throws Exception {
Class<?> c = String.class;
Class[] parameterTypes = new Class[1];
parameterTypes[0] = String.class;
java.lang.reflect.Constructor<?> ctor = c.getConstructor(parameterTypes);
}
Class[] getSuperClasses(Class<?> c) {
Vector<Class<?>> v = new Vector<>();
while (true) {
// :: warning: (unnecessary.equals)
if (c.getSuperclass().equals((new Object()).getClass())) {
break;
}
c = c.getSuperclass();
v.addElement(c);
}
return (Class[]) v.toArray(new Class[0]);
}
void testCast(Object o) {
Object i = (InternedClass) o;
if (i == this) ;
}
}
|