Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bb09cbb
Sound annotations about Object parameters in collection methods
mernst Jan 18, 2020
a14c93a
Fix annotation
mernst Jan 18, 2020
ccf4b75
HashMap permits null keys and values
mernst Jan 25, 2020
414c68f
ArrayList permits null elements
mernst Jan 30, 2020
4dd1653
LinkedList permits null elements
mernst Jan 30, 2020
0cd188a
Reinstate purity annotations
mernst Mar 11, 2020
de03f16
Add purity annotation
mernst Mar 11, 2020
fba7d28
Merge ../jdk-branch-master into collection-object-parameters-may-be-null
mernst Mar 11, 2020
e5c7f8e
Merge ../jdk-branch-master into collection-object-parameters-may-be-null
mernst Mar 11, 2020
b0db19d
Merge ../jdk-branch-master into collection-object-parameters-may-be-null
mernst Mar 11, 2020
fa8cd05
Checkpoint
mernst Mar 12, 2020
aeeb4c9
Make null-friendly classes null-friendly
mernst Mar 12, 2020
2dde4fd
Complete JDK annotations about collection Object parameters
mernst Mar 12, 2020
c437513
Concurrent bulk operations forbid null elements
mernst Mar 25, 2020
7b5325f
Add import statement
mernst Mar 25, 2020
333ca8f
More consistent interpretation of "such that o.equals(e)"
mernst Mar 25, 2020
3605ba4
Add import statement
mernst Mar 25, 2020
f642cdc
Merge ../jdk-branch-master into collection-object-parameters-may-be-null
mernst Mar 25, 2020
1959d14
Add import
mernst Mar 25, 2020
e32a9a2
Add import
mernst Mar 25, 2020
84804f4
Add import
mernst Mar 25, 2020
649224f
Remove comment
mernst Mar 25, 2020
5c434e5
Add import
mernst Mar 25, 2020
e35a2a3
Add import
mernst Mar 25, 2020
56b90a1
Clean up BlockingQueue and BlockingDeque
mernst Mar 25, 2020
180371c
Fix ConcurrentSkipListSet
mernst Mar 25, 2020
ff567b9
Add import
mernst Mar 26, 2020
a7a5237
Add import statement
mernst Mar 26, 2020
97f5a6f
Add import statement
mernst Mar 26, 2020
25c6994
Improved nullness annotations
mernst Mar 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/java.base/share/classes/java/lang/reflect/Field.java
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ public String toGenericString(@GuardSatisfied Field this) {
@SideEffectFree
@CallerSensitive
@ForceInline // to ensure Reflection.getCallerClass optimization
public @Nullable Object get(@GuardSatisfied Field this, @UnknownInitialization @GuardSatisfied @Nullable Object obj)
public @Nullable Object get(@GuardSatisfied Field this, @UnknownInitialization @GuardSatisfied Object obj)
throws IllegalArgumentException, IllegalAccessException
{
if (!override) {
Expand Down
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/util/AbstractCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public boolean isEmpty(@GuardSatisfied AbstractCollection<E> this) {
*/
@Override
@Pure
public boolean contains(@GuardSatisfied AbstractCollection<E> this, @GuardSatisfied @Nullable Object o) {
public boolean contains(@GuardSatisfied AbstractCollection<E> this, @GuardSatisfied Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
Expand Down Expand Up @@ -309,7 +309,7 @@ public boolean add(@GuardSatisfied AbstractCollection<E> this, E e) {
* @throws NullPointerException {@inheritDoc}
*/
@Override
public boolean remove(@GuardSatisfied AbstractCollection<E> this, @Nullable Object o) {
public boolean remove(@GuardSatisfied AbstractCollection<E> this, Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext()) {
Expand Down
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/util/AbstractList.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public E remove(@GuardSatisfied AbstractList<E> this, @IndexFor({"this"}) int in
* @throws NullPointerException {@inheritDoc}
*/
@Pure
public @GTENegativeOne int indexOf(@GuardSatisfied AbstractList<E> this, @GuardSatisfied @Nullable Object o) {
public @GTENegativeOne int indexOf(@GuardSatisfied AbstractList<E> this, @GuardSatisfied Object o) {
ListIterator<E> it = listIterator();
if (o==null) {
while (it.hasNext())
Expand All @@ -222,7 +222,7 @@ public E remove(@GuardSatisfied AbstractList<E> this, @IndexFor({"this"}) int in
* @throws NullPointerException {@inheritDoc}
*/
@Pure
public @GTENegativeOne int lastIndexOf(@GuardSatisfied AbstractList<E> this, @GuardSatisfied @Nullable Object o) {
public @GTENegativeOne int lastIndexOf(@GuardSatisfied AbstractList<E> this, @GuardSatisfied Object o) {
ListIterator<E> it = listIterator(size());
if (o==null) {
while (it.hasPrevious())
Expand Down
8 changes: 4 additions & 4 deletions src/java.base/share/classes/java/util/AbstractMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public boolean isEmpty(@GuardSatisfied AbstractMap<K, V> this) {
* @throws NullPointerException {@inheritDoc}
*/
@Pure
public boolean containsValue(@GuardSatisfied AbstractMap<K, V> this, @GuardSatisfied @Nullable Object value) {
public boolean containsValue(@GuardSatisfied AbstractMap<K, V> this, @GuardSatisfied Object value) {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (value==null) {
while (i.hasNext()) {
Expand Down Expand Up @@ -160,7 +160,7 @@ public boolean containsValue(@GuardSatisfied AbstractMap<K, V> this, @GuardSatis
*/
@EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"})
@Pure
public boolean containsKey(@GuardSatisfied AbstractMap<K, V> this, @GuardSatisfied @Nullable Object key) {
public boolean containsKey(@GuardSatisfied AbstractMap<K, V> this, @GuardSatisfied Object key) {
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Expand Down Expand Up @@ -193,7 +193,7 @@ public boolean containsKey(@GuardSatisfied AbstractMap<K, V> this, @GuardSatisfi
* @throws NullPointerException {@inheritDoc}
*/
@Pure
public @Nullable V get(@GuardSatisfied AbstractMap<K, V> this, @GuardSatisfied @Nullable Object key) {
public @Nullable V get(@GuardSatisfied AbstractMap<K, V> this, @GuardSatisfied Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Expand Down Expand Up @@ -254,7 +254,7 @@ public boolean containsKey(@GuardSatisfied AbstractMap<K, V> this, @GuardSatisfi
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public @Nullable V remove(@GuardSatisfied AbstractMap<K, V> this, @Nullable Object key) {
public @Nullable V remove(@GuardSatisfied AbstractMap<K, V> this, Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
Entry<K,V> correctEntry = null;
if (key==null) {
Expand Down
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/util/ArrayDeque.java
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ public E getLast(@GuardSatisfied ArrayDeque<E> this) {
* @param o element to be removed from this deque, if present
* @return {@code true} if the deque contained the specified element
*/
public boolean removeFirstOccurrence(@GuardSatisfied ArrayDeque<E> this, Object o) {
public boolean removeFirstOccurrence(@GuardSatisfied ArrayDeque<E> this, @Nullable Object o) {
if (o != null) {
final Object[] es = elements;
for (int i = head, end = tail, to = (i <= end) ? end : es.length;
Expand Down Expand Up @@ -475,7 +475,7 @@ public boolean removeFirstOccurrence(@GuardSatisfied ArrayDeque<E> this, Object
* @param o element to be removed from this deque, if present
* @return {@code true} if the deque contained the specified element
*/
public boolean removeLastOccurrence(@GuardSatisfied ArrayDeque<E> this, Object o) {
public boolean removeLastOccurrence(@GuardSatisfied ArrayDeque<E> this, @Nullable Object o) {
if (o != null) {
final Object[] es = elements;
for (int i = tail, end = head, to = (i >= end) ? end : 0;
Expand Down
12 changes: 6 additions & 6 deletions src/java.base/share/classes/java/util/ArrayList.java
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ public boolean contains(@GuardSatisfied ArrayList<E> this, @GuardSatisfied @Null
return indexOfRange(o, 0, size);
}

int indexOfRange(Object o, int start, int end) {
int indexOfRange(@Nullable Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = start; i < end; i++) {
Expand Down Expand Up @@ -365,7 +365,7 @@ int indexOfRange(Object o, int start, int end) {
return lastIndexOfRange(o, 0, size);
}

int lastIndexOfRange(Object o, int start, int end) {
int lastIndexOfRange(@Nullable Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = end - 1; i >= start; i--) {
Expand Down Expand Up @@ -1297,7 +1297,7 @@ public <T> T[] toArray(T[] a) {
return a;
}

public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (o == this) {
return true;
}
Expand All @@ -1317,19 +1317,19 @@ public int hashCode() {
return hash;
}

public int indexOf(Object o) {
public int indexOf(@Nullable Object o) {
int index = root.indexOfRange(o, offset, offset + size);
checkForComodification();
return index >= 0 ? index - offset : -1;
}

public int lastIndexOf(Object o) {
public int lastIndexOf(@Nullable Object o) {
int index = root.lastIndexOfRange(o, offset, offset + size);
checkForComodification();
return index >= 0 ? index - offset : -1;
}

public boolean contains(Object o) {
public boolean contains(@Nullable Object o) {
return indexOf(o) >= 0;
}

Expand Down
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/util/Collection.java
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ public interface Collection<E> extends Iterable<E> {
*/
@CFComment({"lock: not true, because map could contain nulls: AssertParametersNonNull(\"get(#1)\")"})
@Pure
boolean contains(@GuardSatisfied Collection<E> this, @GuardSatisfied @Nullable Object o);
boolean contains(@GuardSatisfied Collection<E> this, @GuardSatisfied Object o);

/**
* Returns an iterator over the elements in this collection. There are no
Expand Down Expand Up @@ -460,7 +460,7 @@ default <T> T[] toArray(IntFunction<T[]> generator) {
* @throws UnsupportedOperationException if the {@code remove} operation
* is not supported by this collection
*/
boolean remove(@GuardSatisfied Collection<E> this, @Nullable Object o);
boolean remove(@GuardSatisfied Collection<E> this, Object o);


// Bulk Operations
Expand Down
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/util/Deque.java
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ public interface Deque<E> extends Queue<E> {
* deque does not permit null elements
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
*/
boolean remove(@GuardSatisfied Deque<E> this, @Nullable Object o);
boolean remove(@GuardSatisfied Deque<E> this, Object o);

/**
* Returns {@code true} if this deque contains the specified element.
Expand All @@ -597,7 +597,7 @@ public interface Deque<E> extends Queue<E> {
* (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>)
*/
@Pure
boolean contains(@GuardSatisfied Deque<E> this, @Nullable Object o);
boolean contains(@GuardSatisfied Deque<E> this, Object o);

/**
* Returns the number of elements in this deque.
Expand Down
2 changes: 1 addition & 1 deletion src/java.base/share/classes/java/util/Dictionary.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public Dictionary() {
* @see java.util.Dictionary#put(java.lang.Object, java.lang.Object)
*/
@Pure
public abstract @Nullable V get(@GuardSatisfied Dictionary<K, V> this, @Nullable Object key);
public abstract @Nullable V get(@GuardSatisfied Dictionary<K, V> this, Object key);

/**
* Maps the specified {@code key} to the specified
Expand Down
6 changes: 3 additions & 3 deletions src/java.base/share/classes/java/util/EnumMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public EnumMap(Map<K, ? extends V> m) {
* @return {@code true} if this map maps one or more keys to this value
*/
@Pure
public boolean containsValue(@Nullable Object value) {
public boolean containsValue(Object value) {
value = maskNull(value);

for (Object val : vals)
Expand All @@ -232,7 +232,7 @@ public boolean containsValue(@Nullable Object value) {
*/
@EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"})
@Pure
public boolean containsKey(@Nullable Object key) {
public boolean containsKey(Object key) {
return isValidKey(key) && vals[((Enum<?>)key).ordinal()] != null;
}

Expand All @@ -256,7 +256,7 @@ private boolean containsMapping(@Nullable Object key, @Nullable Object value) {
* The {@link #containsKey containsKey} operation may be used to
* distinguish these two cases.
*/
public @Nullable V get(@Nullable Object key) {
public @Nullable V get(Object key) {
return (isValidKey(key) ?
unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
}
Expand Down
20 changes: 10 additions & 10 deletions src/java.base/share/classes/java/util/HashMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ public final boolean equals(Object o) {
* to incorporate impact of the highest bits that would otherwise
* never be used in index calculations because of table bounds.
*/
static final int hash(Object key) {
static final int hash(@Nullable Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Expand Down Expand Up @@ -574,7 +574,7 @@ public boolean isEmpty(@GuardSatisfied HashMap<K, V> this) {
* @param key the key
* @return the node, or null if none
*/
final Node<K,V> getNode(int hash, Object key) {
final Node<K,V> getNode(int hash, @Nullable Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
Expand Down Expand Up @@ -824,7 +824,7 @@ public void putAll(@GuardSatisfied HashMap<K, V> this, Map<? extends K, ? extend
* @param movable if false do not move other nodes while removing
* @return the node, or null if none
*/
final Node<K,V> removeNode(int hash, Object key, Object value,
final Node<K,V> removeNode(int hash, @Nullable Object key, @Nullable Object value,
boolean matchValue, boolean movable) {
Node<K,V>[] tab; Node<K,V> p; int n, index;
if ((tab = table) != null && (n = tab.length) > 0 &&
Expand Down Expand Up @@ -933,8 +933,8 @@ final class KeySet extends AbstractSet<K> {
public final void clear() { HashMap.this.clear(); }
@SideEffectFree
public final Iterator<K> iterator() { return new KeyIterator(); }
public final boolean contains(Object o) { return containsKey(o); }
public final boolean remove(Object key) {
public final boolean contains(@Nullable Object o) { return containsKey(o); }
public final boolean remove(@Nullable Object key) {
return removeNode(hash(key), key, null, false, true) != null;
}
@SideEffectFree
Expand Down Expand Up @@ -988,7 +988,7 @@ final class Values extends AbstractCollection<V> {
public final void clear() { HashMap.this.clear(); }
@SideEffectFree
public final Iterator<V> iterator() { return new ValueIterator(); }
public final boolean contains(Object o) { return containsValue(o); }
public final boolean contains(@Nullable Object o) { return containsValue(o); }
@SideEffectFree
public final Spliterator<V> spliterator() {
return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0);
Expand Down Expand Up @@ -1039,15 +1039,15 @@ final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public final Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();
}
public final boolean contains(Object o) {
public final boolean contains(@Nullable Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Node<K,V> candidate = getNode(hash(key), key);
return candidate != null && candidate.equals(e);
}
public final boolean remove(Object o) {
public final boolean remove(@Nullable Object o) {
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Expand Down Expand Up @@ -1079,7 +1079,7 @@ public final void forEach(Consumer<? super Map.Entry<K,V>> action) {
// Overrides of JDK8 Map extension methods

@Override
public V getOrDefault(Object key, V defaultValue) {
public V getOrDefault(@Nullable Object key, V defaultValue) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? defaultValue : e.value;
}
Expand All @@ -1091,7 +1091,7 @@ public V getOrDefault(Object key, V defaultValue) {
}

@Override
public boolean remove(Object key, Object value) {
public boolean remove(@Nullable Object key, @Nullable Object value) {
return removeNode(hash(key), key, value, true, true) != null;
}

Expand Down
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/util/Hashtable.java
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ public synchronized boolean contains(@GuardSatisfied Hashtable<K, V> this, @Guar
* @since 1.2
*/
@Pure
public boolean containsValue(@GuardSatisfied Hashtable<K, V> this, @GuardSatisfied @Nullable Object value) {
public boolean containsValue(@GuardSatisfied Hashtable<K, V> this, @GuardSatisfied Object value) {
return contains(value);
}

Expand All @@ -367,7 +367,7 @@ public boolean containsValue(@GuardSatisfied Hashtable<K, V> this, @GuardSatisfi
*/
@EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"})
@Pure
public synchronized boolean containsKey(@GuardSatisfied Hashtable<K, V> this, @GuardSatisfied @Nullable Object key) {
public synchronized boolean containsKey(@GuardSatisfied Hashtable<K, V> this, @GuardSatisfied Object key) {
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
Expand Down
20 changes: 10 additions & 10 deletions src/java.base/share/classes/java/util/IdentityHashMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ private static int nextKeyIndex(int i, int len) {
*/
@Pure
@SuppressWarnings("unchecked")
public @Nullable V get(@GuardSatisfied IdentityHashMap<K, V> this, @GuardSatisfied Object key) {
public @Nullable V get(@GuardSatisfied IdentityHashMap<K, V> this, @GuardSatisfied @Nullable Object key) {
Object k = maskNull(key);
Object[] tab = table;
int len = tab.length;
Expand All @@ -364,7 +364,7 @@ private static int nextKeyIndex(int i, int len) {
*/
@EnsuresKeyForIf(expression={"#1"}, result=true, map={"this"})
@Pure
public boolean containsKey(@GuardSatisfied IdentityHashMap<K, V> this, @GuardSatisfied Object key) {
public boolean containsKey(@GuardSatisfied IdentityHashMap<K, V> this, @GuardSatisfied @Nullable Object key) {
Object k = maskNull(key);
Object[] tab = table;
int len = tab.length;
Expand All @@ -389,7 +389,7 @@ public boolean containsKey(@GuardSatisfied IdentityHashMap<K, V> this, @GuardSat
* @see #containsKey(Object)
*/
@Pure
public boolean containsValue(@GuardSatisfied IdentityHashMap<K, V> this, @GuardSatisfied Object value) {
public boolean containsValue(@GuardSatisfied IdentityHashMap<K, V> this, @GuardSatisfied @Nullable Object value) {
Object[] tab = table;
for (int i = 1; i < tab.length; i += 2)
if (tab[i] == value && tab[i - 1] != null)
Expand Down Expand Up @@ -536,7 +536,7 @@ public void putAll(@GuardSatisfied IdentityHashMap<K, V> this, Map<? extends K,
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with {@code key}.)
*/
public @Nullable V remove(@GuardSatisfied IdentityHashMap<K, V> this, Object key) {
public @Nullable V remove(@GuardSatisfied IdentityHashMap<K, V> this, @Nullable Object key) {
Object k = maskNull(key);
Object[] tab = table;
int len = tab.length;
Expand Down Expand Up @@ -1005,10 +1005,10 @@ public Iterator<K> iterator() {
public @NonNegative int size() {
return size;
}
public boolean contains(Object o) {
public boolean contains(@Nullable Object o) {
return containsKey(o);
}
public boolean remove(Object o) {
public boolean remove(@Nullable Object o) {
int oldSize = size;
IdentityHashMap.this.remove(o);
return size != oldSize;
Expand Down Expand Up @@ -1117,10 +1117,10 @@ public Iterator<V> iterator() {
public @NonNegative int size() {
return size;
}
public boolean contains(Object o) {
public boolean contains(@Nullable Object o) {
return containsValue(o);
}
public boolean remove(Object o) {
public boolean remove(@Nullable Object o) {
for (Iterator<V> i = iterator(); i.hasNext(); ) {
if (i.next() == o) {
i.remove();
Expand Down Expand Up @@ -1223,13 +1223,13 @@ private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();
}
public boolean contains(Object o) {
public boolean contains(@Nullable Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
return containsMapping(entry.getKey(), entry.getValue());
}
public boolean remove(Object o) {
public boolean remove(@Nullable Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
Expand Down
Loading