| import java.util.HashMap; |
| import java.util.Vector; |
| import org.checkerframework.checker.nullness.qual.*; |
| |
| public class KeyForFlow extends HashMap<String, Object> { |
| |
| String k = "key"; |
| HashMap<String, Object> m = new HashMap<>(); |
| |
| void testContainsKeyForLocalKeyAndLocalMap() { |
| String k_local = "key"; |
| HashMap<String, Object> m_local = new HashMap<>(); |
| |
| if (m_local.containsKey(k_local)) { |
| @KeyFor("m_local") Object s = k_local; |
| } |
| |
| // :: error: (assignment) |
| @KeyFor("m_local") String s2 = k_local; |
| } |
| |
| void testContainsKeyForLocalKeyAndFieldMap() { |
| String k_local = "key"; |
| |
| if (m.containsKey(k_local)) { |
| @KeyFor("m") Object s = k_local; |
| } |
| |
| // :: error: (assignment) |
| @KeyFor("m") String s2 = k_local; |
| } |
| |
| void testContainsKeyForFieldKeyAndLocalMap() { |
| HashMap<String, Object> m_local = new HashMap<>(); |
| |
| if (m_local.containsKey(k)) { |
| @KeyFor("m_local") Object s = k; |
| } |
| |
| // :: error: (assignment) |
| @KeyFor("m_local") String s2 = k; |
| } |
| |
| void testContainsKeyForFieldKeyAndFieldMap() { |
| if (m.containsKey(k)) { |
| @KeyFor("m") Object s = k; |
| } |
| |
| // :: error: (assignment) |
| @KeyFor("m") String s2 = k; |
| } |
| |
| static String k_s = "key"; |
| |
| void testContainsKeyForStaticKeyAndFieldMap() { |
| if (m.containsKey(k_s)) { |
| @KeyFor("m") Object s = k_s; |
| } |
| |
| // :: error: (assignment) |
| @KeyFor("m") String s2 = k_s; |
| } |
| |
| static HashMap<String, Object> m_s = new HashMap<>(); |
| |
| void testContainsKeyForFieldKeyAndStaticMap() { |
| if (m_s.containsKey(k)) { |
| // Currently for this to work, the user must write @KeyFor("classname.static_field") |
| @KeyFor("m_s") Object s = k; |
| } |
| |
| // :: error: (assignment) |
| @KeyFor("m_s") String s2 = k; |
| } |
| |
| void testContainsKeyForFieldKeyAndReceiverMap() { |
| if (containsKey(k)) { |
| @KeyFor("this") Object s = k; |
| } |
| |
| // :: error: (assignment) |
| @KeyFor("this") String s2 = k; |
| } |
| |
| // TODO: The diamond operator does not work here: |
| // Vector<@KeyFor("m2") String> coll = new Vector<>(); |
| // Figure out why not. |
| Vector<@KeyFor("m2") String> coll = new Vector<@KeyFor("m2") String>(); |
| HashMap<String, Object> m2 = new HashMap<>(); |
| String k2 = "key2"; |
| |
| void testCallingPutAfterAdd() { |
| // :: error: (argument) |
| coll.add(k2); |
| m2.put(k2, new Object()); |
| } |
| |
| void testPutForLocalKeyAndLocalMap() { |
| HashMap<String, Object> m2_local = new HashMap<>(); |
| Vector<@KeyFor("m2_local") String> coll_local = new Vector<>(); |
| String k2_local = "key2"; |
| |
| m2_local.put(k2_local, new Object()); |
| coll_local.add(k2_local); |
| } |
| |
| void testPutForLocalKeyAndFieldMap() { |
| String k2_local = "key2"; |
| |
| m2.put(k2_local, new Object()); |
| coll.add(k2_local); |
| } |
| |
| void testPutForFieldKeyAndLocalMap() { |
| HashMap<String, Object> m2_local = new HashMap<>(); |
| Vector<@KeyFor("m2_local") String> coll_local = new Vector<>(); |
| |
| m2_local.put(k2, new Object()); |
| coll_local.add(k2); |
| } |
| |
| void testPutForFieldKeyAndFieldMap() { |
| m2.put(k2, new Object()); |
| coll.add(k2); |
| } |
| |
| /* |
| This scenario is not working since in Vector, "this" gets translated to "coll_local". |
| The same thing happens if the collection is a field instead of a local. |
| However this seems like a low-priority scenario to enable. |
| |
| void testPutForFieldKeyAndReceiverMap() { |
| Vector<@KeyFor("this") String> coll_local = new Vector<>(); |
| |
| put(k2, new Object()); |
| coll_local.add(k2); |
| }*/ |
| |
| class foo { |
| public HashMap<String, Object> m = new HashMap<>(); |
| } |
| |
| void testContainsKeyForFieldKeyAndMapFieldOfOtherClass() { |
| foo f = new foo(); |
| |
| if (f.m.containsKey(k)) { |
| @KeyFor("f.m") Object s = k; |
| } |
| |
| // :: error: (assignment) |
| @KeyFor("f.m") String s2 = k; |
| } |
| |
| void testPutForFieldKeyAndMapFieldOfOtherClass() { |
| foo f = new foo(); |
| Vector<@KeyFor("f.m") String> coll_local = new Vector<>(); |
| f.m.put(k2, new Object()); |
| coll_local.add(k2); |
| } |
| |
| /*public void testAddToListInsteadOfMap(List<@KeyFor("#4") String> la, String b, @KeyFor("#4") String c, Map<String, String> a) { |
| // Disabled error (assignment) |
| List<String> ls1 = la; |
| List<@KeyFor("#4") String> ls2 = la; |
| ls1.add(b); |
| // Disabled error (argument) |
| la.add(b); |
| ls2.add(c); |
| la.add(c); |
| @NonNull String astr = a.get(ls2.get(0)); |
| }*/ |
| } |