diff --git a/src/java.base/share/classes/java/io/InputStreamReader.java b/src/java.base/share/classes/java/io/InputStreamReader.java index 35b97099a499d..72e4d27bab62f 100644 --- a/src/java.base/share/classes/java/io/InputStreamReader.java +++ b/src/java.base/share/classes/java/io/InputStreamReader.java @@ -68,7 +68,7 @@ * @since 1.1 */ -@AnnotatedFor({"index", "mustcall"}) +@AnnotatedFor({"index", "mustcall", "nullness"}) public class InputStreamReader extends Reader { private final StreamDecoder sd; diff --git a/src/java.base/share/classes/java/util/Scanner.java b/src/java.base/share/classes/java/util/Scanner.java index 599ead80409f7..15432a85c1fa4 100644 --- a/src/java.base/share/classes/java/util/Scanner.java +++ b/src/java.base/share/classes/java/util/Scanner.java @@ -319,7 +319,7 @@ * * @since 1.5 */ -@AnnotatedFor({"index", "interning", "lock", "mustcall", "signedness"}) +@AnnotatedFor({"index", "interning", "lock", "mustcall", "nullness", "signedness"}) public final @UsesObjectEquals class Scanner implements Iterator, Closeable { // Internal buffer used to hold input @@ -1687,7 +1687,7 @@ public String nextLine(@GuardSatisfied Scanner this) { * @return the text that matched the specified pattern * @throws IllegalStateException if this scanner is closed */ - public String findInLine(String pattern) { + public @Nullable String findInLine(String pattern) { return findInLine(patternCache.forName(pattern)); } @@ -1709,7 +1709,7 @@ public String findInLine(String pattern) { * @return the text that matched the specified pattern * @throws IllegalStateException if this scanner is closed */ - public String findInLine(Pattern pattern) { + public @Nullable String findInLine(Pattern pattern) { ensureOpen(); if (pattern == null) throw new NullPointerException(); @@ -1756,7 +1756,7 @@ public String findInLine(Pattern pattern) { * @throws IllegalStateException if this scanner is closed * @throws IllegalArgumentException if horizon is negative */ - public String findWithinHorizon(String pattern, @NonNegative int horizon) { + public @Nullable String findWithinHorizon(String pattern, @NonNegative int horizon) { return findWithinHorizon(patternCache.forName(pattern), horizon); } @@ -1791,7 +1791,7 @@ public String findWithinHorizon(String pattern, @NonNegative int horizon) { * @throws IllegalStateException if this scanner is closed * @throws IllegalArgumentException if horizon is negative */ - public String findWithinHorizon(Pattern pattern, @NonNegative int horizon) { + public @Nullable String findWithinHorizon(Pattern pattern, @NonNegative int horizon) { ensureOpen(); if (pattern == null) throw new NullPointerException(); diff --git a/src/java.base/share/classes/java/util/WeakHashMap.java b/src/java.base/share/classes/java/util/WeakHashMap.java index 80bb00e2870a6..7b47a7d69fd50 100644 --- a/src/java.base/share/classes/java/util/WeakHashMap.java +++ b/src/java.base/share/classes/java/util/WeakHashMap.java @@ -145,7 +145,7 @@ * @see java.lang.ref.WeakReference */ @CFComment({"lock: permits null keys and values"}) -@AnnotatedFor({"lock", "index"}) +@AnnotatedFor({"lock", "index", "nullness"}) public class WeakHashMap extends AbstractMap implements Map { diff --git a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java index 57c5291c9b928..7a7220640a9ab 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -39,6 +39,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.CFComment; import java.lang.ref.WeakReference; import java.util.AbstractQueue; @@ -88,7 +90,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -public class ArrayBlockingQueue extends AbstractQueue +@AnnotatedFor({"nullness"}) +public class ArrayBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { /* @@ -510,7 +513,8 @@ public int remainingCapacity() { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ - public boolean remove(@Nullable Object o) { + @CFComment("probably accepts null in practice, but docs at best imply this") + public boolean remove(Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); @@ -542,7 +546,8 @@ public boolean remove(@Nullable Object o) { * @param o object to be checked for containment in this queue * @return {@code true} if this queue contains the specified element */ - public boolean contains(@Nullable Object o) { + @CFComment("probably accepts null in practice, but docs at best imply this") + public boolean contains(Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); @@ -1479,7 +1484,7 @@ public boolean removeIf(Predicate filter) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeAll(Collection c) { + public boolean removeAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1487,7 +1492,7 @@ public boolean removeAll(Collection c) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean retainAll(Collection c) { + public boolean retainAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java index 39d2b7ec60c3a..6d9fd23e143be 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -40,6 +40,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; +import org.checkerframework.framework.qual.AnnotatedFor; import java.lang.invoke.VarHandle; import java.lang.reflect.Field; @@ -97,6 +98,7 @@ * @author Doug Lea * @param the type of elements held in this list */ +@AnnotatedFor({"nullness"}) public class CopyOnWriteArrayList implements List, RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8673264195747942595L; @@ -263,7 +265,7 @@ public int indexOf(@Nullable Object o) { * {@code -1} if the element is not found. * @throws IndexOutOfBoundsException if the specified index is negative */ - public int indexOf(E e, int index) { + public int indexOf(@Nullable E e, int index) { Object[] es = getArray(); return indexOfRange(e, es, index, es.length); } @@ -292,7 +294,7 @@ public int lastIndexOf(@Nullable Object o) { * @throws IndexOutOfBoundsException if the specified index is greater * than or equal to the current size of this list */ - public int lastIndexOf(E e, int index) { + public int lastIndexOf(@Nullable E e, int index) { Object[] es = getArray(); return lastIndexOfRange(e, es, 0, index + 1); } @@ -659,7 +661,7 @@ public boolean containsAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ - public boolean removeAll(Collection c) { + public boolean removeAll(Collection<@Nullable ?> c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -680,7 +682,7 @@ public boolean removeAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ - public boolean retainAll(Collection c) { + public boolean retainAll(Collection<@Nullable ?> c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java index 620cc0e9b88f2..bcd3a35e14ba4 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -41,6 +41,7 @@ import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.SideEffectFree; +import org.checkerframework.framework.qual.AnnotatedFor; import java.util.AbstractSet; import java.util.Collection; @@ -102,6 +103,7 @@ * @author Doug Lea * @param the type of elements held in this set */ +@AnnotatedFor({"nullness"}) public class CopyOnWriteArraySet extends AbstractSet implements java.io.Serializable { private static final long serialVersionUID = 5457747651344034263L; @@ -356,7 +358,7 @@ public boolean addAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ - public boolean removeAll(Collection c) { + public boolean removeAll(Collection<@Nullable ?> c) { return al.removeAll(c); } @@ -379,7 +381,7 @@ public boolean removeAll(Collection c) { * or if the specified collection is null * @see #remove(Object) */ - public boolean retainAll(Collection c) { + public boolean retainAll(Collection<@Nullable ?> c) { return al.retainAll(c); } diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java index 536020fcdde1a..ee280ab2937c4 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -39,6 +39,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.CFComment; import java.util.AbstractQueue; import java.util.Collection; @@ -80,7 +82,8 @@ * @author Doug Lea * @param the type of elements held in this deque */ -public class LinkedBlockingDeque +@AnnotatedFor({"nullness"}) +public class LinkedBlockingDeque extends AbstractQueue implements BlockingDeque, java.io.Serializable { @@ -459,7 +462,7 @@ public E removeLast() { return x; } - public E pollFirst() { + public @Nullable E pollFirst() { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -469,7 +472,7 @@ public E pollFirst() { } } - public E pollLast() { + public @Nullable E pollLast() { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -505,7 +508,7 @@ public E takeLast() throws InterruptedException { } } - public E pollFirst(long timeout, TimeUnit unit) + public @Nullable E pollFirst(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -523,7 +526,7 @@ public E pollFirst(long timeout, TimeUnit unit) } } - public E pollLast(long timeout, TimeUnit unit) + public @Nullable E pollLast(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; @@ -559,7 +562,7 @@ public E getLast() { return x; } - public E peekFirst() { + public @Nullable E peekFirst() { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -569,7 +572,7 @@ public E peekFirst() { } } - public E peekLast() { + public @Nullable E peekLast() { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -579,6 +582,7 @@ public E peekLast() { } } + @CFComment("probably accepts null in practice, but docs at best imply this") public boolean removeFirstOccurrence(Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; @@ -596,6 +600,7 @@ public boolean removeFirstOccurrence(Object o) { } } + @CFComment("probably accepts null in practice, but docs at best imply this") public boolean removeLastOccurrence(Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; @@ -668,7 +673,7 @@ public E remove() { return removeFirst(); } - public E poll() { + public @Nullable E poll() { return pollFirst(); } @@ -676,7 +681,7 @@ public E take() throws InterruptedException { return takeFirst(); } - public E poll(long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E poll(long timeout, TimeUnit unit) throws InterruptedException { return pollFirst(timeout, unit); } @@ -694,7 +699,7 @@ public E element() { return getFirst(); } - public E peek() { + public @Nullable E peek() { return peekFirst(); } @@ -788,6 +793,7 @@ public E pop() { * @param o element to be removed from this deque, if present * @return {@code true} if this deque changed as a result of the call */ + @CFComment("probably accepts null in practice, but docs at best imply this") public boolean remove(Object o) { return removeFirstOccurrence(o); } @@ -816,7 +822,8 @@ public int size() { * @param o object to be checked for containment in this deque * @return {@code true} if this deque contains the specified element */ - public boolean contains(@Nullable Object o) { + @CFComment("probably accepts null in practice, but docs at best imply this") + public boolean contains(Object o) { if (o == null) return false; final ReentrantLock lock = this.lock; lock.lock(); @@ -1342,7 +1349,7 @@ public boolean removeIf(Predicate filter) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeAll(Collection c) { + public boolean removeAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1350,7 +1357,7 @@ public boolean removeAll(Collection c) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean retainAll(Collection c) { + public boolean retainAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java index 7a444647b791d..2ce7100511e40 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -39,6 +39,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.CFComment; import java.util.AbstractQueue; import java.util.Collection; @@ -83,7 +85,8 @@ * @author Doug Lea * @param the type of elements held in this queue */ -public class LinkedBlockingQueue extends AbstractQueue +@AnnotatedFor({"nullness"}) +public class LinkedBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { private static final long serialVersionUID = -6903933977591709194L; @@ -450,7 +453,7 @@ public E take() throws InterruptedException { return x; } - public E poll(long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E poll(long timeout, TimeUnit unit) throws InterruptedException { final E x; final int c; long nanos = unit.toNanos(timeout); @@ -475,7 +478,7 @@ public E poll(long timeout, TimeUnit unit) throws InterruptedException { return x; } - public E poll() { + public @Nullable E poll() { final AtomicInteger count = this.count; if (count.get() == 0) return null; @@ -498,7 +501,7 @@ public E poll() { return x; } - public E peek() { + public @Nullable E peek() { final AtomicInteger count = this.count; if (count.get() == 0) return null; @@ -538,7 +541,8 @@ void unlink(Node p, Node pred) { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ - public boolean remove(@Nullable Object o) { + @CFComment("probably accepts null in practice, but docs for remove at best imply this") + public boolean remove(Object o) { if (o == null) return false; fullyLock(); try { @@ -564,7 +568,8 @@ public boolean remove(@Nullable Object o) { * @param o object to be checked for containment in this queue * @return {@code true} if this queue contains the specified element */ - public boolean contains(@Nullable Object o) { + @CFComment("probably accepts null in practice, but docs for remove at best imply this") + public boolean contains(Object o) { if (o == null) return false; fullyLock(); try { @@ -1029,7 +1034,7 @@ public boolean removeIf(Predicate filter) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeAll(Collection c) { + public boolean removeAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1037,7 +1042,7 @@ public boolean removeAll(Collection c) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean retainAll(Collection c) { + public boolean retainAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); } diff --git a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java index ff017396e2071..e613a419734d8 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -39,6 +39,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.PolyNull; import org.checkerframework.dataflow.qual.Pure; +import org.checkerframework.framework.qual.AnnotatedFor; +import org.checkerframework.framework.qual.CFComment; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -115,8 +117,9 @@ * @author Doug Lea * @param the type of elements held in this queue */ +@AnnotatedFor({"nullness"}) @SuppressWarnings("unchecked") -public class PriorityBlockingQueue extends AbstractQueue +public class PriorityBlockingQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable { private static final long serialVersionUID = 5595510919245408276L; @@ -533,7 +536,7 @@ public boolean offer(E e, long timeout, TimeUnit unit) { return offer(e); // never need to block } - public E poll() { + public @Nullable E poll() { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -556,7 +559,7 @@ public E take() throws InterruptedException { return result; } - public E poll(long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E poll(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); @@ -570,7 +573,7 @@ public E poll(long timeout, TimeUnit unit) throws InterruptedException { return result; } - public E peek() { + public @Nullable E peek() { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -660,7 +663,8 @@ private void removeAt(int i) { * @param o element to be removed from this queue, if present * @return {@code true} if this queue changed as a result of the call */ - public boolean remove(@Nullable Object o) { + @CFComment("probably accepts null in practice, but docs at best imply this") + public boolean remove(Object o) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -703,7 +707,8 @@ void removeEq(Object o) { * @param o object to be checked for containment in this queue * @return {@code true} if this queue contains the specified element */ - public boolean contains(@Nullable Object o) { + @CFComment("probably accepts null in practice, but docs at best imply this") + public boolean contains(Object o) { final ReentrantLock lock = this.lock; lock.lock(); try { @@ -1034,7 +1039,7 @@ public boolean removeIf(Predicate filter) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean removeAll(Collection c) { + public boolean removeAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> c.contains(e)); } @@ -1042,7 +1047,7 @@ public boolean removeAll(Collection c) { /** * @throws NullPointerException {@inheritDoc} */ - public boolean retainAll(Collection c) { + public boolean retainAll(Collection c) { Objects.requireNonNull(c); return bulkRemove(e -> !c.contains(e)); }